LiteFlow逻辑可视化编排设计与实现 04-操作逻辑篇(Control)

背景:我之前写过一篇文章:《Liteflow逻辑编排可视化设计》,分享了我们对LiteFlow这个规则引擎的逻辑可视化设计,而我们这个可视化项目的目标不仅仅只是实现LiteFlow的逻辑可视化,而是实现LiteFlow的逻辑可视化编排。

接下来,我将通过系列文章的形式,进行LiteFlow逻辑可视化编排设计与实现的开发经验分享。

《LiteFlow逻辑可视化编排设计与实现》会以系列文章的形式,有步骤、有重点地分享我们对LiteFlow逻辑可视化编排的实现,目前该系列文章有如下4篇:

  1. LiteFlow逻辑可视化编排设计与实现 01-先导篇
  2. LiteFlow逻辑可视化编排设计与实现 02-数据模型篇(Model)
  3. LiteFlow逻辑可视化编排设计与实现 03-视图呈现篇(View)
  4. LiteFlow逻辑可视化编排设计与实现 04-操作逻辑篇(Control)

以下是《LiteFlow逻辑可视化编排设计与实现 04-操作逻辑篇(Control)》的文章正文。

04-操作逻辑篇(Control)

回顾一下我们在《先导篇》中提到过的内容,作为一名前端开发,我们需要特别关注的要素有三个------数据(Model)、视图(View)和逻辑(Control),即"MVC"------我接下来也是使用"MVC三要素"的知识框架来进行LiteFlow逻辑可视化编排系统的拆解、组合、设计和实现的:

在《数据模型篇》,我们完成了EL表达式的操作符(Operator)的建模工作,最终我们将EL表达式建模成了由ELNode组成的一棵树:

在《视图呈现篇》,我们完成了使用AntV X6的节点(Node)和边(Edge)进行ELNode的逻辑可视化呈现:

接下来,我们将实现LiteFlow逻辑可视化编排的"编排"部分实现了:

我们对"编排"的操作逻辑做进一步的拆解,也就是我们常说的"增删改查"(CRUD)操作了,在这里的具体实现,就是对ELNode模型的树型结构进行"增删改查":

1、ELNode模型的增删改查

我们实现的LiteFlow逻辑可视化编排的增删改查,最终是通过调用ELNode模型的相应方法来实现的,其中定义的部分方法如下:

typescript 复制代码
export default abstract class ELNode {
  /////// 接着上面步骤 1.数据模型(Model)
  /**
   * 添加子节点
   * @param child 子节点
   * @param index 指定位置
   */
  public appendChild(child: ELNode, index?: number);

  /**
   * 删除指定的子节点
   * @param child 子节点
   */
  public removeChild(child: ELNode): boolean;
  
  /**
   * 创建新的节点
   * @param parent 父节点
   */
  public create(parent: ELNode, type?: NodeTypeEnum): ELNode

  /**
   * 删除当前节点
   */
  public remove(): boolean;

  /**
   * 转换为X6的图数据格式
   */
  public toCells(
    previous?: Node,
    cells?: Cell[],
    options?: Record<string, any>,
  ): Cell[] | Node;
  
  /**
   * 转换为EL表达式字符串
   */
  public toEL(): string;
}

目前我们这个LiteFlow逻辑可视化编辑器的功能原型,页面大体是经典的"左中右"3栏布局,内容由以下4个面板组成:左侧的"物料区"、中间的"画布区"、右侧的"设置区",以及顶部的"工具栏":

    1. 物料区:在页面的左侧是"物料区",这里提供了可供选择的各类逻辑组件,主要包括:
      ① 节点类:在实际项目中,节点将会是最多的,这里为了方便只放了一个节点组件,组件的id属性会随机生成为"Placeholder1-9"形式;
      ② 顺序类:串行编排THEN、并行编排WHEN;
      ③ 分支类:选择编排SWITCH、条件编排IF;
      ④ 循环类:FOR循环、WHILE循环。
      通过拖拽左侧物料区的各个逻辑组件到中间画布,可以实现组件节点的新增和修改。
    1. 画布区:页面中间最大的区域是画布区,整个LiteFlow的逻辑可视化在这里进行的呈现,除了逻辑可视化的主要内容"节点"和"边"之外,同时在节点和边上有相关的操作按钮,可以方便进行逻辑组件的"增删改查"操作,目前主要包括的可用操作如下: ① 节点上的可用操作:在节点前面/后面插入节点,替换当前节点,删除当前节点; ② 边上的可用操作:在边所在的位置插入节点(相当于在边前面的节点后面插入新节点)。
    1. 设置区:在页面右侧是设置区,默认显示LiteFlow的EL表达式;在选中某个逻辑节点组件之后,则显示该组件可设置的属性,比如LiteFlow常用的id和tag等属性;
    1. 工具栏:在页面顶部是工具栏,包含LiteFlow逻辑可视化编排时常用的画布缩放、撤销/重做等等功能。

接下来,我们对LiteFlow逻辑可视化编排的"增删改"分别进行讲解。

2、新增(Create)

2.1 通过拖拽新增

在左侧物料区,可以通过拖拽需要的逻辑组件到中间的画布区、实现逻辑组件的新增:

这里的拖拽节点到画布的实现,是使用了AntV X6的Addon.Dnd,简化后的实现方法如下:

typescript 复制代码
const dnd = useMemo(
    () =>
      new Addon.Dnd({
        target: flowGraph,
        scaled: true,
        validateNode: (droppingNode: Node) => {
          const position = droppingNode.getPosition();
          const { node } = droppingNode.getData();
          const cellViewsFromPoint = flowGraph.findViewsFromPoint(
            position.x,
            position.y,
          );
          let cellViews =
            cellViewsFromPoint.filter((cellView) => cellView.isEdgeView()) ||
            [];
          if (cellViews && cellViews.length) {
            const currentEdge = flowGraph.getCellById(
              cellViews[0].cell.id,
            ) as Edge | null;
            let targetNode = currentEdge.getTargetNode();
            let { model: targetModel } = targetNode?.getData<INodeData>() || {};
            targetModel?.append(
              ELBuilder.createELNode(node.type, targetModel),
            );
          }
          
          return false;
        },
      }),
    [flowGraph],
  );

在这里我们做了这么一个设计------只有拖拽节点到画布中的边上、才能新增节点------因此在上面validateNode方法的最后、返回了false

2.2 通过快捷面板(ContextPad)新增

在中间的画布区的节点和边上,有相关的操作按钮,可以方便进行逻辑组件的新增操作: ① 节点附近新增:在节点前面/后面插入节点;

② 边上新增:在边所在的位置插入节点(相当于在边前面的节点后面插入新节点)。

这里我们设计了一个ContextPad组件、用来快捷插入节点------这样就实现了不通过拖拽、而是直接在画布中进行组件的新增。

这里ContextPad组件的实现,是通过使用AntV X6的自定义事件机制,唤起ContextPad组件的实现代码如下:

typescript 复制代码
const showContextPad = debounce((info: any) => {
  node.model?.graph?.trigger('graph:showContextPad', info);
}, 100);
const onPrepend = (event: any) => {
  showContextPad({
    x: event.clientX,
    y: event.clientY,
    node,
    scene: 'prepend',
    title: '前面插入节点',
    edge: null,
  });
};
const onAppend = (event: any) => {
  showContextPad({
    x: event.clientX,
    y: event.clientY,
    node,
    scene: 'append',
    title: '后面插入节点',
    edge: null,
  });
};

3、修改(Update)

2.1 通过拖拽修改

在左侧物料区,可以通过拖拽需要的逻辑组件到中间的画布区的组件节点上、实现该组件节点的替换:

2.2 通过快捷面板(ContextPad)修改

在中间的画布区,节点的工具栏上有一个替换按钮,可以方便进行逻辑组件的替换操作:

2.3 通过设置面板修改

在页面右侧是设置区,在选中某个逻辑节点组件之后,可以设置该组件的LiteFlow属性,比如id和tag等等:

4、删除(Delete)

4.1 通过工具栏删除

在中间的画布区,节点的工具栏上有一个删除按钮,可以方便进行逻辑组件的删除操作:

4.2 通过快捷键删除

在中间的画布区,我们可以通过快捷键backspace或者delete进行删除,比如这里我通过ctrl + a进行组件全选,然后按delete键进行了删除:

这里的实现比较简单,实现代码如下:

typescript 复制代码
flowGraph.bindKey(['backspace', 'del'], () => {
  const toDelCells = flowGraph
    .getSelectedCells()
    .filter((cell) => cell.isNode());
  if (toDelCells.length) {
    Modal.confirm({
      title: `确认要删除选中的节点?`,
      content: '点击确认按钮进行删除,点击取消按钮返回',
      onOk() {
        toDelCells.forEach((node) => {
          const { model } = node.getData() || {};
          model?.remove?.();
        });
        history.push();
      },
    });
  }
  return false;
});

需要注意的是,我们在使用AntV X6进行以上交互实现时,关键的API的是都是通过调用Graph的相关方法实现的。如果大家也使用AntV X6进行类似的图可视化编辑器实现时,所以推荐大家对Graph的相关API一定要熟悉。

以上是我们《LiteFlow逻辑可视化编排设计与实现 04-操作逻辑篇(Control)》的内容,我们完成了------不光可以通过拖拽,而且也可以通过ContextPad快捷面板,以及节点和边上的工具栏的操作按钮------实现LiteFlow的逻辑可视化编排的"增删改查"操作。

相关推荐
weixin_382395232 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__2 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.2 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~3 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华4 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子6 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅6 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni7 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学8 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端