技术栈

使用logicFlow插件绘制。
原生HTML页面也可以,vue或react前端框架也可以,官网有详细安装方法,本文章后面也会详细说明。
官网链接: logicFlow官网地址

需求

前端绘制泳道图结合流程图,达到如下效果
在这里插入图片描述
当然如果仅仅只是长成这样,想必大家用canvas或者svg画图都能解决一大半。
还需要页面能够识别节点所在的泳道,可能节点拖拽拉长后会跨多个泳道,要能知道每个节点移动后从属于哪些泳道(即节点权限问题)。

安装LogicFlow

直接用script引入

在原生html中直接通过script标签引入

<!--LogicFlow core包css-->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@logicflow/core/dist/style/index.css"
/>
<!--LogicFlow extension包css-->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@logicflow/extension/lib/style/index.css"
/>
<!--LogicFlow core包js-->
<script src="https://cdn.jsdelivr.net/npm/@logicflow/core/dist/logic-flow.js"></script>
<!--LogicFlow的插件支持单个引入,这里以菜单插件为例-->
<script src="https://cdn.jsdelivr.net/npm/@logicflow/extension/lib/Menu.js"></script>

这些都是通过官网cdn引入文件,也可以将文件下载到本地引入。

使用 npm 引入

npm install @logicflow/core
npm install @logicflow/extension

绘制一个简单的流程图

import LogicFlow from "@logicflow/core";
import "@logicflow/core/dist/style/index.css";

const lf = new LogicFlow({
  container: document.querySelector("#app"),
  grid: true,
});
lf.render({
  nodes: [
    {
      id: "1",
      type: "rect",
      x: 100,
      y: 100,
      text: "节点1",
    },
    {
      id: "2",
      type: "circle",
      x: 300,
      y: 200,
      text: "节点2",
    },
  ],
  edges: [
    {
      sourceNodeId: "1",
      targetNodeId: "2",
      type: "polyline",
      text: "连线",
    },
  ],
});

绘制泳道

泳道可以用svg或canvas绘制,或者简单点也可以直接用div布局绘制
在这里插入图片描述

在这里插入图片描述
多行多列就可以了。

逻辑交互

最后,如何判断节点从属于哪些泳道呢?
没错,没有简单地办法,就是自己写个小方法用坐标去和泳道的宽高对比
小技巧:logicFlow中lf.getDataById(id)可以获取节点或者连线的具体数据,lf.getNodeDataById(id)也可以获取节点的具体数据,id是节点的id。

// 获取节点的具体数据
console.log(lf.getNodeDataById('1')) 
// { "id": "1", "type": "rect", "x": 75, "y": 68, "properties": { "nodeSize": { "width": 90, "height": 60 } }, "text": { "x": 75, "y": 68, "value": "任务节点1" } }

注意,如果初始化时没有写入"properties": { “nodeSize”: { “width”: 90, “height”: 60 } }时,上面方法获取到的properties字段是空的,可以在初始化节点时就写入默认的properties: { nodeSize: { width: 90, height: 60 } }

上面的x和y就是当前节点的坐标,注意,是以画布左上角点为原点,节点的中心点的坐标。nodesize中的就是节点的宽和高
我们将左边列的表头最上面和画布对齐,上面表头的下边和画布对齐,就可以根据表头的宽高来计算节点的泳道位置了

testNodeBelong(id) {
			// 测试节点从属的泳道
          let nodeYData = this.lf.getDataById(id);
          //测试节点从属    81为每个泳道的高
          start = Math.floor(
            (nodeYData?.y - nodeYData?.properties?.nodeSize?.height / 2) /
              swim.height
          );
          end = Math.floor(
            (nodeYData?.y + nodeYData?.properties?.nodeSize?.height / 2) /
              swim.height
          );
          let Arr = [];
          for (let i in this.columns) {
            if (i >= start && i <= end) {
              Arr.push(this.columns[i].value);
            }
          }
          window.alert(Arr);
        },

columns是竖表头的内容,包含表头的值和表头的高

columns: [
            { value: "产品经理", height: "80px" },
            { value: "泳道图1", height: "80px" },
            { value: "泳道图2", height: "80px" },
            { value: "泳道图3", height: "80px" },
            { value: "泳道图4", height: "80px" },
            { value: "泳道图5", height: "80px" },
            { value: "泳道图6", height: "80px" },
            { value: "泳道图7", height: "80px" },
            { value: "泳道图8", height: "80px" },
          ],
Logo

前往低代码交流专区

更多推荐