@reltio/graph 1.4.1585 → 1.4.1586-mui5

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 (164) hide show
  1. package/index.ts +1 -0
  2. package/package.json +26 -9
  3. package/public/bundle.js +205 -0
  4. package/public/bundle.js.LICENSE.txt +88 -0
  5. package/public/package.json +29 -0
  6. package/scripts/build/index.js +20 -0
  7. package/src/__tests__/GraphView.test.tsx +25 -0
  8. package/src/components/CircleLayout/CircleLayout.tsx +76 -0
  9. package/src/components/CircleLayout/__tests__/CircleLayout.test.tsx +194 -0
  10. package/src/components/GotoButton/GotoButton.tsx +23 -0
  11. package/src/components/GotoButton/__tests__/GotoButton.test.tsx +33 -0
  12. package/src/components/GotoButton/styles.ts +15 -0
  13. package/src/components/GraphArea/GraphArea.tsx +113 -0
  14. package/src/components/GraphArea/__tests__/GraphArea.test.tsx +202 -0
  15. package/src/components/GraphArea/styles.ts +30 -0
  16. package/src/components/GraphLayoutSelector/GraphLayoutSelector.tsx +43 -0
  17. package/src/components/GraphLayoutSelector/__tests__/GraphLayoutSelector.spec.tsx +44 -0
  18. package/src/components/GraphLayoutSelector/styles.ts +15 -0
  19. package/src/components/GraphPerspectiveView/GraphPerspectiveView.tsx +58 -0
  20. package/src/components/GraphPerspectiveView/__tests__/GraphPerspectiveView.test.tsx +115 -0
  21. package/src/components/GraphPerspectiveView/__tests__/useGraphLoader.test.tsx +1519 -0
  22. package/src/components/GraphPerspectiveView/__tests__/useRelationshipTable.test.tsx +1003 -0
  23. package/src/components/GraphPerspectiveView/__tests__/useSelectedEntity.test.tsx +373 -0
  24. package/src/components/GraphPerspectiveView/styles.ts +34 -0
  25. package/src/components/GraphRightSidePanel/GraphRightSidePanel.tsx +27 -0
  26. package/src/components/GraphRightSidePanel/__tests__/GraphRightSidePanel.test.tsx +18 -0
  27. package/src/components/GraphRightSidePanel/icons/relationship-icon.svg +3 -0
  28. package/src/components/GraphRightSidePanel/styles.ts +8 -0
  29. package/src/components/GraphTypeSelector/GraphTypeSelector.tsx +56 -0
  30. package/src/components/GraphTypeSelector/__tests__/GraphTypeSelector.test.tsx +109 -0
  31. package/src/components/GraphTypeSelector/styles.ts +17 -0
  32. package/src/components/HierarchyLayout/HierarchyLayout.ts +102 -0
  33. package/src/components/HierarchyLayout/__tests__/HierarchyLayout.spec.tsx +241 -0
  34. package/src/components/HierarchyLayout/__tests__/buildHierarchy.spec.ts +130 -0
  35. package/src/components/HierarchyLayout/__tests__/calculations.spec.ts +230 -0
  36. package/src/components/HierarchyLayout/buildHierarchy.ts +109 -0
  37. package/src/components/HierarchyLayout/calculations.ts +86 -0
  38. package/src/components/RightPanelEntityDetails/RightPanelEntityDetails.tsx +33 -0
  39. package/src/components/RightPanelEntityDetails/__tests__/RightPanelEntityDetails.test.tsx +39 -0
  40. package/src/components/RightPanelEntityDetails/styles.ts +12 -0
  41. package/src/components/RightPanelProfileBand/RightPanelProfileBand.tsx +33 -0
  42. package/src/components/RightPanelProfileBand/__tests__/RightPanelProfileBand.test.tsx +67 -0
  43. package/src/components/RightPanelProfileBand/styles.ts +8 -0
  44. package/src/components/RightPanelRelationship/RightPanelRelationship.tsx +25 -0
  45. package/src/components/RightPanelRelationship/__tests__/RightPanelRelationship.test.tsx +18 -0
  46. package/src/components/RightPanelRelationship/components/CollapsibleTable/CollapsibleTable.tsx +100 -0
  47. package/src/components/RightPanelRelationship/components/CollapsibleTable/TableHead.tsx +38 -0
  48. package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/CollapsibleTable.test.tsx +169 -0
  49. package/src/components/RightPanelRelationship/components/CollapsibleTable/__tests__/TableHead.test.tsx +107 -0
  50. package/src/components/RightPanelRelationship/components/CollapsibleTable/styles.ts +38 -0
  51. package/src/components/RightPanelRelationship/components/CollapsibleTable/types.ts +20 -0
  52. package/src/components/RightPanelRelationship/components/DeleteRelationDialog/DeleteRelationDialog.tsx +34 -0
  53. package/src/components/RightPanelRelationship/components/DeleteRelationDialog/__tests__/DeleteRelationDialog.test.tsx +46 -0
  54. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationButton.tsx +43 -0
  55. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/GraphAddRelationDialog.tsx +121 -0
  56. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationButton.test.tsx +80 -0
  57. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/GraphAddRelationDialog.test.tsx +262 -0
  58. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/__tests__/mockdata.ts +75 -0
  59. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/styles.ts +25 -0
  60. package/src/components/RightPanelRelationship/components/GraphAddRelationDialog/useCreatableInOutRelationTypes.ts +13 -0
  61. package/src/components/RightPanelRelationship/components/RelationshipTable/RelationshipTable.tsx +126 -0
  62. package/src/components/RightPanelRelationship/components/RelationshipTable/__tests__/RelationshipTable.test.tsx +176 -0
  63. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ControlsCellRenderer.tsx +59 -0
  64. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/DefaultCellRenderer.tsx +29 -0
  65. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ExpandedRowRenderer.tsx +94 -0
  66. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/HeadCellRenderer.tsx +34 -0
  67. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/ProfileCellRenderer.tsx +41 -0
  68. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ControlsCellRenderer.test.tsx +80 -0
  69. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/DefaultCellRenderer.test.tsx +47 -0
  70. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ExpandedRowRenderer.test.tsx +166 -0
  71. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/HeadCellRenderer.test.tsx +23 -0
  72. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/__tests__/ProfileCellRenderer.test.tsx +47 -0
  73. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/DeleteRelationButton.tsx +32 -0
  74. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/components/__tests__/DeleteRelationButton.test.tsx +28 -0
  75. package/src/components/RightPanelRelationship/components/RelationshipTable/cell-renderers/styles.ts +113 -0
  76. package/src/components/RightPanelRelationship/components/RelationshipTable/styles.ts +36 -0
  77. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFilters.tsx +41 -0
  78. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/RelationshipsFiltersDialog.tsx +91 -0
  79. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/__tests__/RelationshipsFilterDialog.test.tsx +192 -0
  80. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsFiltersDialog/styles.ts +34 -0
  81. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/RelationshipsSearchTextField.tsx +31 -0
  82. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/__tests__/RelationshipsSearchTextField.test.tsx +43 -0
  83. package/src/components/RightPanelRelationship/components/RelationshipsFilters/RelationshipsSearchTextField/styles.ts +17 -0
  84. package/src/components/RightPanelRelationship/components/RelationshipsFilters/__tests__/RelationshipsFilters.test.tsx +76 -0
  85. package/src/components/RightPanelRelationship/components/RelationshipsFilters/styles.ts +19 -0
  86. package/src/components/RightPanelRelationship/styles.ts +20 -0
  87. package/src/components/SigmaCustomRenderers/SigmaCustomRenderersContainer.tsx +16 -0
  88. package/src/components/SigmaGraphContainer/SigmaGraphContainer.tsx +55 -0
  89. package/src/components/SigmaGraphContainer/__tests__/SigmaGraphContainer.test.tsx +25 -0
  90. package/src/components/SigmaGraphResizer/SigmaGraphResizer.tsx +13 -0
  91. package/src/components/SigmaGraphResizer/__tests__/SigmaGraphResizer.test.tsx +28 -0
  92. package/src/components/TreeLayout/TreeLayout.tsx +33 -0
  93. package/src/components/TreeLayout/__tests__/TreeLayout.test.tsx +42 -0
  94. package/src/components/TreeLayout/styles.ts +10 -0
  95. package/src/components/ZoomSlider/ZoomSlider.tsx +90 -0
  96. package/src/components/ZoomSlider/__tests__/ZoomSlider.test.tsx +84 -0
  97. package/src/components/ZoomSlider/styles.ts +57 -0
  98. package/src/constants/index.ts +1 -0
  99. package/src/contexts/GraphStateContext.tsx +19 -0
  100. package/src/contexts/SigmaCustomRenderersContext.ts +20 -0
  101. package/src/helpers/relationsHelpers.ts +9 -0
  102. package/src/hooks/__tests__/useGraphLayout.test.tsx +825 -0
  103. package/src/hooks/__tests__/useGraphLayoutSelector.test.tsx +19 -0
  104. package/src/hooks/__tests__/useSelfRelationLoopsRenderer.test.ts +198 -0
  105. package/src/hooks/__tests__/useSigmaCustomRenderers.test.ts +273 -0
  106. package/src/hooks/__tests__/useTooltipRenderer.test.ts +289 -0
  107. package/src/hooks/useGraphLayout.ts +308 -0
  108. package/src/hooks/useGraphLayoutSelector.ts +19 -0
  109. package/src/hooks/useGraphLoader.ts +279 -0
  110. package/src/hooks/useGraphRightSidePanelElements.tsx +36 -0
  111. package/src/hooks/useGraphState.ts +40 -0
  112. package/src/hooks/useGraphType.ts +32 -0
  113. package/src/hooks/useRelationshipTable.ts +212 -0
  114. package/src/hooks/useRelationshipTableFilters.ts +43 -0
  115. package/src/hooks/useSelectedEntity.ts +89 -0
  116. package/src/hooks/useSelfRelationLoopsRenderer.ts +52 -0
  117. package/src/hooks/useSigmaCustomRenderers.ts +112 -0
  118. package/src/hooks/useTooltipRenderer.ts +80 -0
  119. package/src/index.tsx +37 -0
  120. package/src/rendering/canvas/__tests__/hover.spec.ts +31 -0
  121. package/src/rendering/canvas/__tests__/label.spec.ts +64 -0
  122. package/src/rendering/canvas/__tests__/nodeBackground.spec.ts +99 -0
  123. package/src/rendering/canvas/__tests__/selfRelationLoop.spec.ts +88 -0
  124. package/src/rendering/canvas/__tests__/tooltip.spec.ts +33 -0
  125. package/src/rendering/canvas/hover.ts +13 -0
  126. package/src/rendering/canvas/label.ts +33 -0
  127. package/src/rendering/canvas/nodeBackground.ts +61 -0
  128. package/src/rendering/canvas/selfRelationLoop.ts +108 -0
  129. package/src/rendering/canvas/tooltip.ts +38 -0
  130. package/src/rendering/icons/collapseIcon.inline.svg.ts +6 -0
  131. package/src/rendering/icons/expandIcon.inline.svg.ts +5 -0
  132. package/src/rendering/icons/no_photo.inline.svg.ts +13 -0
  133. package/src/rendering/webgl/edge.arrowHead.ts +87 -0
  134. package/src/rendering/webgl/edge.clamped.ts +246 -0
  135. package/src/rendering/webgl/edge.reversedArrowHead.ts +14 -0
  136. package/src/rendering/webgl/helpers/__tests__/imageHelper.spec.ts +36 -0
  137. package/src/rendering/webgl/helpers/imageHelper.ts +13 -0
  138. package/src/rendering/webgl/image.ts +115 -0
  139. package/src/rendering/webgl/node.border.ts +78 -0
  140. package/src/rendering/webgl/node.buttons.ts +241 -0
  141. package/src/rendering/webgl/node.image.ts +169 -0
  142. package/src/rendering/webgl/shaders/edge.clamped.vert.glsl.ts +55 -0
  143. package/src/rendering/webgl/shaders/node.border.frag.glsl.ts +30 -0
  144. package/src/rendering/webgl/shaders/node.border.vert.glsl.ts +37 -0
  145. package/src/rendering/webgl/shaders/node.buttons.frag.glsl.ts +32 -0
  146. package/src/rendering/webgl/shaders/node.buttons.vert.glsl.ts +49 -0
  147. package/src/rendering/webgl/shaders/node.image.frag.glsl.ts +46 -0
  148. package/src/rendering/webgl/shaders/node.image.vert.glsl.ts +42 -0
  149. package/src/types/graphDataTypes.ts +143 -0
  150. package/src/types/sigmaCustomRenderersTypes.ts +13 -0
  151. package/src/utils/__tests__/graph.spec.ts +152 -0
  152. package/src/utils/__tests__/graphLayout.spec.ts +125 -0
  153. package/src/utils/__tests__/hopsData.spec.ts +456 -0
  154. package/src/utils/__tests__/processResponceToGraph.spec.ts +165 -0
  155. package/src/utils/graph.ts +83 -0
  156. package/src/utils/graphLayout.ts +70 -0
  157. package/src/utils/hopsData.ts +198 -0
  158. package/src/utils/processResponseToGraph.ts +32 -0
  159. package/tsconfig.json +4 -0
  160. package/webpack.config.js +10 -0
  161. package/bundle.js +0 -2
  162. package/bundle.js.LICENSE.txt +0 -54
  163. /package/{5271a9e7b6651c852e93.png → public/5271a9e7b6651c852e93.png} +0 -0
  164. /package/{main.css → public/main.css} +0 -0
@@ -0,0 +1,102 @@
1
+ import {useCallback} from 'react';
2
+ import Graph from 'graphology';
3
+ import {rotation} from 'graphology-layout';
4
+ import {HopsResponse, GraphLayout} from '@reltio/mdm-sdk';
5
+ import {Filters, GraphPathType} from '../../types/graphDataTypes';
6
+ import {buildHierarchyNodes, extractDataFromGraph} from './buildHierarchy';
7
+ import {useGraphLayout} from '../../hooks/useGraphLayout';
8
+ import {
9
+ calculateXPos,
10
+ calculateYPos,
11
+ getAngleOfRotation,
12
+ getMaxLvlSize,
13
+ getMaxQuantityNodesOnOneLvl,
14
+ isSimpleGraph
15
+ } from './calculations';
16
+
17
+ type HierarchyLayoutProps = {
18
+ data: HopsResponse;
19
+ graph: Graph;
20
+ selectedNode: string;
21
+ layout: GraphLayout;
22
+ onNodeClick: (node: string) => void;
23
+ onNodeCollapse: (node: string, path: GraphPathType) => void;
24
+ onNodeExpand: (node: string) => void;
25
+ filters?: Filters;
26
+ };
27
+
28
+ export const HierarchyLayout = ({
29
+ data,
30
+ graph,
31
+ selectedNode,
32
+ layout,
33
+ onNodeClick,
34
+ onNodeCollapse,
35
+ onNodeExpand,
36
+ filters
37
+ }: HierarchyLayoutProps) => {
38
+ const hierarchicalLayout = useCallback(
39
+ (graph: Graph) => {
40
+ const tempGraph = graph.copy();
41
+ const angleOfRotation = getAngleOfRotation(layout);
42
+ const graphData = extractDataFromGraph(tempGraph);
43
+ const nodesLength = graphData.nodes.length;
44
+ const shouldUseCheckboardPattern = !isSimpleGraph(nodesLength);
45
+ const maxQuantityNodesOnOneLvl = getMaxQuantityNodesOnOneLvl(nodesLength, layout);
46
+ const nodesHierarchy = buildHierarchyNodes(graphData, selectedNode, maxQuantityNodesOnOneLvl);
47
+ const maxLvlSize = getMaxLvlSize(nodesHierarchy);
48
+ for (let i = 0; i < nodesHierarchy.length; ++i) {
49
+ const isEvenRow = i % 2 === 0;
50
+ const quantityAtLvl = nodesHierarchy[i].length;
51
+
52
+ for (let j = 0; j < quantityAtLvl; ++j) {
53
+ const isEvenItem = j % 2 === 0;
54
+
55
+ const xPos = calculateXPos({
56
+ quantityAtLvl,
57
+ posAtLvl: j,
58
+ max: maxLvlSize,
59
+ isEvenRow,
60
+ layout,
61
+ shouldUseCheckboardPattern
62
+ });
63
+
64
+ const yPos = calculateYPos({
65
+ quantityAtLvl,
66
+ rowNumber: i,
67
+ isEvenItem,
68
+ layout,
69
+ shouldUseCheckboardPattern
70
+ });
71
+
72
+ tempGraph.setNodeAttribute(nodesHierarchy[i][j], 'x', xPos);
73
+ tempGraph.setNodeAttribute(nodesHierarchy[i][j], 'y', yPos);
74
+ }
75
+ }
76
+ rotation.assign(tempGraph, angleOfRotation, {degrees: true});
77
+ return tempGraph.reduceNodes(
78
+ (result, id, {x, y}) => ({
79
+ ...result,
80
+ [id]: {x, y}
81
+ }),
82
+ {}
83
+ );
84
+ },
85
+ [layout, selectedNode]
86
+ );
87
+
88
+ useGraphLayout({
89
+ syncLayout: hierarchicalLayout,
90
+ data,
91
+ graph,
92
+ selectedNode,
93
+ onNodeClick,
94
+ onNodeCollapse,
95
+ onNodeExpand,
96
+ filters
97
+ });
98
+
99
+ return null;
100
+ };
101
+
102
+ export default HierarchyLayout;
@@ -0,0 +1,241 @@
1
+ import React from 'react';
2
+ import {mount} from 'enzyme';
3
+ import {MultiGraph} from 'graphology';
4
+ import {rotation} from 'graphology-layout';
5
+ import {useSetSettings, useSigma} from '@react-sigma/core';
6
+ import * as reactRedux from 'react-redux';
7
+ import {animateNodes} from 'sigma/utils/animate';
8
+ import {HopsResponse, GraphLayout, RelationTypeDirection} from '@reltio/mdm-sdk';
9
+
10
+ import {HierarchyLayout} from '../HierarchyLayout';
11
+ import {fillGraphWithHopsResponse} from '../../../utils/graph';
12
+ import {useGraphLayout} from '../../../hooks/useGraphLayout';
13
+
14
+ jest.mock('sigma/utils/animate', () => ({
15
+ animateNodes: jest.fn()
16
+ }));
17
+
18
+ jest.mock('@react-sigma/core', () => {
19
+ const sigma = jest.requireActual('@react-sigma/core');
20
+ return {
21
+ ...sigma,
22
+ useSigma: jest.fn().mockReturnValue({
23
+ getCamera: () => ({
24
+ setState: () => {}
25
+ }),
26
+ getGraph: () => ({})
27
+ }),
28
+ useLoadGraph: jest.fn().mockReturnValue(jest.fn()),
29
+ useRegisterEvents: jest.fn().mockReturnValue(jest.fn()),
30
+ useSetSettings: jest.fn().mockReturnValue(jest.fn())
31
+ };
32
+ });
33
+
34
+ jest.mock('../../../hooks/useGraphLayout', () => ({
35
+ ...(jest.requireActual('../../../hooks/useGraphLayout') as Record<string, unknown>),
36
+ useGraphLayout: jest.fn().mockImplementation(jest.requireActual('../../../hooks/useGraphLayout').useGraphLayout)
37
+ }));
38
+
39
+ jest.mock('../../../hooks/useSelfRelationLoopsRenderer', () => ({
40
+ ...jest.requireActual<Record<string, unknown>>('../../../hooks/useSelfRelationLoopsRenderer'),
41
+ useSelfRelationLoopsRenderer: jest.fn().mockReturnValue({selfRelationsPathsMap: {}, selfRelationLoopsCanvas: null})
42
+ }));
43
+
44
+ const data: HopsResponse = {
45
+ entities: [
46
+ {uri: 'node1', type: 'hcp'},
47
+ {uri: 'node2', type: 'hcp'},
48
+ {uri: 'node3', type: 'hca'},
49
+ {uri: 'node4', type: 'hco'}
50
+ ],
51
+ relations: [
52
+ {
53
+ uri: 'r1',
54
+ type: 'relType1',
55
+ startObject: {
56
+ objectURI: 'node1'
57
+ },
58
+ endObject: {
59
+ objectURI: 'node2'
60
+ },
61
+ direction: RelationTypeDirection.directed
62
+ },
63
+ {
64
+ uri: 'r2',
65
+ type: 'relType2',
66
+ startObject: {
67
+ objectURI: 'node2'
68
+ },
69
+ endObject: {
70
+ objectURI: 'node3'
71
+ },
72
+ direction: RelationTypeDirection.directed
73
+ },
74
+ {
75
+ uri: 'r3',
76
+ type: 'relType3',
77
+ startObject: {
78
+ objectURI: 'node2'
79
+ },
80
+ endObject: {
81
+ objectURI: 'node4'
82
+ },
83
+ direction: RelationTypeDirection.bidirectional
84
+ }
85
+ ]
86
+ };
87
+
88
+ describe('HierarchyLayout functions behavior', () => {
89
+ const store = {
90
+ profile: {
91
+ entity: {
92
+ uri: 'node1',
93
+ type: 'hcp'
94
+ }
95
+ },
96
+ tenant: {id: 't1'},
97
+ metadata: {
98
+ t1: {
99
+ entityTypes: [],
100
+ relationTypes: []
101
+ }
102
+ }
103
+ };
104
+ beforeAll(() => {
105
+ jest.spyOn(reactRedux, 'useSelector').mockImplementation((selector) => selector(store));
106
+ });
107
+ afterEach(() => {
108
+ jest.clearAllMocks();
109
+ });
110
+
111
+ it('should set correct x and y coordinate for each node', () => {
112
+ jest.spyOn(rotation, 'assign').mockImplementation(jest.fn());
113
+ const graph = new MultiGraph();
114
+ fillGraphWithHopsResponse(graph, data);
115
+ (useSigma as jest.Mock).mockReturnValue({
116
+ getCamera: () => ({
117
+ setState: () => {}
118
+ }),
119
+ getGraph: () => graph
120
+ });
121
+ mount(
122
+ <HierarchyLayout
123
+ data={data}
124
+ graph={graph}
125
+ selectedNode={'node1'}
126
+ onNodeClick={jest.fn()}
127
+ onNodeCollapse={jest.fn()}
128
+ onNodeExpand={jest.fn()}
129
+ layout={GraphLayout.HORIZONTAL_LR}
130
+ />
131
+ );
132
+ expect(animateNodes).toHaveBeenCalledWith(
133
+ graph,
134
+ {
135
+ node1: {
136
+ x: 5,
137
+ y: 0
138
+ },
139
+ node2: {
140
+ x: 5,
141
+ y: 10
142
+ },
143
+ node3: {
144
+ x: 0,
145
+ y: 20
146
+ },
147
+ node4: {
148
+ x: 10,
149
+ y: 20
150
+ }
151
+ },
152
+ {duration: 1000}
153
+ );
154
+ });
155
+
156
+ it('should call useGraphLayout with params', () => {
157
+ const graph = new MultiGraph();
158
+ fillGraphWithHopsResponse(graph, data);
159
+ const props = {
160
+ data,
161
+ graph,
162
+ layout: GraphLayout.HORIZONTAL_LR,
163
+ selectedNode: 'node1',
164
+ onNodeClick: jest.fn(),
165
+ onNodeCollapse: jest.fn(),
166
+ onNodeExpand: jest.fn(),
167
+ filters: {entityTypesUris: ['hcp'], relationTypesUris: []}
168
+ };
169
+
170
+ mount(<HierarchyLayout {...props} />);
171
+ expect(useGraphLayout).toHaveBeenCalledWith({
172
+ syncLayout: expect.any(Function),
173
+ graph: props.graph,
174
+ data: props.data,
175
+ onNodeClick: props.onNodeClick,
176
+ selectedNode: props.selectedNode,
177
+ onNodeCollapse: props.onNodeCollapse,
178
+ onNodeExpand: props.onNodeExpand,
179
+ filters: props.filters
180
+ });
181
+ });
182
+
183
+ describe('Filters behavior', () => {
184
+ const graph = new MultiGraph();
185
+ fillGraphWithHopsResponse(graph, data);
186
+ const props = {
187
+ data,
188
+ graph,
189
+ layout: GraphLayout.HORIZONTAL_LR,
190
+ selectedNode: 'node2',
191
+ onNodeClick: jest.fn(),
192
+ onNodeCollapse: jest.fn(),
193
+ onNodeExpand: jest.fn(),
194
+ filters: {entityTypesUris: ['hca'], relationTypesUris: ['relType3']}
195
+ };
196
+ const setSettings = jest.fn();
197
+ beforeAll(() => {
198
+ (useSetSettings as jest.Mock).mockReturnValue(setSettings);
199
+ });
200
+
201
+ it('should filter nodes in nodeReducer', () => {
202
+ mount(<HierarchyLayout {...props} />);
203
+ expect(setSettings).toHaveBeenCalled();
204
+ const nodeReducer = setSettings.mock.calls[setSettings.mock.calls.length - 1][0].nodeReducer;
205
+ // main entity node shouldn't be filtered
206
+ expect(nodeReducer('node1', graph.getNodeAttributes('node1')).hidden).toBeFalsy();
207
+ // selected entity node shouldn't be filtered
208
+ expect(nodeReducer('node2', graph.getNodeAttributes('node2')).hidden).toBeFalsy();
209
+ expect(nodeReducer('node3', graph.getNodeAttributes('node3')).hidden).toBeFalsy();
210
+ expect(nodeReducer('node4', graph.getNodeAttributes('node4')).hidden).toBe(true);
211
+ });
212
+
213
+ it('should not filter nodes if filters.entityTypesUris is empty', () => {
214
+ mount(<HierarchyLayout {...props} filters={{entityTypesUris: [], relationTypesUris: ['relType3']}} />);
215
+ expect(setSettings).toHaveBeenCalled();
216
+ const nodeReducer = setSettings.mock.calls[setSettings.mock.calls.length - 1][0].nodeReducer;
217
+ expect(nodeReducer('node1', graph.getNodeAttributes('node1')).hidden).toBeFalsy();
218
+ expect(nodeReducer('node2', graph.getNodeAttributes('node2')).hidden).toBeFalsy();
219
+ expect(nodeReducer('node3', graph.getNodeAttributes('node3')).hidden).toBeFalsy();
220
+ expect(nodeReducer('node4', graph.getNodeAttributes('node4')).hidden).toBeFalsy();
221
+ });
222
+
223
+ it('should filter edges in edgeReducer', () => {
224
+ mount(<HierarchyLayout {...props} />);
225
+ expect(setSettings).toHaveBeenCalled();
226
+ const edgeReducer = setSettings.mock.calls[setSettings.mock.calls.length - 1][0].edgeReducer;
227
+ expect(edgeReducer('r1', graph.getEdgeAttributes('r1')).hidden).toBe(true);
228
+ expect(edgeReducer('r2', graph.getEdgeAttributes('r2')).hidden).toBe(true);
229
+ expect(edgeReducer('r3', graph.getEdgeAttributes('r3')).hidden).toBeFalsy();
230
+ });
231
+
232
+ it('should not filter edges if filters.relationTypesUris is empty', () => {
233
+ mount(<HierarchyLayout {...props} filters={{entityTypesUris: ['hca'], relationTypesUris: []}} />);
234
+ expect(setSettings).toHaveBeenCalled();
235
+ const edgeReducer = setSettings.mock.calls[setSettings.mock.calls.length - 1][0].edgeReducer;
236
+ expect(edgeReducer('r1', graph.getEdgeAttributes('r1')).hidden).toBeFalsy();
237
+ expect(edgeReducer('r2', graph.getEdgeAttributes('r2')).hidden).toBeFalsy();
238
+ expect(edgeReducer('r3', graph.getEdgeAttributes('r3')).hidden).toBeFalsy();
239
+ });
240
+ });
241
+ });
@@ -0,0 +1,130 @@
1
+ import {buildHierarchyNodes} from '../buildHierarchy';
2
+ import {GraphologyGraphData} from '../../../types/graphDataTypes';
3
+
4
+ export const graphData = {
5
+ nodes: [
6
+ {id: 'node1', name: 'node1'},
7
+ {id: 'node2', name: 'node2'},
8
+ {id: 'node3', name: 'node3'},
9
+ {id: 'node4', name: 'node4'}
10
+ ],
11
+ edges: [
12
+ {from: 'node1', to: 'node2'},
13
+ {from: 'node2', to: 'node3'},
14
+ {from: 'node2', to: 'node4'}
15
+ ]
16
+ } as GraphologyGraphData;
17
+
18
+ const graphDataWithLargeNumberOfNodesOnSameLvl = {
19
+ nodes: [
20
+ {id: 'node1', name: 'node1'},
21
+ {id: 'node2', name: 'node2'},
22
+ {id: 'node3', name: 'node3'},
23
+ {id: 'node4', name: 'node4'},
24
+ {id: 'node5', name: 'node5'},
25
+ {id: 'node6', name: 'node6'},
26
+ {id: 'node7', name: 'node7'},
27
+ {id: 'node8', name: 'node8'},
28
+ {id: 'node9', name: 'node9'},
29
+ {id: 'node10', name: 'node10'},
30
+ {id: 'node11', name: 'node11'},
31
+ {id: 'node12', name: 'node12'}
32
+ ],
33
+ edges: [
34
+ {from: 'node1', to: 'node2'},
35
+ {from: 'node1', to: 'node3'},
36
+ {from: 'node1', to: 'node4'},
37
+ {from: 'node1', to: 'node5'},
38
+ {from: 'node1', to: 'node6'},
39
+ {from: 'node1', to: 'node7'},
40
+ {from: 'node1', to: 'node8'},
41
+ {from: 'node1', to: 'node9'},
42
+ {from: 'node1', to: 'node10'},
43
+ {from: 'node1', to: 'node11'},
44
+ {from: 'node1', to: 'node12'}
45
+ ]
46
+ } as GraphologyGraphData;
47
+
48
+ const nodesWithLoop = {
49
+ nodes: [
50
+ {id: 'node1', name: 'node1'},
51
+ {id: 'node2', name: 'node2'},
52
+ {id: 'node3', name: 'node3'}
53
+ ],
54
+ edges: [
55
+ {from: 'node1', to: 'node2'},
56
+ {from: 'node2', to: 'node3'},
57
+ {from: 'node3', to: 'node1'}
58
+ ]
59
+ } as GraphologyGraphData;
60
+
61
+ const tenNodesOnTheSameLvl = {
62
+ nodes: [
63
+ {id: 'node1', name: 'node1'},
64
+ {id: 'node2', name: 'node2'},
65
+ {id: 'node3', name: 'node3'},
66
+ {id: 'node4', name: 'node4'},
67
+ {id: 'node5', name: 'node5'},
68
+ {id: 'node6', name: 'node6'},
69
+ {id: 'node7', name: 'node7'},
70
+ {id: 'node8', name: 'node8'},
71
+ {id: 'node9', name: 'node9'},
72
+ {id: 'node10', name: 'node10'},
73
+ {id: 'node11', name: 'node11'}
74
+ ],
75
+ edges: [
76
+ {from: 'node1', to: 'node2'},
77
+ {from: 'node1', to: 'node3'},
78
+ {from: 'node1', to: 'node4'},
79
+ {from: 'node1', to: 'node5'},
80
+ {from: 'node1', to: 'node6'},
81
+ {from: 'node1', to: 'node7'},
82
+ {from: 'node1', to: 'node8'},
83
+ {from: 'node1', to: 'node9'},
84
+ {from: 'node1', to: 'node10'},
85
+ {from: 'node1', to: 'node11'}
86
+ ]
87
+ } as GraphologyGraphData;
88
+
89
+ describe('BuildHierarchyNodes behavior', () => {
90
+ it('should build correct nodes hierarchy', () => {
91
+ expect(buildHierarchyNodes(graphData, 'node1')).toEqual([['node1'], ['node2'], ['node3', 'node4']]);
92
+ expect(buildHierarchyNodes(graphData, 'node1', 1)).toEqual([['node1'], ['node2'], ['node3'], ['node4']]);
93
+ });
94
+
95
+ it('should build correct nodes hierarchy if there are a lot of nodes on the same lvl', () => {
96
+ expect(buildHierarchyNodes(graphDataWithLargeNumberOfNodesOnSameLvl, 'node1')).toEqual([
97
+ ['node1'],
98
+ ['node2', 'node3', 'node4', 'node5', 'node6', 'node7', 'node8', 'node9', 'node10', 'node11'],
99
+ ['node12']
100
+ ]);
101
+ expect(buildHierarchyNodes(graphDataWithLargeNumberOfNodesOnSameLvl, 'node1', 3)).toEqual([
102
+ ['node1'],
103
+ ['node2', 'node3', 'node4'],
104
+ ['node5', 'node6', 'node7'],
105
+ ['node8', 'node9', 'node10'],
106
+ ['node11', 'node12']
107
+ ]);
108
+ expect(buildHierarchyNodes(graphDataWithLargeNumberOfNodesOnSameLvl, 'node1', 5)).toEqual([
109
+ ['node1'],
110
+ ['node2', 'node3', 'node4', 'node5', 'node6'],
111
+ ['node7', 'node8', 'node9', 'node10', 'node11'],
112
+ ['node12']
113
+ ]);
114
+ });
115
+
116
+ it('should build correct nodes hierarchy if all nodes have parent', () => {
117
+ const expectedNodesHierarchy = [['node1'], ['node2'], ['node3']];
118
+ const hierarchy = buildHierarchyNodes(nodesWithLoop, 'node1');
119
+ expect(hierarchy).toEqual(expectedNodesHierarchy);
120
+ });
121
+
122
+ it('should build correct nodes hierarchy if there are only 10 of nodes on the same lvl', () => {
123
+ const expectedNodesHierarchy = [
124
+ ['node1'],
125
+ ['node2', 'node3', 'node4', 'node5', 'node6', 'node7', 'node8', 'node9', 'node10', 'node11']
126
+ ];
127
+ const hierarchy = buildHierarchyNodes(tenNodesOnTheSameLvl, 'node1');
128
+ expect(hierarchy).toEqual(expectedNodesHierarchy);
129
+ });
130
+ });