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

Chart.js TS自定义插件中如何获取数据集的rotation与circumference?

问题:Chart.js自定义插件中获取数据集选项的TypeScript类型错误

我在为Chart.js开发自定义插件时,需要获取第一个数据集的rotation和circumference配置。当前代码通过datasetMeta._dataset能正常运行,但TypeScript报错——官方类型定义中不存在_dataset这个私有属性。求正确的实现方式。

原插件代码

const gaugeNeedle: Plugin<"doughnut"> = {
  id: "gaugeNeedle",
  afterDatasetDraw(chart: Chart<"doughnut">, args, options) {
    if (!chart || typeof options.needleValue === "undefined") {
      return;
    }
    const {
      ctx,
      chartArea: { width },
    } = chart;
    const datasetMeta: ChartMeta<"doughnut"> = chart.getDatasetMeta(0);
    const { rotation, circumference } = datasetMeta._dataset; // TypeScript报错:不存在_dataset属性
    ctx.save();
    const { needleValue, dataTotal } = options;
    const angle =
      (((1 / dataTotal) * needleValue * circumference - (90 - rotation)) /
        180) *
      Math.PI;
    const cx = width / 2;
    const cy = datasetMeta.data[0].y;

    // 剩余绘制逻辑...
  }
};

原图表配置代码

const data = useMemo<ChartData<"doughnut", number[], string>>(
  () => ({
    labels: ["Filled", "Unfilled"],
    datasets: [
      {
        label: "Speedometer",
        data: [value, 100 - value], // 示例数据:65%已填充,35%未填充
        borderWidth: 0,
        borderRadius: 10,
        cutout: "85%", // 调整仪表盘粗细
        circumference: 240,
        rotation: -120,
        backgroundColor: (context: ScriptableContext<"doughnut">) => {
          const chart = context.chart;
          const { chartArea } = chart;
          if (!chartArea) {
            return undefined;
          }
          if (context.dataIndex === 0) {
            return getGradient(chart, value);
          } else {
            return "grey";
          }
        },
      },
    ],
  }),
  [value],
);

解决方法

不要依赖私有属性_dataset(这类属性可能在Chart.js版本迭代中被移除或修改),直接通过公开APIchart.data.datasets获取数据集配置,这是类型安全且稳定的方式:

修改后的插件代码

const gaugeNeedle: Plugin<"doughnut"> = {
  id: "gaugeNeedle",
  afterDatasetDraw(chart: Chart<"doughnut">, args, options) {
    if (!chart || typeof options.needleValue === "undefined") {
      return;
    }
    const {
      ctx,
      chartArea: { width },
      data: { datasets },
    } = chart;
    
    // 获取第一个数据集,添加类型检查避免空值报错
    const targetDataset = datasets[0];
    if (!targetDataset) return;
    
    // 直接从数据集配置中取rotation和circumference,可设置默认值兼容边界情况
    const { rotation = -120, circumference = 240 } = targetDataset;
    
    ctx.save();
    const { needleValue, dataTotal } = options;
    const angle =
      (((1 / dataTotal) * needleValue * circumference - (90 - rotation)) /
        180) *
      Math.PI;
    const cx = width / 2;
    const datasetMeta: ChartMeta<"doughnut"> = chart.getDatasetMeta(0);
    const cy = datasetMeta.data[0].y;

    // 剩余绘制逻辑...
  }
};

补充说明

如果需要的是Chart.js内部计算后的rotation和circumference(而非配置的原始值),可以用类型断言临时绕过TypeScript检查,但需注意版本兼容性:

const datasetMeta: ChartMeta<"doughnut"> = chart.getDatasetMeta(0);
const { rotation, circumference } = (datasetMeta as any)._dataset;

但优先推荐第一种通过chart.data.datasets获取的方式,因为私有属性不具备API稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:39:56