蚂蚁金服数据可视化团队曾经开源了一款G6-Editor,但后来停止了对外支持,学习成本太高

好在后来他们团队的大牛高力结合 React + G6 开源了一个 GG-Editor(其实就是G6-Editor)

不过相关的文档还是太少,实际的使用依然是一个不断摸索的过程...

常见问题: https://github.com/gaoli/GGEditor/issues/130

一、引用 GG-Editor

直接通过 npm 或 yarn 安装依赖

npm install --save gg-editor

由于对 GG-Editor 不熟悉,所以我将它自带的 Demo 作为模版,在此基础上进行开发

node_modules/gg-editor/demo/src/ 下的 Flow 目录和 components、common 目录拷出来,放到开发目录下进行改造

这个 demo 基于 ant 开发,所以需要引入 ant

npm install --save antd

另外 demo 使用了 CSS Modules,需要在项目配置中启用

比如在我的项目中,就把原本的 index.css 重命名为 index.module.css,然后修改相应的引入路径

由于只是开发可视化流程,所以 components 目录下多余的文件(以 Koni 和 Mind 开头的文件)都以删掉

然后将 Flow/index.js 提出来作为项目入口,改造后的目录如下:

二、 Item 节点配置

demo 启动之后的界面是这样的

左边是 gg-editor 提供的四种基础节点类型,其对应的组件是 /components/EditorItemPanel

这个组件下引入了四个 gg-deitor <Item> 组件,官方提供的 API 如下:

http://ggeditor.com/docs/api/itemPanel.zh-CN.html

其中 type 有 node 和 edge 两个值可选,node 就是节点,edge 是连接节点的连线

shape 可选参数有:圆形 'flow-circle' | 圆角矩形 'flow-rect' | 菱形 'flow-rhombus' | 椭圆矩形 'flow-capsule'

src 可以引入一张图片作为当前节点的预览样式

也可以自定义子节点,<Item /> 会接收 props.children 作为预览样式

需要注意的是,不管是 src 还是子节点,都只是一个预览样式,并不等于编辑器画板中的样式

而画板中的样式,由 model 决定,其配置项如下:

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 // 渲染层级
}

不过 model 默认会继承 <Item> 组件的 props.shape 和 props.size,所以通常 model 只需配置 color、label

这里有个比较难受的地方:画板中的节点样式由 model 控制,而节点预览样式由 CSS 或者图片控制,要想保证二者统一,就会需要很多额外的工作

三、自定义节点

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

<ReisterNode> 可以接收上面三个参数,其中 name 是组件名称

在 <Item> 的 shape 属性中指定 name,就能拖拽生成自定义的节点

extend 可以继承一个基本图形('flow-circle', 'flow-rect' 等)

config 可以参考官方的 Issues:https://github.com/gaoli/GGEditor/issues/76

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

然后在 ItemPanel 中的 <Item> 指定组件名称

最后在 <Flow> 组件下面引入

如果还是不明白 <ReisterNode> 如何使用,可以参考这个 Demo:https://codesandbox.io/s/4j62moqy0w

四、Flow 编辑器配置

官方文档地址:http://ggeditor.com/docs/api/flow.zh-CN.html

组件默认可以将连线到空白处,设置 noEndEdge 为 false 就只能在节点之间连线

align 参数可以设置对齐的样式,比如对齐线:

<Flow align={{
line: {
stroke: 'blue', // 对齐线颜色
lineWidth: // 对齐线宽度
}
}} />

shortcut 可以配置内置的快捷键命令,支持的命令有:

但经过试验,只有适用页面为 All 的命令可配置,而其它命令(如 Ctrl+C)都无效

组件本身默认的连线是曲线 'flow-smooth',在编辑时可以手动修改,也可以在 graph 中限定连线类型:

<Flow graph={{edgeDefaultShape: 'flow-polyline-round'}}/>

更多关于 graph 的配置项可以参考这里:https://www.yuque.com/antv/g6/api-graph

在 <FLow> 组件上,最重要的是监听事件:

  <Flow onNodeClick={(e) => {
console.log(e);
}}
/>

事件是整个编辑器的灵魂,下面将重点介绍一下 GG-Editor 的 Page Events

五、页面事件 Page Events

官方文档:http://ggeditor.com/docs/api/pageEvents.zh-CN.html

文档中对支持的事件和事件对象都有说明,这里不再细说,主要分享几个场景

// 事件总览参考 /node_modules/gg-editor/src/common/constants.js

1. 拖拽节点,区分新节点还是旧节点

监听拖拽放置事件:onDrop

从 <ItemPanel> 拖拽新节点到画布的时候,onDrop 返回的事件对象是这样的:

这时 currentItem 和 currentShape 都是 undefined

而如果只是挪动旧节点的位置,这两个字段会记录拖拖动的图形图项

或者监听节点拖动结束事件:onNodeDragEnd

这个事件只会在拖动画布上的节点才会触发

2. 锚点连线取消

连线触发的事件很多,比如 onDrop、onDragEnd,不过个人推荐监听 onAfterChange

当子项更改的时候会触发 onAfterChange 事件,如果是连线,事件对象如下:

如果有需求,当目标节点已经连线的时候,就取消连线,就可以根据 item 或者 model 对象中的参数进行判断

最后用结合异步函数 <withPropsAPI> 组件取消连线:

这里用到的 <withPropsAPI> 组件,是 GG-Editor 自带的包装组件

经过 <withPropsAPI> 包装的组件,会自带 propsAPI 属性

executeCommand() 方法可以执行上面第四部分 (shortcut) 提到的所有命令

3. 保存

上面 <withPropsAPI> 提供的 propsAPI 属性中,包含了 save() 方法

可以封装一个 SaveButton 组件,暴露一个 onSave 事件

然后用 <withPropsAPI> 包装该组件

详情可以参考这个 Demo: https://codesandbox.io/s/r4kzkn441m

4. 自定义键盘操作

上面提到过,Ctrl + C 的复制快捷键无效

但这个功能十分关键,可以通过监听 onKeyDownonKeyUp 手动创建这个快捷命令

创建一个 keysDown 字段来记录按下的按键,keyUp 时清空

小结:

上面的内容只介绍了 GG-Editor 核心的几个组件和功能

像 <Minimap>、<ContextMenu>、<Toolbar> 这些组件参考 Demo 就足够,所以并没有提及

基于上面的介绍,已经能够使用 GG-Editor 进行开发,如果有其它疑问,可以在 GitHub 仓库提 Issues

最后发一下牢骚:阅读源码这种事,必须配一个程序员鼓励师才能开展

在 React 项目中引入 GG-Editor 编辑可视化流程的更多相关文章

  1. react项目中引入了redux后js控制路由跳转方案

    如果你的项目中并没有用到redux,那本文你可以忽略 问题引入 纯粹的单页面react应用中,通过this.props.history.push('/list')就可以进行路由跳转,但是加上了redu ...

  2. 【React踩坑记五】React项目中引入并使用react-ace代码编辑插件(自定义列表提示)

    最近有一个引入sql编辑器插件的需求,要求代码高亮显示,代码智能提示,以及支持自定义代码提示列表等功能.中途在自定义代码提示列表中由于没有相关demo,所以踩了一些坑,遂将其整理如下,以便日后查看. ...

  3. 【React踩坑记四】React项目中引入并使用js-xlsx上传插件(结合antdesign的上传组件)

    最近有一个前端上传并解析excel/csv表格数据的需求. 于是在github上找到一个14K star的前端解析插件 github传送门 官方也有,奈何实在太过于浅薄.于是做了以下整理,避免道友们少 ...

  4. react 项目中 引入 bootstrap

    react-bootstrap是一个非常受欢迎的针对react封装过的bootstrap,它本身不包含css,所以也是需要使用bootstrap原生库. 在create-react-app建的项目目录 ...

  5. react项目中引入百度地图打包报错问题

    一.我正常引入百度地图,调试时候是好使的,但是打包时候就报错 引入方法如下: 报错如图 正常调试是好使的,但是打包报这个错,解析不了这个BMap,那么怎么办呢? 然后我就转用了window办法,虽然因 ...

  6. 【已解决】React项目中按需引入ant-design报错TypeError: injectBabelPlugin is not a function

    react项目中ant-design按需加载,使用react-app-rewired的时候报错 运行npm start或者yarn start报如下错误: TypeError: injectBabel ...

  7. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

  8. 在react项目中使用ECharts

    这里我们要在自己搭建的react项目中使用ECharts,我们可以在ECharts官网上看到有一种方式是在 webpack 中使用 ECharts,我们需要的就是这种方法. 我们在使用ECharts之 ...

  9. 优雅的在React项目中使用Redux

    概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux react-redux React插件,作用:方便在 ...

随机推荐

  1. KB奇遇记(3):糟糕的IT现状

    2015年8月3号,终于告别了过去来到了KB. 公司给安排的住房是一间套房里的小房间,小的简直连坐的地方都没有了,中间一个大床将房间隔了两边,显得特别狭小.由于是刚来,我也不好要求太多.但就这个小房间 ...

  2. 【Android】Context的使用

    Android开发经常需要使用Context来启动Activity,或者打开SharedPreferences,或者构建一个Dialog.最近老是用到getContext(),getApplicati ...

  3. 实战FFmpeg--编译iOS平台使用的FFmpeg库(支持arm64的FFmpeg2.6.2)

    编译环境:Mac OS X 10.10.2 ,Xcode 6.3  iOS SDK 8.3        FFmpeg库的下载地址是 http://www.ffmpeg.org/releases/ . ...

  4. [b0006] Spark 2.0.1 伪分布式搭建练手

    环境: 已经安装好: hadoop 2.6.4  yarn 参考: [b0001] 伪分布式 hadoop 2.6.4 准备: spark-2.0.1-bin-hadoop2.6.tgz 下载地址:  ...

  5. java.lang.IllegalArgumentException: Prometheus requires that all meters with the same name have the same set of tag keys.

    创建Spring Cloud Sleuth对应Zipkin服务,引入依赖: <dependency> <groupId>io.zipkin.java</groupId&g ...

  6. 【mysql】pymysql.err.InterfaceError Interface Error: (0, '')

    八成是丢失连接了 while 1: try: self.conn.ping(reconnect=True) self.cur.execute(sql,tuple(item.values())) sel ...

  7. C++:基本类型的转换

    C++:基本类型的转换 一.string转为int [参考:https://blog.csdn.net/m0_37316917/article/details/82712017] string num ...

  8. linux so库方式

    gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

  9. luoguP4343自动刷题机(二分标准题)

    https://www.luogu.org/problem/P4343 参考博客:https://www.luogu.org/blog/ofnoname/solution-p4343 这真是一语点醒梦 ...

  10. (day51)三、ORM、路由层、版本差异、流程图

    目录 一.ORM关系建立 (一)ForeignKey(一对多) (二)ManyToManyField(多对多) (三)OneToOneField(一对一) 二.django请求生命周期流程图 三.ur ...