You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 7集成Chart.js切换数据时旧图表残留鼠标悬停异常问题

解决Angular 7中Chart.js切换日期时图表叠加的问题

嘿,我一眼就看出问题所在了——你每次切换日期时都直接创建新的Chart实例,但旧的实例并没有被销毁!Canvas元素上残留着旧图表的渲染内容,而且旧实例的鼠标悬停事件监听还在生效,所以才会出现多层叠加、tooltip乱跳的情况。

下面给你具体的修复方案,直接套进你的代码里就行:

1. 销毁旧Chart实例再创建新的

Chart.js提供了destroy()方法,能彻底清除旧实例的所有内容、事件监听和内存占用。你需要在创建新图表前,先检查并销毁已存在的实例。

修改resetChart()方法

把你的resetChart改成这样:

public resetChart(){
  // 关键:先销毁旧实例,避免叠加
  if(this.mainChart){
    this.mainChart.destroy();
  }
  this.mainChart = new Chart(ChargeUnitDailyComponent.CHART_ID, {
    type: 'line',
    fillOpacity: .3,
    data: {
      labels: [],
      datasets: []
    },
    options: {
      legend: { display: true },
      scales: {
        xAxes: [{ display: true }],
        yAxes: [{ display: true }],
      },
      events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"]
    }
  })
}

额外保险:在setChartDataFromEntities创建新图表前也检查销毁

虽然setChart里已经调用了resetChart,但为了防止意外情况,你可以在创建最终图表前再加一次销毁检查:

setChartDataFromEntities(
  aDate: Date,
  aChargeUnitArray: ChargeUnit[]
){
  // ... 你的其他代码 ...

  // 创建新图表前先销毁旧实例
  if(this.mainChart){
    this.mainChart.destroy();
  }

  this.mainChart = new Chart(ChargeUnitDailyComponent.CHART_ID, {
    type: 'line',
    data: {
      labels: lChartLabelsArray,
      datasets: lChartDataArray,
    },
    options: {
      legend: { display: false },
      scales: {
        xAxes: [{ display: true }],
        yAxes: [{ display: true }],
      },
      responsive: true,
    },
  })
  // 这里其实不需要调用update(),因为new Chart()已经完成渲染了
  // this.mainChart.update() 可以删掉
  let lDiff = new Date().getTime() - this.loadingDate.getTime()
  this.setStatus('Chart loaded:' + moment(lDiff).format('mm\'ss\'\''), true)
}

2. 移除HTML中重复的Chart.js脚本

你的component.html里有一行<script src="node_modules/chart.js/src/chart.js"></script>,这完全没必要!你已经在组件里通过import Chart = require('chart.js')引入了库,重复引入会导致Chart.js多次初始化,也是引发异常的潜在原因,直接删掉这行。

为什么这样能解决问题?

  • destroy()方法会清除Canvas上的所有绘制内容,移除旧实例绑定的所有事件监听(比如鼠标悬停的tooltip触发),并释放相关内存。
  • 确保每次创建新图表时,Canvas都是干净的状态,不会和旧实例的内容叠加。

这样修改后,你切换上/下一日时,旧图表会被彻底清理,新图表能正常渲染,再也不会出现叠加的情况啦!

内容的提问来源于stack exchange,提问作者Pipo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:38:17