Day 55 · 工业大屏常用图表 — 仪表盘、雷达、拓扑与主题定制
工业大屏的图表选型和互联网 BI 完全不同:BI 追求信息密度,大屏追求三米外一眼可读。今天的四类图表是工业大屏的高频主角:gauge 仪表盘(设备温度/压力/液位)、radar 雷达图(设备健康度多维评估)、graph 拓扑图(产线/管网连接关系)、pictorialBar 象形柱(能耗排名)。外加两个工程能力:主题定制(统一工业深色风)和大屏适配(transform scale 下的图表策略)。明天 BOSS 战的全部零件今天备齐。
目录
- 一、工业大屏图表选型地图
- 二、gauge 仪表盘:设备状态的第一现场
- 三、radar 雷达图:设备健康度多维评估
- 四、graph 拓扑图:连接关系的可视化
- 五、pictorialBar 象形柱:能耗排名
- 六、主题定制:统一工业深色风
- 七、大屏适配:transform scale 下的图表策略
- 八、常见坑点
- 九、自测挑战
- 十、总结
一、工业大屏图表选型地图
| 图表 | 回答的问题 | 工业场景 | 大屏占比 |
|---|---|---|---|
| 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 大屏项目的图表模块预演。