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
相关产品推荐
相关产品推荐

