for循环 绘制Echarts图表之后,点击 添加图表向前插入图表遇到实例未更新

一、问题及预期

for循环 绘制图表之后,点击 添加图表, 应该展示空表的初始状态,但是展示的是上一个图表正常有数据的图表

二、复盘

  1. 采用index 作为下标去渲染图表实例
  2. 导致点击【添加图表】按钮的时候向前添加的下标为0 ,和原来存在为0的下标实例重复,从而导致会展示【上一个图表正常有数据的图表】
  3. 不使用index作为图表实例渲染,采用随机数或者是时间戳去做绘制图表
  4. 新增的数据会初始展示空表 【正确】
  5. 新增的数据点击查询正常出现图表 【正确】

三、案例代码

为了确保点击"添加新图表"后,新图表展示为空白的初始状态,同时之前的图表展示正常有数据的状态,你需要在addNewChart方法中正确初始化新图表,并保证不影响已有图表的状态。以下是修改后的addNewChart方法,以及相关的初始化图表的逻辑:

  1. 修改addNewChart方法:确保添加新图表时,不会影响到已有图表的显示。

    private addNewChart() {
    const timestamp = new Date().getTime(); // 使用时间戳生成唯一标识
    const obj = {
    formCustom: {
    groupField: '',
    calculateField: 'requestId',
    granularity: 60,
    },
    name: '',
    chartType: 1,
    isCollect: false,
    isInitChart: false,
    cardItemId: ${timestamp}, // 为每个图表卡片分配一个唯一ID
    tableData: [], // 确保新图表的数据为空
    chartTableData: [], // 确保新图表的数据为空
    numberTotal: 0, // 对于数字类型的图表,初始化总数为0
    };
    this.chartCardList.unshift(obj); // 将新图表添加到数组的开头
    this.$nextTick(() => {
    this.initChartInstances(); // 初始化图表实例
    });
    }

  2. 初始化图表实例:在添加新图表后,你需要重新初始化所有图表的实例,以确保新添加的图表能够正确显示。这里我们添加一个initChartInstances方法来处理这个逻辑。

    private initChartInstances() {
    this.chartCardList.forEach((cardItem, index) => {
    if (cardItem.chartType !== 1 && cardItem.chartType !== 2) { // 假设只有类型3, 4, 5, 6需要初始化图表
    const chartRef = this.refs[`chart_{cardItem.cardItemId || cardItem.formCustom.id}`];
    const chartDom = Array.isArray(chartRef) ? chartRef[0] : chartRef;
    if (chartDom) {
    this.initChart(chartDom, cardItem.cardItemId, cardItem.chartType, cardItem.chartTableData);
    }
    }
    });
    }

  3. 调整initChartHandle方法:确保initChartHandle方法能够正确处理新添加的图表卡片。

    private initChartHandle(cardItem: any, resRows: any, cardItemId: number) {
    // 你的原始逻辑...
    this.$nextTick(() => {
    this.initChartInstances(); // 确保在DOM更新后重新初始化图表实例
    });
    }

通过上述修改,每次添加新图表时,都会重新初始化所有图表的实例,确保新添加的图表展示为空白的初始状态,而不会影响到已有图表的显示。请注意,这里的initChartInstances方法假设只有特定类型的图表需要初始化ECharts实例,你可能需要根据实际情况调整这部分逻辑。

四、实例案例

复制代码
  <mtd-card
      class="card-box"
      v-for="(cardItem, index) in chartCardList"
      :key="cardItem.cardItemId"
    >
     <div
              :ref="`chart_${cardItem.cardItemId || cardItem.formCustom.id}`"
              class="chart-box"
            ></div>
</mtd-card>

 private chartInstances: any = [];
 
private addNewChart() {
    const timestamp = new Date().getTime(); // 使用时间戳生成唯一标识
    const obj = {
      formCustom: {
        groupField: '',
        calculateField: 'requestId',
        granularity: 60,
      },
      name: '',
      chartType: 1,
      isCollect: false,
      cardItemId: `${timestamp}`, // 为每个图表卡片分配一个唯一ID
    };
    this.chartCardList.unshift(obj);

    this.$nextTick(() => {
      this.initChartInstances(); // 初始化图表实例
    });
  }
  // 初始化图表实例
  private initChartInstances() {
    this.chartCardList.forEach((cardItem: any) => {
      if (cardItem.chartType !== 1 && cardItem.chartType !== 2) {
        // 类型3, 4, 5, 6需要初始化图表
        const chartRef =
          this.$refs[`chart_${cardItem.cardItemId || cardItem.formCustom.id}`];
        const chartDom = Array.isArray(chartRef) ? chartRef[0] : chartRef;
        if (chartDom) {
          this.initChart(
            chartDom,
            cardItem.cardItemId,
            cardItem.chartType,
            cardItem.chartTableData,
          );
        }
      }
    });
  }
 private initChartHandle(cardItem: any, resRows: any) {
    // 获取新添加的DOM元素并初始化图表
    this.$nextTick(() => {
      const chartRef =
        this.$refs[`chart_${cardItem.cardItemId || cardItem.formCustom.id}`];

      const chartDom = Array.isArray(chartRef)
        ? (chartRef[0] as Element)
        : null;
      if (chartDom) {
        this.initChart(
          chartDom,
          cardItem.cardItemId,
          cardItem.chartType,
          resRows,
        );
      }
    });
  }

 private initChart(
    dom: any,
    index: number,
    chartType: number,
    resRows: SearchPicTableType[],
  ) {
    const myChart = echarts.init(dom);

    const option = switchChart(chartType, resRows);

    myChart.setOption(option, true);
    // 存储ECharts实例以便后续更新
    this.chartInstances[index] = myChart;
  }
相关推荐
老华带你飞13 分钟前
商城推荐系统|基于SprinBoot+vue的商城推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·商城推荐系统
JS.Huang14 分钟前
【JavaScript】Pointer Events 与移动端交互
前端·javascript
一 乐17 分钟前
物业管理系统|小区物业管理|基于SprinBoot+vue的小区物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端
H_HX12620 分钟前
vue3 - 图片放大镜效果实现
前端·vue.js·vue3·vueuse·图片放大镜
yinuo1 小时前
Git Submodule 与 Subtree 全方位对比:使用方式与场景选择
前端
yinuo2 小时前
深入理解与实战 Git Subtree
前端
向上的车轮2 小时前
Actix Web 不是 Nginx:解析 Rust 应用服务器与传统 Web 服务器的本质区别
前端·nginx·rust·tomcat·appche
Liudef062 小时前
基于LLM的智能数据查询与分析系统:实现思路与完整方案
前端·javascript·人工智能·easyui
潘小安2 小时前
跟着 AI 学(三)- spec-kit +claude code 从入门到出门
前端·ai编程·claude
金梦人生3 小时前
让 CLI 更友好:在 npm 包里同时支持“命令行传参”与“交互式对话传参”
前端·npm