Chart.js结合Ng2-Charts更新图表数据:解决API返回前提前渲染问题
问题原因
你遇到的是异步API请求和同步图表初始化的时序冲突:getLastMachineStatusByMac是异步网络请求,你在ngOnInit中同步调用setGraphData()时,API尚未返回结果,this.hot还未被赋值为目标值,图表先使用初始值完成渲染后,后续this.hot的更新不会自动触发图表重绘,因此展示数值和预期不符。
解决方案
你可以选择两种方式解决,按需选择即可:
方案1:拿到API数据后再渲染图表
通过条件渲染控制图表的初始化时机,完全避免预渲染错误数值的问题:
- 新增数据加载状态标记,只有数据准备完成后才加载渲染图表组件
- 把
setGraphData()的调用移到API请求的回调逻辑中
代码修改示例
TS文件修改:
export class MachineDetailsComponent implements OnInit { hot :number; hotGaugeData: MultiDataSet=[]; // 新增加载状态标记 isDataLoaded = false; constructor(private machinesService: MachinesService) { } ngOnInit() { this.route.params.subscribe(params => { this.machinesService.getLastMachineStatusByMac(params.mac).subscribe((res) =>{ this.hot = Math.floor((res.hotWaterDistance * 100) / 200); // 拿到数据后再设置图表数据 this.setGraphData(); // 标记数据加载完成 this.isDataLoaded = true; }); }); // 删掉原来此处的setGraphData()同步调用 } setGraphData() { this.hotGaugeData=[]; this.hotGaugeData[0]=[this.hot, 100-this.hot]; } }
HTML文件修改:
给canvas元素添加*ngIf控制渲染时机:
<canvas *ngIf="isDataLoaded" id="hotGauge" baseChart [labels]="GaugeLabels" [chartType]="GaugeType" [options]="hotGaugeOptions" [colors]="hotGaugeColors" [legend]="GaugeLegend" [data]="hotGaugeData">
方案2:数据更新后强制图表重绘
如果需要提前渲染图表框架,拿到数据后再更新数值,可以直接通过更新数据集引用或者调用图表实例的更新方法触发重绘:
- ng2-charts会监听
data输入属性的引用变化,只要重新赋值hotGaugeData就会自动触发重绘 - 也可以通过模板引用拿到
BaseChartDirective实例,手动调用update()方法强制重绘
代码修改示例
TS文件修改:
import { BaseChartDirective } from 'ng2-charts'; export class MachineDetailsComponent implements OnInit { hot :number; hotGaugeData: MultiDataSet=[]; // 引入图表实例引用 @ViewChild(BaseChartDirective) hotGaugeChart!: BaseChartDirective; constructor(private machinesService: MachinesService) { } ngOnInit() { // 可以先给初始值渲染空图表/默认状态图表 this.hot = 0; this.setGraphData(); this.route.params.subscribe(params => { this.machinesService.getLastMachineStatusByMac(params.mac).subscribe((res) =>{ this.hot = Math.floor((res.hotWaterDistance * 100) / 200); // 重新设置图表数据,触发变更检测 this.setGraphData(); // 可选:如果引用没变化也可以手动调用update强制重绘 // this.hotGaugeChart?.update(); }); }); } setGraphData() { // 这里重新赋值数组,改变引用触发ng2-charts的自动重绘 this.hotGaugeData = [[this.hot, 100-this.hot]]; } }
内容的提问来源于stack exchange,提问作者Andre Mendes
相关产品推荐
相关产品推荐

