Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

超级好用的流程库 - ggEditor #49

Open
lulujianglab opened this issue Feb 29, 2020 · 0 comments
Open

超级好用的流程库 - ggEditor #49

lulujianglab opened this issue Feb 29, 2020 · 0 comments

Comments

@lulujianglab
Copy link
Owner

在一些中后台应用的开发中,有些业务往往需要用到流程设计器,比如:管理网络、审批流程等等...正是因为有多种业务都需要使用到流程图的功能,所以对于能快速产出一个流程设计器是非常必须的

工具选择

古话说的好,预先善其事,必先利其器。所以首先要做的就是选择一个合适的开源基础库,站在巨人的肩膀上,总是跑的更快

开源时代,社区的资源总是非常丰富,身为小程序媛的我漏出幸福的微笑😊

  • joint.js 支持多种交互式图表创建,但有收费版本和免费版本的区分,更丰富的功能可能就需要收费了
  • jsPlumb 是一套完全开源的流程图创建工具,上手简单,底层是基于 Canvas 技术,但唯一美中不足的是,基于 jQuery,所以对于大批量流程的操作,在性能上可能不能达到最佳
  • d3 d3 应该很多人都熟悉,非常好的可视化基础库,相应的,上手成本相对高一些
  • spritejs 同样是基于 Canvas,据说是月影大大一个人写的(✨✨眼),官网写的超好啦...
  • ggEditor 蚂蚁金服数据可视化团队的大神高力结合 react + g6 开源的流程库,它的前身是 g6Editor,也是他们团队开源的产品,官方说法是学习成本太高,停止了对外支持。底层也是 Canvas 技术,虽然 ggEditor 目前开源的文档不多,但是潜力无穷,使用起来非常便捷,上手也比较简单,貌似是去年开源的,社区相对还没那么活跃,所以它的使用依然是一个摸索的过程

最终,我选择了 ggEditor,因为它完全开源,使用很简单,很轻量级,而且天然基于 react,非常完美

快速构建

引用 ggEditor

我们可以按照 github 上 ggEditor 的安装步骤操作

启动之后的界面效果可以参考:http://ggeditor.com/demo/#/flow

我们可以看到它的官方 demo 功能是比较齐全的,基本上已经实现了一个元素拖拽及元素属性编辑的完整功能

属性解析

我们知道整个流程编辑器基本可以分为三部分,一部分是左侧的元素面板区,另一部分是右侧的元素属性配置区,再就是中间的流程展示区,每个流程元素上可以有相应的事件响应

所以这里主要介绍以上相应的属性

  • Item 节点配置

    • 其中 type 有 node 和 edge 两个值可选,node 就是节点,edge 是连接节点的连线,当我们初始化加载元素和保存导出元素数据时也是以这两种为key
    • shape 可选参数有:圆形 flow-circle | 圆角矩形 flow-rect | 菱形 flow-rhombus | 椭圆矩形 flow-capsule
    • src 可以引入一张图片作为当前节点的预览样式
    • 编辑器画板中的样式是由 model 决定,model 默认会继承 组件的 props.shapeprops.size,所以通常 model 只需配置 color、label。配置项如下:
      model: {
        color: '#333', // 节点主题色(选中颜色、激活颜色基于该值)
        size: [10, 10], // [x, y] 节点尺寸
        shape: 'cirle', // 图形:圆形 circle | 圆角矩形 rect | 菱形 rhombus | 椭圆矩形 capsule
        style: { // 关键形样式(可覆盖color的普通样式,但激活、选中依然无效,坑!)
          fill: 'red', // 填充背景
          stroke: 'blue' // 形状描边
        },
        label: { // 节点标签
          text: '开始节点', // 文本内容
          fill: 'green' // 文本颜色
        },
        index: 1 // 渲染层级
      }
  • Flow 编辑器配置
    在 组件上,最重要的是监听事件:
    js <Flow onNodeClick={(e) => { console.log(e); }}/>
    更多的我们可以参考页面事件 Page Events

    • 拖拽节点时,区分是新节点还是旧节点。可以用onDrop - 监听拖拽放置事件,如果是从元素面板区拖拽新节点到画布上,onDrop 返回的事件对象中 currentItemcurrentShape 都是 undefined。而如果是挪动旧节点的位置,这两个字段会记录拖动的图形图项。当然,也可以监听节点拖动结束事件 - onNodeDragEnd,这个事件只会在拖动画布上的节点时才触发

    • 锚点连线取消,比如有一个需求是当目标节点已经连线的时候,就取消连线。可以用 onAfterChange 事件,根据 item(type: 'edge') 或者 model(source:'xxxx') 对象中的参数进行判断。最后用结合异步函数和 <withPropsAPI> 组件取消连线:

      handleAddItem = (e) => {
        this.apiAction('undo')
      }
      
      apiAction = (command) => {
        const { propsAPI } = this.props
        setTimeout(() => {
          propsAPI.executeCommand(command)
        }, 0)
      }

      <withPropsAPI>是 ggEditor 自带的包装组件,同时它又自带 propsAPI 属性,更多的属性值我们可以参考 propsAPI

    • 保存数据。上面 <withPropsAPI> 提供的 propsAPI 属性中,包含了 save() 方法�。我们可以封装一个 SaveButton 组件,暴露一个 onSave 事件,然后用 <withPropsAPI> 包装该组件。具体可参考 demo

    • 自定义键盘操作。可以通过监听 onKeyDownonKeyUp 手动创建多个快捷命令

      handleKeyUp = e => {
        // 键盘抬起时重置记录的按键
        this.keysDown = ''
      }
      
      handleKeyDown = e => {
        // 拼接按键命令
        if (this.keysDown.length === 0) {
          this.keysDown = e.domEvent.key
        } else {
          this.keysDown += `+${e.domEvent.key}`
        }
      
        // 自定义键盘操作
        switch (this.keysDown) {
          case 'Meta+c':
            this.diyCopyCommand()
            break
          case 'Control+c':
            this.diyCopyCommand()
            break
          case 'Meta+v':
            this.diyPasteCommand()
            break
          case 'Control+v':
            this.diyPasteCommand()
            break
          default: break
        }
      }
      
      // 自定义复制
      diyCopyCommand = () => {
        const { propsAPI } = this.props
        let selected = propsAPI.getSelected()
        if (selected.length > 0) {
          this.commandAction('copy')
        }
      }
      
      // 自定义粘贴
      diyPasteCommand = () => {
        this.commandAction('paste')
      }

以上只是 ggEditor 的核心组件和功能。还有很多组件没有提交,比如 <Minimap><ContextMenu><Toolbar> ,我们可以具体去看项目 demo

其他的属性解析可以参考官网 API

自定义节点

如果 <Item> 自带的参数不满足需求,可以使用 <ReisterNode> 来封装自己的 <Item>

比如自定义一个 start-node,就可以自行封装一个 node 组件

具体可以参考 Issues

兼容 IE11

ggEditor 是基于 umijs 脚手架的, umijs不得不说,太简单粗暴,默认不支持IE,如果需要支持,需要我们开启配置

需要在 .umirc.js 中配置

targets: {
  ie: 11,
}

dva 版本问题

Chrome warning

image

IE bug

image

查看后发现都是指向同一个问题,因为 dva 的最新版本,具体可以看看升级dva最新版提示Warning: Please use require("dva").dynamic instead of require("dva/dynamic"). Support for the latter will be removed in the next major release.2.6.0-beta.4 版本新抛出警告

为了快速解决这个问题,我去瞅了眼 ant-design-pro,发现它三天前提交的,但是dva版本仍是用的低版本,非常 nice

以上,便可快速解决 IE11 白屏的问题

参考文档

在 React 项目中引入 GG-Editor 编辑可视化流程

常见问题

PS:终于用上自己写的博客系统写文章啦,体验还是非常八错的 😊😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant