@aloudata/ink-lineage 0.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +27 -0
- package/src/assets/big/dataSourceTypeIcon.ts +65 -0
- package/src/assets/big/entityType.ts +1 -0
- package/src/assets/big/index.ts +5 -0
- package/src/assets/big/lineageIcon.ts +35 -0
- package/src/assets/big/tableTypeIcon.ts +17 -0
- package/src/assets/big/tipIcon.ts +1 -0
- package/src/assets/index.ts +14 -0
- package/src/components/Edges/DefaultEdge.ts +196 -0
- package/src/components/Edges/FoldEdge.ts +97 -0
- package/src/components/Edges/LineageEdge.ts +24 -0
- package/src/components/Edges/index.ts +3 -0
- package/src/components/Nodes/AssetNode.ts +438 -0
- package/src/components/Nodes/ColumnNode.ts +491 -0
- package/src/components/Nodes/CustomNode.ts +63 -0
- package/src/components/Nodes/DefaultNode.ts +74 -0
- package/src/components/Nodes/DowngradeNode.ts +115 -0
- package/src/components/Nodes/TableNode.ts +534 -0
- package/src/components/Nodes/index.ts +4 -0
- package/src/components/index.ts +2 -0
- package/src/constant/index.ts +1 -0
- package/src/constant/nodeStyle.ts +141 -0
- package/src/index.ts +6 -0
- package/src/manager/BaseManager.ts +20 -0
- package/src/manager/DataProcessor.ts +782 -0
- package/src/manager/ExpandManager.ts +93 -0
- package/src/manager/FoldLineageManager.ts +196 -0
- package/src/manager/GraphEventManager.ts +90 -0
- package/src/manager/LineageManager.ts +680 -0
- package/src/manager/RightKeyMenuManager.ts +114 -0
- package/src/manager/SearchNodeManager.ts +188 -0
- package/src/manager/ToolbarManager.ts +42 -0
- package/src/manager/index.ts +8 -0
- package/src/manager/nodeManager/AssetEventManager.ts +442 -0
- package/src/manager/nodeManager/BaseEventManager.ts +68 -0
- package/src/manager/nodeManager/ColumnEventManager.ts +467 -0
- package/src/manager/nodeManager/CustomEventManager.ts +11 -0
- package/src/manager/nodeManager/TableEventManager.ts +87 -0
- package/src/manager/nodeManager/index.ts +3 -0
- package/src/types/NodeConfig.ts +69 -0
- package/src/types/eventEnum.ts +58 -0
- package/src/types/index.ts +3 -0
- package/src/types/manager.ts +75 -0
- package/src/types/node.ts +246 -0
- package/src/utils/downgradeNode.ts +22 -0
- package/src/utils/foldNode.ts +345 -0
- package/src/utils/getIconByType.ts +104 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/node.ts +294 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
import { getNodeHeight, runtime } from '@aloudata/ink-graph-new';
|
|
2
|
+
import { InkLineageManager, IParsedGraphData } from '..';
|
|
3
|
+
import { ColumnNode, TableNode } from '../../components';
|
|
4
|
+
import { COL_HEIGHT } from '../../constant';
|
|
5
|
+
import {
|
|
6
|
+
EDashType,
|
|
7
|
+
EDirection,
|
|
8
|
+
EElementType,
|
|
9
|
+
EEntityType,
|
|
10
|
+
EExpandType,
|
|
11
|
+
EOverviewType,
|
|
12
|
+
IColResBase,
|
|
13
|
+
TDataBase,
|
|
14
|
+
IColumnConfig,
|
|
15
|
+
INodeConfig,
|
|
16
|
+
EColumnEvents,
|
|
17
|
+
EEventEnum,
|
|
18
|
+
} from '../../types';
|
|
19
|
+
import { getRelatedData } from '../../utils';
|
|
20
|
+
import { BaseEventManager } from './BaseEventManager';
|
|
21
|
+
import _ from 'lodash';
|
|
22
|
+
|
|
23
|
+
export class ColumnEventManager<
|
|
24
|
+
TTableData extends TDataBase<TColumnData>,
|
|
25
|
+
TColumnData extends IColResBase,
|
|
26
|
+
> extends BaseEventManager<TTableData, TColumnData> {
|
|
27
|
+
constructor(lineageManager: InkLineageManager<TTableData, TColumnData>) {
|
|
28
|
+
super(lineageManager, EColumnEvents);
|
|
29
|
+
this.registerExtraEvents();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
registerExtraEvents(): void {
|
|
33
|
+
this.lineageManager.on(EColumnEvents.CLICK, (node: ColumnNode) => {
|
|
34
|
+
this.onClick(node);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
onClick(node: ColumnNode) {
|
|
39
|
+
const onlyShowRelated =
|
|
40
|
+
!!this.lineageManager?.rightKeyMenuManager?.onlyShowRelated;
|
|
41
|
+
|
|
42
|
+
// hide context menu
|
|
43
|
+
this.lineageManager?.hideContextMenu();
|
|
44
|
+
|
|
45
|
+
if (node.isForbidden) return;
|
|
46
|
+
|
|
47
|
+
// show detail panel
|
|
48
|
+
this.showDetailPanel(node);
|
|
49
|
+
|
|
50
|
+
if (!onlyShowRelated) {
|
|
51
|
+
// update active nodes
|
|
52
|
+
this.lineageManager?.updateActiveNodes([node.config as IColumnConfig<TColumnData>]);
|
|
53
|
+
|
|
54
|
+
this.lineageManager?.setRelatedNodesAndEdges(node.config as IColumnConfig<TColumnData>);
|
|
55
|
+
|
|
56
|
+
// refresh toolbar related status
|
|
57
|
+
this.lineageManager?.refreshToolbarRelatedStatus(node.config as IColumnConfig<TColumnData>);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
onLeftIconClick(node: ColumnNode) {
|
|
62
|
+
if (this.lineageManager.isExpanding) return;
|
|
63
|
+
|
|
64
|
+
const iconType = (node.leftIcon as any).iconType as EExpandType;
|
|
65
|
+
if (iconType === EExpandType.EXPAND) {
|
|
66
|
+
this.handleExpand({ direction: EDirection.INPUT, node });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (iconType === EExpandType.FOLD) {
|
|
70
|
+
this.handleFold(EDirection.INPUT, node);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
onRightIconClick(node: ColumnNode) {
|
|
75
|
+
if (this.lineageManager.isExpanding) return;
|
|
76
|
+
|
|
77
|
+
const iconType = (node.rightIcon as any).iconType as EExpandType;
|
|
78
|
+
if (iconType === EExpandType.EXPAND) {
|
|
79
|
+
this.handleExpand({ direction: EDirection.OUTPUT, node });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (iconType === EExpandType.FOLD) {
|
|
83
|
+
this.handleFold(EDirection.OUTPUT, node);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onContextMenu(node: ColumnNode) {
|
|
88
|
+
const { isStartNode, id } = node.config;
|
|
89
|
+
const { name } = node.config.data;
|
|
90
|
+
const translate = runtime.sceneGraphManager.getPosition(node.colText);
|
|
91
|
+
const [translateX, translateY] = translate;
|
|
92
|
+
const x = 70 + translateX;
|
|
93
|
+
const y = Number(node.colText.style.y) + translateY - 20;
|
|
94
|
+
|
|
95
|
+
this.lineageManager.showContextMenu({
|
|
96
|
+
id,
|
|
97
|
+
visible: true,
|
|
98
|
+
x,
|
|
99
|
+
y,
|
|
100
|
+
type: EElementType.COLUMN,
|
|
101
|
+
typeCode: 'Table',
|
|
102
|
+
isStartNode,
|
|
103
|
+
parentGuid: node.config.tableId || '',
|
|
104
|
+
parentName: node.config.tableName || '',
|
|
105
|
+
name,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
showDetailPanel = (node: ColumnNode) => {
|
|
110
|
+
// 将data同步到atom,触发更新
|
|
111
|
+
const { userClosed, visible } =
|
|
112
|
+
this.lineageManager.rightKeyMenuManager.overviewState;
|
|
113
|
+
let overviewType = EOverviewType.COLUMN;
|
|
114
|
+
|
|
115
|
+
if (node.node?.config?.data?.type === EEntityType.TEMP_TABLE) {
|
|
116
|
+
overviewType = EOverviewType.TEMP_COLUMN;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.lineageManager.setOverview({
|
|
120
|
+
...this.lineageManager.rightKeyMenuManager.overviewState,
|
|
121
|
+
targetId: node.config.id,
|
|
122
|
+
type: overviewType,
|
|
123
|
+
visible: !(userClosed && !visible),
|
|
124
|
+
initial: true,
|
|
125
|
+
caliberIsHighlight: false,
|
|
126
|
+
taskIsHighlight: false,
|
|
127
|
+
// tableName: this.props.data.parent._data_.name,
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
handleFold(direction: EDirection, node: ColumnNode) {
|
|
132
|
+
if (this.lineageManager?.foldLineageManager.isFoldChecked) {
|
|
133
|
+
this.lineageManager?.foldLineageManager?.unfoldNodes();
|
|
134
|
+
this.lineageManager?.update();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.lineageManager?.resetActiveNodes();
|
|
138
|
+
|
|
139
|
+
const { nodes, edges } = this.lineageManager.parsedData;
|
|
140
|
+
|
|
141
|
+
// find related nodes and edges
|
|
142
|
+
const relatedNodesAndEdges = getRelatedData<TTableData, TColumnData>(
|
|
143
|
+
node.config as IColumnConfig<TColumnData>,
|
|
144
|
+
nodes,
|
|
145
|
+
edges,
|
|
146
|
+
direction,
|
|
147
|
+
// this.lineageManager?.rightKeyMenuManager?.edgeDashVisible,
|
|
148
|
+
);
|
|
149
|
+
if (!relatedNodesAndEdges) return;
|
|
150
|
+
|
|
151
|
+
const { relatedNodes, relatedEdges } = relatedNodesAndEdges;
|
|
152
|
+
|
|
153
|
+
const relatedNodesIds = relatedNodes.map((n) => n.id);
|
|
154
|
+
|
|
155
|
+
relatedNodesIds.forEach((nodeId) => {
|
|
156
|
+
// find all inputNodes
|
|
157
|
+
const inputNodes: string[] = [];
|
|
158
|
+
// find all outputNodes
|
|
159
|
+
const outputNodes: string[] = [];
|
|
160
|
+
|
|
161
|
+
edges.forEach((edge) => {
|
|
162
|
+
if (
|
|
163
|
+
edge.target === nodeId &&
|
|
164
|
+
(edge.visible || edge.relationType === EDashType.INDIRECT)
|
|
165
|
+
) {
|
|
166
|
+
inputNodes.push(edge.source);
|
|
167
|
+
}
|
|
168
|
+
if (
|
|
169
|
+
edge.source === nodeId &&
|
|
170
|
+
(edge.visible || edge.relationType === EDashType.INDIRECT)
|
|
171
|
+
) {
|
|
172
|
+
outputNodes.push(edge.target);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// exclude multi relation nodes
|
|
177
|
+
if (!inputNodes.every((item) => relatedNodesIds.includes(item))) return;
|
|
178
|
+
if (!outputNodes.every((item) => relatedNodesIds.includes(item))) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let node = this.lineageManager.getNodeInstanceById(nodeId);
|
|
183
|
+
|
|
184
|
+
if (!node) {
|
|
185
|
+
this.lineageManager.graph.nodes?.forEach((n) => {
|
|
186
|
+
n.relatedColumns?.forEach((c) => {
|
|
187
|
+
if (c.id === nodeId) {
|
|
188
|
+
node = c;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (node instanceof TableNode) {
|
|
196
|
+
// exclude curr node
|
|
197
|
+
if (nodeId === node.config?.id) return;
|
|
198
|
+
|
|
199
|
+
node.config.isRelated = false;
|
|
200
|
+
node.update(node.config, node.container);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (node instanceof ColumnNode) {
|
|
204
|
+
node.destroy();
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
relatedEdges.forEach((edgeCfg) => {
|
|
209
|
+
const edge = this.lineageManager.getEdgeInstanceById(edgeCfg.id);
|
|
210
|
+
|
|
211
|
+
if (edge) {
|
|
212
|
+
// edge.config.isFolded = true;
|
|
213
|
+
// edge.destroy();
|
|
214
|
+
// edge.update();
|
|
215
|
+
|
|
216
|
+
this.lineageManager.setData({
|
|
217
|
+
...this.lineageManager.parsedData,
|
|
218
|
+
edges: this.lineageManager.parsedData.edges.filter(
|
|
219
|
+
(e) => e.id !== edgeCfg.id,
|
|
220
|
+
),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
this.lineageManager?.resetRelatedNodes(false);
|
|
226
|
+
this.lineageManager?.update();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async handleExpand(data: {
|
|
230
|
+
direction: EDirection;
|
|
231
|
+
depth?: number;
|
|
232
|
+
node: ColumnNode;
|
|
233
|
+
}) {
|
|
234
|
+
const { depth = 1, direction, node } = data;
|
|
235
|
+
// get prev start related column id
|
|
236
|
+
node.prevStartRelatedColumnId =
|
|
237
|
+
this.lineageManager.expandManager.prevStartRelatedColumnId;
|
|
238
|
+
|
|
239
|
+
const onlyShowRelated =
|
|
240
|
+
!!this.lineageManager?.rightKeyMenuManager?.onlyShowRelated;
|
|
241
|
+
|
|
242
|
+
if (onlyShowRelated) {
|
|
243
|
+
// 开启仅相关的时候扩展
|
|
244
|
+
// 1. 先打开仅相关
|
|
245
|
+
this.lineageManager.updateRelatedTableVisible(false, false);
|
|
246
|
+
// 2. 接下来按照正常逻辑扩展
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// reset active nodes
|
|
250
|
+
this.lineageManager?.resetActiveNodes();
|
|
251
|
+
|
|
252
|
+
// reset related nodes
|
|
253
|
+
this.lineageManager?.resetRelatedNodes(false);
|
|
254
|
+
|
|
255
|
+
// show expand loading
|
|
256
|
+
this.lineageManager?.showExpandLoading(node, direction);
|
|
257
|
+
|
|
258
|
+
// fetch data
|
|
259
|
+
const params = {
|
|
260
|
+
depth,
|
|
261
|
+
direction,
|
|
262
|
+
guid: node.config.id,
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const getNewDataPromise = new Promise<IParsedGraphData<TDataBase<IColResBase>, IColResBase>>((resolve) => {
|
|
266
|
+
this.lineageManager.once(EEventEnum.COLUMN_EXPAND_RESPONSE,
|
|
267
|
+
(response: IParsedGraphData<TDataBase<IColResBase>, IColResBase>) => {
|
|
268
|
+
resolve(response);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
this.lineageManager.emit(EEventEnum.COLUMN_EXPAND, params);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// Wait for the response
|
|
275
|
+
const newData = await getNewDataPromise;
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
// hide expand loading
|
|
279
|
+
this.lineageManager?.hideExpandLoading();
|
|
280
|
+
|
|
281
|
+
if (!newData) return;
|
|
282
|
+
|
|
283
|
+
const { nodes, edges } = newData;
|
|
284
|
+
|
|
285
|
+
if (
|
|
286
|
+
nodes.length > 0 &&
|
|
287
|
+
nodes.some(
|
|
288
|
+
(e) => e.id === node.config.tableId && e.data?.isHotspot,
|
|
289
|
+
) &&
|
|
290
|
+
direction !== EDirection.BOTH
|
|
291
|
+
) {
|
|
292
|
+
// hotspot expand
|
|
293
|
+
this.lineageManager.updateHotspotModalState({
|
|
294
|
+
id: node.config.id,
|
|
295
|
+
visible: true,
|
|
296
|
+
direction,
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (nodes.length > 0 && nodes.some((e) => e.data?.isHotspot)) {
|
|
303
|
+
if (direction === EDirection.BOTH) return;
|
|
304
|
+
|
|
305
|
+
this.lineageManager.emit(EEventEnum.INDIRECT_TIPS, {
|
|
306
|
+
message: '存在热点资产',
|
|
307
|
+
description:
|
|
308
|
+
'本次探索过程中存在热点资产,热点资产默认不继续探索,请手动探索后展开',
|
|
309
|
+
position: 'top-center',
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (nodes.length > 1) {
|
|
314
|
+
// save prev start related column id
|
|
315
|
+
this.lineageManager.expandManager.prevStartRelatedColumnId =
|
|
316
|
+
node.config.id;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (edges.length <= 0) {
|
|
320
|
+
// no more input
|
|
321
|
+
if (direction === EDirection.INPUT) {
|
|
322
|
+
node.config.hasMoreInput = false;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// no more output
|
|
326
|
+
if (direction === EDirection.OUTPUT) {
|
|
327
|
+
node.config.hasMoreOutput = false;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
this.lineageManager.emit(EEventEnum.INDIRECT_TIPS, { message: `该节点无${direction === EDirection.INPUT ? '上游' : '下游'}血缘` });
|
|
331
|
+
} else {
|
|
332
|
+
if (
|
|
333
|
+
edges.every((edge) => edge.relationType === EDashType.INDIRECT) &&
|
|
334
|
+
this.lineageManager?.rightKeyMenuManager?.edgeDashVisible ===
|
|
335
|
+
EDashType.DIRECT
|
|
336
|
+
) {
|
|
337
|
+
this.lineageManager.emit(EEventEnum.INDIRECT_TIPS, { message: '当前字段只有间接血缘,请打开间接血缘开关后查看' });
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const prevNodesConfig = this.lineageManager.parsedData.nodes;
|
|
341
|
+
let prevEdgesConfig = this.lineageManager.parsedData.edges;
|
|
342
|
+
|
|
343
|
+
// 如果是从起始列往下扩展并且不是同一个列,先清空之前所有节点下的的relatedColumns,再把新的parse后的列赋值给每一个表下
|
|
344
|
+
// 展开列是起始资产的列且展开列不是起始资产的第一个列
|
|
345
|
+
if (
|
|
346
|
+
node.config.isStartNode &&
|
|
347
|
+
node.prevStartRelatedColumnId !== node.config?.id
|
|
348
|
+
) {
|
|
349
|
+
// find related nodes and edges
|
|
350
|
+
// 获取起始资产首列的上下游列,包含间接血缘
|
|
351
|
+
if (node.prevStartRelatedColumnId) {
|
|
352
|
+
prevEdgesConfig = prevEdgesConfig.filter((e) => {
|
|
353
|
+
return !e.data.relationTypeCode.includes('Column');
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// clear all related columns
|
|
358
|
+
prevNodesConfig.forEach((n) => {
|
|
359
|
+
// clear related edges
|
|
360
|
+
n.relatedColumns = [];
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// difference nodes
|
|
365
|
+
// 去除nodes中id等于prevNodesConfig.id中的节点,得到改变深度后的额外节点
|
|
366
|
+
const differentObjects = _.differenceBy(nodes, prevNodesConfig, 'id');
|
|
367
|
+
|
|
368
|
+
// common nodes
|
|
369
|
+
// 找出prevNodesConfig中id等于nodes中id的节点
|
|
370
|
+
const commonObjects = _.intersectionBy(prevNodesConfig, nodes, 'id');
|
|
371
|
+
|
|
372
|
+
differentObjects.forEach((n) => {
|
|
373
|
+
n.relatedColumns = n.children;
|
|
374
|
+
n.relatedColumns.forEach((col) => {
|
|
375
|
+
col.isRelatedColumn = true;
|
|
376
|
+
});
|
|
377
|
+
n.children = [];
|
|
378
|
+
n.isFolded = false;
|
|
379
|
+
n.style.height = getNodeHeight(n);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
commonObjects.forEach((n) => {
|
|
383
|
+
n.isFolded = false;
|
|
384
|
+
// 展开后得到的所有节点中找到第一个交集节点
|
|
385
|
+
const sameNodeNew = nodes.find((node) => node.id === n.id);
|
|
386
|
+
if (sameNodeNew) {
|
|
387
|
+
n.relatedColumns = _.unionBy(
|
|
388
|
+
[...n.relatedColumns, ...sameNodeNew.children],
|
|
389
|
+
'id',
|
|
390
|
+
) as IColumnConfig<TColumnData>[];
|
|
391
|
+
n.relatedColumns.forEach((col) => {
|
|
392
|
+
col.isRelatedColumn = true;
|
|
393
|
+
});
|
|
394
|
+
n.style.height = getNodeHeight(n);
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// show related edges
|
|
399
|
+
edges.forEach((e) => {
|
|
400
|
+
const prevEdge = prevEdgesConfig.find((edge) => edge.id === e.id);
|
|
401
|
+
if (prevEdge) {
|
|
402
|
+
prevEdge.isFolded = false;
|
|
403
|
+
//
|
|
404
|
+
if (e.relationType !== prevEdge.relationType) {
|
|
405
|
+
prevEdge.relationType = EDashType.ALL;
|
|
406
|
+
prevEdge.style.strokeDasharray = [0];
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
e.isFolded = false;
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
const newNodesConfig = _.concat(prevNodesConfig, differentObjects);
|
|
414
|
+
//
|
|
415
|
+
const newEdgesConfig = _.unionBy([...prevEdgesConfig, ...edges], 'id');
|
|
416
|
+
|
|
417
|
+
// update related column position
|
|
418
|
+
newNodesConfig.forEach((n) => {
|
|
419
|
+
n.relatedColumns
|
|
420
|
+
.sort((a, b) => {
|
|
421
|
+
return a.data?.position - b.data?.position;
|
|
422
|
+
})
|
|
423
|
+
.forEach((col, i) => {
|
|
424
|
+
col.position = {
|
|
425
|
+
x: 0,
|
|
426
|
+
y: i * COL_HEIGHT,
|
|
427
|
+
};
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
this.lineageManager.setData({
|
|
432
|
+
nodes: newNodesConfig as INodeConfig<TTableData, TColumnData>[],
|
|
433
|
+
edges: newEdgesConfig,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!onlyShowRelated) {
|
|
438
|
+
const currRelatedColumn = node.node.config.relatedColumns.find(
|
|
439
|
+
(col) => col.id === node.config.id,
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
// update active nodes
|
|
443
|
+
this.lineageManager?.updateActiveNodes([currRelatedColumn as IColumnConfig<TColumnData>]);
|
|
444
|
+
|
|
445
|
+
// cache related edges
|
|
446
|
+
this.lineageManager?.setRelatedNodesAndEdges(node.config as IColumnConfig<TColumnData>, false);
|
|
447
|
+
} else {
|
|
448
|
+
// update active nodes
|
|
449
|
+
this.lineageManager?.updateActiveNodes([
|
|
450
|
+
this.lineageManager.cachedRelatedNodeConfig,
|
|
451
|
+
]);
|
|
452
|
+
|
|
453
|
+
// cache related edges
|
|
454
|
+
this.lineageManager?.setRelatedNodesAndEdges(
|
|
455
|
+
this.lineageManager.cachedRelatedNodeConfig,
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
// 开启仅相关的时候扩展 FIXME: 这里需要优化 @yunke
|
|
459
|
+
// this.lineageManager.updateRelatedTableVisible(true);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// calc fold nodes
|
|
463
|
+
this.lineageManager?.updateFoldStatus(
|
|
464
|
+
this.lineageManager.foldLineageManager.isFoldChecked,
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { InkLineageManager } from "..";
|
|
2
|
+
import { ECustomEvents, IColResBase, TDataBase } from "../..";
|
|
3
|
+
import { AssetEventManager } from "./AssetEventManager";
|
|
4
|
+
|
|
5
|
+
export class CustomEventManager<TTableData extends TDataBase<TColumnData>,
|
|
6
|
+
TColumnData extends IColResBase,> extends AssetEventManager<TTableData, TColumnData> {
|
|
7
|
+
constructor(lineageManager: InkLineageManager<TTableData, TColumnData>) {
|
|
8
|
+
super(lineageManager, ECustomEvents);
|
|
9
|
+
super.registerExtraEvents();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { DataProcessor, InkLineageManager } from '..';
|
|
3
|
+
import { AssetEventManager } from './AssetEventManager';
|
|
4
|
+
import { EEventEnum, ETableEvents, IColResBase, IColumnConfig, TDataBase } from '../../types';
|
|
5
|
+
import { TableNode } from '../../components';
|
|
6
|
+
|
|
7
|
+
export class TableEventManager<
|
|
8
|
+
TTableData extends TDataBase<TColumnData>,
|
|
9
|
+
TColumnData extends IColResBase,
|
|
10
|
+
> extends AssetEventManager<TTableData, TColumnData> {
|
|
11
|
+
constructor(lineageManager: InkLineageManager<TTableData, TColumnData>) {
|
|
12
|
+
super(lineageManager, ETableEvents);
|
|
13
|
+
this.registerExtraEvents();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
registerExtraEvents(): void {
|
|
17
|
+
super.registerExtraEvents();
|
|
18
|
+
this.lineageManager.on(
|
|
19
|
+
ETableEvents.CONTROL_TOGGLE_GROUP,
|
|
20
|
+
(node: TableNode) => {
|
|
21
|
+
this.onControlBarToggleClick(node);
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async onControlBarToggleClick(node: TableNode) {
|
|
27
|
+
// hide side icon
|
|
28
|
+
this.hideSideIcon(node);
|
|
29
|
+
|
|
30
|
+
// update toggle type
|
|
31
|
+
node.config.isOpen = !node.config?.isOpen;
|
|
32
|
+
|
|
33
|
+
if (node.config.isOpen === true) {
|
|
34
|
+
// fetch data while no children
|
|
35
|
+
const columnsConfig = node.config?.children;
|
|
36
|
+
if (
|
|
37
|
+
_.isArray(columnsConfig) &&
|
|
38
|
+
columnsConfig.length !== node.config?.data?.columnCount
|
|
39
|
+
) {
|
|
40
|
+
// 获取外部的数据
|
|
41
|
+
const getColumnListPromise = new Promise<any>((resolve) => {
|
|
42
|
+
this.lineageManager.once(
|
|
43
|
+
EEventEnum.TABLE_OPEN_RESPONSE,
|
|
44
|
+
(response: any) => {
|
|
45
|
+
resolve(response);
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
this.lineageManager.emit(EEventEnum.TABLE_OPEN, {
|
|
50
|
+
id: node.config.id,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Wait for the response
|
|
55
|
+
const columnsRes = await getColumnListPromise;
|
|
56
|
+
|
|
57
|
+
const columns = columnsRes?.columns || [];
|
|
58
|
+
|
|
59
|
+
// parse columns data
|
|
60
|
+
const parsedColumns =
|
|
61
|
+
columns?.map((col) => {
|
|
62
|
+
const parsedColConfig = DataProcessor.parseColumn(
|
|
63
|
+
col,
|
|
64
|
+
node.config.isStartNode,
|
|
65
|
+
node.config.id,
|
|
66
|
+
node.config.data?.name,
|
|
67
|
+
) as IColumnConfig<TColumnData>;
|
|
68
|
+
|
|
69
|
+
return parsedColConfig;
|
|
70
|
+
}) || [];
|
|
71
|
+
|
|
72
|
+
node.config.children = parsedColumns;
|
|
73
|
+
}
|
|
74
|
+
// show all children
|
|
75
|
+
node.config.children.forEach((child) => {
|
|
76
|
+
child.visible = true;
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
// hide all children
|
|
80
|
+
node.config.children.forEach((child) => {
|
|
81
|
+
child.visible = false;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// update node
|
|
85
|
+
this.lineageManager.update({ shouldGroupNodes: false });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { IBaseEdgeConfig, IBaseNodeConfig } from "@aloudata/ink-graph-new";
|
|
2
|
+
import { EDashType, ERelationType, IColResBase, TDataBase } from "..";
|
|
3
|
+
|
|
4
|
+
export interface IEdgeConfig extends IBaseEdgeConfig {
|
|
5
|
+
id: string;
|
|
6
|
+
type: string;
|
|
7
|
+
relationType: EDashType;
|
|
8
|
+
isFolded: boolean; // 展开/收起
|
|
9
|
+
canBeFold: boolean; // 合并链路
|
|
10
|
+
data: {
|
|
11
|
+
srcGuid: string;
|
|
12
|
+
dstGuid: string;
|
|
13
|
+
relationTypeCode: ERelationType;
|
|
14
|
+
fold?: boolean;
|
|
15
|
+
};
|
|
16
|
+
source: string;
|
|
17
|
+
target: string;
|
|
18
|
+
style?: {
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface INodeConfig<T extends TDataBase<M>, M extends IColResBase> extends IBaseNodeConfig {
|
|
24
|
+
data: T;
|
|
25
|
+
children: IColumnConfig<M>[];
|
|
26
|
+
isStartNode: boolean;
|
|
27
|
+
isOpen: boolean; // open table
|
|
28
|
+
visible: boolean; // see: direct & indirect & - & +
|
|
29
|
+
isRelated: boolean; // see: related & uncorrelated
|
|
30
|
+
isFolded: boolean; // see: fold & unfold
|
|
31
|
+
isFoldInput: boolean;
|
|
32
|
+
isFoldOutput: boolean;
|
|
33
|
+
isExpandOutput: boolean;
|
|
34
|
+
isExpandInput: boolean;
|
|
35
|
+
canExpandInput: boolean; // has edge.target === this
|
|
36
|
+
canExpandOutput: boolean; // has edge.source === this
|
|
37
|
+
canFoldInput: boolean;
|
|
38
|
+
canFoldOutput: boolean;
|
|
39
|
+
hasMoreInput: boolean; // has more input data
|
|
40
|
+
hasMoreOutput: boolean; // has more output data
|
|
41
|
+
canBeFold: boolean;
|
|
42
|
+
pagination: {
|
|
43
|
+
pageNum: number; // current page index
|
|
44
|
+
pageSize: number; // page size
|
|
45
|
+
total: number; // columns count
|
|
46
|
+
totalPage: number; // page count
|
|
47
|
+
};
|
|
48
|
+
relatedColumns: IColumnConfig<M>[]; // related columns are expanded out
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface IColumnConfig<T> extends IBaseNodeConfig {
|
|
53
|
+
id: string;
|
|
54
|
+
tableId: string;
|
|
55
|
+
tableName: string;
|
|
56
|
+
visible: boolean;
|
|
57
|
+
isRelated: boolean;
|
|
58
|
+
isRelatedColumn: boolean;
|
|
59
|
+
isFolded: boolean;
|
|
60
|
+
canBeFold: boolean;
|
|
61
|
+
canExpandInput: boolean;
|
|
62
|
+
canExpandOutput: boolean;
|
|
63
|
+
canFoldInput: boolean;
|
|
64
|
+
canFoldOutput: boolean;
|
|
65
|
+
hasMoreInput: boolean;
|
|
66
|
+
hasMoreOutput: boolean;
|
|
67
|
+
isStartNode: boolean;
|
|
68
|
+
data: T;
|
|
69
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export enum ETableEvents {
|
|
2
|
+
HEADER_CLICK = 'table:headerClick',
|
|
3
|
+
CONTROL_TOGGLE_GROUP = 'table:controlToggleGroup',
|
|
4
|
+
LEFT_ICON_CLICK = 'table:leftIconClick',
|
|
5
|
+
RIGHT_ICON_CLICK = 'table:rightIconClick',
|
|
6
|
+
CONTEXT_MENU = 'table:contextMenu',
|
|
7
|
+
HOTSPOT_EXPAND = 'table:hotspotExpand',
|
|
8
|
+
EXPAND = 'table:rightExpand',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export enum ECustomEvents {
|
|
12
|
+
HEADER_CLICK = 'custom:headerClick',
|
|
13
|
+
LEFT_ICON_CLICK = 'custom:leftIconClick',
|
|
14
|
+
RIGHT_ICON_CLICK = 'custom:rightIconClick',
|
|
15
|
+
CONTEXT_MENU = 'custom:contextMenu',
|
|
16
|
+
HOTSPOT_EXPAND = 'custom:hotspotExpand',
|
|
17
|
+
EXPAND = 'custom:rightExpand',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export enum EColumnEvents {
|
|
21
|
+
CLICK = 'column:click',
|
|
22
|
+
LEFT_ICON_CLICK = 'column:leftIconClick',
|
|
23
|
+
RIGHT_ICON_CLICK = 'column:rightIconClick',
|
|
24
|
+
CONTEXT_MENU = 'column:contextMenu',
|
|
25
|
+
HOTSPOT_EXPAND = 'column:hotspotExpand',
|
|
26
|
+
EXPAND = 'column:rightExpand',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 表资产和自定义资产的共同事件类型
|
|
30
|
+
export type AssetEventType = typeof ETableEvents | typeof ECustomEvents;
|
|
31
|
+
|
|
32
|
+
// 合并所有事件枚举类型
|
|
33
|
+
export type EventEnumType = AssetEventType | typeof EColumnEvents;
|
|
34
|
+
|
|
35
|
+
// 各个事件回调
|
|
36
|
+
export enum EEventEnum {
|
|
37
|
+
TABLE_EXPAND = 'table:expand',
|
|
38
|
+
TABLE_EXPAND_RESPONSE = 'table:expandResponse',
|
|
39
|
+
|
|
40
|
+
TABLE_OPEN = 'table:open',
|
|
41
|
+
TABLE_OPEN_RESPONSE = 'table:openResponse',
|
|
42
|
+
|
|
43
|
+
COLUMN_EXPAND = 'column:expand',
|
|
44
|
+
COLUMN_EXPAND_RESPONSE = 'column:expandResponse',
|
|
45
|
+
|
|
46
|
+
CONTEXT_MENU = 'contextmenu:contextmenu',
|
|
47
|
+
|
|
48
|
+
OVERVIEW = 'overview:overview',
|
|
49
|
+
|
|
50
|
+
HOTSPOT_MODAL_UPDATE = 'hotspotModalData:update',
|
|
51
|
+
|
|
52
|
+
HOTSPOT_TIPS = 'hotspotTips:hotspotTipsData',
|
|
53
|
+
|
|
54
|
+
TOOLBAR = 'TOOLBAR',
|
|
55
|
+
|
|
56
|
+
// 间接血缘提示
|
|
57
|
+
INDIRECT_TIPS = 'indirectTips:indirectTips',
|
|
58
|
+
}
|