@blueking/bkflow.js
v0.1.11
Published
a visual edit flowchart plugin
Downloads
774
Readme
Install
tnpm install @tencent/bkflow
基本用法-引入对象
import D3Graph from '@tencent/bkflow'
let flowGraph = null // 全局定义,不要定义到Vue的data里面,D3数据绑定和Vue数据绑定冲突
初始化实例
flowGraph = new D3Graph('#flowgraph', options)
Options
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|------|------|------|------|------|
| mode | 画布模式, 编辑(edit)模式可以拖拽、点击节点,只读模式(readonly)会屏蔽拖拽、点击事件 | String | edit / readonly | readonly |
| background | 背景颜色 | String | —— | #ddd |
| renderVisibleArea | 是否只渲染可视区域内模板 | Boolean | —— | false |
| canvasPadding | 画布填充 | Object | —— | { x: 0, y: 0 } |
| autoBestTarget | 自动连接最优连线 | Boolean | true / false | true |
| nodeConfig | 渲染节点模板配置 | Array | —— | [{ type: 'default', width: 30, height: 30, radius: '50%' }], |
| nodeTemplateKey | 匹配节点模板的key, 对应NodeConfig里面的模板类型的Key,这个Key需要在节点信息里面包含 | String | —— | type |
| zoom | 缩放相关 | Object | —— | —— |
| zoomFilter | 缩放的过滤函数,可以根据实际情况设置其缩放行为,参数为event
。默认情况下配置了 zoom 后所有行为均允许缩放。 | Function | —— | —— |
| lineConfig | 连线配置, 分别配置连线颜色和hover颜色 | Object | —— | —— |
| nodeClick | 节点点击事件类型(D3的Zoom会影响mouseup,hover弹出元素初次点击节点不触发click、mouseup,因此重写了click事件,根据需要选择是否启用) | String | native(原生事件) / Refactoring(重构点击事件) | native |
| onNodeRender | 节点渲染时的回调函数, 返回Html字符串 | Function | —— | —— |
| onLineConnectBefore | 完成连线之前的回调函数 | Function | —— | —— |
| onLineDelete | 删除连线之前函数 | Function | —— | —— |
| tree | 渲染树形结构配置 | Object | —— | 参考下面Tree配置 |
nodeConfig 配置说明
类型: Array
- 可配置多个模板,不同节点根据指定的type获取对应的配置,渲染图形宽度、高度、radius
可配置项
- type: 节点类型,对应渲染画布的数据中不同模板, 此处的type为默认值,和nodeTemplateKey配合使用,nodeTemplateKey 定义此处key的名称,方便渲染数据处不同key的需求
- width:节点宽度,目前只支持'px'
- height:节点高度, 目前只支持'px'
- radius:节点四个角半径,String类型,可以是px|em|rem|n%|vw|vh
Tree配置
tree: {
// TODO: horizontal 调试渲染结果
mode: 'vertical', // horizontal | vertical,
node: {
width: 300,
height: 50
}
}
// 必须调用方法:
/**
* 渲染Tree
* @param {*} treeData 渲染数据 { name: '', children: [] } 可以是数组,数组的话渲染多棵树
* @param {*} id id字段
* @param {*} name name字段
*/
instance.renderTree(treeData, 'spanID', 'spanID')
| 参数 | 说明 | 类型 | 可选值 | 默认值 | |------|------|------|------|------| | mode | 树形结构方向 | String | vertical/horizontal | vertical | | node | 节点配置(目前只支持设置宽高) | Object | -- | { width: 300, height: 50 } |
zoom 配置
zoom: {
scaleExtent: [1, 1],
controlPanel: false,
tools: []
}
| 参数 | 说明 | 类型 | 可选值 | 默认值 | |------|------|------|------|------| | scaleExtent | 缩放倍数限制,默认为[1, 1], 即不可进行缩放操作 | Array | —— | [1, 1] | | controlPanel | 缩放控制板,默认关闭 | Boolean | true / false | false | | tools | 控制面板放大、缩小、还原的icon和text | Object | -- | -- |
zoom tools 配置
[{
text: '放大',
icon: 'icon-plus-circle',
type: 'zoomIn'
}, {
text: '缩小',
icon: 'icon-minus-circle',
type: 'zoomOut'
}, {
text: '还原',
icon: 'icon-full-screen',
type: 'resetPosition'
}]
lineConfig
{
canvasLine: false, // canvas模式(大数据渲染时启用Canvas模式。默认svg模式)渲染连线
color: '#ddd',
activeColor: '#3a84ff'
}
对外提供的方法
调用方式
flowGraph.on('fn', callback)
可用方法
| 方法名 | 说明 | 参数说明 | |------|------|------| | nodeDblClick | 节点双击事件 | (node, event) | | nodeMouseEnter | 鼠标滑入节点事件 | (node, event) | | nodeMouseLeave | 鼠标离开节点事件 | (node, event) | | nodeDragEnd | 节点拖拽结束事件 | (node, event) | | lineConnected | 连线结束事件 | (node, event) | | nodeClick | 节点点击事件 | (node, event) |
全部事件定义
/** 对外分发事件 */
const EVENTS = {
/** 可视区域改变事件 */
VISIBLE_AREA_CHANGED: 'visibleAreaChanged',
/** 可视区域移动中 */
VISIBLE_AREA_CHANGING: 'visibleAreaChanging',
/** 更新可视区域节点之前事件 */
BEFORE_VISIVLE_NODE_UPDATE: 'beforeVisibleNodeUpdate',
/** 配置节点渲染时回调,可在此处返回节点模板 */
ON_NODE_RENDER: 'onNodeRender',
/** 结束连线之前 */
ON_LINE_CONNECT_BEFORE: 'onLineConnectBefore',
/** 连线完成 */
ON_LINE_CONNECTED: 'lineConnected',
ON_NODE_MOUSE_ENTER: 'nodeMouseEnter',
ON_NODE_MOUSE_LEAVE: 'nodeMouseLeave',
ON_NODE_MOUSE_DOWN: 'nodeMousedown',
ON_NODE_MOUSE_UP: 'nodeMouseup',
/** 画布拖拽结束 */
ON_CANVAS_DRAG_END: 'canvasDragEnd',
/** 画布拖拽开始 */
ON_CANVAS_DRAG_START: 'canvasDragStart',
/** 节点拖拽结束 */
ON_NODE_DRAG_END: 'nodeDragEnd',
/** 节点鼠标左键双击事件 */
ON_NODE_DBCLICK: 'nodeDblClick',
ON_NODE_CLICK: 'nodeClick',
/** 连线删除点击事件 */
ON_LINE_DELETE_CLICK: 'lineDeleteClick',
ON_LINE_MOUSE_ENTER: 'lineMouseEnter',
ON_LINE_MOUSE_LEAVE: 'lineMouseLeave'
}
注意:
组件默认抛出的所有事件都是注册到了最外层的容器DOM元素,如果需要针对渲染的节点模板内部监听具体的元素事件,请根据DOM属性判断(Class、Attribute、ID)等
举个例子:
监听节点内部的一个ICON的点击事件
/** 监听点击事件 **/
handleGraphNodeClick(e, data) {
const nodeId = data.id
/** 处理点击事件样式改变 **/
this.handleClickedNodeClass(nodeId, e)
/** 根据点击DOM Class判断具体行为 **/
if (/__bk-node-setting/.test(e.target.className)) {
const index = this.graphData.locations.findIndex(node => node.id === nodeId)
if (index >= 0) {
/** 删除节点 **/
if (/bk-delete/.test(e.target.className)) {
this.handleDeleteNode(index, data)
}
/** 复制节点 */
if (/bk-copy/.test(e.target.className)) {
const sourceNode = this.graphData.locations[index]
this.handleCopyNode(sourceNode)
}
/** 查看更多 **/
if (/icon-more/.test(e.target.className)) {
this.handleAppendMoreAction(data)
}
}
}
/** 点击关联任务,查看 */
if (/icon-chain/.test(e.target.className)) {
this.handleNodeDblClick(data, 'referTask')
}
}
数据结构
var data = {
locations: [
{ id: 'node1', x: 100, y: 100 },
{ id: 'node2', x: 280, y: 100 },
{ id: 'node3', x: 460, y: 100 },
{ id: 'node4', x: 400, y: 220 }
],
lines: [
{ id: 'line1', source: {id: 'node1'}, target: {id: 'node2'} },
{ id: 'line2', source: {id: 'node2'}, target: {id: 'node3'} },
{ id: 'line3', source: {id: 'node3'}, target: {id: 'node4'} },
]
}
| key | 说明 | |------|------| | locations | 节点配置信息 | | lines | 连线配置信息 |
只读模式
var instance = new bkflow('#graph-wrapper', {
mode: 'readonly',
nodeConfig: [{ type: 'default', width: 70, height: 40, radius: '2px'}],
lineConfig: {canvasLine: false, color: '#a9adb6', activeColor: '#3a84ff'},
onNodeRender: function (node) {
return '<div class="node-item">'+ node.id +'</div>'
}
})
instance.renderGraph(data)
一个例子
mounted() {
flowGraph = new D3Graph('#flowgraph', {
mode: 'edit',
nodeTemplateKey: 'groupTemplate',
canvasPadding: { x: 15, y: 15 },
background: 'rgba(0,0,0,0)',
lineConfig: {
canvasLine: false,
color: '#c4c6cc',
activeColor: '#3a84ff'
},
nodeConfig: [
{ groupTemplate: 'graph-square', width: 62, height: 62, radius: '4px' },
{ groupTemplate: 'graph-round', width: 72, height: 72, radius: '50%' },
{ groupTemplate: 'graph-ractangle', width: 225, height: 42, radius: '4px' }
],
zoom: {
scaleExtent: [0.5, 3],
controlPanel: true
},
nodeClick: 'Refactoring',
onNodeRender: node => new NodeTemplate(node).getTemplateById(node.groupTemplate, this.isReadonly && 'readonly' || 'edit', this.action),
onLineConnectBefore: this.beforeLineConnected,
onLineDelete: this.beforeLineDelete
})
.on('nodeDblClick', (node, event) => {
if (!this.isReadonly) {
this.handleNodeDblClick(node)
}
}, 'node')
.on('nodeMouseEnter', (node, event) => {
if (this.action === 'monitor') {
this.activeNode = node
this.$refs['bkGraphMonitor'].handleMouseenter(event)
}
}, 'node')
.on('nodeMouseLeave', (node, event) => {
if (this.action === 'monitor') {
this.activeNode = node
this.$refs['bkGraphMonitor'].handleMouseleave(event)
}
}, 'node')
.on('nodeDragEnd', (node, event) => {
this.updateLocations(node)
}, 'node')
.on('lineConnected', (line, evt) => {
this.updateLines(line)
}, 'line')
.on('nodeClick', (node, event) => {
!this.isReadonly && this.handleGraphNodeClick(event, node)
}, 'node')
}