src/components/monitor/LineChart.vue
@@ -5,7 +5,10 @@
    </template>
    <template #footer>
      <!-- 单页数据量-->
      <SliderBar></SliderBar>
      <SliderBar
        v-model:progress="progress"
        @size-change="(e) => (pageSize = e)"
      ></SliderBar>
    </template>
  </BaseCard>
</template>
@@ -18,6 +21,7 @@
export default {
  props: {
    loading: Boolean,
    factorDatas: {
      type: FactorDatas
      // default: () => new FactorDatas()
@@ -25,41 +29,74 @@
    selectFactorType: {
      type: Array,
      default: () => ['1']
    }
    },
    // 当前选中高亮的数据点索引
    locateIndex: Number
  },
  data() {
    return {
      lineChart: null,
      option: null
      allXAxis: [],
      allSeries: [],
      option: null,
      pageSize: 200,
      progress: 0
    };
  },
  emits: ['chartClick'],
  watch: {
    factorDatas: {
      handler() {
        this.refreshChart();
        this.initData();
        this.changeChartRange();
      },
      deep: true
    },
    selectFactorType: {
      handler() {
        this.refreshChart();
      },
      deep: true
        this.changeChartSeries();
      }
    },
    progress() {
      this.changeChartRange();
    },
    pageSize() {
      this.changeChartRange();
    },
    locateIndex(nV, oV) {
      if (nV == oV) return;
      // 1. 定位点应该展示在趋势图中间,因此定位百分比往前偏移当前_size的一半
      let i = nV - parseInt(this.pageSize / 2);
      // 2. 确保索引不会超出范围
      i = i < 0 ? 0 : i;
      // 3. 获取索引对应的进度百分比
      this.progress = (i / (this.allXAxis.length - this.pageSize)) * 100;
      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'
              }
            }
          ]
        };
      }
      this.changeChartRange();
    }
  },
  computed: {
    /**
     * 获取横坐标
     */
    xAxis() {
      return this.factorDatas.times.map((v) => {
  methods: {
    initData() {
      this.allXAxis = this.factorDatas.times.map((v) => {
        return v.split(' ')[1];
      });
    },
    /**
     * 获取监测数据纵坐标
     */
    allSeries() {
      const res = [];
      for (const key in this.factorDatas.factor) {
        if (Object.hasOwnProperty.call(this.factorDatas.factor, key)) {
@@ -68,6 +105,7 @@
            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) {
@@ -76,34 +114,67 @@
          });
        }
      }
      return res;
      this.allSeries = res;
    },
    showSeries() {
      return this.allSeries.filter((s) => {
    // 修改图表展示的折线图类型
    changeChartSeries() {
      this.option.series = this.getShowSeries();
      this.option.legend.data = this.getLegends(this.option.series);
      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);
      const legends = this.getLegends(showSeries);
      if (!this.option) {
        this.option = factorLineOption(xAxis, showSeries, legends);
      } else {
        this.option.xAxis.data = xAxis;
        this.option.series = showSeries;
        this.option.legend.data = legends;
      }
      // 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) => {
        if (sIndex && eIndex) {
          s.data = s.allData.slice(sIndex, eIndex);
        }
      });
      const res = this.allSeries.filter((s) => {
        return this.selectFactorType.includes(s.key);
      });
      return res;
    },
    legends() {
      return this.showSeries.map((s) => {
    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 = (sIndex / this.allXAxis.length) * 100;
      const endPer = (eIndex / this.allXAxis.length) * 100;
      return { sIndex, eIndex, startPer, endPer };
    },
    getLegends(series) {
      return series.map((s) => {
        return s.name;
      });
    }
  },
  methods: {
    initChart() {
      this.lineChart = echarts.init(this.$refs.lineChart);
    },
    refreshChart() {
      const option = factorLineOption(
        this.xAxis,
        this.showSeries,
        this.legends
      );
      this.lineChart.setOption(option, { notMerge: true });
    }
  beforeUnmount() {
    // this.$refs.lineChart && this.$refs.lineChart.clear();
  },
  mounted() {
    this.initChart();
    this.lineChart = echarts.init(this.$refs.lineChart);
    this.lineChart.on('click', (e) => {
      this.$emit('chartClick', e.dataIndex);
    });
  }
};
</script>