LogicFlow 是一款流程图编辑框架,提供了一系列流程图交互、编辑所必需的功能和简单灵活的节点自定义、插件等拓展机制,方便我们快速在业务系统内满足类流程图的需求。
核心能力
- 可视化模型:通过 LogicFlow 提供的直观可视化界面,用户可以轻松创建、编辑和管理复杂的逻辑流程图。
- 高可定制性:用户可以根据自己的需要定制节点、连接器和样式,创建符合特定用例的定制逻辑流程图。
- 灵活易拓展: 内置提供丰富的插件,用户也可根据自身需求定制复杂插件实现业务需求。
- 自执行引擎: 执行引擎支持浏览器端执行流程图逻辑,为无代码执行提供新思路。
- 数据可转换:支持 LogicFlow 数据与 BPMN、Turbo 等各种后端执行引擎数据结构转换能力。
添加 logic-flow 基础代码
$ npm install @logicflow/core --save
在 App.vue 文件中, 添加 logic-flow 核心代码;
<script setup lang="ts">
import { onMounted, ref } from "vue";
import LogicFlow from "@logicflow/core";
import "@logicflow/core/es/index.css";
const container = ref();
onMounted(() => {
const lf = new LogicFlow({
container: container.value,
grid: true,
});
lf.render();
});
</script>
<template>
<div class="container" ref="container"></div>
</template>
<style scoped>
.container {
width: 100%;
height: 100%;
}
</style>
使用内置拖拽面板
安装 @logicflow/extension 扩展依赖, 先看一下内置拖拽面板如何使用;
npm install @logicflow/extension --save
再次修改 App.vue 文件内容, 导入 DndPanel 对象及扩展所需要的样式模块;
import { DndPanel } from "@logicflow/extension";
import "@logicflow/extension/lib/style/index.css";
在实例化 LogicFlow 对象时, 通过选项 plugins 配置 DndPanel 对象;
const lf = new LogicFlow({
...
plugins: [DndPanel],
});
在实例化 LogicFlow 对象后, 通过实例对象 lf.extension.dndPanel 中的 setPatternItems 方法设置拖拽面板的内容:
// icons 是一组图标对象(Base64字符串)
import { icons } from "./icons";
lf.extension.dndPanel.setPatternItems([
{
label: "选区",
icon: icons.select,
},
{
type: "circle",
text: "开始",
label: "开始节点",
icon: icons.start,
},
{
type: "rect",
label: "用户任务",
icon: icons.task,
},
{
type: "rect",
label: "系统任务",
icon: icons.task,
},
{
type: "diamond",
label: "条件判断",
icon: icons.condition,
},
{
type: "circle",
text: "结束",
label: "结束节点",
icon: icons.end,
},
]);
重新预览效果, 可以看到内置拖拽面板已经生效;
在React中的使用示例(使用CRA搭建开发环境)
package.json
{
"name": "logicflow-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@logicflow/core": "^2.0.0",
"@logicflow/extension": "^2.0.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"antd": "^5.20.1",
"insert-css": "^2.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
<style>
html, body, #root{
margin: 0;
padding: 0;
height: 100%;
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
src/index.js
import ReactDOM from 'react-dom/client';
import React, { useEffect, useRef } from "react";
import { Button } from "antd";
import LogicFlow from "@logicflow/core";
import {
BpmnElement,
BpmnXmlAdapter,
Control,
Menu,
SelectionSelect,
DndPanel,
} from "@logicflow/extension";
import "@logicflow/core/es/index.css";
import "@logicflow/extension/lib/style/index.css";
import insertCss from 'insert-css';
const root = ReactDOM.createRoot(document.getElementById('root'));
const App = () => {
const container = useRef(null);
const lfRef = useRef(null);
useEffect(() => {
lfRef.current = new LogicFlow({
container: container.current,
stopZoomGraph: true,
metaKeyMultipleSelected: true,
grid: true,
keyboard: {
enabled: true,
},
snapline: true,
plugins: [
BpmnElement,
BpmnXmlAdapter,
Control,
Menu,
SelectionSelect,
DndPanel,
],
});
lfRef.current.setPatternItems([
{
label: "选区",
icon: "data:image/png;base64,iVBO