跳转至

LogicFlow自定义边实战

官方文档:LogicFlow自定义边相关文档

和节点一样,LogicFlow 的边也支持基于继承的自定义机制。同样也只需同时继承viewmodel。 但是和节点不一样的是,由于边的编辑复杂度问题,绝大多数情况下,自定义边时不推荐自定义view。 只需要在自定义edgeModel中样式类即可。

为什么不推荐自定义view

在LogicFlow中,边(Edge)和节点(Node)的自定义机制提供了灵活的方式来扩展和定制图形和行为。这种机制基于面向对象的继承原理,允许开发者通过继承并扩展现有的模型(Model)和视图(View)类来创建自定义的边和节点。

Model 和 View 的含义:

  • Model:负责数据的管理和业务逻辑。对于边而言,EdgeModel包含了边的基础数据(如起点、终点、标签等)以及与这些数据相关的业务逻辑(如数据初始化、数据更新逻辑等)。Model层不涉及任何与显示相关的细节。

  • View:负责图形的渲染和展示逻辑。EdgeView控制边的渲染方式,包括边的形状、颜色、粗细等视觉属性。View层专注于如何在画布上绘制边,但不包含业务逻辑。

为什么不推荐自定义 Edge 的 View:

边的渲染和编辑比节点更为复杂,主要因为边涉及到更多的几何计算和交互处理。边的显示不仅仅是简单的图形,还可能包括箭头、标签、动画等元素,且边的形状可能是直线、曲线或其他更复杂的形状。此外,边的编辑(如拖动边来改变形状或方向)涉及到更为复杂的几何计算和用户交互逻辑。

由于这些原因,LogicFlow官方文档建议在大多数情况下,自定义边时不推荐自定义View层。通过在EdgeModel中定义样式和行为,开发者可以满足绝大多数的自定义需求,同时避免处理边渲染和编辑的复杂性。这种方法简化了自定义边的过程,使得开发者可以更加专注于业务逻辑的实现,而不是边的几何和交互细节。

简而言之,不推荐自定义边的View是因为管理和实现边的视觉和交互逻辑相对复杂,而通过Model来定义样式和部分行为已经足够满足大多数自定义需求,且更加简单和高效。

选择自定义边继承的内置边

// 直线
import { LineEdge, PolylineEdgeModel } from "@logicflow/core";
// 折线
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
// 贝塞尔曲线
import { BezierEdge, BezierEdgeModel } from "@logicflow/core";
// 圆角折线 CurvedEdge
import { CurvedEdge, CurvedEdgeModel } from "@logicflow/extension";

下面以 bezier 为例继承修改

import { BezierEdge, BezierEdgeModel } from "@logicflow/core";
class myCurvedEdge extends BezierEdge {}
class myCurvedEdgeModel extends BezierEdgeModel {
  // 流程图上所有的节点实例操作以及事件,行为监听都在 LogicFlow 实例上进行。
  constructor(data, graphModel) {
    super(data, graphModel);
    // 禁用边的拖动
    this.draggable = false;
  }
  // 初始化边数据。
  initEdgeData(data) {
    super.initEdgeData(data);
    this.radius = 8;
  }
  // 自定义边样式属性.
  getEdgeStyle() {
    const style = super.getEdgeStyle();
    style.strokeWidth = 2;
    // style.stroke = "rgb(130, 179, 102)";
    style.stroke = "#ccc";
    return style;
  }
  // 设置 model 形状属性,每次 properties 发生变化会触发
  setAttributes() {
    // 设置边动画
    // this.isAnimation = true;
    // 根据业务属性进行右键操作权限的判断
    const { properties: { isRefuellingEngineer }} = this;
    if (!isRefuellingEngineer) {
      // 单独为非禁用的元素设置菜单。
      console.log(!isRefuellingEngineer);
      this.menu = [];
    }
  }
  // 自定义边动画样式
  getEdgeAnimationStyle() {
    const style = super.getEdgeAnimationStyle();
    style.strokeDasharray = "15 5";
    style.animationDuration = "50s";
    style.stroke = "#ccc";
    return style;
  }
}

export default {
  type: "TaskEdge",
  view: myCurvedEdge,
  model: myCurvedEdgeModel
};

步骤

1.选择需要继承的内置的边

// 直线
import { LineEdge, PolylineEdgeModel } from "@logicflow/core";
// 折线
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
// 贝塞尔曲线
import { BezierEdge, BezierEdgeModel } from "@logicflow/core";
// 圆角折线 CurvedEdge
import { CurvedEdge, CurvedEdgeModel } from "@logicflow/extension";

2.对选择的继承内容进行编辑

import { BezierEdge, BezierEdgeModel } from "@logicflow/core";
class myCurvedEdge extends BezierEdge {}
class myCurvedEdgeModel extends BezierEdgeModel {
  // 流程图上所有的节点实例操作以及事件,行为监听都在 LogicFlow 实例上进行。
  constructor(data, graphModel) {
    super(data, graphModel);
    // 禁用边的拖动
    this.draggable = false;
  }
  // 初始化边数据。
  initEdgeData(data) {
    super.initEdgeData(data);
    this.radius = 8;
  }
  // 自定义边样式属性.
  getEdgeStyle() {
    const style = super.getEdgeStyle();
    style.strokeWidth = 2;
    // style.stroke = "rgb(130, 179, 102)";
    style.stroke = "#ccc";
    return style;
  }
  // 设置 model 形状属性,每次 properties 发生变化会触发
  setAttributes() {
    // this.isAnimation = true;
    this.menu = [];
  }
  // 自定义边动画样式
  getEdgeAnimationStyle() {
    const style = super.getEdgeAnimationStyle();
    style.strokeDasharray = "15 5";
    style.animationDuration = "50s";
    style.stroke = "#ccc";
    return style;
  }
}
// 导出给予组件使用 ,TaskEdge 为名称
export default {
  type: "TaskEdge",
  view: myCurvedEdge,
  model: myCurvedEdgeModel
};

3.使用

const formatEdgesData = edgesInit.map(item => ({
  type: "TaskEdge", // line 、 polyline 、 bezier 、 TaskEdge
  sourceNodeId: item.parentId,
  targetNodeId: item.childId,
  properties: {
    ...item
  }
}));