@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.
Files changed (50) hide show
  1. package/package.json +27 -0
  2. package/src/assets/big/dataSourceTypeIcon.ts +65 -0
  3. package/src/assets/big/entityType.ts +1 -0
  4. package/src/assets/big/index.ts +5 -0
  5. package/src/assets/big/lineageIcon.ts +35 -0
  6. package/src/assets/big/tableTypeIcon.ts +17 -0
  7. package/src/assets/big/tipIcon.ts +1 -0
  8. package/src/assets/index.ts +14 -0
  9. package/src/components/Edges/DefaultEdge.ts +196 -0
  10. package/src/components/Edges/FoldEdge.ts +97 -0
  11. package/src/components/Edges/LineageEdge.ts +24 -0
  12. package/src/components/Edges/index.ts +3 -0
  13. package/src/components/Nodes/AssetNode.ts +438 -0
  14. package/src/components/Nodes/ColumnNode.ts +491 -0
  15. package/src/components/Nodes/CustomNode.ts +63 -0
  16. package/src/components/Nodes/DefaultNode.ts +74 -0
  17. package/src/components/Nodes/DowngradeNode.ts +115 -0
  18. package/src/components/Nodes/TableNode.ts +534 -0
  19. package/src/components/Nodes/index.ts +4 -0
  20. package/src/components/index.ts +2 -0
  21. package/src/constant/index.ts +1 -0
  22. package/src/constant/nodeStyle.ts +141 -0
  23. package/src/index.ts +6 -0
  24. package/src/manager/BaseManager.ts +20 -0
  25. package/src/manager/DataProcessor.ts +782 -0
  26. package/src/manager/ExpandManager.ts +93 -0
  27. package/src/manager/FoldLineageManager.ts +196 -0
  28. package/src/manager/GraphEventManager.ts +90 -0
  29. package/src/manager/LineageManager.ts +680 -0
  30. package/src/manager/RightKeyMenuManager.ts +114 -0
  31. package/src/manager/SearchNodeManager.ts +188 -0
  32. package/src/manager/ToolbarManager.ts +42 -0
  33. package/src/manager/index.ts +8 -0
  34. package/src/manager/nodeManager/AssetEventManager.ts +442 -0
  35. package/src/manager/nodeManager/BaseEventManager.ts +68 -0
  36. package/src/manager/nodeManager/ColumnEventManager.ts +467 -0
  37. package/src/manager/nodeManager/CustomEventManager.ts +11 -0
  38. package/src/manager/nodeManager/TableEventManager.ts +87 -0
  39. package/src/manager/nodeManager/index.ts +3 -0
  40. package/src/types/NodeConfig.ts +69 -0
  41. package/src/types/eventEnum.ts +58 -0
  42. package/src/types/index.ts +3 -0
  43. package/src/types/manager.ts +75 -0
  44. package/src/types/node.ts +246 -0
  45. package/src/utils/downgradeNode.ts +22 -0
  46. package/src/utils/foldNode.ts +345 -0
  47. package/src/utils/getIconByType.ts +104 -0
  48. package/src/utils/index.ts +3 -0
  49. package/src/utils/node.ts +294 -0
  50. package/tsconfig.json +30 -0
@@ -0,0 +1,491 @@
1
+ import {
2
+ Rect,
3
+ Text,
4
+ Image,
5
+ getTextDomWidth,
6
+ getNodeHeight,
7
+ Graph,
8
+ } from '@aloudata/ink-graph-new';
9
+ import _ from 'lodash';
10
+ import { DefaultNode } from './DefaultNode';
11
+ import {
12
+ COL_HEIGHT,
13
+ COL_ORDER_TEXT_X,
14
+ COL_ORDER_TEXT_Y,
15
+ COL_PK_FK_Y,
16
+ COL_TEXT_X,
17
+ COL_TEXT_Y,
18
+ NODE_WIDTH,
19
+ RECT_LINE_WIDTH,
20
+ SIDE_ICON_SIZE,
21
+ } from '../../constant';
22
+ import { fkIcon, pkIcon } from '../../assets';
23
+ import {
24
+ EDashType,
25
+ EElementType,
26
+ EExpandType,
27
+ IColumnConfig,
28
+ IColResBase,
29
+ INodeConfig,
30
+ TDataBase,
31
+ EColumnEvents,
32
+ EEventEnum,
33
+ } from '../../types';
34
+ import { TableNode } from '.';
35
+ import { getEventTypeByNodeType } from '../../utils';
36
+
37
+ export class ColumnNode extends DefaultNode {
38
+ prevStartRelatedColumnId: string = '';
39
+
40
+ declare config: IColumnConfig<IColResBase>;
41
+
42
+ colText: Text;
43
+
44
+ colDesc: Text;
45
+
46
+ isForbidden: boolean;
47
+
48
+ constructor(
49
+ graph: Graph,
50
+ config: IColumnConfig<IColResBase>,
51
+ public node: TableNode,
52
+ public position: number,
53
+ ) {
54
+ super(graph, config);
55
+ this.elementType = EElementType.TABLE;
56
+ this.eventType = getEventTypeByNodeType(EElementType.COLUMN);
57
+
58
+ this.render();
59
+ }
60
+
61
+ render() {
62
+ if (!this.config.data) return;
63
+
64
+ this.container.name = 'column-group';
65
+ this.container.style.y = this.position * COL_HEIGHT;
66
+ this.container.style.cursor = 'default';
67
+
68
+ const { position, name, constraint } = this.config.data;
69
+
70
+ this.isForbidden = this.isForbiddenColumn();
71
+
72
+ this.container.style.zIndex = this.config.style.zIndex;
73
+
74
+ this.bgRect = new Rect({
75
+ name: 'column-bgRect',
76
+ style: {
77
+ x: 8,
78
+ fill: this.isForbidden ? '#fff' : this.config?.style?.fill || '#fff',
79
+ stroke: this.isForbidden
80
+ ? '#DBDBDB'
81
+ : this.config?.style?.stroke || '#DBDBDB',
82
+ lineWidth: RECT_LINE_WIDTH,
83
+ width: NODE_WIDTH - 16,
84
+ height: COL_HEIGHT,
85
+ zIndex: 0,
86
+ },
87
+ });
88
+
89
+ this.container.addEventListener('click', () => {
90
+ this.lineageManager.emit(EColumnEvents.CLICK, this);
91
+ });
92
+
93
+ this.container.addEventListener('contextmenu', (e) => {
94
+ e.preventDefault();
95
+ this.contextmenuClick();
96
+ });
97
+
98
+ this.container.addEventListener('mouseenter', () => {
99
+ if (this.isForbidden) return;
100
+
101
+ this.node.isHoverColumn = true;
102
+ // show side icon
103
+ this.onHover();
104
+ this.node.onLeave();
105
+ this.showSideIcon();
106
+ });
107
+
108
+ this.container.addEventListener('mouseleave', () => {
109
+ this.node.isHoverColumn = false;
110
+ // hide side icon
111
+ this.onLeave();
112
+ // this.node.onHover();
113
+ this.hideSideIcon();
114
+ });
115
+
116
+ // 用于hover到sideIcon区域时也能显示sideIcon
117
+ const colHideRect = new Rect({
118
+ name: 'column-bgRect-hide',
119
+ style: {
120
+ x: -20,
121
+ fill: '#0000',
122
+ stroke: '#0000',
123
+ lineWidth: RECT_LINE_WIDTH,
124
+ width: NODE_WIDTH + 40,
125
+ height: COL_HEIGHT - 1,
126
+ zIndex: 9,
127
+ cursor: this.isForbidden ? 'not-allowed' : 'default',
128
+ },
129
+ });
130
+
131
+ const colOrderText = new Text({
132
+ style: {
133
+ x: COL_ORDER_TEXT_X + 8,
134
+ y: COL_ORDER_TEXT_Y,
135
+ text: position || '-',
136
+ fill: '#A2A2A2',
137
+ fontSize: 12,
138
+ fontWeight: 400,
139
+ fontFamily: 'Tahoma',
140
+ zIndex: 2,
141
+ opacity: this.isForbidden ? 0.5 : 1,
142
+ },
143
+ });
144
+
145
+ const desc =
146
+ this.config.data?.displayName || this.config.data?.description || '';
147
+ const descLengh = getTextDomWidth(desc, 12, 'Tahoma');
148
+ const isDescExist = desc && descLengh > 0;
149
+
150
+ this.colText = new Text({
151
+ name: 'column-text',
152
+ style: {
153
+ x: COL_TEXT_X + 8,
154
+ y: COL_TEXT_Y,
155
+ wordWrap: true,
156
+ wordWrapWidth: isDescExist ? 150 : 240,
157
+ textOverflow: 'ellipsis',
158
+ maxLines: 1,
159
+ text: name,
160
+ fill: '#171717',
161
+ fontSize: 12,
162
+ fontWeight: 400,
163
+ fontFamily: 'PingFang SC',
164
+ zIndex: 2,
165
+ opacity: this.isForbidden ? 0.5 : 1,
166
+ },
167
+ });
168
+
169
+ this.container.appendChild(colHideRect);
170
+ this.container.appendChild(this.bgRect);
171
+ this.container.appendChild(colOrderText);
172
+ this.container.appendChild(this.colText);
173
+
174
+ // desc
175
+ if (isDescExist) {
176
+ this.colDesc = new Text({
177
+ name: 'column-desc-text',
178
+ style: {
179
+ x: 300 - 20,
180
+ y: COL_TEXT_Y,
181
+ wordWrap: true,
182
+ wordWrapWidth: 85,
183
+ textOverflow: 'ellipsis',
184
+ textAlign: 'right',
185
+ maxLines: 1,
186
+ text: desc,
187
+ fill: '#4B5563',
188
+ fontSize: 12,
189
+ fontWeight: 400,
190
+ fontFamily: 'PingFang SC',
191
+ zIndex: 2,
192
+ opacity: this.isForbidden ? 0.5 : 1,
193
+ },
194
+ });
195
+ this.container.appendChild(this.colDesc);
196
+ }
197
+
198
+ // PK、FK
199
+ if (!_.isNil(constraint) && ['PK', 'FK'].includes(constraint)) {
200
+ const columnType = new Image({
201
+ style: {
202
+ x: 190, // FIXME @yk
203
+ y: COL_PK_FK_Y,
204
+ width: 12,
205
+ height: 12,
206
+ img: constraint === 'PK' ? pkIcon : fkIcon,
207
+ cursor: 'pointer',
208
+ zIndex: 2,
209
+ },
210
+ });
211
+ this.container.appendChild(columnType);
212
+ }
213
+
214
+ if (
215
+ !this.isForbidden &&
216
+ (this.config.isRelatedColumn || this.config.isStartNode)
217
+ ) {
218
+ this.leftIcon = new Image({
219
+ name: `sideIcon-img-left`,
220
+ style: {
221
+ x: -SIDE_ICON_SIZE - 5,
222
+ y: COL_HEIGHT / 2 - SIDE_ICON_SIZE / 2,
223
+ width: SIDE_ICON_SIZE,
224
+ height: SIDE_ICON_SIZE,
225
+ cursor: 'pointer',
226
+ zIndex: 99,
227
+ visibility: 'visible',
228
+ },
229
+ });
230
+
231
+ this.leftIcon.addEventListener('click', (e) => {
232
+ e.preventDefault();
233
+ e.stopPropagation();
234
+ this.leftIconClick();
235
+ });
236
+
237
+ this.rightIcon = new Image({
238
+ name: `sideIcon-img-right`,
239
+ style: {
240
+ x: NODE_WIDTH + 6,
241
+ y: COL_HEIGHT / 2 - SIDE_ICON_SIZE / 2,
242
+ width: SIDE_ICON_SIZE,
243
+ height: SIDE_ICON_SIZE,
244
+ cursor: 'pointer',
245
+ zIndex: 99,
246
+ visibility: 'visible',
247
+ },
248
+ });
249
+
250
+ this.rightIcon.addEventListener('click', (e) => {
251
+ e.preventDefault();
252
+ e.stopPropagation();
253
+ this.rightIconClick();
254
+ });
255
+
256
+ this.container.appendChild(this.leftIcon);
257
+ this.container.appendChild(this.rightIcon);
258
+ }
259
+ }
260
+
261
+ onHover() {
262
+ if (!this.config) return;
263
+ if (this.config.style.stroke === '#3271C9') return;
264
+
265
+ this.bgRect.setAttribute('stroke', '#3271C9');
266
+ this.container.setAttribute('zIndex', 3);
267
+ }
268
+
269
+ onLeave() {
270
+ if (!this.config) return;
271
+ if (this.config.style.stroke === '#3271C9') return;
272
+
273
+ this.bgRect.setAttribute('stroke', '#DBDBDB');
274
+ this.container.setAttribute('zIndex', 2);
275
+ }
276
+
277
+ destroy(): void {
278
+ const filteredArray = _.reject(this.node.config.relatedColumns, {
279
+ id: this.id,
280
+ });
281
+
282
+ this.node.config.relatedColumns = filteredArray;
283
+
284
+ if (filteredArray.length === 0) {
285
+ this.node.config.isRelated = false;
286
+ }
287
+
288
+ this.config = null;
289
+
290
+ this.node.update(this.node.config, this.node.container);
291
+ }
292
+
293
+ isForbiddenColumn() {
294
+ return (
295
+ !this.config.isRelatedColumn &&
296
+ this.node.config.relatedColumns.some((c) => c.id === this.id && c.visible)
297
+ );
298
+ }
299
+
300
+ showSideIcon = () => {
301
+ const { config } = this;
302
+
303
+ const onlyShowRelated =
304
+ !!this.lineageManager?.rightKeyMenuManager?.onlyShowRelated;
305
+
306
+ // check left
307
+ // show expand left side icon
308
+ if (config.canExpandInput) {
309
+ if (onlyShowRelated && config.isStartNode && !config.isRelatedColumn) {
310
+ } else {
311
+ this.showLeftIcon(EExpandType.EXPAND);
312
+ }
313
+ }
314
+
315
+ // show close left side icon
316
+ if (config.canFoldInput) {
317
+ if (onlyShowRelated) {
318
+ } else {
319
+ this.showLeftIcon(EExpandType.FOLD);
320
+ }
321
+ }
322
+
323
+ // check right
324
+ // show expand right side icon
325
+ if (config.canExpandOutput) {
326
+ if (onlyShowRelated && config.isStartNode && !config.isRelatedColumn)
327
+ return;
328
+
329
+ this.showRightIcon(EExpandType.EXPAND);
330
+ }
331
+
332
+ // show close right side icon
333
+ if (config.canFoldOutput && !onlyShowRelated) {
334
+ this.showRightIcon(EExpandType.FOLD);
335
+ }
336
+ };
337
+
338
+ handleHotspotExpand(data: { resData }) {
339
+ const { resData: parsedData } = data;
340
+
341
+ if (parsedData.nodes.length > 1) {
342
+ // save prev start related column id
343
+ this.lineageManager.expandManager.prevStartRelatedColumnId =
344
+ this.config.id;
345
+ }
346
+
347
+ const { nodes: newNodes, edges: newEdges } = parsedData;
348
+
349
+ if (
350
+ newEdges.every((edge) => edge.relationType === EDashType.INDIRECT) &&
351
+ this.lineageManager?.rightKeyMenuManager?.edgeDashVisible ===
352
+ EDashType.DIRECT
353
+ ) {
354
+ this.lineageManager.emit(EEventEnum.INDIRECT_TIPS, {
355
+ message: '当前字段只有间接血缘,请打开间接血缘开关后查看',
356
+ });
357
+ }
358
+
359
+ const prevNodesConfig = this.lineageManager.parsedData.nodes;
360
+ let prevEdgesConfig = this.lineageManager.parsedData.edges;
361
+
362
+ // 如果是从起始列往下扩展并且不是同一个列,先清空之前所有节点下的的relatedColumns,再把新的parse后的列赋值给每一个表下
363
+ // 展开列是起始资产的列且展开列不是起始资产的第一个列
364
+ if (
365
+ this.config.isStartNode &&
366
+ this.prevStartRelatedColumnId !== this.config?.id
367
+ ) {
368
+ // find related nodes and edges
369
+ // 获取起始资产首列的上下游列,包含间接血缘
370
+ if (this.prevStartRelatedColumnId) {
371
+ prevEdgesConfig = prevEdgesConfig.filter((e) => {
372
+ return !e.data.relationTypeCode.includes('Column');
373
+ });
374
+ }
375
+
376
+ // clear all related columns
377
+ prevNodesConfig.forEach((n) => {
378
+ // clear related edges
379
+ n.relatedColumns = [];
380
+ });
381
+ }
382
+
383
+ // difference nodes
384
+ // 去除nodes中id等于prevNodesConfig.id中的节点,得到改变深度后的额外节点
385
+ const differentObjects = _.differenceBy(
386
+ newNodes,
387
+ prevNodesConfig,
388
+ 'id',
389
+ ) as unknown as INodeConfig<TDataBase<IColResBase>, IColResBase>[];
390
+
391
+ // common nodes
392
+ // 找出prevNodesConfig中id等于nodes中id的节点
393
+ const commonObjects = _.intersectionBy(prevNodesConfig, newNodes, 'id');
394
+
395
+ differentObjects.forEach((n) => {
396
+ n.relatedColumns = n.children;
397
+ n.relatedColumns.forEach((col) => {
398
+ col.isRelatedColumn = true;
399
+ });
400
+ n.children = [];
401
+ n.isFolded = false;
402
+ n.style.height = getNodeHeight(n);
403
+ });
404
+
405
+ commonObjects.forEach((n) => {
406
+ n.isFolded = false;
407
+ // 展开后得到的所有节点中找到第一个交集节点
408
+ const sameNodeNew = newNodes.find((node) => node.id === n.id);
409
+ if (sameNodeNew) {
410
+ n.relatedColumns = _.unionBy(
411
+ [...n.relatedColumns, ...sameNodeNew.children],
412
+ 'id',
413
+ );
414
+ n.relatedColumns.forEach((col) => {
415
+ col.isRelatedColumn = true;
416
+ });
417
+ n.style.height = getNodeHeight(n);
418
+ }
419
+
420
+ sameNodeNew.data.isHotspot =
421
+ n.data.isHotspot || sameNodeNew.data.isHotspot;
422
+ });
423
+
424
+ // show related edges
425
+ newEdges.forEach((e) => {
426
+ const prevEdge = prevEdgesConfig.find((edge) => edge.id === e.id);
427
+ if (prevEdge) {
428
+ prevEdge.isFolded = false;
429
+ //
430
+ if (e.relationType !== prevEdge.relationType) {
431
+ prevEdge.relationType = EDashType.ALL;
432
+ prevEdge.style.strokeDasharray = [0];
433
+ }
434
+ } else {
435
+ e.isFolded = false;
436
+ }
437
+ });
438
+
439
+ const newNodesConfig = _.concat(prevNodesConfig, differentObjects);
440
+ //
441
+ const newEdgesConfig = _.unionBy([...prevEdgesConfig, ...newEdges], 'id');
442
+
443
+ // update related column position
444
+ newNodesConfig.forEach((n) => {
445
+ n.relatedColumns
446
+ .sort((a, b) => {
447
+ return a.data?.position - b.data?.position;
448
+ })
449
+ .forEach((col, i) => {
450
+ col.position = {
451
+ x: 0,
452
+ y: i * COL_HEIGHT,
453
+ };
454
+ });
455
+ });
456
+
457
+ this.lineageManager.setData({
458
+ nodes: newNodesConfig,
459
+ edges: newEdgesConfig,
460
+ });
461
+
462
+ const onlyShowRelated =
463
+ !!this.lineageManager?.rightKeyMenuManager?.onlyShowRelated;
464
+ if (!onlyShowRelated) {
465
+ const currRelatedColumn = this.node.config.relatedColumns.find(
466
+ (col) => col.id === this.config.id,
467
+ );
468
+
469
+ // update active nodes
470
+ this.lineageManager?.updateActiveNodes([currRelatedColumn]);
471
+
472
+ // cache related edges
473
+ this.lineageManager?.setRelatedNodesAndEdges(this.config, false);
474
+ } else {
475
+ // update active nodes
476
+ this.lineageManager?.updateActiveNodes([
477
+ this.lineageManager.cachedRelatedNodeConfig,
478
+ ]);
479
+
480
+ // cache related edges
481
+ this.lineageManager?.setRelatedNodesAndEdges(
482
+ this.lineageManager.cachedRelatedNodeConfig,
483
+ );
484
+ }
485
+
486
+ // calc fold nodes
487
+ this.lineageManager?.updateFoldStatus(
488
+ this.lineageManager.foldLineageManager.isFoldChecked,
489
+ );
490
+ }
491
+ }
@@ -0,0 +1,63 @@
1
+ import { Text, Image, Graph } from '@aloudata/ink-graph-new';
2
+ import { AssetNode } from './AssetNode';
3
+ import { EElementType, EEntityType, INodeConfig, IColResBase, TDataBase, AssetEventType } from '../../types';
4
+ import { entityDefaultType } from '../../assets';
5
+ import { getEntityTypeIcon, getEventTypeByNodeType } from '../../utils';
6
+ import { TABLE_HEADER_NAME_WRAP_WIDTH } from '../../constant';
7
+
8
+ export class CustomNode extends AssetNode {
9
+ declare config: INodeConfig<TDataBase<IColResBase>, IColResBase>;
10
+
11
+ constructor(graph: Graph, config: INodeConfig<TDataBase<IColResBase>, IColResBase>) {
12
+ super(graph, config);
13
+ this.elementType = EElementType.CUSTOM;
14
+ this.eventType = getEventTypeByNodeType(EElementType.CUSTOM) as AssetEventType;
15
+ }
16
+
17
+ render(config: INodeConfig<TDataBase<IColResBase>, IColResBase>) {
18
+ this.renderAssetNode();
19
+
20
+ this.renderCustomHeader();
21
+
22
+ // refresh table height
23
+ this.updateNodeHeight();
24
+ }
25
+
26
+ renderCustomHeader() {
27
+ const { data } = this.config;
28
+ const { typeCode, typeCodeName, icon } = data;
29
+ const img =
30
+ data.type === EEntityType.CUSTOM
31
+ ? icon || entityDefaultType
32
+ : (getEntityTypeIcon(typeCode, data.type) as string);
33
+ const entityTypeIcon = new Image({
34
+ style: {
35
+ x: 12,
36
+ y: 12,
37
+ width: 20,
38
+ height: 20,
39
+ img,
40
+ cursor: 'pointer',
41
+ },
42
+ });
43
+
44
+ const typeCodeNameText = new Text({
45
+ style: {
46
+ x: 36,
47
+ y: 43,
48
+ text: typeCodeName,
49
+ fontSize: 12,
50
+ fontWeight: 400,
51
+ lineHeight: 16,
52
+ fontFamily: 'PingFang SC',
53
+ textBaseline: 'middle',
54
+ wordWrap: true,
55
+ wordWrapWidth: TABLE_HEADER_NAME_WRAP_WIDTH,
56
+ fill: '#4B5563',
57
+ },
58
+ });
59
+
60
+ this.headerGroup.appendChild(typeCodeNameText);
61
+ this.headerGroup.appendChild(entityTypeIcon);
62
+ }
63
+ }
@@ -0,0 +1,74 @@
1
+ import { BaseNode, Graph, Image } from '@aloudata/ink-graph-new';
2
+ import {
3
+ EElementType,
4
+ EExpandType,
5
+ EXPAND_BUTTON_TYPE,
6
+ IColumnConfig,
7
+ INodeConfig,
8
+ IColResBase,
9
+ TDataBase,
10
+ EventEnumType,
11
+ } from '../../types';
12
+ import { InkLineageManager } from '../../manager';
13
+
14
+ export class DefaultNode extends BaseNode<
15
+ INodeConfig<TDataBase<IColResBase>, IColResBase> | IColumnConfig<IColResBase>
16
+ > {
17
+ static lineageManager: InkLineageManager<TDataBase<IColResBase>, IColResBase>;
18
+
19
+ eventType: EventEnumType;
20
+
21
+ elementType: EElementType;
22
+
23
+ leftIcon: Image;
24
+
25
+ rightIcon: Image;
26
+
27
+ isHoverColumn?: boolean;
28
+
29
+ get lineageManager(): InkLineageManager<TDataBase<IColResBase>, IColResBase> {
30
+ return DefaultNode.lineageManager;
31
+ }
32
+
33
+ constructor(
34
+ graph: Graph,
35
+ config:
36
+ | INodeConfig<TDataBase<IColResBase>, IColResBase>
37
+ | IColumnConfig<IColResBase>,
38
+ ) {
39
+ super(graph, config);
40
+ }
41
+
42
+ rightIconClick() {
43
+ this.lineageManager.emit(this.eventType.RIGHT_ICON_CLICK, this);
44
+ }
45
+
46
+ leftIconClick() {
47
+ this.lineageManager.emit(this.eventType.LEFT_ICON_CLICK, this);
48
+ }
49
+
50
+ contextmenuClick() {
51
+ this.lineageManager.emit(this.eventType.CONTEXT_MENU, this);
52
+ }
53
+
54
+ hideSideIcon = () => {
55
+ this.leftIcon?.setAttribute('visibility', 'hidden');
56
+ this.rightIcon?.setAttribute('visibility', 'hidden');
57
+ };
58
+
59
+ showLeftIcon(type: EExpandType) {
60
+ if (!this.leftIcon) return;
61
+
62
+ this.leftIcon.style.img = EXPAND_BUTTON_TYPE[type];
63
+ this.leftIcon.setAttribute('visibility', 'visible');
64
+ (this.leftIcon as any).iconType = type;
65
+ }
66
+
67
+ showRightIcon(type: EExpandType) {
68
+ if (!this.rightIcon) return;
69
+
70
+ this.rightIcon.style.img = EXPAND_BUTTON_TYPE[type];
71
+ this.rightIcon.setAttribute('visibility', 'visible');
72
+ (this.rightIcon as any).iconType = type;
73
+ }
74
+ }