<template>
|
<BaseCard size="medium">
|
<template #content>
|
<div ref="lineChart" class="line-chart"></div>
|
</template>
|
<template #footer>
|
<!-- 单页数据量-->
|
<SliderBar
|
v-model:progress="progress"
|
@size-change="(e) => (pageSize = e)"
|
></SliderBar>
|
</template>
|
</BaseCard>
|
</template>
|
|
<script>
|
import * as echarts from 'echarts';
|
import { FactorDatas } from '@/model/FactorDatas';
|
import { factorName } from '@/constant/factor-name';
|
import { factorLineOption } from '@/utils/chart/chart-option';
|
|
// 带可拖动进度条的折线图
|
export default {
|
props: {
|
loading: Boolean,
|
factorDatas: {
|
type: FactorDatas
|
// default: () => new FactorDatas()
|
},
|
selectFactorType: {
|
type: Array,
|
default: () => ['1']
|
},
|
// 当前选中高亮的数据点索引
|
locateIndex: Number
|
},
|
data() {
|
return {
|
allXAxis: [],
|
allSeries: [],
|
option: null,
|
pageSize: 200,
|
progress: 0,
|
// 对应progress进度下,所展示数据的起始索引
|
sIndex: 0
|
};
|
},
|
emits: ['chartClick'],
|
watch: {
|
factorDatas: {
|
handler() {
|
this.initData();
|
this.changeChartRange();
|
},
|
deep: true
|
},
|
selectFactorType: {
|
handler() {
|
this.changeChartSeries();
|
}
|
},
|
progress() {
|
this.changeChartRange();
|
},
|
pageSize() {
|
this.changeChartRange();
|
},
|
locateIndex(nV, oV) {
|
if (nV == oV) return;
|
for (const iterator of this.allSeries) {
|
// if (iterator.name == factorName || (iterator.name == 'TVOC' || factorName == 'VOC')) {
|
iterator.markLine = {
|
symbol: 'none',
|
data: [
|
{
|
name: '选中',
|
xAxis: this.allXAxis[nV],
|
label: {
|
color: 'white'
|
},
|
lineStyle: {
|
color: 'yellow'
|
}
|
}
|
]
|
};
|
}
|
// 计算超出单页数据量的长度
|
let len = this.allXAxis.length - this.pageSize;
|
len = len < 0 ? 0 : len;
|
// 定位点应该展示在趋势图中间,因此定位百分比往前偏移当前_size的一半
|
let i = nV - parseInt(this.pageSize / 2);
|
// 确保索引不会超出范围
|
i = i < 0 ? 0 : i;
|
i = i > len ? len : i;
|
// 获取索引对应的进度百分比
|
const _progress = (i / len) * 100;
|
if (this.progress != _progress) {
|
this.progress = _progress;
|
} else {
|
this.changeChartRange();
|
}
|
}
|
},
|
methods: {
|
initData() {
|
this.allXAxis = this.factorDatas.times.map((v) => {
|
return v.split(' ')[1];
|
});
|
const res = [];
|
for (const key in this.factorDatas.factor) {
|
if (Object.hasOwnProperty.call(this.factorDatas.factor, key)) {
|
const e = this.factorDatas.factor[key];
|
res.push({
|
key: key,
|
name: factorName[e.factorName],
|
type: 'line',
|
allData: e.datas.map((v) => v.factorData),
|
data: e.datas.map((v) => v.factorData),
|
showAllSymbol: true,
|
animationDelay: function (idx) {
|
return idx * 10;
|
}
|
});
|
}
|
}
|
this.allSeries = res;
|
},
|
// 修改图表展示的折线图类型
|
changeChartSeries() {
|
this.option.series = this.getShowSeries();
|
this.lineChart.setOption(this.option, { notMerge: true });
|
},
|
changeChartRange() {
|
const { sIndex, eIndex, startPer, endPer } = this.getRange();
|
const showSeries = this.getShowSeries(sIndex, eIndex);
|
const xAxis = this.getShowXAxis(sIndex, eIndex);
|
if (!this.option) {
|
this.option = factorLineOption(xAxis, showSeries);
|
} else {
|
this.option.xAxis.data = xAxis;
|
this.option.series = showSeries;
|
}
|
// this.option.dataZoom[0].start = startPer;
|
// this.option.dataZoom[0].end = endPer;
|
this.lineChart.setOption(this.option, { notMerge: true });
|
},
|
getShowXAxis(sIndex, eIndex) {
|
return this.allXAxis.slice(sIndex, eIndex);
|
},
|
getShowSeries(sIndex, eIndex) {
|
this.allSeries.forEach((s) => {
|
s.data = s.allData.slice(sIndex, eIndex);
|
});
|
const res = this.allSeries.filter((s) => {
|
return this.selectFactorType.includes(s.key);
|
});
|
return res;
|
},
|
getRange() {
|
let len = this.allXAxis.length - this.pageSize;
|
len = len < 0 ? 0 : len;
|
const sIndex = Math.round((len * this.progress) / 100);
|
const eIndex = sIndex + this.pageSize;
|
const startPer = (this.sIndex / this.allXAxis.length) * 100;
|
const endPer = (eIndex / this.allXAxis.length) * 100;
|
this.sIndex = sIndex;
|
return { sIndex, eIndex, startPer, endPer };
|
}
|
},
|
beforeUnmount() {
|
// this.$refs.lineChart && this.$refs.lineChart.clear();
|
},
|
mounted() {
|
this.lineChart = echarts.init(this.$refs.lineChart);
|
this.lineChart.on('click', (e) => {
|
console.log(e);
|
this.$emit('chartClick', this.sIndex + e.dataIndex);
|
});
|
}
|
};
|
</script>
|
<style scoped>
|
.line-chart {
|
/* width: 200px; */
|
height: 280px;
|
}
|
</style>
|