LogicFlow 学习笔记——9. LogicFlow 进阶 节点

该文章已生成可运行项目,

LogicFlow 进阶 节点(Node)

连线规则

在某些时候,我们可能需要控制边的连接方式,比如开始节点不能被其他节点连接、结束节点不能连接其他节点、用户节点后面必须是判断节点等,想要达到这种效果,我们需要为节点设置以下两个属性。

  • sourceRules - 当节点作为边的起始节点(source)时的校验规则
  • targetRules - 当节点作为边的目标节点(target)时的校验规则

以正方形(square)为例,在边时我们希望它的下一节点只能是圆形节点(circle),那么我们应该给square添加作为source节点的校验规则。

import {
   
    RectNode, RectNodeModel } from '@logicflow/core';
class SquareModel extends RectNodeModel {
   
   
  initNodeData(data) {
   
   
    super.initNodeData(data);

    const circleOnlyAsTarget = {
   
   
      message: "正方形节点下一个节点只能是圆形节点",
      validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) => {
   
   
        return targetNode.type === "circle";
      },
    };
    this.sourceRules.push(circleOnlyAsTarget);
  }
}

在上例中,我们为modelsourceRules属性添加了一条校验规则,校验规则是一个对象,我们需要为其提供messagevalidate属性。
message属性是当不满足校验规则时所抛出的错误信息,validate则是传入规则的校验的回调函数。validate方法有两个参数,分别为边的起始节点(source)和目标节点(target),我们可以根据参数信息来决定是否通过校验,其返回值是一个布尔值。

提示
当我们在面板上进行边操作的时候,LogicFlow会校验每一条规则,只有全部通过后才能连接。
在边时,当鼠标松开后如果没有通过自定义规则(validate方法返回值为false),LogicFlow会对外抛出事件connection:not-allowed

lf.on('connection:not-allowed', (msg) => {
   
   
	console.log(msg)
})

下面举个例子,通过设置不同状态下节点的样式来展示连接状态
在节点model中,有个state属性,当节点连接规则校验不通过时,state属性值为5。我们可以通过这个属性来实现连线是节点的提示效果。

新建src/views/Example/LogicFlowAdvance/NodeExample/Component/HexagonNode/index.ts代码如下:

import {
   
    ConnectRule, PointTuple, PolygonNode, PolygonNodeModel } from '@logicflow/core'

class CustomHexagonModel extends PolygonNodeModel {
   
   
  setAttributes(): void {
   
   
    const width = 100
    const height = 100
    const x = 50
    const y = 50
    // 计算六边形,中心点为 [50, 50],宽高均为 100
    const pointsList: PointTuple[] = [
      [x - 0.25 * width, y - 0.5 * height],
      [x + 0.25 * width, y - 0.5 * height],
      [x + 0.5 * width, y],
      [x + 0.25 * width, y + 0.5 * height],
      [x - 0.25 * width, y + 0.5 * height],
      [x - 0.5 * width, y]
    ]
    this.points = pointsList
  }

  getConnectedSourceRules(): ConnectRule[] {
   
   
    const rules = super.getConnectedSourceRules()
    const geteWayOnlyAsTarget = {
   
   
      message: '下一个节点只能是 circle',
      validate: (source: any, target: any, sourceAnchor: any, targetAnchor: any) => {
   
   
        console.log(
          'sourceAnchor, targetAnchor, source, target',
          sourceAnchor,
          targetAnchor,
          source,
          target
        )
        return target.type === 'circle'
      }
    }
    rules.push(geteWayOnlyAsTarget)
    return rules
  }

  getNodeStyle(): {
   
   
    [x: string]: any
    fill?: string | undefined
    stroke?: string | undefined
    strokeWidth?: number | undefined
  } {
   
   
    const style = super.getNodeStyle()
    if (this.properties.isSelected) {
   
   
      style.fill = 'red'
    }
    if (this.isHovered) {
   
   
      style.stroke = 'red'
    }
    // 如果此节点不允许被连接,节点变红
    if (this.state === 5) {
   
   
      style.fill = 'red'
    }
    if (this.state === 4) {
   
   
      style.fill = 'green'
    }
    return style
  }
}

export default {
   
   
  type: 'HexagonNode',
  view: PolygonNode,
  model: CustomHexagonModel
}

之后新建src/views/Example/LogicFlowAdvance/NodeExample/Example01.vue代码如下:

<script setup lang="ts">
import LogicFlow, {
     
      Definition } from '@logicflow/core'
import {
     
      onMounted } from 'vue'
import HexagonNode from './Component/HexagonNode'
import '@logicflow/core/dist/style/index.css'

const data = {
     
     
  nodes: [
    {
     
     
      id: '1',
      type: 'rect',
      x: 300,
      y: 100
    },
    {
     
     
      id: '2',
      type: 'circle',
      x: 300,
      y: 250
    },
    {
     
     
      id: '3',
      type: 'HexagonNode',
      x: 100,
      y: 100,
      text: '只能连接到圆'
    }
  ],
  edges: []
}

const SilentConfig = {
     
     
  stopScrollGraph: true,
  stopMoveGraph: true,
  stopZoomGraph: true
}

const styleConfig: Partial<Definition> = {
     
     
  style: {
     
     
    rect: {
     
     
      rx: 5,
      ry: 5,
      strokeWidth: 2
    },
    circle: {
     
     
      fill: '#f5f5f5',
      stroke: '#666'
    },
    ellipse: {
     
     
      fill: '#dae8fc',
      stroke: '#6c8ebf'
    },
    polygon: {
     
     
      fill: '#d5e8d4',
      stroke: '#82b366'
    },
    diamond: {
     
     
      fill: '#ffe6cc',
      stroke: '#d79b00'
    },
    text: {
     
     
      color: '#b85450',
      fontSize: 12
    }
  }
}

onMounted(() => {
     
     
  const lf = new LogicFlow({
     
     
    container: document.getElementById('container')!,
    grid: true,
    ...SilentConfig,
    ...<
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stack Stone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值