【图表+ECharts】day55-industrial-charts

作者:mario 发布时间: 2026-09-03 阅读量:4 评论数:0

Day 55 · 工业大屏常用图表 — 仪表盘、雷达、拓扑与主题定制

工业大屏的图表选型和互联网 BI 完全不同:BI 追求信息密度,大屏追求三米外一眼可读。今天的四类图表是工业大屏的高频主角:gauge 仪表盘(设备温度/压力/液位)、radar 雷达图(设备健康度多维评估)、graph 拓扑图(产线/管网连接关系)、pictorialBar 象形柱(能耗排名)。外加两个工程能力:主题定制(统一工业深色风)和大屏适配(transform scale 下的图表策略)。明天 BOSS 战的全部零件今天备齐。


目录


一、工业大屏图表选型地图

图表 回答的问题 工业场景 大屏占比
gauge 仪表盘 “这台设备现在什么状态?” 炉温、压力、液位、转速 ⭐⭐⭐⭐⭐
折线图(Day 51) “趋势如何?有没有异常?” 温度曲线、产量走势 ⭐⭐⭐⭐⭐
柱状/象形柱 “谁多谁少?” 车间能耗排名 ⭐⭐⭐⭐
radar 雷达 “综合健康度如何?” 设备体检报告、班组绩效 ⭐⭐⭐
graph 拓扑 “怎么连接的?哪里断了?” 产线流程、管网、供配电 ⭐⭐⭐
数字翻牌器 “关键 KPI 是多少?” 总产量、告警数、OEE ⭐⭐⭐⭐

选型铁律:大屏不是图表博览会——每张图必须能被一句"业务问题"描述(“3 号炉温度是否超限?”),描述不出来的图就删掉。


二、gauge 仪表盘:设备状态的第一现场

2.1 基础仪表盘

import * as echarts from "echarts";

/**
 * 基础仪表盘:炉温监控
 */
const gaugeOption = {
  series: [
    {
      type: "gauge",
      min: 0,
      max: 120,
      splitNumber: 6,               // 刻度分段(内部跑 nice 算法——你 Day 50 的老朋友)
      axisLine: {
        // ⭐ 分段着色:正常区/警告区/危险区(工业仪表盘的灵魂)
        lineStyle: {
          width: 20,
          color: [
            [80 / 120, "#00c6ff"],      // 0~80 正常:蓝
            [100 / 120, "#ffd666"],     // 80~100 警告:黄
            [1, "#ff4d4f"],             // 100~120 危险:红
          ],
        },
      },
      pointer: { itemStyle: { color: "auto" } },   // 指针颜色跟随所在区段
      axisTick: { distance: -20, length: 6 },
      splitLine: { distance: -20, length: 20 },
      axisLabel: { distance: 30, color: "#6a7a94" },
      detail: {
        // 中央数值显示
        valueAnimation: true,          // 数值变化时动画滚动(大屏质感的关键)
        formatter: "{value} ℃",
        color: "#e0e8f0",
        fontSize: 32,
        offsetCenter: [0, "60%"],
      },
      title: { offsetCenter: [0, "85%"], fontSize: 14 },
      data: [{ value: 92, name: "1号炉温度" }],
    },
  ],
};

2.2 进度环风格(现代大屏主流)

经典指针表偏"工业复古",现代大屏更爱无指针进度环

/**
 * 进度环式仪表盘:极简风格
 * 核心思路:仪表盘当进度条用——只显示进度弧 + 大数字
 */
const ringOption = {
  series: [
    {
      type: "gauge",
      startAngle: 225,          // 起始角:左下
      endAngle: -45,            // 终止角:右下(总跨度 270°)
      min: 0,
      max: 100,
      pointer: { show: false },   // ⭐ 不要指针
      progress: {
        show: true,               // ⭐ 进度弧
        roundCap: true,           // 圆头
        width: 14,
        itemStyle: { color: "#00c6ff" },
      },
      axisLine: { lineStyle: { width: 14, color: [[1, "#1a2740"]] } },  // 背景弧
      axisTick: { show: false },
      splitLine: { show: false },
      axisLabel: { show: false },
      title: { show: true, offsetCenter: [0, "30%"] },
      detail: {
        valueAnimation: true,
        fontSize: 40,
        color: "#00c6ff",
        offsetCenter: [0, 0],
        formatter: (v: number) => `${v}%`,
      },
      data: [{ value: 76.5, name: "设备综合效率 OEE" }],
    },
  ],
};

💡 数值动画的原理你早就懂了valueAnimation 就是 Day 50 的 animate() 插值——起点旧值、终点新值、600ms easeOutCubic。ECharts 把它内建进了 gauge/数字类组件。

2.3 状态驱动的颜色变化

/**
 * 按数值动态换进度色:正常蓝 → 警告黄 → 危险红
 * 大屏常见需求:颜色本身携带告警语义
 */
function ringColor(v: number): string {
  if (v >= 90) return "#ff4d4f";
  if (v >= 80) return "#ffd666";
  return "#00c6ff";
}

chart.setOption({
  series: [{
    type: "gauge",
    progress: { itemStyle: { color: ringColor(currentValue) } },
    detail: { color: ringColor(currentValue) },
    data: [{ value: currentValue }],
  }],
});

三、radar 雷达图:设备健康度多维评估

3.1 为什么用雷达

设备健康度是多维度综合指标(温度稳定性、振动、能耗效率、故障率、维护及时性)——柱状图看不出"哪一维是短板拖了整体",雷达图的面积和凹陷一眼可读。

3.2 实现

/**
 * 设备健康度雷达图:单设备 vs 厂区平均(对比才有意义)
 */
const radarOption = {
  radar: {
    // ⭐ indicator 定义维度(名称 + 各维最大值——各维量纲不同,必须显式给 max)
    indicator: [
      { name: "温度稳定性", max: 100 },
      { name: "振动控制", max: 100 },
      { name: "能耗效率", max: 100 },
      { name: "故障率控制", max: 100 },
      { name: "维护及时性", max: 100 },
    ],
    shape: "polygon",           // 'polygon' 多边形 | 'circle' 圆形
    splitNumber: 4,
    axisName: { color: "#6a7a94" },
    splitLine: { lineStyle: { color: "rgba(106,122,148,0.2)" } },
    splitArea: { show: false },
  },
  series: [
    {
      type: "radar",
      data: [
        {
          value: [92, 68, 85, 74, 90],
          name: "3号机组",
          areaStyle: { color: "rgba(0,198,255,0.25)" },   // 半透明面积:健康度直观化
          lineStyle: { color: "#00c6ff" },
        },
        {
          value: [80, 80, 78, 82, 75],
          name: "厂区平均",
          lineStyle: { color: "#6a7a94", type: "dashed" },
          symbol: "none",
        },
      ],
    },
  ],
};

3.3 雷达图的使用纪律

  • 维度 3~7 个:少于 3 个不像雷达,多于 7 个挤成一团看不清
  • 各维 max 必须统一量纲(都换算成 0~100 分),否则面积比较失去意义
  • 必须对比着画(vs 历史值 / vs 平均值),单一个体孤零零一张雷达没有信息量

四、graph 拓扑图:连接关系的可视化

4.1 你已经写过拓扑编辑器

第 7 周 BOSS 战的流程图编辑器(节点 + 贝塞尔连线 + 拖拽)就是手工版拓扑图。ECharts graph 系列是它的声明版——数据给你,布局和绘制它来。

4.2 力引导布局 vs 固定布局

/**
 * 产线拓扑:固定坐标布局(工业场景首选——产线位置是物理事实,不能"力引导"乱飘)
 */
const graphOption = {
  series: [
    {
      type: "graph",
      layout: "none",            // ⭐ 固定坐标(x/y 自己给);'force' 是力引导自动布局
      symbol: "roundRect",
      symbolSize: [90, 40],      // 节点尺寸:宽90 高40(近似流程图节点)
      roam: true,                // 允许缩放平移(复用你写过的 viewport 能力)
      label: { show: true, color: "#e0e8f0" },
      edgeSymbol: ["none", "arrow"],          // 连线末端箭头
      edgeSymbolSize: 8,
      // 节点数据(类比第 7 周的 FlowNode)
      data: [
        { id: "n1", name: "原料上料", x: 100, y: 200, itemStyle: { color: "#1a2740", borderColor: "#3a4a6a" } },
        { id: "n2", name: "加热炉", x: 300, y: 200, itemStyle: { color: "#2a1a20", borderColor: "#ff4d4f" } },   // 异常节点红边
        { id: "n3", name: "轧制", x: 500, y: 200 },
        { id: "n4", name: "质检", x: 300, y: 350 },
      ],
      // 连线数据(类比 FlowEdge)
      edges: [
        { source: "n1", target: "n2" },
        { source: "n2", target: "n3" },
        { source: "n3", target: "n4" },
        // 异常链路:红色高亮(第 7 周"连线选中态"的业务化)
        { source: "n2", target: "n3", lineStyle: { color: "#ff4d4f", width: 2 } },
      ],
    },
  ],
};

4.3 力引导布局什么时候用

// 关系网络没有物理位置(组织关系、告警传播链)时用 force:
series: [{
  type: "graph",
  layout: "force",
  force: {
    repulsion: 200,        // 节点间斥力(越大摊得越开)
    edgeLength: [60, 120], // 边长范围
    gravity: 0.1,          // 向心力(防止飞散)
  },
  data: orgNodes,
  edges: orgEdges,
}]

🎯 选型口诀:有物理位置用 none + 坐标(产线/管网),纯关系用 force(组织/传播链)。工业场景 90% 是前者。


五、象形柱 pictorialBar:能耗排名

普通柱状图的柱子是矩形,象形柱把柱子换成图标/形状——大屏上"车间能耗排名"用能量符号、人员排名用人形符号,视觉记忆点拉满。

/**
 * 车间能耗排名:symbolRepeat 象形柱
 * 原理:用重复的小图标堆叠出"柱子",数量即数值——像温度计刻度
 */
const pictorialOption = {
  grid: { left: 80, right: 40, top: 20, bottom: 30, containLabel: true },
  xAxis: { type: "value", show: false },
  yAxis: {
    type: "category",
    inverse: true,                      // ⭐ 排名从上往下:第 1 名在顶
    data: ["3车间", "1车间", "4车间", "2车间"],
  },
  series: [
    // 第一层:背景槽(灰色全长度,形成"进度槽"视觉)
    {
      type: "pictorialBar",
      symbol: "rect",
      symbolRepeat: true,               // 重复堆叠
      symbolSize: [14, 6],              // 每个小块的尺寸
      symbolMargin: 2,                  // 块间距
      symbolClip: true,                 // ⭐ 裁剪:只显示数据长度部分
      data: [98, 85, 72, 60],
      itemStyle: { color: "#00c6ff" },
      z: 1,                             // 前景层
      animationDuration: 1200,
    },
    {
      type: "pictorialBar",
      symbol: "rect",
      symbolRepeat: true,
      symbolSize: [14, 6],
      symbolMargin: 2,
      symbolClip: false,                // 背景层:不裁剪,全长度
      data: [100, 100, 100, 100],
      itemStyle: { color: "rgba(26,39,64,0.8)" },
      z: 0,                             // 背景层
    },
  ],
};

双 pictorialBar 叠加(前景裁剪 + 背景全长)是排名组件的标准技法——原理就是你 Day 44 的 clip 蒙版思维:背景全画、前景按数据比例裁剪


六、主题定制:统一工业深色风

6.1 为什么不用默认主题

默认 ECharts 是浅色调——逐图改配置会改到吐且不一致。主题 = 把所有图表的默认样式集中定义一次

6.2 注册自定义主题

import * as echarts from "echarts";

/**
 * 工业深色主题:一次定义,处处生效
 * 所有图表 init 时传主题名,不再逐图写 textStyle
 */
const industrialDark = {
  backgroundColor: "transparent",
  textStyle: { color: "#8fa3c0", fontFamily: "sans-serif" },
  title: { textStyle: { color: "#e0e8f0" }, left: "center" },
  legend: { textStyle: { color: "#8fa3c0" } },
  categoryAxis: {
    axisLine: { lineStyle: { color: "#3a4a6a" } },
    axisTick: { show: false },
    axisLabel: { color: "#6a7a94" },
    splitLine: { show: false },
  },
  valueAxis: {
    axisLine: { show: false },
    axisLabel: { color: "#6a7a94" },
    splitLine: { lineStyle: { color: "rgba(106,122,148,0.15)" } },
  },
  color: [
    "#00c6ff", "#00ff88", "#ffd666", "#ff4d4f",
    "#7b61ff", "#ff85c0", "#36cfc9", "#ffc53d",
  ],   // 调色盘:系列自动轮询取色
};

echarts.registerTheme("industrial-dark", industrialDark);

// 使用:
const chart = echarts.init(el, "industrial-dark");

6.3 主题的工程价值

  • 改一处全局生效:品牌色调整时只改 industrialDark
  • 图表一致性:大屏上 10 个图表的刻度色/网格线完全一致(人眼对不一致极敏感)
  • 配置瘦身:每个 option 里不再重复写颜色,可读性回升

七、大屏适配:transform scale 下的图表策略

7.1 大屏缩放的通用方案

工业大屏(如 3840×2160 目标屏)通常按 1920×1080 设计,再用 CSS 整体放大:

/**
 * 大屏整体缩放:设计稿 1920×1080,按目标分辨率 transform scale
 * ⚠️ 这会带来 canvas 模糊问题(见下)
 */
function fitScreen(): void {
  const designW = 1920, designH = 1080;
  const scaleX = window.innerWidth / designW;
  const scaleY = window.innerHeight / designH;
  const scale = Math.min(scaleX, scaleY);   // 等比缩放防变形
  const el = document.querySelector<HTMLElement>("#screen")!;
  el.style.transform = `scale(${scale})`;
  el.style.transformOrigin = "left top";
  el.style.width = `${designW}px`;
  el.style.height = `${designH}px`;
}
window.addEventListener("resize", fitScreen);
fitScreen();

7.2 canvas 模糊的修复

transform: scale(2) 会把 canvas 像素拉伸 2 倍——位图放大必糊。修复:按目标物理分辨率重设 canvas 尺寸,再让 ECharts 按逻辑尺寸布局

/**
 * 高清大屏初始化:devicePixelRatio 之外再乘大屏缩放比
 * echarts.init 的 opts.devicePixelRatio 支持显式指定(不读浏览器默认值)
 */
function initCrispChart(el: HTMLElement, screenScale: number): echarts.ECharts {
  return echarts.init(el, "industrial-dark", {
    // 总像素比 = 浏览器 DPR × 大屏缩放比
    devicePixelRatio: (window.devicePixelRatio || 1) * screenScale,
  });
}

7.3 字号的档位设计

大屏文字规范(设计稿 1080p 基准):

元素 字号 说明
KPI 大数字 40~56px 三米外可读
图表标题 18~20px
轴标签 12~13px 再小就是装饰不是信息
图例/单位 11~12px

反模式:把 4K 屏当 1080p 用(不缩放、字号全调大 2 倍)——ECharts 内部布局按 CSS 像素算,字号翻倍会把轴标签挤爆,一定要走 7.1+7.2 的缩放路线。


八、常见坑点

坑 1:gauge 数值动画在频繁更新时"抽搐"

每秒 setOption 一次 value,动画永远播不完就重开。修复:数据更新频率 > 1 次/秒时关 valueAnimation,或把动画时长调短到 800ms 以下。

坑 2:radar 各维量纲不统一

一维是"次数"(0~2000)、一维是"百分比"(0~100),面积图完全失真。修复:先归一化到统一分数(0~100),indicator.max 全部设 100。

坑 3:graph 节点坐标超出视野

layout: ‘none’ 时坐标是自己给的,节点飞出容器看不见。修复:数据准备阶段做坐标归一化(映射到 0~1000 的逻辑坐标系),roam 允许用户平移微调。

坑 4:pictorialBar 双层没对齐

前景层和背景层的 symbolSize/symbolMargin 不一致导致错位。修复:抽成共享常量。

坑 5:transform scale 后图表模糊

见 7.2——devicePixelRatio 显式传 浏览器 DPR × 缩放比。验证方法:截屏放大看刻度文字边缘有没有毛刺。

坑 6:主题注册了但没生效

echarts.registerTheme 必须在 echarts.init(el, "industrial-dark") 之前执行(模块加载顺序问题)。修复:主题文件作为独立模块,在入口文件顶部 import。


九、自测挑战

T1 · 三表盘组件(40 分钟)

用 2.2 的进度环做一个"三设备温度"组件行:每个 gauge 独立实例、状态色动态变化、valueAnimation 平滑过渡。今天核心作业,直接复用到明天 BOSS 战

T2 · 雷达对比图(20 分钟)

设备体检雷达:本机 vs 历史均值 双系列,面积半透明。给一维故意做凹陷,验证"短板一眼可见"。

T3 · 产线拓扑(30 分钟)

用 graph + layout: ‘none’ 画 6 节点产线拓扑(含 1 个故障红节点 + 1 条异常红连线),开 roam 拖拽缩放——对比第 7 周手写编辑器,写 200 字"ECharts 替我省了什么/我手写版多了什么"。

T4 · 主题 + 缩放集成(30 分钟)

注册 industrial-dark 主题,做 1920×1080 设计稿 + transform scale 大屏壳,验证 7.2 的 devicePixelRatio 修复前后截图对比(放大看文字边缘)。


十、总结

今天的零件清单(明天 BOSS 战的全部素材):

零件 用途 关键配置
进度环 gauge KPI/温度/压力 progress.show + pointer: false + valueAnimation
radar 设备健康度 indicator 统一量纲 + 双系列对比
graph 产线拓扑 layout: 'none' + roam + 状态色
pictorialBar 能耗排名 双层叠加 + symbolClip
industrial-dark 主题 全局风格统一 registerTheme
大屏缩放 分辨率适配 transform scale + 显式 devicePixelRatio

明天 BOSS 战:工厂设备监控面板——今天全部零件 + Day 53 的联动面板骨架 + Day 54 的性能武器 + 可拔插数据源(为第 9 周 WebSocket 埋好的接口),组装成阶段 2 大屏项目的图表模块预演。

评论