tf-flow-diagram
v0.1.3
Published
流程图组件
Downloads
2
Readme
流程图组件
本组件基于yarn构建
1. 安装
import TfFlowDiagram from 'tf-flow-diagram'
2. API文档
data = [ ...nodes, ...data ]
opts = { isTipEmptyShow: false, // 如果提示内容为空, 是否显示提示, 默认false
// 如果当前没有设置status状态, 是否依据其它的进行推导
// 例如: -> 3 ->
// 1 -> 2 -> -> 5 // 如果设置了3的状态, 那么2和1的状态能推导出来; 如果设置了5的状态, 那么4,3,2,1的状态都能推导出来
// -> 4 ->
statusTrace: true,
...opts
};
let temp = { /* // 格式如下: '5': { pre: ['3', '4'], // 上一级节点 status: 'xx', // 当前节点的状态 to: [] // 下一级节点 } */ }
let result = data.reduce((pre, cur) => { let name = cur.nodeName; let preName = cur.preNodeName
if (preName) { // 开始和结束节点的preNodeName为空
if (!temp[preName]) {
temp[preName] = { pre: [], status: '', to: [] }
}
temp[preName].to.push(name)
pre.linkDataArray.push({
from: preName,
to: name,
// color: 'xx'
// ...
})
}
if (!temp[name]) {
temp[name] = { pre: [preName], status: cur.status || '', to: [] }
} else {
temp[name].pre.push(preName);
}
// 只push到nodeDataArray一次
if (temp[name].pre.length > 1) return pre;
let isTipEmpty = !cur.approvalPerson
pre.nodeDataArray.push({
key: cur.nodeName,
text: cur.nodeName,
tooltip: '审批人/' + {1: '且', 2: '或'}[cur.approvalRelation] + '\n' + (cur.approvalPerson || '').split(';').join('\n'),
category: cur.category || (opts.isTipEmptyShow ? '' : (isTipEmpty ? 'notip' : '' )),
status: cur.status,
// bgColor: 'xx',
// textColor: 'xx',
// ...
})
return pre;
}, { nodeDataArray: [], linkDataArray: [] })
// 递归, 推导状态 function trace(obj, temp) { obj.pre.forEach(v => { if (temp[v] && !temp[v].status) { temp[v].status = '1' trace(temp[v], temp) } }) }
if (opts.statusTrace) { for(var i in temp) { if (temp[i].status === '1' || temp[i].status === '2') { trace(temp[i], temp); } } } // 最后的流程节点 let lastNodes = { names: [], // 最后的流程节点可能有多个 passed: [], // 状态为已通过的, 一般只有一个, 但是我程序里面不限制 lines: [], // 最后的流程节点指向结束节点的线条 passedToEndLine: [] // 最后的流程节点(状态为已通过)指向结束节点的线条 }; let endNodeIndex = -1; // 结束节点在nodeDataArray的位置
for (let i in temp) { // 配置 temp[i].config = this.props.statusMatchConfig(temp[i].status)
if(endNode && temp[i].to.length === 0
&& temp[i].status !== endNode.status) {
let line = {
from: i,
to: endNode.nodeName
}
lastNodes.names.push(i);
lastNodes.lines.push(line);
result.linkDataArray.push(line)
if (temp[i].status == '1') {
lastNodes.passed.push(i)
lastNodes.passedToEndLine.push(line)
}
}
}
// 设置颜色, 文本等配置信息 result.nodeDataArray.map((v, index) => { let { config } = temp[v.key]
v.bgColor = config.bgColor
v.textColor = config.textColor
v.borderColor = config.borderColor
v.borderWidth = config.borderWidth
v.margin = config.margin
v.font = config.font
v.textAlign = config.textAlign
if (v.status === '100') {
endNodeIndex = index;
}
})
result.linkDataArray.map(v => { if (temp[v.to]) { v.color = temp[v.to].config.lineColor } })
// 指向结束节点的线条 let notPassed = this.props.statusMatchConfig('3') lastNodes.lines.forEach(v => { v.color = notPassed.lineColor }) // 设置结束节点 if (lastNodes.passed.length > 0) { let config = this.props.statusMatchConfig('1') let endConfig = this.props.statusMatchConfig('100').passed || {}; config = { ...config, ...endConfig }
// 重置结束节点的配置
if (endNodeIndex > -1) {
let node = result.nodeDataArray[endNodeIndex];
result.nodeDataArray[endNodeIndex] = { ...node, ...config }
}
// 指向结束节点的线条颜色
lastNodes.passedToEndLine.forEach(v => v.color = config.lineColor);
}
// 将一些数据挂载到上面去 result.__ = {temp, lastNodes, endNodeIndex };console.log(result) return result; } statusMatchConfig
<td>
</td>
</tr>
<tr>
<td>customNodes</td>
<td>定义额外的节点, 如: 开始和结束节点</td>
<td>
</td>
</tr>
<tr>
<td>onBuiltInNodeTemplateClick</td>
<td>自定义节点模板: 点击</td>
<td><pre>(opts, ...rest) => {}</pre></td>
</tr>
<tr>
<td>onBuiltInShapeClick</td>
<td>自定义节点模板: 形状点击</td>
<td><pre>(opts, ...rest) => {}</pre></td>
</tr>
<tr>
<td>onBuiltInTextClick</td>
<td>自定义节点模板: 文本点击</td>
<td><pre>(opts, ...rest) => {}</pre></td>
</tr>
3. 使用示例
import React, { useRef } from "react";
import TfFlowDiagram from 'tf-flow-diagram'
var responseData = [
{
"nodeName": "1", // 节点名称
"preNodeName": "开始", // 上一级节点名称
"approvalRelation": 1, // 审批人关系 1且 2或
"approvalPerson":"19380_代办;14231_已办", // 审批人, 分号分隔
//"status" : '3' // 状态, '1': 已通过, '2': 当前节点, '3': 未执行(默认), '0': 开始节点, '100': 结束节点
},
{
"nodeName": "2", // 节点名称
"preNodeName": "1", // 上一级节点名称
"approvalRelation": 1,// 审批人关系 1且 2或
"approvalPerson":"19380_代办;14231_已办", // 审批人, 分号分隔
"status" : '1' // 状态, '1': 已通过, '2': 当前节点, '3': 未执行(默认), '0': 开始节点, '100': 结束节点
},
{
"nodeName": "3", // 节点名称
"preNodeName": "2", // 上一级节点名称
"approvalRelation": 1,// 审批人关系 1且 2或
"approvalPerson":"19380_代办;14231_已办", // 审批人, 分号分隔
"status" : '2' // 状态, '1': 已通过, '2': 当前节点, '3': 未执行(默认), '0': 开始节点, '100': 结束节点
},
{
"nodeName": "4", // 节点名称
"preNodeName": "2", // 上一级节点名称
"approvalRelation": 1,// 审批人关系 1且 2或
"approvalPerson":"19380_代办;14231_已办", // 审批人, 分号分隔
"status" : '1' // 状态, '1': 已通过, '2': 当前节点, '3': 未执行(默认), '0': 开始节点, '100': 结束节点
},
{
"nodeName": "5", // 节点名称
"preNodeName": "3", // 上一级节点名称
"approvalRelation": 1,// 审批人关系 1且 2或
"approvalPerson":"19380_代办;14231_已办", // 审批人, 分号分隔
"status" : '' // 状态, '1': 已通过, '2': 当前节点, '3': 未执行(默认), '0': 开始节点, '100': 结束节点
},
{
"nodeName": "5", // 节点名称
"preNodeName": "4", // 上一级节点名称
"approvalRelation": 1,// 审批人关系 1且 2或
"approvalPerson":"19380_代办;14231_已办", // 审批人, 分号分隔
"status" : '' // 状态, '1': 已通过, '2': 当前节点, '3': 未执行(默认), '0': 开始节点, '100': 结束节点
}
]
export default function App() {
let flowDiagram = useRef(null)
function handleClick() {
flowDiagram.current.setModel(responseData)
}
return (
<div>
<button onClick={handleClick}>更改数据</button>
<TfFlowDiagram
ref={ flowDiagram }
builtInTooltipTextConverter = {
(opts) => (data, textNode) => {
return data.tooltip || '暂无提示数据'
}
}
onBuiltInTextClick = {
(opts, ...rest) => {
console.log('文字点击:', rest)
}
}
/>
</div>
)
}
4. 命令
npm start // 运行测试
npm run build // 构建生产
npm run pub // 发布
5. 版本更新说明
0.0.1:
初始版本