LogicFlow自定义节点:矩形、HTML(vue3)
效果:
LogicFlow 内部是基于MVVM
模式进行开发的,分别使用preact
和mobx
来处理 view 和 model,所以当我们自定义节点的时候,需要为这个节点定义view
和model
。
参考官方文档:节点 | LogicFlow
1、自定义矩形节点
customRect.ts文件:
import { RectNode, RectNodeModel, h } from '@logicflow/core';
class TodoNodeView extends RectNode {
getShape() {
// 获取XxxNodeModel中定义的形状属性
const { model } = this.props;
const { x, y, width, height, radius } = model;
// 获取XxxNodeModel中定义的样式属性
const style = model.getNodeStyle();
return h('g', {}, [
h('rect', {
...style,
x: x - width / 2,
y: y - height / 2,
width,
height,
rx: radius,
ry: radius,
}),
// h(
// // 待办图标
// 'svg',
// {
// x: x - width / 2 + 5,
// // y: y - height / 2 + 5,
// // width: 25,
// // height: 25,
// y: y - height / 2 - 2,
// width: 30,
// height: 30,
// viewBox: '0 0 1274 1024',
// },
// h('path', {
// fill: '#6f757d',
// d: 'M735.483537 563.043418c-127.277094 0-230.472576 103.195482-230.472576 230.484006s103.195482 230.472576 230.472576 230.472576 230.472576-103.195482 230.472576-230.461147-103.184053-230.495435-230.472576-230.495435z m104.555573 333.999509a29.99058 29.99058 0 0 1-42.288546 0l-83.434159-83.434159a29.876286 29.876286 0 0 1-8.686296-22.56151V671.679264a29.922004 29.922004 0 0 1 59.832578 0v108.40726l74.576423 74.656428a29.99058 29.99058 0 0 1 0 42.299975z',
// // d:
// // "M655.807326 287.35973m-223.989415 0a218.879 218.879 0 1 0 447.978829 0 218.879 218.879 0 1 0-447.978829 0ZM1039.955839 895.482975c-0.490184-212.177424-172.287821-384.030443-384.148513-384.030443-211.862739 0-383.660376 171.85302-384.15056 384.030443L1039.955839 895.482975z",
// }),
// h('path', {
// fill: '#6f757d',
// d: 'M481.992276 793.538853a253.514119 253.514119 0 0 1 144.318236-228.883898q-8.114829-0.377168-16.321093-0.377169h-204.585129c-191.498538 0-347.360404 152.010179-347.360403 338.856977v19.921335c0 99.709534 153.278836 99.709534 347.360403 99.709534h221.729134A253.468402 253.468402 0 0 1 481.992276 793.538853zM490.118535 546.665178c150.707235 0 273.344019-122.648213 273.344018-273.355447S640.848628 0 490.118535 0 216.785945 122.636784 216.785945 273.309731 339.365583 546.665178 490.118535 546.665178z',
// }),
// ),
]);
}
}
class TodoNodeModel extends RectNodeModel {
getNodeStyle() {
const style = super.getNodeStyle();
style.stroke = '#ffffff'; //节点边框颜色
style.fill = '#ffffff'; //填充色
return style;
}
initNodeData(data) {
super.initNodeData(data); //调用父类的方法
this.width = 180;
this.height = 60;
this.radius = 10;
}
}
export default {
type: 'TodoNode',
view: TodoNodeView,
model: TodoNodeModel,
};
2、自定义HTML节点
customHtml.ts文件:
import { HtmlNodeModel, HtmlNode } from '@logicflow/core';
class UmlModel extends HtmlNodeModel {
setAttributes() {
// 设置节点宽高和锚点
const width = 80;
const height = 88;
this.width = width;
this.height = height;
}
}
class UmlNode extends HtmlNode {
setHtml(rootEl) {
const { properties } = this.props.model;
const node_md = this.props.model;
const el = document.createElement('div');
el.className = 'uml-wrapper';
el.id = node_md.id; // html 节点绑定节点唯一ID;即可通过id 获取对应dom元素 并进行相关业务操作
const html = `
<div class="logdom-hml" ></div>
`;
el.innerHTML = '我是一个小天才';
el.style.backgroundColor = 'pink';
// 需要先把之前渲染的子节点清除掉。
rootEl.innerHTML = '';
rootEl.appendChild(el);
}
}
export default {
type: 'Htmlnode',
view: UmlNode,
model: UmlModel,
};
注册自定义节点
我们可以在创建LogicFlow
实例之后,render
之前,使用register方法来注册自定义节点。
<template>
<div class="composer">
<div class="workflow-app" id="container"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
// import { forEach, map, has } from 'lodash-es';
import LogicFlow from '@logicflow/core';
import '@logicflow/core/dist/style/index.css';
import { Control } from '@logicflow/extension';
import TodoNode from './customRect';
import Htmlnode from './ProgressNode';
const lf = ref();
const render = (data: any) => {
lf.value.render(data);
};
onMounted(() => {
renderGraphData();
render({
nodes: [
{
id: '1',
type: 'TodoNode',
x: 200,
y: 200,
text: '开始',
},
{
id: '2',
type: 'TodoNode',
x: 600,
y: 300,
text: '流程节点1',
},
{
id: '3',
type: 'Htmlnode',
x: 600,
y: 500,
},
],
edges: [
{
type: 'bezier',
sourceNodeId: 1,
targetNodeId: 2,
},
],
});
});
const renderGraphData = () => {
const container: any = document.querySelector('#container');
if (container) {
lf.value = new LogicFlow({
plugins: [Control],
background: {
backgroundColor: '#f5f6f7',
},
grid: {
size: 10,
type: 'dot',
config: {
color: '#DEE0E3',
thickness: 1,
},
},
keyboard: {
// 键盘事件开关
enabled: true,
},
// style: {
// rect: {
// // 矩形节点样式
// stroke: '#31A5FF',
// strokeWidth: 1,
// fill: '#fff',
// },
// },
container,
});
lf.value.register(TodoNode); //注册节点
lf.value.register(Htmlnode); //注册节点
// console.log('画布', lf.value.getGraphData()); //打印画布数据
lf.value.on('node:click', (data: any) => {
console.log('点击了', data.data.text.value, data);
});
}
};
</script>
<style lang="less" scoped>
.composer {
height: 100%;
width: 100%;
.workflow-app {
width: 100%;
height: 100%;
}
}
</style>