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

Chart.js图表刷新后不显示,打开F12控制台后恢复显示求助

问题原因与解决方案

核心原因

你直接修改了stocksData内部的labels和datasets数组元素,Angular的变更检测机制无法捕捉到这种对象内部属性的修改,导致ng2-charts没有触发图表重绘。而打开控制台触发窗口resize时,ng2-charts会监听resize事件并主动调用图表更新方法,此时数据已经加载完成,所以图表能正常显示。

解决方案

方案1:重新赋值stocksData(推荐)

通过重新创建stocksData对象,触发引用变更,让Angular检测到数据变化并更新图表:

import { Component } from '@angular/core';
import { ChartData } from 'chart.js';
import { IInventory } from 'src/app/models/inventory';
import { IStorage } from 'src/app/models/storage';
import { InventoryService } from 'src/app/services/inventory.service';
import { StorageService } from 'src/app/services/storage.service';

@Component({
  selector: 'app-stocks-chart',
  templateUrl: './stocks-chart.component.html',
  styleUrls: ['./stocks-chart.component.scss']
})
export class StocksChartComponent {

  stocks: IInventory[]
  storages: IStorage[]
  selectedStorage: string = ''
  stocksData: ChartData<'doughnut'> = {
    labels: [],
    datasets: [
      { data: [] }
    ]
  }
  stocksLabels: string[]
  
  constructor(private inventory: InventoryService, private storages: StorageService) {
    inventory.getInventory().subscribe((res: IInventory[]) => {
      this.stocks = res;
      // 用Map整理数据,避免重复遍历查找
      const productStockMap = new Map<string, number>();
      res.forEach(item => {
        const currentStock = productStockMap.get(item.productName) || 0;
        productStockMap.set(item.productName, currentStock + item.stock);
      });
      // 重新赋值整个stocksData对象
      this.stocksData = {
        labels: Array.from(productStockMap.keys()),
        datasets: [{ data: Array.from(productStockMap.values()) }]
      };
    })
  }
}

方案2:手动触发变更检测

注入ChangeDetectorRef,在修改数据后手动通知Angular检测变化:

import { Component, ChangeDetectorRef } from '@angular/core';
import { ChartData } from 'chart.js';
import { IInventory } from 'src/app/models/inventory';
import { IStorage } from 'src/app/models/storage';
import { InventoryService } from 'src/app/services/inventory.service';
import { StorageService } from 'src/app/services/storage.service';

@Component({
  selector: 'app-stocks-chart',
  templateUrl: './stocks-chart.component.html',
  styleUrls: ['./stocks-chart.component.scss']
})
export class StocksChartComponent {

  stocks: IInventory[]
  storages: IStorage[]
  selectedStorage: string = ''
  stocksData: ChartData<'doughnut'> = {
    labels: [],
    datasets: [
      { data: [] }
    ]
  }
  stocksLabels: string[]
  
  constructor(
    private inventory: InventoryService, 
    private storages: StorageService,
    private cdr: ChangeDetectorRef
  ) {
    inventory.getInventory().subscribe((res: IInventory[]) => {
      this.stocks = res
      res.map((item: IInventory) => {
        if (this.stocksData.labels?.includes(item.productName)) {
          this.stocksData.datasets[0].data[this.stocksData.labels.indexOf(item.productName)] += item.stock
        } else {
          this.stocksData.labels?.push(item.productName)
          this.stocksData.datasets[0].data.push(item.stock)
        }
      });
      // 手动触发变更检测
      this.cdr.detectChanges();
    })
  }
}

方案3:手动调用图表更新方法

获取图表指令引用,在数据加载完成后主动调用更新:

  1. 修改HTML模板,添加模板引用:
<canvas
  #chartRef
  baseChart
  type="doughnut"
  [data]="stocksData"
></canvas>
  1. 修改Component代码:
import { Component, ViewChild } from '@angular/core';
import { ChartData } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts';
import { IInventory } from 'src/app/models/inventory';
import { IStorage } from 'src/app/models/storage';
import { InventoryService } from 'src/app/services/inventory.service';
import { StorageService } from 'src/app/services/storage.service';

@Component({
  selector: 'app-stocks-chart',
  templateUrl: './stocks-chart.component.html',
  styleUrls: ['./stocks-chart.component.scss']
})
export class StocksChartComponent {

  stocks: IInventory[]
  storages: IStorage[]
  selectedStorage: string = ''
  stocksData: ChartData<'doughnut'> = {
    labels: [],
    datasets: [
      { data: [] }
    ]
  }
  stocksLabels: string[]
  @ViewChild('chartRef') chartRef!: BaseChartDirective;
  
  constructor(private inventory: InventoryService, private storages: StorageService) {
    inventory.getInventory().subscribe((res: IInventory[]) => {
      this.stocks = res
      res.map((item: IInventory) => {
        if (this.stocksData.labels?.includes(item.productName)) {
          this.stocksData.datasets[0].data[this.stocksData.labels.indexOf(item.productName)] += item.stock
        } else {
          this.stocksData.labels?.push(item.productName)
          this.stocksData.datasets[0].data.push(item.stock)
        }
      });
      // 手动更新图表
      this.chartRef.update();
    })
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:19:59