VUE3 中导入Visio 图形

微软的Visio是一个功能强大的图形设计工具,它能够绘制流程图,P&ID,UML 类图等工程设计中常用的图形。它要比其它图形设计软件要简单许多。以后我的博文中将更多地使用VISO 来绘制图形。之前我一直使用的是corelDraw。

Visio 已经在工程设计中得到广泛的应用。

本博客讨论如何将Visio 设计的SVG 导入webHMI。

目的与方法

我的目标是使用Visio 绘制石化行业的工艺和仪表流程图(P&ID ),并将它导入VUE3 的前端显示出来。

  • 直接导入Web 不做任何的修改和添加
  • 图形要能够携带一些数据属性
  • 能够与后端的OPC UA 模型相对应
  • 实现图形可点击

之前我曾经使用其它的方式:

  • 使用autoCAD 绘制,输出DXF
  • 使用corelDaw ,Inkscape 等软件绘制,然后人工添加内置的javascript小程序
  • 使用javascript 的widget canvas 绘制
  • 使用SVG和svidget 插件实现。

在我过往的博文中可以找到我的实验,这些方法或多或少需要额外的编程,或者格式转换。这次我们尝试直接导入Visio 产生的SVG 图形。

实现

简单的P&ID 图

使用Visio 就不多说了,我画了一个简单的P&ID图。

Visio 图形添加数据属性

图形中需要包含一些数据,最常见的需要一个DataTag 能够将图形与后端数据相对应,我这里使用OPCUA 作为后端信息模型,所以,至少我们需要OPCUA 节点的基本信息:

  • NodeId
  • BrowseName
  • DisplayName
  • NodeType

值得庆幸的是Visio 图形支持添加数据属性,它们成为形状数据,添加的具体方式是右键点击图形,选择"数据"=》"定义形状数据"

你可以点击新建,添加新的属性,在上图中,我们添加了NodeId 。

当从Visio 导出SVG 文件时,形状数据会作为专用属性(v:custProps)

XML 复制代码
<g id="group1-1" transform="translate(100.535,-89.6214)" v:mID="1" v:groupContext="group" v:layerMember="0">
			<v:custProps>
				<v:cp v:nameU="Description" v:lbl="说明" v:type="0" v:sortKey="0" v:langID="2052"/>
				<v:cp v:nameU="Material" v:lbl="材料" v:type="0" v:sortKey="1" v:langID="2052"/>
				<v:cp v:nameU="Manufacturer" v:lbl="制造商" v:type="0" v:sortKey="2" v:langID="2052"/>
				<v:cp v:nameU="Model" v:lbl="型号" v:type="0" v:sortKey="3" v:langID="2052"/>
				<v:cp v:nameU="NodeId" v:lbl="NodeId" v:type="0" v:langID="2052" v:val="VT4(5401)"/>
			</v:custProps>

在前端载入时,我们要读取NodeId 的值,将它填写到<g> 的onclick 参数中 (见下面的源代码)

SVG 嵌入到HTML 中

SVG 嵌入到HTML 网页中有许多的方法,之前我使用嵌入在<object> 中。

使用<object>
javascript 复制代码
<object
      id="svg-object"
      type="image/svg+xml"
      data="motor.svg"
      width="300"
      height="300"
    ></object>

作为HMI,SVG 图形中的每一个图形都是可以点击的(Click able),这需要在导入HTML 时添加到<g> 中,但是我发现,在<object> 内部的SVG 添加了onclick 之后,无法方位VUE3 中的OnClick 函数,即便增加了Window.οnclick=this.Click 也不行。<object>内部无法调用外部函数。

使用vite-svg-loader插件

第二种方式是使用vite-svg-loader插件,

TypeScript 复制代码
<script setup>
import { onUpdated } from "vue";
import pid from "@/assets/pid.svg?component";
</script>
<template>
  <div class="container">
    <h1 class="text-info">系统视图</h1>
<pid />
</template>

结果发现也不行。vite-svg-loader 只是装入了图形,将数据的内容都阉割掉了。

可行的方式-直接导入SVG到HTML

经过不断的尝试,采用了如下可行的方式:

将SVG 直接作为字符串插入到<div> 中去。读取SVG 的方式可以为两种:

  • 通过axios 从后端读取
  • 通过import pid from "@/assets/pid.svg@raw"
最终的代码
TypeScript 复制代码
<script setup>
import { onUpdated, onMounted } from "vue";
import Steam from "@/assets/demoA.svg?raw";
import $ from "jquery";
onMounted(() => {
  document.getElementById("svg-object").innerHTML = Steam;
  window.onClick = onClick;
  BrowseData();
});

function BrowseData() {
  let groups = [];

  $("g").each(function () {
    let id = $(this).attr("id");
    var NodeId = null;

    $(this)
      .find("v\\:cp")
      .each(function () {
        let attributes = $(this)[0].attributes;
        if (attributes["v:lbl"].nodeValue == "NodeId") {
          if (id) {
            let regex = /\((.+?)\)/g;
            let str = attributes["v:val"].nodeValue;
            NodeId = str.match(regex)[0];
            console.log(id + NodeId);
          }
        }
      });
    if (NodeId) $(this).attr("onclick", "onClick('" + NodeId + "')");
  });
}
function onClick(id) {
  alert(id + " Clicked");
}
</script>

<template>
  <div class="container">
    <h1 class="text-info">系统视图</h1>

    <div id="svg-object"></div>
  </div>
</template>
<style scoped>
</style>

小结

在自动化系统中,HMI 逐步转向HTML5。但是这是标准化不够的部分,如何将HTML 的UI 与后台的信息模型建立对应关系,是值得探讨的。这里我们尝试了Visio 图形与前端HTML5 UI,后端OPCUA 信息模型建立简单,清晰的对应方式。尽管没有使用DEXPI 标准,但是SVG 似乎更加便捷。

相关推荐
python算法(魔法师版)18 小时前
HTML5 Canvas和JavaScript的3D粒子星系效果
javascript·3d·html5
Beginner x_u21 小时前
HTML-拓展知识 字符实体与URL地址
html5·url·字符实体
python算法(魔法师版)1 天前
旅游风景的代码项目
javascript·css3·html5·旅游·风景
浪浪山小白兔1 天前
深入理解JavaScript中的Location对象
开发语言·前端·javascript·html·html5
我命由我123452 天前
NPM 与 Node.js 版本兼容问题:npm warn cli npm does not support Node.js
前端·javascript·前端框架·npm·node.js·html5·js
浪浪山小白兔2 天前
HTML5 语义元素详解
前端·html·html5
浪浪山小白兔3 天前
HTML5 新表单属性详解
前端·html·html5
浪浪山小白兔3 天前
HTML5 常用事件详解
前端·html·html5
PABL014 天前
uniapps使用HTML5的io模块拷贝文件目录
sqlite·uniapp·html5
陈奕迅本讯4 天前
HTML5和CSS3拔高
前端·css3·html5