LogicFlow 重构绘制 Dagre 层次图

1,059 阅读4分钟

DAGRE 层次图

基于 LogicFlow 重构项目内 @antv/g6 dagre 层次图

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"),
  // ...
});
lf.render({
    nodes: [{ id: ... }],
    edges: [{ id: ... }]
})

LogicFlow 官方使用文档:docs.logic-flow.cn/docs/#/zh/

LogicFlow 介绍

LogicFlow 提供了一系列流程图交互、编辑所必需的功能和简单灵活的节点自定义、插件等拓展机制。

架构图

图片: lfjk

核心包 @logicflow/core 提供了流程图编辑器基础的能力

拓展插件包 @logicflow/extension 是基于核心包的拓展性开发的插件,提供如菜单、画板等

LogicFlow 内置了一些基础节点和边,若实现自己业务节点与边的需求,需采用继承重写对应的方法。

自定义节点 Node

// rect 矩形
import { RectNode, RectNodeModel } from "@logicflow/core";

// 定义节点 view
class CustomNodeView extends RectNode {}
// 定义节点 model
class CustomNodeModel extends RectNodeModel {}

export default {
  type: "CustomNode",
  view: CustomNodeView,
  model: CustomNodeModel
};

自定义边 Edge

// edge 折线
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";

// 定义边 view
class CustomEdgeView extends PolylineEdge {}
// 定义边 model
class CustomEdgeModel extends PolylineEdgeModel {}

export default {
  type: "CustomEdge",
  view: CustomEdgeView,
  model: CustomEdgeModel
};

自定义属性 properties

提供 properties 字段用于开发者存放自己业务相关的属性,然后可以在自定义节点的时候,基于这些properties 自己进行处理。

const data = {
    nodes: [
        {
            id: 'TA0007',
            type: 'CustomNode',
            // ...
            properties: {
                bgColor: '#ffa179',
                parentId: 'TA0006'
            }
        }
    ],
    edges: [
        // ...
    ]
}

LogicFlow 重构绘制层次图所遇到的问题

  1. 每个节点都需要自己设置位置 x y 属性,且为必须
  2. 节点无法通过设置初始节点位置,自动计算后续节点位置
  3. 使用直角折线时,节点之间连接会出现异常弯折现象,需手动配置 pointsList 边的轨迹
  4. 连接线无法根据边设置的节点锚点 id,将指定的节点通过锚点进行连接
  5. 没有布局方法,遇到节点重复或相同无法自动改变节点位置

绘制节点位置坐标

  1. 确定第一个节点默认初始位置坐标 x y
  2. 计算子节点相对于父节点位置
  3. 子节点一排多个位置处理
  4. 计算节点左右边距
  5. 计算节点上下边距

处理不同节点具有相同子节点

  1. 判断是否具有相同子节点
  2. 统计相同子节点 id,计算当前 id 最后子节点位置
  3. 将所有相同 id 的坐标位置修改为最后子节点位置

处理前后对比

image.png

image.png

处理子节点位置重复

  1. 判断是否因相同子节点处理方法导致的节点数据位置相同,若是则不处理
  2. 记录重复节点位置信息,将前置节点的子节点层级下移
  3. 子节点层级下移后,重新计算位置xy,并再次判断是否与已知节点位置重复

处理前后对比

image.png

image.png

绘制直角折线

  1. 利用 LogicFlow pointsList 属性配置边的轨迹,绘制向下垂直折线

补充 svg

path 属性

path 元素是用来定义形状的通用元素。

<svg>
  <path d="M 10 10 L 10 60" fill="transparent" stroke="black" />
</svg>

绘制直线命令

M:起始命令,是移动画笔的位置,但不画线

L:移动命令,将会在当前位置(M起始点)和新位置(L所在点)之间画一条线段

Z:闭合路径命令,会从当前点画一条直线到路径的起点,尽管我们不总是需要闭合路径,但是它还是经常被放到路径的最后。

polyline 属性

polyline 元素是 SVG 的一个基本形状,用来创建一系列直线连接多个点。典型的一个 polyline 是用来创建一个开放的形状,最后一点不与第一点相连。

<svg>
  <polyline points="770,0 770,51 800,51" fill="none" stroke="black" stroke-width="0.5" />
</svg>

LogicFlowpointsList 设置的属性x y值,对应为 SVG polyline 元素中的 points 属性

pointsList 属性配置:

pointsList: [{ x: 770, y: 0 }, { x: 770, y: 51 }, { x: 800, y: 51 }]
{ x: 770, y: 0 }   // 起点位置
{ x: 770, y: 51 }  // 折点位置
{ x: 800, y: 51 }  // 终点位置

image.png

最后

对于连接线无法根据边设置的节点锚点 id,将指定的节点通过锚点进行连接问题,官方 github 提出 issue:github.com/didi/LogicF…