@nywqs/scada-engine
v2.0.3
Published
自研 SCADA 组态引擎 - 基于 AntV X6
Downloads
898
Maintainers
Readme
@nywqs/scada-engine
基于 AntV X6 + Vue 3 的自研 SCADA 组态引擎。旨在为工业物联网(IIoT)提供高性能、可扩展的可视化组态解决方案,支持拖拽式界面设计、实时数据绑定及复杂的流程编排。
特性
- 🛠 可视化编辑器:基于 AntV X6 构建的专业级图形编辑能力,支持节点拖拽、连线编排、框选复制等操作。
- 📦 丰富组件库:
- 基础组件:矩形、圆形、文本等基础矢量图形。
- IoT 组件:支持 ECharts 图表(仪表盘、折线图)、3D 设备模型(电机、管道、阀门、储罐等)、指示灯、开关等工业控件。
- 🔗 多源数据集成:内置服务层,支持 WebSocket、MQTT、HTTP 请求及 SSE(Server-Sent Events)等多种实时数据接入方式。
- 🎨 动画引擎:内置独立的动画调度器(AnimationScheduler)与动画引擎(AnimationEngine),支持脉冲、闪烁、旋转等节点特效。
- ⚙️ 流程编排:内置可视化工作流编辑器(Workflow Editor),支持通过逻辑节点(条件判断、定时器、HTTP 请求、自定义代码)编排复杂业务流程。
- 🔐 授权与安全:基于 ECDSA P-256 + SHA-256 的数字签名授权机制,保障软件使用安全。
- 🚀 性能优化:支持视口裁剪(Viewport Culling)技术,在保证视觉效果的同时优化大数据量场景下的渲染性能。
安装
环境要求
确保你的项目中已安装以下依赖:
npm install vue@^3.4.0 @antv/x6@^3.1.6 echarts@^5.5.0 pinia@^2.1.0 @vueuse/core@^10.0.0安装引擎
npm install @nywqs/scada-engine
# 或
pnpm add @nywqs/scada-engine
# 或
yarn add @nywqs/scada-engine快速开始
1. 全局注册
在你的应用入口文件(如 main.ts)中引入并注册组件:
import { createApp } from 'vue'
import ScadaEngine from '@nywqs/scada-engine'
import '@nywqs/scada-engine/dist/scada-engine.css' // 引入样式
import App from './App.vue'
const app = createApp(App)
app.use(ScadaEngine)
app.mount('#app')2. 在组件中使用
最核心的组件是 ScadaCanvas,它承载了画布编辑器和预览功能。
<template>
<div class="scada-container" style="width: 100vw; height: 100vh;">
<ScadaCanvas
ref="canvasRef"
:auth-code="authCode"
@node-click="handleNodeClick"
/>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ScadaCanvas } from '@nywqs/scada-engine'
const canvasRef = ref()
const authCode = '你的授权码' // 商业版本需要
const handleNodeClick = (node) => {
console.log('点击了节点:', node.id)
}
// 使用 API 方法
onMounted(() => {
// 添加节点
canvasRef.value?.addNode('rect')
// 获取画布数据
const data = canvasRef.value?.getCanvasData()
console.log('画布数据:', data)
})
</script>
<style scoped>
.scada-container {
position: relative;
}
</style>3. 自定义组件注册
你可以注册自定义的 SCADA 组件:
import { componentRegistry } from '@nywqs/scada-engine'
// 注册自定义组件
componentRegistry.register({
type: 'custom-sensor',
name: '自定义传感器',
category: 'iot',
icon: '🔌',
defaultSize: { width: 100, height: 100 },
props: {
value: { type: 'number', default: 0 },
unit: { type: 'string', default: '°C' }
},
component: () => import('./components/CustomSensor.vue')
})4. 数据绑定与实时更新
import { dataSourceManager } from '@nywqs/scada-engine'
// 配置 WebSocket 数据源
await dataSourceManager.addSource({
id: 'ws-1',
type: 'websocket',
url: 'ws://localhost:8080',
autoConnect: true
})
// 订阅数据更新
dataSourceManager.subscribe('device_01.temperature', (value) => {
console.log('温度更新:', value)
})目录结构
项目采用了清晰的模块划分:
src/
├── components/ # 核心 UI 组件
│ ├── canvas/ # 画布组件
│ │ ├── ScadaCanvas.vue # 核心画布组件
│ │ ├── composables/ # 画布组合式 API
│ │ ├── config/ # 画布配置
│ │ └── types/ # 画布类型定义
│ ├── configurators/ # 配置器组件
│ │ ├── BindingCard.vue # 数据绑定配置
│ │ ├── EventCard.vue # 事件配置
│ │ └── ...
│ ├── dialogs/ # 对话框组件
│ │ ├── AttributeConfigDialog.vue
│ │ ├── CustomCodeDialog.vue
│ │ └── ...
│ ├── layout/ # 布局组件
│ │ ├── Header.vue # 顶部工具栏
│ │ └── Footer.vue # 底部版权栏
│ ├── panels/ # 面板组件
│ │ ├── PropertyPanel.vue # 属性面板
│ │ ├── ComponentLibrary.vue # 组件库面板
│ │ ├── CanvasConfigPanel.vue # 画布配置面板
│ │ └── ContextMenu.vue # 右键菜单
│ └── property-tabs/ # 属性标签页
│ ├── BasicPropertiesTab.vue
│ ├── DataPropertiesTab.vue
│ └── EdgePropertiesTab.vue
├── scada-components/ # SCADA 组件库
│ ├── basic/ # 基础图形组件
│ │ ├── rect.ts # 矩形组件
│ │ ├── circle.ts # 圆形组件
│ │ └── text.ts # 文本组件
│ ├── iot/ # IoT 设备组件
│ │ ├── echarts-gauge/ # ECharts 仪表盘
│ │ ├── echarts-line/ # ECharts 折线图
│ │ └── model3d/ # 3D 设备模型
│ ├── svg/ # SVG 组件系统
│ │ ├── core/ # SVG 核心(加载器、解析器)
│ │ ├── rendering/ # SVG 渲染引擎
│ │ ├── helpers/ # SVG 辅助工具
│ │ └── examples/ # SVG 示例组件
│ ├── canvas/ # 画布配置管理
│ │ ├── config.ts # 预设配置
│ │ ├── manager.ts # 配置管理器
│ │ └── types.ts # 类型定义
│ ├── registry.ts # 组件注册表
│ └── types.ts # 组件类型定义
├── services/ # 数据服务层
│ ├── dataSourceManager.ts # 数据源管理器
│ ├── websocketService.ts # WebSocket 服务
│ ├── mqttService.ts # MQTT 服务
│ ├── httpService.ts # HTTP 服务
│ ├── sseService.ts # SSE 服务
│ └── dataParser.ts # 数据解析器
├── utils/ # 工具函数与引擎核心
│ ├── animation/ # 动画系统
│ │ ├── animation-engine.ts # 动画引擎
│ │ └── animation-scheduler.ts # 动画调度器
│ ├── canvas/ # 画布操作工具
│ │ ├── graph-operations.ts # 画布操作
│ │ ├── node-operations.ts # 节点操作
│ │ ├── edge-operations.ts # 连线操作
│ │ └── layer-manager.ts # 图层管理
│ ├── core/ # 核心工具
│ │ ├── common.ts # 通用工具
│ │ ├── storage.ts # 本地存储
│ │ ├── file.ts # 文件操作
│ │ └── message.ts # 消息提示
│ ├── data/ # 数据处理
│ │ ├── binding-service.ts # 数据绑定服务
│ │ └── node-property.ts # 节点属性管理
│ ├── events/ # 事件系统
│ │ ├── event-manager.ts # 事件管理器
│ │ ├── event-utils.ts # 事件工具
│ │ └── context-menu.ts # 右键菜单
│ ├── integrations/ # 集成模块
│ │ ├── auth-crypto.ts # 授权加密
│ │ └── draco-loader.ts # 3D 模型加载
│ └── performance/ # 性能优化
│ ├── viewport-culling.ts # 视口裁剪
│ └── worker-manager.ts # Worker 管理
├── views/ # 视图页面
│ ├── workflow/ # 流程编排模块
│ │ ├── WorkflowDialog.vue # 流程编辑对话框
│ │ ├── components/ # 流程组件
│ │ ├── services/ # 流程服务
│ │ └── types/ # 流程类型
│ └── Preview.vue # 预览页面
├── types/ # 全局类型定义
│ ├── device.ts # 设备类型
│ ├── binding.ts # 绑定类型
│ ├── workflow.ts # 流程类型
│ └── ...
├── constants/ # 常量定义
│ ├── theme.ts # 主题常量
│ ├── layout.ts # 布局常量
│ └── animation.ts # 动画常量
├── workers/ # Web Workers
│ └── dataProcessor.worker.ts # 数据处理 Worker
├── styles/ # 全局样式
│ ├── theme.css # 主题样式
│ └── components/ # 组件样式
├── index.ts # 库入口文件
├── main.ts # 开发入口文件
└── App.vue # 根组件核心概念
画布 (ScadaCanvas)
画布是整个系统的核心,提供以下能力:
- 编辑模式:用于设计组态画面。
- 预览模式:用于运行展示,隐藏编辑 UI。
- 数据绑定:支持将设备点位(Point)绑定到组件属性,实时更新显示。
组件注册系统 (ComponentRegistry)
引擎使用了懒加载注册机制来优化性能。
- 支持按分类(
basic,iot)获取组件列表。 - 支持动态注册新组件。
数据服务 (Data Services)
引擎不强制绑定特定后端,提供了灵活的数据接入适配器:
- WebSocket:适用于高频实时数据。
- MQTT:适用于物联网消息订阅。
- HTTP:适用于请求-响应式查询。
- SSE:适用于服务器推送事件。
流程引擎 (Workflow Engine)
内置的可视化脚本系统,允许用户在画布上通过图形化节点编写逻辑,无需编写大量代码即可实现:
- 定时触发任务
- 条件判断分支
- HTTP 外部请求
- 自定义 JavaScript 代码执行
API 参考
ScadaCanvas 方法
通过 ref 可以直接调用画布的操作方法:
| 方法 | 说明 |
|------|------|
| 文件操作 | |
| save() | 保存当前画布数据到 LocalStorage |
| exportFile() | 导出当前画布为 JSON 文件 |
| importFile() | 触发文件选择器导入 JSON |
| 视图操作 | |
| preview() | 跳转到预览页面 |
| workflow() | 打开流程编排弹窗 |
| 画布操作 | |
| zoomIn() / zoomOut() | 放大/缩小画布 |
| setZoom(scale) | 设置画布缩放比例 |
| clearAll() | 清空画布所有元素 |
| 节点操作 | |
| addNode(type) | 添加指定类型的节点 |
| updateNode(data) | 更新节点数据 |
| deleteNode() | 删除当前选中的节点 |
| getSelectedNode() | 获取当前选中的节点 |
| selectNode(nodeId) | 选中指定节点 |
| clearSelection() | 取消选中 |
| 数据访问 | |
| getGraph() | 获取 X6 Graph 实例 |
| getCanvasData() | 获取画布完整数据(包含节点、连线和配置) |
| loadCanvasData(data) | 加载画布数据 |
| getAllNodes() | 获取所有节点 |
| getNodeById(nodeId) | 根据 ID 获取节点 |
| 画布配置 | |
| getConfigManager() | 获取画布配置管理器 |
| updateCanvasConfig(config) | 更新画布配置 |
| setCanvasSize(width, height) | 设置画布大小 |
| setBackgroundColor(color) | 设置背景颜色 |
| 动画控制 | |
| getAnimationEngine() | 获取动画引擎 |
数据结构示例
getCanvasData() 返回的结构大致如下:
{
"version": "1.0",
"config": {
"width": 1920,
"height": 1080,
"grid": true
},
"cells": [
{
"id": "node-1",
"type": "rect",
"x": 100,
"y": 100,
"label": "电机",
"data": { "binding": "device_01_status" }
}
]
}许可证
本项目采用 MIT 许可证。内置的组件库和引擎功能可以免费用于学习和非商业项目。
商业授权:如需将本引擎用于商业产品并隐藏底部版权标识,请联系作者获取数字签名授权。
作者
- nywqs
如有问题或建议,欢迎提交 Issue 或联系作者。
