HMI 主题系统
Darra HMI 提供 39 种预设主题,覆盖现代仪表盘、工业 SCADA、数字孪生、触摸屏等多种场景。主题系统基于 CSS 变量体系,切换主题 = 切换 <body class="theme-xxx">,所有 <darra-*> 控件自动跟随。
主题与皮肤的关系:主题 = 完整的视觉方案(颜色 + 字体 + 间距 + 圆角 + 阴影 + 背景纹理),皮肤 = 主题的 CSS 变量层。每个主题对应一个皮肤文件,用户可基于现有主题创建自定义皮肤。
主题架构
Darra HMI 主题系统
│
├── 基础主题层 (CSS 变量)
│ ├── --darra-bg, --darra-panel-bg, --darra-text, ...
│ └── 所有 darra-* 控件自动消费
│
├── 控件主题层 (Shadow DOM / CSS Parts)
│ ├── darra-button, darra-gauge, darra-trend ...
│ └── 每个控件内部使用 CSS 变量 + 部件样式
│
├── Chart.js 主题层
│ ├── 柱状图 / 折线图 / 饼图配色
│ └── 通过 Darra.setTheme() 自动同步
│
└── DevExtreme 主题层
├── dx-theme-material / dx-theme-generic / dx-theme-fluent
└── 通过 DevExtreme ThemeManager 切换
主题文件位于 Darra_Software_PLC/Darra_PLC_Service/HMI/Static/themes/,每个主题一个 CSS 文件:
themes/
├── modern.css # 现代深色(默认)
├── industrial.css # 工业浅色
├── motion.css # 运动控制
├── robot.css # 机器人示教器
├── digital-twin.css # 数字孪生
├── touch-panel.css # 触摸屏大按钮
├── high-contrast.css # 高对比度(无障碍)
├── ...
└── custom/ # 用户自定义主题目录
└── brand-red.css
主题类型与适用场景
1. 现代风格 (6 种)
| 主题名 | 说明 | 适用场景 |
|---|---|---|
modern | 现代深色,蓝紫主色 | 数据大屏、车间总览 |
modern-light | 现代浅色,蓝紫主色 | 办公区监控 |
ocean | 海洋蓝渐变 | 水处理、船舶 |
aurora | 极光绿渐变 | 新能源、环保 |
sunset | 暖橙渐变 | 冶金、热处理 |
graphite | 石墨灰,极简 | 高端设备、展厅 |
2. 工业风格 (8 种)
| 主题名 | 说明 | 适用场景 |
|---|---|---|
industrial | 经典工业,浅色绿底黑字 | 通用 SCADA |
industrial-dark | 工业深色 | 昏暗机房 |
steel | 冷钢灰 | 冶金、重工 |
petrochemical | 石化蓝 | 化工、炼油 |
pharma | 医药白,洁净 | 医药、食品 |
water | 水务蓝 | 水处理、泵站 |
energy | 能源绿 | 电力、光伏 |
logistics | 物流橙 | 仓储、分拣 |
3. ECharts 风格 (6 种)
ECharts 主题专用于 Chart.js / ECharts 图表渲染,提供专业级配色方案:
| 主题名 | 说明 | 色板特征 |
|---|---|---|
echarts-default | ECharts 默认色板 | 蓝-红-黄-绿-紫 |
echarts-mint | 薄荷清新 | 青-绿-蓝渐变 |
echarts-roma | 暖色调 | 橙-红-棕-黄 |
echarts-macarons | 马卡龙柔和 | 粉-蓝-紫-黄低饱和 |
echarts-shine | 明亮高对比 | 纯色高饱和,适合大屏 |
echarts-walden | 北欧风 | 灰蓝-米白-墨绿 |
4. DevExpress 风格 (6 种)
DevExpress 主题作用于 <darra-dx-*> 控件(DataGrid / TreeList / PivotGrid / Form / Gauge 等):
| 主题名 | 说明 |
|---|---|
dx-material-blue | Material Design 蓝 |
dx-material-teal | Material Design 青 |
dx-material-purple | Material Design 紫 |
dx-generic-light | 通用浅色 |
dx-generic-dark | 通用深色 |
dx-fluent | Fluent Design(Windows 11 风格) |
5. 数字孪生风格 (5 种)
专为 3D 场景、数字孪生、元宇宙风格 HMI 设计:
| 主题名 | 说明 | 适用场景 |
|---|---|---|
digital-twin | 数字孪生默认,暗色发光 | 3D 工厂仿真 |
cyberpunk | 赛博朋克,霓虹紫 | 展示、概念 |
hologram | 全息蓝,透明效果 | 科技展厅 |
matrix | 矩阵绿 | 数据可视化 |
glassmorphism | 毛玻璃效果 | 现代 UI |
6. 触摸屏风格 (5 种)
针对触摸屏操作优化,按钮更大、间距更宽、交互反馈更明显:
| 主题名 | 说明 |
|---|---|
touch-panel | 通用触摸,48px 最小触摸目标 |
touch-panel-dark | 触摸深色 |
touch-heavy | 重工业触摸(戴手套操作) |
kiosk | 自助查询机,大字 |
mobile | 手机竖屏优化 |
7. 无障碍与辅助 (3 种)
| 主题名 | 说明 |
|---|---|
high-contrast | 高对比度白底黑字 |
high-contrast-dark | 高对比度黑底白字 |
colorblind-safe | 色盲安全配色(蓝-橙主色,避开红-绿) |
主题切换
运行时切换(JS API)
Darra.setTheme('industrial')
console.log(Darra.getTheme()) // 'industrial'
切换时自动完成:
<body class="theme-industrial">更新- 所有
<darra-*>控件重绘 - Chart.js 图表配色同步更新
- DevExtreme 控件主题同步切换
- 触发
themeChanged事件 - 当前主题名存入
localStorage['darra-hmi-theme'],刷新后保持
按钮切换
<button @click="Darra.setTheme('modern')">现代</button>
<button @click="Darra.setTheme('industrial')">工业</button>
<button @click="Darra.setTheme('digital-twin')">数字孪生</button>
项目级默认
在 HMIProjectDef.ActiveSkin 中设置默认主题:
{
"ActiveSkin": "touch-panel",
"AllowUserThemeSwitch": true
}
AllowUserThemeSwitch: false 可禁用用户侧切换,固定使用项目默认主题。
按页面指定主题
// 在 pageEnter 事件中按页面切换
Darra.on('pageEnter', ({ route }) => {
switch (route) {
case '/': Darra.setTheme('modern'); break
case '/alarm': Darra.setTheme('industrial'); break
case '/3d': Darra.setTheme('digital-twin'); break
}
})
自定义主题
方式一:覆盖 CSS 变量(推荐)
在 HMIProjectDef.CustomSkins 中添加自定义皮肤:
{
"CustomSkins": [
{
"Name": "brand-blue",
"DisplayName": "公司蓝",
"BaseTheme": "modern",
"Variables": {
"--darra-primary": "#005A9E",
"--darra-bg": "#0A1628",
"--darra-panel-bg": "#112240",
"--darra-text": "#E6F1FF",
"--darra-success": "#22C55E",
"--darra-warning": "#F59E0B",
"--darra-danger": "#EF4444",
"--darra-border": "#1D3A5C",
"--darra-radius": "6px",
"--darra-font": "'MiSans', 'Segoe UI', sans-serif",
"--darra-shadow": "0 4px 20px rgba(0,90,158,0.2)"
},
"ExtraCss": ".my-header { background: linear-gradient(90deg, #005A9E, #0077BE); }"
}
],
"ActiveSkin": "brand-blue"
}
| 字段 | 类型 | 说明 |
|---|---|---|
Name | string | 主题标识名,用于 setTheme('brand-blue') |
DisplayName | string | 用户界面显示的名称 |
BaseTheme | string | 基础主题名,继承其所有 CSS 变量 |
Variables | object | 要覆盖的 CSS 变量键值对 |
ExtraCss | string | 额外的 CSS 规则 |
BaseTheme 支持以下值:modern / industrial / touch-panel / high-contrast / digital-twin。
方式二:完整 CSS 文件
在 custom/ 目录下创建完整的主题 CSS 文件:
/* custom/brand-red.css */
body.theme-brand-red {
--darra-bg: #1A0A0A;
--darra-panel-bg: #2D1515;
--darra-text: #FFE6E6;
--darra-primary: #D7263D;
--darra-success: #22C55E;
--darra-warning: #F59E0B;
--darra-danger: #FF0000;
--darra-border: #4A2020;
--darra-radius: 4px;
--darra-font: 'MiSans', sans-serif;
--darra-shadow: 0 4px 16px rgba(215,38,61,0.3);
}
然后在 HMIProjectDef.CustomSkins 中引用:
{
"Name": "brand-red",
"DisplayName": "品牌红",
"CssFile": "custom/brand-red.css"
}
主题与品牌定制
品牌色板
企业品牌色板通过覆盖 4 个核心 CSS 变量实现:
| 变量 | 用途 | 品牌映射示例 |
|---|---|---|
--darra-primary | 主品牌色(按钮/链接/图表主线) | 企业标准蓝 #005A9E |
--darra-success | 成功/运行(绿 LED/状态栏) | 品牌辅助绿 #2E7D32 |
--darra-warning | 告警(黄/橙) | 品牌警告色 #ED6C02 |
--darra-danger | 危险/停止(红 LED/急停) | 品牌红色 #C62828 |
企业字体
{
"Variables": {
"--darra-font": "'CompanyBrand', 'MiSans', 'Segoe UI', sans-serif"
},
"ExtraCss": "@font-face { font-family: 'CompanyBrand'; src: url('/static/fonts/brand.woff2') format('woff2'); }"
}
字体文件放在 HMI 静态资源的 fonts/ 目录下,随 Service 分发。
背景与 Logo
{
"ExtraCss": "body { background-image: url('/static/img/company-bg.png'); background-size: cover; } .logo { background-image: url('/static/img/logo.svg'); }"
}
主题 CSS 变量完整参考
| 变量 | 默认值(modern) | 用途 |
|---|---|---|
--darra-bg | #1A1D23 | 页面底色 |
--darra-panel-bg | #23272E | 面板/卡片底色 |
--darra-text | #E6E8EB | 主文本颜色 |
--darra-text-muted | #8B8FA3 | 次要文本 |
--darra-primary | #4F7CFF | 主色(按钮/链接/图表主线) |
--darra-success | #22C55E | 成功(绿 LED/运行态) |
--darra-warning | #F59E0B | 警告(黄/橙色) |
--darra-danger | #EF4444 | 危险(红 LED/停止/故障) |
--darra-border | #333942 | 边框颜色 |
--darra-radius | 8px | 默认圆角 |
--darra-font | 'MiSans','Segoe UI',sans-serif | 字体族 |
--darra-shadow | 0 4px 16px rgba(0,0,0,0.3) | 默认阴影 |
--darra-grid-gap | 16px | 网格布局间距 |
--darra-gauge-bg | #2A2E36 | 仪表盘背景 |
--darra-input-bg | #2A2E36 | 输入框底色 |
--darra-input-border | #4A4E58 | 输入框边框 |
--darra-hover | rgba(79,124,255,0.1) | 悬浮态高亮 |
--darra-selected | rgba(79,124,255,0.2) | 选中态高亮 |
--darra-touch-target | 32px | 触摸目标最小尺寸 |
主题性能与最佳实践
- 避免运行时切换重负载主题:数字孪生类主题(
digital-twin/cyberpunk)含大量渐变和阴影,切换时建议先显示加载指示 - 自定义主题继承基础主题:用
BaseTheme继承而非完整重写,减少 CSS 体积 - 品牌主题作为项目默认:在
ActiveSkin中指定公司品牌主题,新建项目自动应用 - 色盲安全主题的适用场景:食品/制药行业 FDA 审计建议启用
colorblind-safe - 触摸屏主题的触控优化:
touch-panel主题自动将最小触摸目标提升至 48px,适合手套操作 - 主题与夜间模式联动:监听
themeChanged事件,Chart.js 图表同步调用chart.update('none')
排错表
| 现象 | 原因 | 解决 |
|---|---|---|
| 切换主题后控件颜色不变 | CSS 变量未更新 | 检查 ExtraCss 中是否覆盖了 --darra-* 变量 |
| 自定义主题不生效 | BaseTheme 拼写错误 | 检查 BaseTheme 名称是否与内置主题名完全一致 |
| Chart.js 图表未跟随主题 | 图表未调用 update | 在 themeChanged 事件中调用 chart.update() |
| 主题文件 404 | 文件未部署 | 确认 CSS 文件在 HMI/Static/themes/ 目录下 |