Drawio 矢量绘图工具#

有时我们需要将 AutoFlowchart 生成的流程图导入到 draw.io 中进行再次编辑,这儿有两种方式:

  1. AutoFlowchart 导出的 xml 文件再导入到 draw.io 中(实际验证 drawio 无法识别)。

  2. AutoFlowchart 导出的 svg 图片再导入到 draw.io 中。可以导入但只能作为一个整体,无法修改流程图内部元素。

Drawio 文件内容#

先创建 1 个空的 .drawio 文件,查看其 xml 内容, 再添 1 个方框再查看其 xml 内容。从而学习 .drawio 文件中 xml 元素作用。

空 drawio 文件内容#
 1<mxfile host="65bd71144e">
 2    <diagram id="nOCopejOBnysMZQZ02U5" name="第 1 页">
 3        <mxGraphModel dx="1626" dy="787" 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">
 4            <root>
 5                <mxCell id="0"/>
 6                <mxCell id="1" parent="0"/>
 7            </root>
 8        </mxGraphModel>
 9    </diagram>
10</mxfile>

在图中放入 1 个矩形框后, .drawio 文件内容:

添加 1 个矩形#
 1<mxfile host="65bd71144e">
 2    <diagram id="nOCopejOBnysMZQZ02U5" name="第 1 页">
 3        <mxGraphModel dx="1386" dy="787" 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">
 4            <root>
 5                <mxCell id="0"/>
 6                <mxCell id="1" parent="0"/>
 7                <mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
 8                    <mxGeometry x="230" y="370" width="120" height="60" as="geometry"/>
 9                </mxCell>
10            </root>
11        </mxGraphModel>
12    </diagram>
13</mxfile>

其中 7-9 行就是添加的这个矩形对应的 xml 内容, 我们人为在 root 元素下添加跟 7-9 类似内容,文件内容如下:

通过修改xml文件来添加矩形框#
 1<mxfile host="65bd71144e">
 2    <diagram id="nOCopejOBnysMZQZ02U5" name="第 1 页">
 3        <mxGraphModel dx="1118" dy="787" 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">
 4            <root>
 5                <mxCell id="0"/>
 6                <mxCell id="1" parent="0"/>
 7                <mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
 8                    <mxGeometry x="230" y="370" width="120" height="60" as="geometry"/>
 9                </mxCell>
10                <mxCell id="5" value="通过修改xml文件插入" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
11                    <mxGeometry x="370" y="280" width="120" height="60" as="geometry"/>
12                </mxCell>
13            </root>
14        </mxGraphModel>
15    </diagram>
16</mxfile>

重新打开 drawio 文件可以看到多插入的矩形框。可以看出:

  1. 每个图形都由 <mxCell></mxCell> 包裹

  2. 矩形内的文本由 value 属性指定

  3. 矩形的大小由 <mxGeometry> 中的 x y width height 来指定

注意

如果只是把上面10-12内容另存为1个xml文件,再通过drawio导入这个xml文件。还是 不能 添加要插入的的矩形的。未能达到导入文件生成图形的目的

Drawio 复制粘贴内容#

上面大致明白了 drawio 绘图的内容,但仍没能探究出如何通过导入 xml 文件来生成绘图元素。 今天突然意识到 drawio 绘图过程中可以通复制粘贴来插入新的图形的,哪我们只要搞清楚复制的内容。是不就可以通过文件导入图文元素了呢?说干就干:

  1. 在 drawio 中选中上面手动插入的矩形框, Ctr-c 复制

  2. 新建个 xml 文件, Ctr-v 将内容原封不动粘贴进去

  3. 在 draio 中删除刚刚复制了的矩形框

  4. 在 draio 中选择菜单 文件 -> 导入… 导入新建的 xml 文件

神奇的 1 幕出现了,刚刚删除的矩形框又回来了!✌️ 哪我们再来看看粘贴的内容:

%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%E9%80%9A%E8%BF%87%E4%BF%AE%E6%94%B9xml%E6%96%87%E4%BB%B6%E6%8F%92%E5%85%A5%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22370%22%20y%3D%22280%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E

我的个乖乖,这都是些啥啊?😭 突然,看到哪么多 % 想起这些有没有可能是 URL 编码后的文本呢? 于是在 VsCode 中按 F1 输入 Transform:Encode / Decode... 后选择 Decode URL segment, 又神奇的得到了如下内容:

<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="通过修改xml文件插入" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="370" y="280" width="120" height="60" as="geometry"/></mxCell></root></mxGraphModel>

是不一下子就很熟悉了,再格式化一下:

<mxGraphModel>
    <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />
        <mxCell id="2" value="通过修改xml文件插入" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1"
            parent="1">
            <mxGeometry x="370" y="280" width="120" height="60" as="geometry" />
        </mxCell>
    </root>
</mxGraphModel>

备注

上面的软件用到了 Vscode 中的另一个好用的插件 Transformer ,也可以通过 Python 来解码得到:

>>> import urllib.parse
>>> urllib.parse.unquote('%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%E9%80%9A%E8%BF%87%E4%BF%AE%E6%94%B9xml%E6%96%87%E4%BB%B6%E6%8F%92%E5%85%A5%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22370%22%20y%3D%22280%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E')
'<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="通过修改xml文件插入" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="370" y="280" width="120" height="60" as="geometry"/></mxCell></root></mxGraphModel>'
>>>

AutoFlowchart 导出文件内容#

AutoFlowchart 打 C 源文件,导出部分流程图:

../_images/AutoFlowchart_Test001.svg

上图对应导出的 xml 和 svg 文件如下:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="260" height="290" xmlns="http://www.w3.org/2000/svg">
    <desc>AutoFlowchart</desc>
    <rect x="32" y="20" width="75" height="30" rx="15" ry="15" fill="none" stroke="black"
        stroke-width="2" />
    <text x="70" y="42" style="text-anchor:middle" font-size="12">START</text>
    <polyline points="70,50,70,70" fill="none" stroke="black" stroke-width="2" />
    <rect x="32" y="220" width="75" height="30" rx="15" ry="15" fill="none" stroke="black"
        stroke-width="2" />
    <text x="70" y="242" style="text-anchor:middle" font-size="12">END</text>
    <polygon points="70,70,120,100,70,130,20,100" fill="none" stroke="black" stroke-width="2" />
    <text x="70" y="106" style="text-anchor:middle" font-size="12">(xTask == TaskHandleVoltage)</text>
    <polyline points="70,130,70,150" fill="none" stroke="black" stroke-width="2" />
    <polyline points="120,100,190,100,190,150" fill="none" stroke="black" stroke-width="2" />
    <polyline points="190,200,190,200,70,200,70,220" fill="none" stroke="black" stroke-width="2" />
    <polyline points="70,200,70,220" fill="none" stroke="black" stroke-width="2" />
    <rect x="20" y="150" width="100" height="30" fill="none" stroke="black" stroke-width="2" />
    <text x="70" y="171" style="text-anchor:middle" font-size="12">Code</text>
    <polyline points="70,180,70,200" fill="none" stroke="black" stroke-width="2" />
    <rect x="140" y="150" width="100" height="30" fill="none" stroke="black" stroke-width="2" />
    <text x="190" y="171" style="text-anchor:middle" font-size="12">Code</text>
    <polyline points="190,180,190,200" fill="none" stroke="black" stroke-width="2" />
</svg>

svg 文件中跟流程图相关的标签主要有 4 个:

  1. text 用于绘制图中文字

  2. rect 用于绘制图中的方框(圆角方框、直角方框),圆角多 rxry 属性,它们表示倒角半径

  3. polygon 用于绘制图中棱形,两个数据表示 1 个点(x值,y值)

  4. polyline 用于绘制线段,两个数据表示 1 个点(x值,y值)

<?xml version="1.0" encoding="UTF-8"?>
<Root Scale="1" BaseWidth="50" BaseHeight="30" SpaceHorz="20" SpaceVert="20"
    FontName="MS Sans Serif" FontSize="12" FontColor="0">
    <IF Mode="301" Text="(xTask == TaskHandleVoltage)" BegPos="1671" EndPos="1894" FileName=""
        ID="30" Status="1">
        <YES Mode="303" Text="Yes" BegPos="1703" EndPos="1796" FileName="" ID="32" Status="1">
            <Code Mode="210"
                Text="board_segment_display_for_halt(DISPLAY_ERROR_CODE_VOLTAGE_OVERFLOW);"
                BegPos="1718" EndPos="1785" FileName="" ID="35" Status="1" />
        </YES>
        <NO Mode="305" Text="No" BegPos="1803" EndPos="1894" FileName="" ID="34" Status="1">
            <Code Mode="210"
                Text="board_segment_display_for_halt(DISPLAY_ERROR_CODE_TIMER_OVERFLOW);"
                BegPos="1818" EndPos="1883" FileName="" ID="36" Status="1" />
        </NO>
    </IF>
</Root>

xml 只有 IF, YES, NO 3种类型标签,它比 svg 多了层级关系,但没有对象之间的连线数据

综上情况将导出的 svg 改为 drawio 支持的 xml 可能相对简单点

再探 Drawio 文件内容#

  1. 基本图形:

    在 Drawio 是通过 mxCellstyle 属性来改变图形元素的形状的:

    图形名

    style 属性的 shape 值

    样图

    矩形

    shape=rect;

    ../_images/%E7%9F%A9%E5%BD%A2.svg

    棱形

    shape=rhombus;

    ../_images/%E6%A3%B1%E5%BD%A2.svg

    椭圆

    shape=ellipse;

    ../_images/%E6%A4%AD%E5%9C%86.svg

    文本

    shape=text;

    ../_images/%E6%96%87%E6%9C%AC.svg

    矩形 矩形style 属性添加 rounded=1; [1] arcSize=50; [2] 可得到 圆角矩形

    注解

  2. 连接线:

mxCell 添加 edge="1" 就可以定义 箭头线 , 若再在 style 属性中添加 shape=link; 就可以得到 连接线

示例

连线方式

styleedgeStyle

子属性配置

直连

两点直连走线

none

正交

正交走线

orthogonalEdgeStyle

简单

简单走线

elbowEdgeStyle

elbow=vertical; 表示垂直方向,默认为表示水平方

等尺寸

等尺寸走线

isometricEdgeStyle

elbow=vertical; 表示垂直方向,默认为表示水平方

曲线

曲线走线

orthogonalEdgeStyle

再增加 curved=1;

实体

实体走线

entityRelationEdgeStyle

导出的 svg 转为 Drawio 文件#

我们只要将 AutoFlowchart 导出的 svg 文件按 Drawio 文件内容写入到 xml 文件中,就可以实现在 Drawio 中导入功能了。

具体实现代码

../_images/%E6%9C%80%E7%BB%88%E7%94%9F%E6%88%90%E6%95%88%E6%9E%9C%E5%9B%BE.png

通过导入转换后的 xml 文件。可以看出每个元素都是可以再次在 Drawio 中编辑的。

text 标签改为 value 属性方式处理#

原来转换 svg 文件中的 text 标签是直接新绘制一个 Text 的 Drawio 元素, 再在改为通过 text 标签给的文本位置, 和已经绘制好的框图元素进行比较。或文本位置在某个框图内,就直接修改该框图的 value 属性值

直接绘制 text 效果
../_images/%E6%9C%80%E7%BB%88%E7%94%9F%E6%88%90%E6%95%88%E6%9E%9C%E5%9B%BE.png
将 text 添加到 value 属性的效果
../_images/%E6%96%87%E6%9C%AC%E4%BB%A5%E5%B1%9E%E6%80%A7value%E6%96%B9%E5%BC%8F%E6%B7%BB%E5%8A%A0%E7%9A%84%E6%95%88%E6%9E%9C.png

注意

将文本添加到 value 属性方式,必须先将所有框图元素绘制完。否则会添加文本失败

导出的 xml 转 Drawio 文件#

待续…