# 进阶
# 官方后端数据源下载并开发
TIP
官方提供了标准的后端数据源,并同时提供了源代码,首先需要下载数据源源代码,并写好自己的数据源逻辑,启动数据源
- 打开下载的java项目(可以使用 Eclipse 或 IDEA )
- 主要代码介绍 (WebSocketServer)
package com.lazykee.sourcewebsocketzk.server;
import com.alibaba.fastjson.JSON;
import com.lazykee.sourcewebsocketzk.utils.HttpUtil;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @author LAZYKEE
* @version 1.0
* @date 2021/12/30 23:20
*/
@ServerEndpoint("/zkSource")
@Component
public class WebSocketServer {
private static final CopyOnWriteArraySet<WebSocketServer> WEB_SOCKET_SET = new CopyOnWriteArraySet<>();
public Long heartTime;
public static Set<WebSocketServer> getWebSocketSet() {
return WEB_SOCKET_SET;
}
private Session session;
@OnOpen
public void onOpen(Session session) throws IOException {
this.session = session;
WEB_SOCKET_SET.add(this);
this.heartTime = System.currentTimeMillis();
// 发送示例数据
String demo = "{\"num_1_1\":0.2503,\"num_1_2\":0.1752,\"num_10_5\":8.2418,\"num_100_1\":75.6374,\"num_1000_1\":124.023,\"list_10_1\":[3.5628,6.9725,8.3505,4.636,8.6265],\"list_100_1\":[24.5654,99.8544,5.1336,86.5468,55.3747],\"text_1\":\"黄梅时节家家雨\",\"img_1\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAAXNSR0IArs4c6QAAAqRJREFUeF7t1bERgEAMBDEojv5LggaAYNMTuQPLv8N5X8d9+AgQeBU4BeJlEPgWEIjXQeBHQCCeBwGBeAMEmoA/SHMzNSIgkJFDW7MJCKS5mRoREMjIoa3ZBATS3EyNCAhk5NDWbAICaW6mRgQEMnJoazYBgTQ3UyMCAhk5tDWbgECam6kRAYGMHNqaTUAgzc3UiIBARg5tzSYgkOZmakRAICOHtmYTEEhzMzUiIJCRQ1uzCQikuZkaERDIyKGt2QQE0txMjQgIZOTQ1mwCAmlupkYEBDJyaGs2AYE0N1MjAgIZObQ1m4BAmpupEQGBjBzamk1AIM3N1IiAQEYObc0mIJDmZmpEQCAjh7ZmExBIczM1IiCQkUNbswkIpLmZGhEQyMihrdkEBNLcTI0ICGTk0NZsAgJpbqZGBAQycmhrNgGBNDdTIwICGTm0NZuAQJqbqREBgYwc2ppNQCDNzdSIgEBGDm3NJiCQ5mZqREAgI4e2ZhMQSHMzNSIgkJFDW7MJCKS5mRoREMjIoa3ZBATS3EyNCAhk5NDWbAICaW6mRgQEMnJoazYBgTQ3UyMCAhk5tDWbgECam6kRAYGMHNqaTUAgzc3UiIBARg5tzSYgkOZmakRAICOHtmYTEEhzMzUiIJCRQ1uzCQikuZkaERDIyKGt2QQE0txMjQgIZOTQ1mwCAmlupkYEBDJyaGs2AYE0N1MjAgIZObQ1m4BAmpupEQGBjBzamk1AIM3N1IiAQEYObc0mIJDmZmpEQCAjh7ZmExBIczM1IiCQkUNbswkIpLmZGhEQyMihrdkEBNLcTI0ICGTk0NZsAgJpbqZGBAQycmhrNgGBNDdTIwICGTm0NZuAQJqbqREBgYwc2ppNQCDNzdSIgEBGDm3NJiCQ5mZqROABWVrikf/PyvkAAAAASUVORK5CYII=\"}";
sendMessage(demo);
}
@OnClose
public void onClose() {
System.out.println("连接关闭");
WEB_SOCKET_SET.remove(this);
}
@OnMessage
public void onMessage(String message) {
Map map = JSON.parseObject(message, Map.class);
String name = (String) map.get("name");
/**
* 数据源心跳监听接口
* 该接口用户切勿修改,是数据源心跳的监听接口
*/
if ("zk_heart".equals(name)) {
try {
this.session.getBasicRemote().sendText("zk_heart");
this.heartTime = System.currentTimeMillis();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 注册测点登记接口
* 该接口用户切勿修改,可进行逻辑处理
* 接收到的值为:图纸上对该数据源的所有注册点位信息
* 用户可根据注册的点位信息筛选发送的数据
*/
if ("register".equals(name)){
System.out.println("--------------------------------");
System.out.println("收到用户注册测点");
List<String> registerPointList = (List<String>) map.get("data");
for (String point : registerPointList) {
System.out.print(point + ", ");
}
System.out.println("");
System.out.println("--------------------------------");
}
/**
* HTTP GET 代理数据源
* 该接口封装了代理的 HTTP GET 请求接口
* 封装目的:没有同源限制,客户端可以与任意服务器通信
* 返回的数据用户可通过 sendMessage() 方法向页面输出
*/
if ("HTTPGET".equals(name)){
System.out.println("--------------------------------");
System.out.println("收到 HTTPGET 请求");
String url = (String) map.get("url");
Map<String, String> header = (Map<String, String>) map.get("header");
System.out.println(url);
System.out.println(header);
String res = HttpUtil.httpGet(url, header);
System.out.println(res);
System.out.println("--------------------------------");
}
/**
* HTTP POST 代理数据源
* 该接口封装了代理的 HTTP POST 请求接口
* 封装目的:没有同源限制,客户端可以与任意服务器通信
* 返回的数据用户可通过 sendMessage() 方法向页面输出
*/
if ("HTTPPOST".equals(name)){
System.out.println("--------------------------------");
System.out.println("收到 HTTPPOST 请求");
String url = (String) map.get("url");
Map<String, Object> params = (Map<String, Object>) map.get("params");
Map<String, String> header = (Map<String, String>) map.get("header");
String res = HttpUtil.httpPost(url, params, header);
System.out.println(res);
System.out.println("--------------------------------");
}
// 用户动画发送数据
/**
* 接收页面写入的Websocket数据,用户可自行数据进行后续处理
*/
if ("data".equals(name)){
System.out.println("收到用户发送数据");
Object userData = map.get("data");
System.out.println(JSON.toJSONString(userData));
}
}
@OnError
public void onError(Session session, Throwable error) {
}
/**
* 数据推送接口,该接口将数据发送给页面
*/
public static void sendMessage(String message) throws IOException {
for (WebSocketServer item : WEB_SOCKET_SET) {
if (item.session.isOpen()) {
item.session.getBasicRemote().sendText(message);
}
}
}
}
编写好相应的后端数据源逻辑后,启动后端数据源项目
# 前端数据源连接
# 1. 打开数据源管理面板
TIP
数据源管理面板的打开有两种方式:
数据源在点击图纸空白处时,在配置栏选择数据源面板,点击数据源
在用户头像上单击,点击数据源管理
数据源管理面板如图所示
# 2. 在弹出面板点击添加项目
- 输入项目相关信息,点击添加,选择刚才新建的项目
# 3. 新建的项目下,添加数据源
点击添加数据源,输入相关数据源信息
# 4. 建好的数据源添加测点
- 选择新建的数据源,右侧出现数据源配置信息
TIP
- 原始点管理:能从服务器接收到的测点数据信息,可直接勾选进行添加
- 添加原始点:从服务器暂时未获取到的测点数据信息,在后面会有数据,则可以通过手动添加
- 添加中间点:用户需要对原始点数据进行一定的处理和运算,则可以添加中间测点
# 5. 原始点添加
- 点击原始点管理
- 勾选需要的测点,点击保存更改
- 在数据源信息面板可以看到添加好的原始点
TIP
如果原始点管理面板中没有需要的测点,说明这个测点的数据可能是延迟发送的,此时,可以在确定测点数据结构(key)的情况下,手动添加原始点
- 手动添加原始点,点击添加原始点
- 弹出的面板中填写原始点信息
- 点击确定,可在原始点中查看到添加好的原始点
# 6. 添加中间点
TIP
当用户需要对原始测点的结果进行计算或相应的逻辑处理时,可以添加中间点,中间点支持js语法编辑
点击添加中间点
左侧为源测点,可通过点击快速复制引用的测点
- 编辑完成后,点击连接开启,即可观察实时计算值是否正确
# 图纸中数据源添加
TIP
图纸中的数据源支持在数据源中自定义添加的数据源,也可导入管理员预置的数据源
# 1. 点击导入我的数据源
- 展开对应项目,选择数据源进行导入
- 导入成功后,可在数据源列表中查看到数据源
- 点击实时数据查看,可查看该数据源下的实时数据点位值
- 可点击测点列表,查看全部数据源的所有点位信息
# 2. 导入公共数据源
管理员可预置内部数据源,用户可自行导入管理员预置好的数据源进行导入
- 数据源管理内置了数据源的复制和粘贴功能,便于不同图纸间的数据源迁移,点击复制后,将会弹出粘贴数据源的按钮,在对应图纸中点击粘贴即可应用
- 点击更新按钮,数据源将变为可编辑状态,对数据源可进行更改
注:当更改唯一识别码时,会提示是否将绑定测点的key都进行替换,(对于用户脚本中的key,尚无法替换)方便一次更改图纸的所有数据源
- 数据源识别码:当同一张图纸上添加多个数据源时,用户辨别数据测点是来自哪一个数据源,同一张图纸的多个数据源,唯一识别码不可重复
# 元素动画使用
说明
当前版本大部分元素支持动画操作,不支持动画的元素组件有(图表组件、视频组件、Vue组件)
# 动画介绍
动画的类型分为 连续动画、补间动画、事件动画三种,其具体解释如下
连续动画
当图纸/导出网页一旦打开就会启动连续动画,直至网页关闭。(如图形的连续旋转、线条的连续流动、颜色的连续闪烁等等)补间动画
当达到相应的启动条件时,动画过渡到目标状态,当动画达到停止条件时,动画还原到初始状态。(如旋转一定角度、进行一定的位移、背景变为某种颜色、图形进行隐藏/显示等)事件动画 当达到一定条件时,执行相应的特殊条件,如向后台发送请求、播放音频、弹出面板、页面跳转等特殊的动作
# 动画启动/停止条件
启动条件包含立即启动、动作条件启动和数据阈值启动三种
停止条件包含不停止、动作条件停止和数据阈值停止三种
启动条件:立即启动
画布打开后,立即启动该动画启动条件:动作条件启动
通过识别用户的交互动作进行启动,如点击、鼠标移入等,实现动画的启动启动条件:数据阈值启动
通过绑定相应的数据测点,当该数据满足阈值区间时,进行动画的启动停止条件:不停止
动画启动后,不再停止,持续运动下去停止条件:动作条件停止
通过识别用户的交互动作进行启动,如点击、鼠标移入等,实现动画的停止停止条件:数据阈值停止
通过绑定相应的数据测点,当该数据满足阈值区间时,进行动画的停止
# 添加一个立即启动动画
- 设置动画参数
其他参数说明
- 执行动作:动画的动作类型
- 旋转中心:动画运动时围绕的中心点
- 旋转方向:正向/逆向旋转
- 速度绑定:绑定数据测点,运动的速度随测点值的变化而变化
- 速度:运动的速度,范围在0-100之间
- 添加动画,长按F1预览动画效果,按F4打开预览窗口
# 添加一个随数据变化启动/停止的动画
- 将启动条件设置为数据阈值启动,将停止条件设置为数据阈值停止
- 点击测点选择,在弹出面板中选择需要的测点
- 配置项说明
- 测点选择:选择触发动画的数据测点
- 启动判断:
设置启动/停止时数值判断时,条件框以x
标识当前的测点值,使用js语法进行条件的判断
- 如当需要测点值
大于 5
时启动条件应设置为
x > 5
- 如当需要测点值
等于 1
时启动条件应设置为
x === 1
- 当需要测点值
大于等于3,并且小于8
的时候启动,则启动条件应设置为
3 <= x < 8
或
(x >= 3) && (x < 8)
- 当需要测点值
小于3,或大于等于8
的时候启动,则启动条件应设置为
(x < 3) || (x >= 8)
其他配置参数参考上述介绍
# 添加一个随数据大小动画速度随之改变的动画
- 打开速度绑定
- 点击测点选择,在弹出面板中选择需要的测点
- 设置速度测点值
说明:速度测点值为从数据源接收的测点数据值
如测点数据值的范围在[10, 20]
之间,则速度测点值可设置为 10 - 20, 当接收到的值为 10 时,动画的速度为0(停止运动),当测点值为20时,速度达到100(速度最大值)
# 数据绑定
数据绑定介绍
通过于数据测点进行数据绑定,可以实现随着数据的变化,页面数据的实时更新显示,页面元素的高度、宽度、位置、角度随数据变化而变化的效果,数据绑定案例如:
- 页面实时数据展示
- 水池水位实时图形化展示
- 小车位置位置坐标实时图形化左边展示
- 仪表指针随数值变化旋转到对应位置
- ...
# 显示测点实时数据
- 使用Text文本元素(基础形状/文本)
- 配置数据绑定测点
- 其他配置:
- 绑定类型:选择为数据显示
- 保留小数点:配置显示的测点数据的保留位数
- 添加绑定,通过
F2
快速预览数据效果,或F4
打开预览窗口
# 根据数据变化相应的效果(水位示例)
- 添加一个背景元素,作为水池外壳效果,示例设置高度为400
- 添加一个数据绑定元素,作为水位展示元素,示例设置高度为10(最低水位高度)
- 设置数据绑定元素的
样式/边框缩放
为关闭
- 为数据绑定元素添加数据绑定配置
- 高度变化值:
本示例中背景高度为400,绑定元素高度为10
高度的变化值为 10 + 变化值 = 最高水位值
即当数值为水位最小值时(水空位数值)绑定元素的高度为10 + 0
数值为水位最大值时(水满位数值)为10 + 390
等于背景的最大高度 - 零刻度值:当水位最低点时对应的测点值数值
- 满刻度值:当水位最高点时对应的测点值数值
如水位传感器的变化范围在 [80, 160]之间,则零刻度值为80
,满刻度值为160
参考中心:参考中心为图形变化时,位置不动的基点
参考中心有以下几种
如水位变化时,需要水位高度向上变化,则设置底部中央为基点,高度变化朝上方增加或减少