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

