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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:01:46