乐吾乐大屏上动态绘制卡片界面

45 阅读3分钟

乐吾乐大屏上动态绘制卡片界面

自动渲染界面上的故障详情

公司最近用乐吾乐大屏可视化组态软件这个编辑工具,因为工具支持以2D/2.5D等形式构建实时数据展示、监控告警、动态交互的组态画面,完全满足国产化需求。(上面这么多基本不用看 我就是复制官网的介绍语介绍下)其实主要是目的就是把自己写的东西记录下来

开始

1. 导入数据

image.png 注意这里导入的数据,属性名 和ws接口推送过来的id要保持一致,不然数据不能同步

image.png

ae9d793d1f8b7a20c170892be86a2700.png

2. 在初始化中开始写代码

image.png

在这个里面将静态界面绘制出来


let newArr = meta2d.store.data.networks[0].children; //获取刚才导入的excel数据
const bottleImage = "/file/2025/0227/1/1/绿色边框_5496fd7b.png";
const normalIcon = "/file/2025/0227/1/1/正常_dfae3f67.png";
const warningIcon = "/file/2025/0227/1/1/预警_2a00e0ce.png";

// 按比例缩小的尺寸
const startX = 74;
const startY = 74;
const BGSizeW = 337; // 原421 * 0.8
const BGSizeH = 66;  // 原82 * 0.8
const horizontalSpacing = 16; // 原20 * 0.8
const verticalSpacing = 16;   // 原20 * 0.8
const colsPerRow = 5;

// 按类别分组
const groupedData = {};
newArr.forEach(item => {
    const category = item.label.split('#')[0] + '#';

    if (!groupedData[category]) {
        groupedData[category] = [];
    }
    groupedData[category].push(item);
});

let currentY = startY;
const categories = Object.keys(groupedData);

for (let catIndex = 0; catIndex < categories.length; catIndex++) {
    const category = categories[catIndex];
    const categoryItems = groupedData[category];

    // 如果是第一个类别之后,增加额外的垂直间距
    if (catIndex > 0) {
        currentY += verticalSpacing * 2;
    }

    for (let i = 0; i < categoryItems.length; i++) {
        const row = Math.floor(i / colsPerRow);
        const col = i % colsPerRow;

        const bgX = startX + col * (BGSizeW + horizontalSpacing);
        const bgY = currentY + row * (BGSizeH + verticalSpacing);

        // 添加背景图(按比例缩小)
        meta2d.addPen({
            image: bottleImage,
            x: bgX,
            y: bgY,
            width: BGSizeW,
            height: BGSizeH,
            id: `bg_${category}_${i + 1}`,
            name: "image",
            canvasLayer: 3,
        }, true, true, true);

        // 添加状态图标(按比例缩小)
        const statusIcon = categoryItems[i].value == "0" ? warningIcon : normalIcon;
        meta2d.addPen({
            image: statusIcon,
            x: bgX + 8,  // 缩小偏移量
            y: bgY + 16, // 缩小偏移量
            width: 32,   // 原40 * 0.8
            height: 32,  // 原40 * 0.8
            id: categoryItems[i].id + 'status',
            name: "image",
            canvasLayer: 3,
        }, true, true, true);

        // 添加文本标签(按比例缩小)
        meta2d.addPen({
            text: categoryItems[i].label,
            x: bgX + 48, // 缩小偏移量
            y: bgY + (BGSizeH - 32) / 2, // 调整垂直居中
            height: 32,  // 原40 * 0.8
            width: 265,  // 原331 * 0.8
            textAlign: "center",
            color: categoryItems[i].value == '0' ? "#ff5959" : "#000000",
            fontStyle: "bold",
            fontSize: 18, // 原22 * 0.8
            borderRadius: 4, // 原5 * 0.8
            id: categoryItems[i].id,
            visible: true,
            name: "text",
            canvasLayer: 3,
        }, true, true, true);
    }

    // 更新当前Y坐标,为下一个类别准备位置
    const rowsInCategory = Math.ceil(categoryItems.length / colsPerRow);
    currentY += rowsInCategory * (BGSizeH + verticalSpacing);
}


3. 从webscoker接口获取数据

接着在初始化中写代码

// 创建一个WebSocket连接  地址乱写一个
var socket = new WebSocket('ws://192.0.0.0:8085//ws/iot/scada');

// 建立连接之后发送数据:字符串 -- 所有属性名的组合用逗号隔开。
socket.onopen = function (event) {
    let idString = newArr.map(item => item.id).join(',');
    socket.send(idString);
};

// 接收到消息时触发
socket.onmessage = function (event) {
    let newArr = JSON.parse(event.data); //拿到返回值了
    newArr.forEach(item => {
        const id = item.id; // 获取数据项的ID
        const value = item.value; // 获取值
        // 根据value值设置文字颜色和图标
        if (value == "0") {
            meta2d.setValue({
                id: id,
                color: "#ff5959",  // 红色
            }, { render: true });

            meta2d.setValue({
                id: id + 'status',
                image: "/file/2025/0227/1/1/预警_2a00e0ce.png"  // 预警图标
            }, { render: true });

        } else if (value == "1") {
            // 值为1:正常状态 - 黑色文字,正常图标
            meta2d.setValue({
                id: id,
                color: "#000000",  // 黑色
            }, { render: true });

            meta2d.setValue({
                id: id + 'status',
                image: "/file/2025/0227/1/1/正常_dfae3f67.png"  // 正常图标
            }, { render: true });
        }

    });
};

// 连接关闭时触发
socket.onclose = function (event) {
    console.log('Connection closed.');
    // 关闭连接
    socket.close();
};

// 发生错误时触发
socket.onerror = function (error) {
    console.error('WebSocket Error: ', error);
};

这样在onmessage里可以更改刚才创建的卡片的状态和文字 通过meta2d.setValue方法,对了这里通过id去更改 ,所有创建初始化的id需要有规则

最后的界面

image.png

结束语

这种写法可以根据故障信息自动生成全界面渲染,无需手动绘制卡片; 点位状态实时驱动文字颜色、图标动态变化(故障红色警示/正常绿色);

解决的问题: 消除人工绑定点位与卡片的重复劳动,维护成本降低。 状态反馈延迟降低至毫秒级,提升故障响应速度。