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

Chart.js v3.9.1如何实现环形图数据的定时更新?

解决Chart.js v3.9.1环形图无法定时更新数据的问题

问题场景

用Chart.js v3.9.1开发了一个从API获取数据的环形图,图表能正常显示,但没法实现每2秒自动更新数据。原代码如下:

原Chart.js代码

const totalRunTime = current_array.MTConnectStreams.Streams.DeviceStream.ComponentStream[12].Samples.DynamicBasicData[1];
const totalTimeRemaining = current_array.MTConnectStreams.Streams.DeviceStream.ComponentStream[12].Samples.DynamicBasicData[13];
const timeRemaining = ((totalTimeRemaining / totalRunTime) * 100)

// Setup
const datapoints = [(100 - timeRemaining), timeRemaining];
const data = {
  datasets: [{
      data: datapoints,
      backgroundColor: ['rgba(20, 121, 255, 0.7)', 'rgba(208, 208, 208, 0.5)'],
      borderWidth: 1,
      cutout: '70%'
  }]
};

// Counter
const counter = {
  id: 'counter',
  beforeDraw( chart, args, options ) {
    const { ctx, chartArea: { top, right, bottom, left, width, height } } = chart;
    ctx.save();

    ctx.font = options.fontSize + 'px ' + options.fontFamily;
    ctx.textAlign = 'center';
    ctx.fillStyle = options.fontColor;
    ctx.fillText(datapoints[0].toFixed(3) + '%', width / 2, (height / 2) + (options.fontSize * 0.34));
  }
};

// Config
const config = {
  type: 'doughnut',
  data,
  options: {
    plugins: {
      legend: {
        display: false
      },
      tooltip: {
        enabled: false
      },
      counter: {
        fontColor: '#193b68',
        fontSize: '16',
        fontFamily: 'Sofia Pro Medium'
      }
    }
  },
  plugins: [counter]
};

// Render init
const doughnutChart = new Chart(
  document.getElementById('doughnutChart'),
  config
);

setInterval(function addData(chart, data) {
  chart.data.datasets.forEach((dataset) => {
      dataset.data = data;
  });
  chart.update('none');
  }, 2000
);

原HTML代码

<canvas id="doughnutChart"></canvas>

问题原因

  1. 数据未重新获取:初始化时只取了一次current_array的数据,定时器里没有重新请求API或更新current_array,导致始终用初始值更新
  2. 定时器参数错误:setInterval里的addData函数需要传入chart和data,但实际执行时没传参,data为undefined,无法更新图表
  3. 插件数据未同步:自定义counter插件直接用初始化时的datapoints变量,没从当前图表实例取最新数据,导致中心百分比不更新

修复后的完整代码

修复后的Chart.js代码

// 封装获取最新数据的函数
function getLatestData() {
  // 若current_array来自API,需在此处补充API请求逻辑,确保拿到最新数据
  const totalRunTime = current_array.MTConnectStreams.Streams.DeviceStream.ComponentStream[12].Samples.DynamicBasicData[1];
  const totalTimeRemaining = current_array.MTConnectStreams.Streams.DeviceStream.ComponentStream[12].Samples.DynamicBasicData[13];
  const timeRemaining = ((totalTimeRemaining / totalRunTime) * 100);
  return [(100 - timeRemaining), timeRemaining];
}

// Counter插件:从图表实例中获取最新数据
const counter = {
  id: 'counter',
  beforeDraw(chart, args, options) {
    const { ctx, chartArea: { width, height } } = chart;
    ctx.save();

    ctx.font = `${options.fontSize}px ${options.fontFamily}`;
    ctx.textAlign = 'center';
    ctx.fillStyle = options.fontColor;
    // 从当前图表数据中取最新值
    const latestValue = chart.data.datasets[0].data[0];
    ctx.fillText(`${latestValue.toFixed(3)}%`, width / 2, (height / 2) + (options.fontSize * 0.34));
    ctx.restore(); // 恢复上下文,避免影响其他绘制
  }
};

// Config
const config = {
  type: 'doughnut',
  data: {
    datasets: [{
      data: getLatestData(), // 初始化时调用一次获取数据
      backgroundColor: ['rgba(20, 121, 255, 0.7)', 'rgba(208, 208, 208, 0.5)'],
      borderWidth: 1,
      cutout: '70%'
    }]
  },
  options: {
    plugins: {
      legend: { display: false },
      tooltip: { enabled: false },
      counter: {
        fontColor: '#193b68',
        fontSize: '16',
        fontFamily: 'Sofia Pro Medium'
      }
    }
  },
  plugins: [counter]
};

// 初始化图表
const doughnutChart = new Chart(
  document.getElementById('doughnutChart'),
  config
);

// 定时更新图表
setInterval(() => {
  const newData = getLatestData();
  // 更新图表数据
  doughnutChart.data.datasets[0].data = newData;
  // 触发图表更新,'none'表示无动画
  doughnutChart.update('none');
}, 2000);

修复后的HTML代码(不变)

<canvas id="doughnutChart"></canvas>

关键修复说明

  • 封装数据获取函数:把数据计算逻辑放到getLatestData里,每次定时器触发时调用,确保拿到最新数据(如果是API数据源,需在函数内补充请求逻辑更新current_array)
  • 修正定时器逻辑:直接在定时器回调里获取新数据,赋值给图表的dataset.data后调用update方法完成更新
  • 插件同步数据:插件内部从chart.data.datasets[0].data取最新值,不再依赖外部变量,保证中心百分比和图表数据同步

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:45:49