如何在Node-RED中使用chart.js创建双轴饼图
Node-RED 基于Chart.js实现双标签当日活动饼图方案
你卡的双轴标签思路本身走偏了:饼图属于极坐标类图表,不支持笛卡尔坐标系的双轴配置,示例里的外侧分类标签、内侧数值标签是通过Chart.js自定义插件直接在画布绘制实现的,不需要调整坐标轴参数。
实现步骤
1. 节点准备
- 确保已安装
node-red-dashboard组件,直接使用ui_template节点编写原生Chart.js代码即可,不要用自带的ui_chart节点——后者对自定义插件的支持有限,很容易出现配置不生效的问题。 - 提前整理好当日活动数据,参考格式如下:
// 24小时活动数据,数值总和为24对应全天时长 const activityData = { labels: ["睡眠", "工作", "运动", "娱乐", "家务", "其他"], values: [8, 7, 1, 3, 1, 4], colors: ["#60acfc", "#32c5e9", "#93d987", "#ffb980", "#d15b47", "#b8bdd1"] }
2. 注册双标签自定义插件
在ui_template节点的脚本区先注册自定义插件,分别实现外侧带引导线的分类标签、饼块内部的数值标签渲染:
Chart.register({ id: 'pieDoubleLabel', afterDatasetsDraw(chart) { const { ctx } = chart; const arcList = chart.getDatasetMeta(0).data; arcList.forEach((arc, idx) => { const midAngle = (arc.startAngle + arc.endAngle) / 2; // 渲染外侧分类标签+引导线 ctx.save(); ctx.font = '14px system-ui'; ctx.fillStyle = '#333'; ctx.textAlign = midAngle < Math.PI ? 'left' : 'right'; const outPosX = arc.x + Math.cos(midAngle) * (arc.outerRadius + 22); const outPosY = arc.y + Math.sin(midAngle) * (arc.outerRadius + 22); // 画引导线 ctx.beginPath(); ctx.strokeStyle = '#aaa'; ctx.lineWidth = 1; ctx.moveTo(arc.x + Math.cos(midAngle)*(arc.outerRadius+6), arc.y + Math.sin(midAngle)*(arc.outerRadius+6)); ctx.lineTo(outPosX - (midAngle < Math.PI ? 6 : -6), outPosY); ctx.stroke(); // 写分类文字 ctx.fillText(activityData.labels[idx], outPosX, outPosY); ctx.restore(); // 渲染饼块内部数值标签 ctx.save(); ctx.font = 'bold 16px system-ui'; ctx.fillStyle = '#fff'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; const inPosX = arc.x + Math.cos(midAngle) * (arc.innerRadius + (arc.outerRadius - arc.innerRadius)/2); const inPosY = arc.y + Math.sin(midAngle) * (arc.innerRadius + (arc.outerRadius - arc.innerRadius)/2); ctx.fillText(`${activityData.values[idx]}h`, inPosX, inPosY); ctx.restore(); }) } })
3. 初始化饼图
在ui_template的HTML区放画布容器,脚本区在DOM加载完成后初始化图表:
<!-- HTML部分 --> <div style="height: 420px; padding: 20px;"> <canvas id="activityPie"></canvas> </div>
// JS初始化部分 const pieCtx = document.getElementById('activityPie').getContext('2d'); new Chart(pieCtx, { type: 'pie', data: { labels: activityData.labels, datasets: [{ data: activityData.values, backgroundColor: activityData.colors, borderColor: '#fff', borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, // 关闭默认图例,用外侧自定义标签代替 tooltip: { callbacks: { label: (ctx) => `${ctx.label}:${ctx.raw}小时,占比${(ctx.raw/24*100).toFixed(1)}%` } } } } })
调参说明
- 如果标签位置偏移,修改代码里
arc.outerRadius + 22这类偏移数值即可,适配你的画布尺寸。 - 如果要做环形饼图,在options里加
cutout: '40%'配置就行,内侧标签会自动适配位置。 - 颜色、字体大小直接改对应代码里的参数即可,和示例效果对齐。
内容的提问来源于stack exchange,提问作者ymym
相关产品推荐
相关产品推荐

