Skip to content

Commit 0a44119

Browse files
feat: 支持节点更新时自定义diff字段
feat: 支持节点更新时自定义diff字段
2 parents c8300f9 + f0e4b22 commit 0a44119

File tree

8 files changed

+116
-91
lines changed

8 files changed

+116
-91
lines changed

README.en-US.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ the configuration of canvas
8484
| minimap | whether to show minimap | [minimap Prop](#minimap-prop)<font color="c41d7f"> { }</font> | - |
8585
| delayDraw | Delayed rendering. This component must ensure that the canvas container rendering (including animation execution) is completed before rendering, otherwise the coordinates will be offset, for example:Animation of Ant Design Modal | <font color="c41d7f"> number</font> | 0 |
8686
| autoLayout | custom layout | [autoLayout Prop](#auto-layout-prop)<font color="c41d7f"> {}</font> | - |
87-
87+
| diffOptions | Collection of diff fields for node updates| Array&#60; string&#62; | - |
8888

8989
<br>
9090

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ npm install react-monitor-dag
8282
| minimap | 是否开启缩略图 | [minimap Prop](#minimap-prop)<font color="c41d7f"> { }</font> | - |
8383
| delayDraw | 是否延迟加载 | <font color="c41d7f"> number</font> | 0 |
8484
| autoLayout | 自定义布局 | [autoLayout Prop](#auto-layout-prop)<font color="c41d7f"> {}</font> | - |
85+
| diffOptions | 节点更新时diff的字段集合| Array&#60; string&#62; | - |
8586
<br>
8687

8788
### <a name='edge-prop'></a><b>edge</b>

example/index.jsx

Lines changed: 87 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,24 @@
11
'use strict';
22

3-
import React from 'react';
3+
import React, { useState, useEffect } from 'react';
44
import ReactDOM from 'react-dom';
5-
import {BrowserRouter as Router} from 'react-router-dom';
6-
import {Layout, Pagination, Input} from 'antd';
7-
import {CloseCircleOutlined, CheckOutlined} from '@ant-design/icons';
5+
import { BrowserRouter as Router } from 'react-router-dom';
6+
import { Layout, Pagination, Input } from 'antd';
7+
import { CloseCircleOutlined, CheckOutlined } from '@ant-design/icons';
88
import MonitorDag from '../src/index.tsx';
99
import mockData from './mock_data/data';
10+
import _ from 'lodash';
1011
import 'antd/dist/antd.css';
1112
import './index.less';
1213

13-
const {Header} = Layout;
14+
const { Header } = Layout;
1415
const { Search } = Input;
1516

16-
const nodeMenu = [{
17-
key: 'detail',
18-
title: '节点信息',
19-
onClick: (key, data) => {
20-
console.log('click detail info')
21-
}
22-
}, {
23-
key: 'run',
24-
render: (key, data) => {
25-
return <span>节点运行</span>
26-
},
27-
onClick: (key, data) => {
28-
console.log('run node');
29-
}
30-
}]
31-
3217
const edgeMenu = [{
3318
key: 'detail',
3419
title: '线段信息',
3520
onClick: (key, data) => {
36-
console.log('click detail info',data)
21+
console.log('click detail info', data)
3722
}
3823
}, {
3924
key: '监控流程',
@@ -60,74 +45,92 @@ const groupMenu = [{
6045
console.log('run node');
6146
}
6247
}]
63-
48+
const Demo = () => {
49+
const [canvasData, setCanvasData] = useState(mockData);
50+
const nodeMenu = [{
51+
key: 'detail',
52+
title: '节点信息',
53+
onClick: (key, data) => {
54+
console.log('click detail info');
55+
}
56+
}, {
57+
key: 'run',
58+
render: (key, data) => {
59+
return <span>节点运行</span>
60+
},
61+
onClick: (key, data) => {
62+
console.log('run node');
63+
}
64+
}];
65+
return <MonitorDag
66+
data={canvasData}
67+
nodeMenu={nodeMenu}
68+
edgeMenu={edgeMenu}
69+
groupMenu={groupMenu}
70+
config={{
71+
focusCenter: true,
72+
direction: 'top-bottom',
73+
autoLayout: {
74+
enable: false,
75+
isAlways: false,
76+
},
77+
labelRender: (label, info) => {
78+
return label;
79+
},
80+
labelTipsRender: (label, info) => {
81+
return `${label}: 自定义label tips`;
82+
},
83+
nodeRender: (nodeOpts) => {
84+
return (
85+
<span className="node-text">{nodeOpts.title + nodeOpts.id + nodeOpts.status}</span>
86+
)
87+
},
88+
// diffOptions: ['status'],
89+
// statusNote: {
90+
// notes: [{
91+
// code: 'fail',
92+
// render: () => {
93+
// return <span><CloseCircleOutlined />失败</span>
94+
// }
95+
// }, {
96+
// code: 'success',
97+
// render: () => {
98+
// return <span><CheckOutlined />成功</span>
99+
// }
100+
// }]
101+
// },
102+
nodeTipsRender: (nodeOpts) => {
103+
return <span>{nodeOpts.title}: 自定义节点tips</span>
104+
},
105+
endpointTipsRender: (pointOpts) => {
106+
return <span>自定义锚点tips</span>
107+
},
108+
group: {
109+
enablePagination: true,
110+
enableSearch: true
111+
},
112+
minimap: {
113+
enable: true,
114+
config: {
115+
nodeColor: 'rgba(216, 216, 216, 0.13)',
116+
activeNodeColor: '#F66902',
117+
viewportStyle: {
118+
'background-color': 'rgba(216, 216, 216, 0.07)'
119+
},
120+
groups: mockData.groups,
121+
nodes: mockData.nodes
122+
}
123+
},
124+
}}
125+
/>
126+
}
64127

65128
ReactDOM.render((
66129
<Router>
67130
<Layout>
68131
<Header className='header'>DTDesign-React运维/监控图</Header>
69132
<Layout>
70-
<MonitorDag
71-
data={mockData}
72-
nodeMenu={nodeMenu}
73-
edgeMenu={edgeMenu}
74-
groupMenu={groupMenu}
75-
config={{
76-
focusCenter: true,
77-
direction: 'top-bottom',
78-
autoLayout: {
79-
enable: false,
80-
isAlways: false,
81-
},
82-
labelRender: (label, info) => {
83-
return label;
84-
},
85-
labelTipsRender: (label, info) => {
86-
return `${label}: 自定义label tips`;
87-
},
88-
// nodeRender: (nodeOpts) => {
89-
// return (
90-
// <span className="node-text">{nodeOpts.title + nodeOpts
91-
// .id}</span>
92-
// )
93-
// },
94-
// statusNote: {
95-
// notes: [{
96-
// code: 'fail',
97-
// render: () => {
98-
// return <span><CloseCircleOutlined />失败</span>
99-
// }
100-
// }, {
101-
// code: 'success',
102-
// render: () => {
103-
// return <span><CheckOutlined />成功</span>
104-
// }
105-
// }]
106-
// },
107-
nodeTipsRender: (nodeOpts) => {
108-
return <span>{nodeOpts.title}: 自定义节点tips</span>
109-
},
110-
endpointTipsRender: (pointOpts) => {
111-
return <span>自定义锚点tips</span>
112-
},
113-
group: {
114-
enablePagination: true,
115-
enableSearch: true
116-
},
117-
minimap: {
118-
enable: true,
119-
config: {
120-
nodeColor: 'rgba(216, 216, 216, 0.13)',
121-
activeNodeColor: '#F66902',
122-
viewportStyle: {
123-
'background-color': 'rgba(216, 216, 216, 0.07)'
124-
},
125-
groups: mockData.groups,
126-
nodes: mockData.nodes
127-
}
128-
},
129-
}}
130-
/>
133+
<Demo />
131134
</Layout>
132135
</Layout>
133136
</Router>

example/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"html-webpack-plugin": "^3.2.0",
3636
"less": "~3.7.0",
3737
"less-loader": "~4.1.0",
38+
"lodash": "^4.17.21",
3839
"mini-css-extract-plugin": "~0.9.0",
3940
"style-loader": "~0.21.0",
4041
"ts-loader": "~8.0.14",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-monitor-dag",
3-
"version": "1.0.17",
3+
"version": "1.0.18",
44
"description": "一个基于React的运维/监控DAG图",
55
"main": "dist/index.js",
66
"pack": "pack/index.js",

src/adaptor.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,21 @@ export let transformInitData = (info) => {
7373
}
7474
}
7575

76-
export let diffPropsData = (newData, oldData) => {
76+
export let diffPropsData = (newData, oldData, diffOptions = []) => {
77+
let updateNodes = [];
7778
let addNodes = _.differenceWith(newData.nodes, oldData.nodes, (a, b) => {
7879
return a.id === b.id;
7980
});
8081
let rmNodes = _.differenceWith(oldData.nodes, newData.nodes, (a, b) => {
8182
return a.id === b.id;
8283
});
84+
if (diffOptions.length > 0) {
85+
updateNodes = _.differenceWith(newData.nodes, oldData.nodes, (a, b) => {
86+
return diffOptions.reduce((pre, cur) => {
87+
return pre && a[cur] === b[cur];
88+
}, a[diffOptions[0]] === b[diffOptions[0]]);
89+
})
90+
}
8391
let addEdges = _.differenceWith(newData.edges, oldData.edges, (a, b) => {
8492
return (
8593
a.sourceNode === b.sourceNode &&
@@ -112,6 +120,7 @@ export let diffPropsData = (newData, oldData) => {
112120
return {
113121
addNodes,
114122
rmNodes,
123+
updateNodes,
115124
addEdges,
116125
rmEdges,
117126
updateStatus

src/canvas/canvas.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ export default class MonitorCanvas extends Canvas {
4343
});
4444
this.focusCenterWithAnimate();
4545
}
46-
};
46+
};

src/index.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ interface config {
2323
showActionIcon?: boolean,// 是否操作icon:放大,缩小,聚焦
2424
focusCenter?: boolean, //是否初始化的时候把所有节点居中
2525
draggable?: boolean, // 是否允许节点拖拽
26+
diffOptions?: Array<string>, // 更新节点时,需要diff的字段集合(默认节点diff节点id)
2627
edge?: { //定制线段的类型,todo需要思考
2728
type: string,
2829
config: any,
@@ -254,12 +255,22 @@ export default class MonitorDag extends React.Component<ComProps, any> {
254255
data: _.cloneDeep(newProps.data),
255256
registerStatus: _.cloneDeep(newProps.registerStatus)
256257
});
257-
let diffInfo = diffPropsData(result, this.canvasData);
258+
let diffInfo = diffPropsData(result, this.canvasData, _.get(this, 'props.config.diffOptions', []));
259+
if (diffInfo.rmNodes.length > 0) {
260+
this.canvas.removeNodes(diffInfo.rmNodes.map(item => item.id));
261+
}
258262
if (diffInfo.addNodes.length > 0) {
259263
this.canvas.addNodes(diffInfo.addNodes);
260264
}
261-
if (diffInfo.rmNodes.length > 0) {
262-
this.canvas.removeNodes(diffInfo.rmNodes.map(item => item.id));
265+
if(diffInfo.updateNodes.length > 0) {
266+
let removeData = this.canvas.removeNodes(diffInfo.updateNodes.map(item => item.id), false, true);
267+
let _addNodes = this.canvas.addNodes(diffInfo.updateNodes, true);
268+
_addNodes.forEach(item => {
269+
item.mounted && item.mounted();
270+
});
271+
this.canvas.addEdges(removeData.edges.map(edge => {
272+
return edge.options;
273+
}), true);
263274
}
264275
if (diffInfo.addEdges.length > 0) {
265276
this.canvas.addEdges(diffInfo.addEdges);

0 commit comments

Comments
 (0)