logicflow流程图手把手入门教程(附demo)

6,862 阅读5分钟

本文正在参加「金石计划」 

logicflow流程图入门教程(带demo)

开源

个人开源的leno-admin后台管理项目,前端技术栈:reactHooksant-design;后端技术栈:koamysqlredis,整个项目包含web端electron客户端mob移动端template基础模板,能够满足你快速开发一整套后台管理项目;如果你觉得不错,就为作者点个✨star✨吧,你的支持就是对我最大的鼓励;

演示地址

文档地址

源码github地址

logicflow线上demo

一、安装

npm i @logicflow/core
npm i @logicflow/extension

二、基本使用

2-1、设置流程网格背景

1、导入配置文件

import LogicFlow from '@logicflow/core'

// 引入整体背景的样式
import '@logicflow/core/dist/style/index.css'

2、设置流程图载体

<div class="bpmn-example-container">
    <div ref="logicContainer" class="viewport" />
 </div>

3、配置基础项

export default {
  data() {
    return {
      lf: null,
      config: {
        stopScrollGraph: true, // 禁止鼠标滚动移动画布
        stopZoomGraph: true, // 禁止缩放
        metaKeyMultipleSelected: true,
        // 背景网格大小
        grid: {
          size: 10,
          type: 'dot'
        },
        keyboard: {
          enabled: true
        },
        snapline: true
      }
    }
  },
  mounted() {
    // 初始项目注册
    this.lf = new LogicFlow({
      ...this.config,
      plugins: [
      ],
      container: this.$refs.logicContainer,
      isSilentMode: this.isType === 'preview'
    })
    this.lf.render()
  }
}

样式设置

.bpmn-example-container {
  height: calc(100vh - 50px);
  position: relative;
  overflow: hidden;

  .viewport {
    height: 100%;
    overflow: hidden;
    position: relative;
  }
}

4、最终效果

2-2、配置右上角基本工具栏

1、导入配置文件

// 引入 extension相关操作的样式
import '@logicflow/extension/lib/style/index.css'
// 引入相关插件
import { Control } from '@logicflow/extension'

2、注册插件

    // 初始项目注册
    this.lf = new LogicFlow({
      ...this.config,
      // 之后所有的插件都放置到plugins之中即可
      plugins: [
        // 右上方 控制面板
        Control
      ],
      container: this.$refs.logicContainer,
      isSilentMode: this.isType === 'preview'
    })

3、最终效果

4、自定义工具栏

当前我们也可以自己定义工具栏里面的内容,现在我就在工具栏中定义保存和关闭当前页面的按钮,方法也挺简单的~

1、添加保存和删除功能

官方提供了addItem这个函数来进行自定义添加,里面包含了标题,icon,文本,方法等等的配置项,能够很轻松的就进行工具栏的自定义配置:

  mounted() {
   saveClosePage() {
      this.lf.extension.control.addItem({
        iconClass: 'el-icon-files',
        title: '',
        text: '保存',
        onClick: (lf, ev) => {

        }
      })
      this.lf.extension.control.addItem({
        iconClass: 'el-icon-close',
        title: '',
        text: '关闭',
        onClick: (lf, ev) => {

        }
      })
    }
   }

然后这个配置项的函数一定要放置到lf.render渲染之前调用即可!

.viewport ::v-deep .el-icon-files {
      font-size: 20px;
}
.viewport ::v-deep .el-icon-close {
      font-size: 20px;
}

2、添加后的效果

2-3、配置左侧可拖拽的流程图标

1、设置节点

  data() {
    return {
      // 定义左侧的流程图表 注意 type的命名需要与实际js配置项里的一致
      nodeList: [
        {
          text: '开始',
          type: 'start',
          class: 'node-start'
        },
        {
          text: '矩形',
          type: 'rect',
          class: 'node-rect'
        },
        {
          type: 'end',
          text: '结束',
          class: 'node-end'
        }
      ]
    }

2、配置节点node

新建nodes文件夹,里面存储node节点的配置文件,index.js文件进行统一的导出配置;

start开始节点的详情配置项:

export default function registerStart(lf) {
  lf.register('start', ({ CircleNode, CircleNodeModel, h }) => {
    class StartNode extends CircleNode {
      getLabelShape() {
        const { model } = this.props
        const {
          x,
          y
        } = model
        return h(
          'text',
          {
            fill: '#000000',
            fontSize: 12,
            x: x - 12,
            y: y + 4,
            width: 50,
            height: 25
          },
          'Start'
        )
      }
      getShape() {
        const { model } = this.props
        const {
          x,
          y,
          r
        } = model
        const {
          fill,
          stroke,
          strokeWidth } = model.getNodeStyle()
        return h(
          'g',
          {
          },
          [
            h(
              'circle',
              {
                cx: x,
                cy: y,
                r,
                fill,
                stroke,
                strokeWidth
              }
            ),
            this.getLabelShape()
          ]
        )
      }
    }
    class StartModel extends CircleNodeModel {
      // 自定义节点形状属性
      initNodeData(data) {
        data.text = {
          value: (data.text && data.text.value) || '',
          x: data.x,
          y: data.y + 35,
          dragable: false,
          editable: true
        }
        super.initNodeData(data)
        this.r = 20
      }
      // 自定义节点样式属性
      getNodeStyle() {
        const style = super.getNodeStyle()
        return style
      }
      // 自定义锚点样式
      getAnchorStyle() {
        const style = super.getAnchorStyle()
        style.hover.r = 8
        style.hover.fill = 'rgb(24, 125, 255)'
        style.hover.stroke = 'rgb(24, 125, 255)'
        return style
      }
      // 自定义节点outline
      getOutlineStyle() {
        const style = super.getOutlineStyle()
        style.stroke = '#88f'
        return style
      }
      getConnectedTargetRules() {
        const rules = super.getConnectedTargetRules()
        const notAsTarget = {
          message: '起始节点不能作为连线的终点',
          validate: () => false
        }
        rules.push(notAsTarget)
        return rules
      }
    }
    return {
      view: StartNode,
      model: StartModel
    }
  })
}

3、导入节点,并配置,并渲染dom

1、导入节点

// 导入所有自定义节点
import { registerStart, registerEnd,registerTask} from './nodes'

2、注册节点

    // 注册左侧可拖拽的node节点 在render渲染前
    registerStart(this.lf)
    registerTask(this.lf)
    registerEnd(this.lf)

3、渲染节点

    <!-- 左侧流程节点 -->
    <div class="node-panel">
      <div
        v-for="item in nodeList"
        :key="item.text"
        class="node-item"
        @mousedown="$_dragNode(item)"
      >
        <div class="node-item-icon" :class="item.class">
          <div
            v-if="item.type === 'user' || item.type === 'time'"
            class="shape"
          />
        </div>
        <span class="node-label">{{ item.text }}</span>
      </div>
    </div>

4、节点的scss

里面的图片素材可以直接到我的demo地址中拿去,自己进行配置也可以~

.node-panel {
  position: absolute;
  top: 10px;
  left: 15px;
  width: 70px;
  padding: 20px 10px;
  background-color: white;
  box-shadow: 0 0 10px 1px rgb(228, 224, 219);
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 101;
}
.node-item {
  margin-bottom: 15px;
  text-align: center;
}
.node-item-icon {
  width: 30px;
  height: 30px;
  background-size: cover;
}
.node-label {
  font-size: 12px;
  margin-top: 5px;
  user-select: none;
}
.node-start {
  background: url('./imgs/start.png') no-repeat;
  background-size: cover;
}
.node-rect {
  border: 1px solid black;
}
.node-end {
  background: url('./imgs/end.png') no-repeat;
  background-size: cover;
}

5、导入节点右键的删除...的功能项

import {  Menu } from '@logicflow/extension'

 plugins: [
        // 启动节点 右键鼠标菜单
        Menu
      ],

4、最终效果

2-4、配置节点框选功能

1、引入插件

import {  SelectionSelect } from '@logicflow/extension'

2、注册插件

 plugins: [
    // 开启框选功能
     SelectionSelect
],

3、设置dom、scss,方法

 <div class="pattern-selection" @mousedown="openSelection" />
 <div style="margin-bottom: 15px; font-size: 12px">选区</div>
.pattern-selection {
  width: 36px;
  height: 36px;
  background: url('./imgs/选区域.png') no-repeat;
  background-size: cover;
  cursor: pointer;
  opacity: 0.99;
}
    // 选取
    openSelection() {
      this.lf.updateEditConfig({
        stopMoveGraph: true
      })

4、最终效果

2-4、配置节点之间的插入功能

1、引入插件

import {  InsertNodeInPolyline } from '@logicflow/extension'

2、注册插件

 plugins: [
   // 允许中间插入节点
     InsertNodeInPolyline,
],

2-5、配置下载流程图片功能

1、引入插件

import {  Snapshot } from '@logicflow/extension'

2、注册插件

 plugins: [
        // 开启导出功能
        Snapshot
],

3、设置dom、scss,方法

   <!-- 底部下载 -->
    <div class="graph-io">
      <span id="download-img" title="下载图片" @mousedown="downloadImage">
        <i class="el-icon-picture-outline down-img" />
      </span>
    </div>
.graph-io {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 9999;
  background: rgba(255, 255, 255, 0.8);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  padding: 10px;
  display: flex;
}
.graph-io {
  .down-img {
    font-size: 18px;
    color: #328cff;
  }
  span {
    margin: 0 5px;
    cursor: pointer;
  }
}
    // 下载图片
    downloadImage() {
      this.lf.getSnapshot()
    }

4、最终效果

下载后的图片👇

三、其他

可以去官网看下详情的api配置项,非常丰富

logic-flow 官网地址

demo代码地址

进阶-数据如何操控

四、结语

以上是我个人对logicflow入门的一些浅薄理解,当然流程图类的开源库还有很多,比如蚂蚁的G6,bpmnjs等等,如果文章有不正确的地方,欢迎大家指正,谢谢~