欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

实战体验:轻松上手mxGraph与drawio的使用教程(第1部分)

最编程 2024-08-07 12:24:28
...

最近接触了mxGraph和drawio,在这两者的基础上开发相应的业务,根据相应的数据解析出相应节点的坐标,样式,以及进行节点连线。本文在对mxGraph和drawio有一点的了解的基础下进行的研究,涉及具体的业务,不对源码进行深入探讨,凭喜好食用,有不正确之处,望不吝赐教。

涉及相应的业务逻辑: 1.解析数据,绘制节点; 2.节点关系连线; 3.绘图保存和渲染。

1.解析数据并绘图


介绍 drawio有多种绘图数据的保存和渲染格式,这里采用了xml格式的数据进行数据一系列操作。

原本的数据给定了图元的坐标轴,图元的基本样式,要做的就是解析出需要的数据。

这里采x2js库进行数据格式的转换,可以进行xml,dom,js等相应的数据格式解析转换。

数据解析后为json数据格式,然后使用x2js将数据转化为xml字符串格式,然后丢到graph中渲染。

节点图片

相关属性解析

<?xml version='1.0' encoding='utf-8'?>
<mxGraphModel dx="126" dy="115" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
  <root>
    <mxCell id="0" />
    <mxCell id="1" parent="0" />
    <mxCell id="5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=1;" edge="1" parent="1" source="2" target="3">
      <mxGeometry relative="1" as="geometry" />
    </mxCell>
    <mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
        <mxGeometry x="140" y="230" width="120" height="60" as="geometry" />
    </mxCell>
    <mxCell id="3" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
      <mxGeometry x="430" y="230" width="120" height="60" as="geometry" />
    </mxCell>
  </root>
</mxGraphModel>

画板坐标轴

具体的数据包含在root标签中,每一个图元由一个mxCell标签包住。第一和第二个分别为画板和层级图元。

mxCell标签中主要属性:

id:唯一值,重复id无法渲染;

value:图元中的文本,文本样式可以如此方式添加value="value",可能会在parseXml解析出现错误,是由于双引号错误匹配问题,导致解析失败。可以采用转码的方式添加,如value="&lt;font color=&quot;#FF8000&quot;&gt;value&lt;/font&gt;",测试支持渲染转码后的标签;

style:图元的样式,包含内容很多,识别不同的图元也在style中,图元的样式也在style中,如上,rounded=0;表示的是矩形,还包含许多可用属性;

parent:表示图元的父级图元的id;

source(线):线条的出发点图元的id;

target(线):线条的终点图元的id。

具体的图元基本包含mxGeometry标签,包含一些几何信息。

x:x轴的坐标,坐标轴如上图所示;

y:y轴的坐标;

width:图元的宽度;

height:图元的高度。

更多具体属性可以绘图查看。

绘制代码

/**
*   editorUi中有解析数据和绘制到画板的方法,直接调用即可,会自动刷新画板中的数据,性能挺不错的。
**/
var hdCall = function (xmlfile) {
    const win = Common.getActiveWindow();     // 可以初始化后获取到相应的ui值,几乎所有逻辑的方法和属性都绑定在win或者editorUi中
    const editorUi = getEditorUi();
    
    if (xmlfile == null || xmlfile.length == 0) {
      xmlfile = "<?xml version='1.0' encoding='utf-8'?>";
      xmlfile += '<mxGraphModel dx="247" dy="121" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="" style="shape=mxgraph.electrical.节点;whiteSpace=wrap;html=1;fillColor=#000000;strokeColor=#000000;strokeWidth=1" vertex="1" parent="1"><mxGeometry x="70" y="100" width="40" height="40" as="geometry"/></mxCell></root></mxGraphModel>';
    } else {
      xmlfile = "<?xml version='1.0' encoding='utf-8'?>" + xmlfile;
    }
    // 渲染代码
    var doc = win.mxUtils.parseXml(xmlfile); // 将xml字符串解析成dom
    var dec = new win.mxCodec(doc); 
    dec.decode(doc.documentElement, editorUi.editor.graph.getModel());
}

2.连线


单线连接:

相关的xml

<?xml version='1.0' encoding='utf-8'?>
<mxGraphModel dx="126" dy="115" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
  <root>
    <mxCell id="0" />
    <mxCell id="1" parent="0" />
    <mxCell id="5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=1;" edge="1" parent="1" source="2" target="3">
      <mxGeometry relative="1" as="geometry" />
    </mxCell>
    <mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
        <mxGeometry x="140" y="230" width="120" height="60" as="geometry" />
    </mxCell>
    <mxCell id="3" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
      <mxGeometry x="430" y="230" width="120" height="60" as="geometry" />
    </mxCell>
  </root>
</mxGraphModel>

当只有一条线的时候,可以采用最简单的中心点连接方式(默认)。 上述代码中mxCell中的id为5的为关系线条,其中表示依赖关系,可以复制添加即可。关键字段为parent,source和target。连接线会根据给定的source和target自动采用中心点连接。

多线连接:

如果出现相同两个点多条连接线,可以采用边缘锚点关系进行连接。边缘锚点在定义图元的时候会给出。如下代码中,connections字段中定义了可连接的锚点。

<shape aspect="variable" h="100" name="Circle" strokewidth="inherit" w="100">
    <connections>
        <constraint name="N" perimeter="0" x="0.5" y="0"/>
        <constraint name="S" perimeter="0" x="0.5" y="1"/>
        <constraint name="W" perimeter="0" x="0" y="0.5"/>
        <constraint name="E" perimeter="0" x="1" y="0.5"/>
    </connections>
    <foreground>
        <ellipse h="100" w="100" x="0" y="0"/>
        <stroke/>
    </foreground>
</shape>

相关线的sytle值:

1-4: "endArrow=classic;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;exitX=1;exitY=0.25;exitDx=0;exitDy=0;"

2-5: "endArrow=classic;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;exitX=1;exitY=0.75;exitDx=0;exitDy=0;"

3-6: "endArrow=classic;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;"

关键字段:

箭头进入的锚点:entryX; entryY

箭头出来的锚点:exitX; exitY

具体值的意义:

将相关的比例值赋值到对应的字段,会自动连接对应的锚点。

线条Style的其他属性:

颜色:fillColor

描边:strokeColor

宽度:strokeWidth

3.绘图保存和渲染


主要对画板数据的获取和保存。 对画板的数据获取,主要是获取画板的xml数据。

/**
*   editorUi中有获取画板的绘制xml数据的方法,直接调用即可,结果为xml格式的数据。
**/
const editorUi = getEditorUi();
const xml = editorUi.editor.getGraphXml()

推荐阅读