@truedat/core 8.8.4 → 8.8.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/core",
3
- "version": "8.8.4",
3
+ "version": "8.8.6",
4
4
  "description": "Truedat Web Core",
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -54,7 +54,7 @@
54
54
  "@testing-library/jest-dom": "^6.6.3",
55
55
  "@testing-library/react": "^16.3.0",
56
56
  "@testing-library/user-event": "^14.6.1",
57
- "@truedat/test": "8.8.4",
57
+ "@truedat/test": "8.8.6",
58
58
  "identity-obj-proxy": "^3.0.0",
59
59
  "jest": "^29.7.0",
60
60
  "redux-saga-test-plan": "^4.0.6"
@@ -95,5 +95,5 @@
95
95
  "swr": "^2.3.3",
96
96
  "turndown": "^7.2.2"
97
97
  },
98
- "gitHead": "eebd748d118e628959e9d935e9ba9baaebe0a8e1"
98
+ "gitHead": "608a876aa3b04799eb2e1bb5b5f071a81e2b509e"
99
99
  }
@@ -20,7 +20,7 @@ import {
20
20
  import ELK from "elkjs/lib/elk.bundled.js";
21
21
  import ConceptNode from "./graph/ConceptNode";
22
22
  import ColoredEdge from "./graph/ColoredEdge";
23
- import { getTargetSlotOffset } from "./graph/edgeLayout";
23
+
24
24
  import "@xyflow/react/dist/style.css";
25
25
 
26
26
  const nodeTypes = { concept: ConceptNode };
@@ -29,20 +29,13 @@ const edgeTypes = { colored: ColoredEdge };
29
29
  const elk = new ELK();
30
30
  const DEFAULT_NODE_WIDTH = 130;
31
31
  const DEFAULT_NODE_HEIGHT = 44;
32
- const TRANSLATE_EXTENT_PADDING = 400;
33
- const DEFAULT_GRAPH_HEIGHT = "640px";
32
+ const DEFAULT_GRAPH_HEIGHT = "70vh";
34
33
  const EXPANDED_GRAPH_HEIGHT = "82vh";
35
- const DEFAULT_MIN_ZOOM = 0.1;
36
- const DEFAULT_MAX_ZOOM = 2;
37
- const FIT_VIEW_PADDING = 0.08;
38
- const DEFAULT_TRANSLATE_EXTENT = [
39
- [-800, -600],
40
- [800, 600],
41
- ];
34
+ const DEFAULT_MIN_ZOOM = 0.01;
35
+ const DEFAULT_MAX_ZOOM = 0.8;
36
+ const FIT_VIEW_PADDING = 0.2;
42
37
  const CONTROL_TOOLTIP_DELAY = 120;
43
38
  const DEFAULT_EDGE_STROKE = "var(--td-graph-edge-stroke, #b0b8c8)";
44
- const MIN_NODE_VERTICAL_GAP = 12;
45
-
46
39
  const getIncomingEdgeGroupKey = (edge, stroke) =>
47
40
  `${edge.target}::${stroke || DEFAULT_EDGE_STROKE}`;
48
41
 
@@ -158,124 +151,6 @@ const orderNodesByRelationGroup = (nodes = [], edges = [], rootNodeId) => {
158
151
  });
159
152
  };
160
153
 
161
- const getNodeHeight = (node) =>
162
- node.height ?? node.measured?.height ?? DEFAULT_NODE_HEIGHT;
163
-
164
- const getNodeCenterY = (node) =>
165
- (node.y ?? node.position?.y ?? 0) + getNodeHeight(node) / 2;
166
-
167
- const alignNodesToConnectionPoints = (nodes = [], edges = [], rootNodeId) => {
168
- if (!rootNodeId) return nodes;
169
-
170
- const levels = buildSignedNodeLevels(nodes, edges, rootNodeId);
171
-
172
- if (!levels.size) return nodes;
173
-
174
- const nodeById = new Map(nodes.map((node) => [node.id, node]));
175
- const desiredCentersById = new Map();
176
-
177
- nodes.forEach((node) => {
178
- const rank = levels.get(node.id) || 0;
179
-
180
- if (rank === 0) return;
181
-
182
- const preferredEdges = edges.filter((edge) => {
183
- if (rank < 0 && edge.source === node.id) {
184
- const neighbourRank = levels.get(edge.target);
185
- return (
186
- neighbourRank !== undefined &&
187
- Math.abs(neighbourRank) < Math.abs(rank)
188
- );
189
- }
190
-
191
- if (rank > 0 && edge.target === node.id) {
192
- const neighbourRank = levels.get(edge.source);
193
- return (
194
- neighbourRank !== undefined &&
195
- Math.abs(neighbourRank) < Math.abs(rank)
196
- );
197
- }
198
-
199
- return false;
200
- });
201
-
202
- if (preferredEdges.length !== 1) return;
203
-
204
- const edge = preferredEdges[0];
205
- const slotOffset = getTargetSlotOffset(
206
- edge.data?.targetSlotIndex,
207
- edge.data?.targetSlotCount,
208
- );
209
-
210
- if (rank < 0) {
211
- const targetNode = nodeById.get(edge.target);
212
-
213
- if (!targetNode) return;
214
-
215
- desiredCentersById.set(node.id, getNodeCenterY(targetNode) + slotOffset);
216
- return;
217
- }
218
-
219
- const sourceNode = nodeById.get(edge.source);
220
-
221
- if (!sourceNode) return;
222
-
223
- desiredCentersById.set(node.id, getNodeCenterY(sourceNode) - slotOffset);
224
- });
225
-
226
- const nodesByRank = new Map();
227
-
228
- nodes.forEach((node) => {
229
- const rank = levels.get(node.id) || 0;
230
- const bucket = nodesByRank.get(rank) || [];
231
-
232
- bucket.push(node);
233
- nodesByRank.set(rank, bucket);
234
- });
235
-
236
- const alignedNodes = new Map();
237
-
238
- nodesByRank.forEach((rankNodes) => {
239
- const orderedNodes = [...rankNodes].sort((nodeA, nodeB) => {
240
- const desiredA =
241
- desiredCentersById.get(nodeA.id) ?? getNodeCenterY(nodeA);
242
- const desiredB =
243
- desiredCentersById.get(nodeB.id) ?? getNodeCenterY(nodeB);
244
-
245
- if (desiredA !== desiredB) return desiredA - desiredB;
246
-
247
- return (
248
- (nodeA.y ?? nodeA.position?.y ?? 0) -
249
- (nodeB.y ?? nodeB.position?.y ?? 0)
250
- );
251
- });
252
-
253
- // eslint-disable-next-line fp/no-let
254
- let previousBottom = Number.NEGATIVE_INFINITY;
255
-
256
- orderedNodes.forEach((node) => {
257
- const height = getNodeHeight(node);
258
- const desiredCenter =
259
- desiredCentersById.get(node.id) ?? getNodeCenterY(node);
260
- const desiredTop = desiredCenter - height / 2;
261
- const nextTop = Math.max(
262
- desiredTop,
263
- previousBottom + MIN_NODE_VERTICAL_GAP,
264
- );
265
-
266
- // eslint-disable-next-line fp/no-mutation
267
- previousBottom = nextTop + height;
268
- alignedNodes.set(node.id, {
269
- ...node,
270
- y: nextTop,
271
- position: { ...(node.position || {}), x: node.x, y: nextTop },
272
- });
273
- });
274
- });
275
-
276
- return nodes.map((node) => alignedNodes.get(node.id) || node);
277
- };
278
-
279
154
  export const getMinZoomForDiagram = (
280
155
  nodes = [],
281
156
  viewportWidth,
@@ -317,44 +192,6 @@ GraphControlTooltip.propTypes = {
317
192
  children: PropTypes.node.isRequired,
318
193
  };
319
194
 
320
- const getTranslateExtent = (nodes = []) => {
321
- if (!nodes.length) return DEFAULT_TRANSLATE_EXTENT;
322
-
323
- const bounds = nodes.reduce(
324
- (acc, node) => {
325
- const width = node.measured?.width ?? node.width ?? DEFAULT_NODE_WIDTH;
326
- const height =
327
- node.measured?.height ?? node.height ?? DEFAULT_NODE_HEIGHT;
328
- const x = node.position?.x ?? node.x ?? 0;
329
- const y = node.position?.y ?? node.y ?? 0;
330
-
331
- return {
332
- minX: Math.min(acc.minX, x),
333
- minY: Math.min(acc.minY, y),
334
- maxX: Math.max(acc.maxX, x + width),
335
- maxY: Math.max(acc.maxY, y + height),
336
- };
337
- },
338
- {
339
- minX: Number.POSITIVE_INFINITY,
340
- minY: Number.POSITIVE_INFINITY,
341
- maxX: Number.NEGATIVE_INFINITY,
342
- maxY: Number.NEGATIVE_INFINITY,
343
- },
344
- );
345
-
346
- return [
347
- [
348
- bounds.minX - TRANSLATE_EXTENT_PADDING,
349
- bounds.minY - TRANSLATE_EXTENT_PADDING,
350
- ],
351
- [
352
- bounds.maxX + TRANSLATE_EXTENT_PADDING,
353
- bounds.maxY + TRANSLATE_EXTENT_PADDING,
354
- ],
355
- ];
356
- };
357
-
358
195
  const LayoutFlow = ({
359
196
  initialNodes,
360
197
  initialEdges,
@@ -445,7 +282,6 @@ const LayoutFlow = ({
445
282
  }, [initialEdges]);
446
283
  const [nodes, setNodes, onNodesChange] = useNodesState(parsedNodes);
447
284
  const [edges, setEdges, onEdgesChange] = useEdgesState(parsedEdges);
448
- const translateExtent = useMemo(() => getTranslateExtent(nodes), [nodes]);
449
285
  const layoutInput = useMemo(() => {
450
286
  const safeNodes = orderNodesByRelationGroup(
451
287
  parsedNodes.filter((node) => node && node.id),
@@ -509,8 +345,11 @@ const LayoutFlow = ({
509
345
  "elk.direction": "RIGHT",
510
346
  "elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
511
347
  "elk.layered.crossingMinimization.forceNodeModelOrder": true,
512
- "elk.layered.spacing.nodeNodeBetweenLayers": 60,
513
- "elk.spacing.nodeNode": 40,
348
+ "elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX",
349
+ "elk.layered.spacing.nodeNodeBetweenLayers": 50,
350
+ "elk.spacing.nodeNode": 32,
351
+ "elk.spacing.edgeNodeBetweenLayers": 8,
352
+ "elk.spacing.edgeEdgeBetweenLayers": 8,
514
353
  };
515
354
  const graph = {
516
355
  id: "root",
@@ -532,14 +371,8 @@ const LayoutFlow = ({
532
371
  node.position = { x: node.x, y: node.y };
533
372
  });
534
373
 
535
- const alignedChildren = alignNodesToConnectionPoints(
536
- children,
537
- edgesToLayout,
538
- rootNodeId,
539
- );
540
-
541
- setNodes(alignedChildren);
542
- scheduleFitView(alignedChildren, edgesToLayout);
374
+ setNodes(children);
375
+ scheduleFitView(children, edgesToLayout);
543
376
  })
544
377
  .catch(() => {
545
378
  if (currentLayoutRunId !== layoutRunId.current) return;
@@ -590,11 +423,10 @@ const LayoutFlow = ({
590
423
  onInit={onInit}
591
424
  onNodeClick={onNodeClick}
592
425
  nodesConnectable={false}
593
- translateExtent={translateExtent}
594
426
  nodeTypes={nodeTypes}
595
427
  edgeTypes={edgeTypes}
596
428
  attributionPosition="bottom-left"
597
- minZoom={minZoom}
429
+ minZoom={DEFAULT_MIN_ZOOM}
598
430
  >
599
431
  <Background
600
432
  variant={BackgroundVariant.Dots}
@@ -71,9 +71,9 @@ describe("<Graph />", () => {
71
71
  { x: 0, y: 0, width: 100, height: 50 },
72
72
  600,
73
73
  300,
74
- 0.1,
75
- 2,
76
- 0.08,
74
+ 0.01,
75
+ 0.8,
76
+ 0.2,
77
77
  );
78
78
  });
79
79
 
@@ -28,7 +28,10 @@
28
28
 
29
29
  &:hover {
30
30
  border-color: var(--td-graph-node-hover-border, #2f3443);
31
- box-shadow: var(--td-graph-node-hover-shadow, 0 6px 18px rgba(21, 26, 36, 0.14));
31
+ box-shadow: var(
32
+ --td-graph-node-hover-shadow,
33
+ 0 6px 18px rgba(21, 26, 36, 0.14)
34
+ );
32
35
  }
33
36
 
34
37
  &--active {
@@ -36,7 +39,10 @@
36
39
  color: var(--td-graph-node-active-text, #ffffff);
37
40
  font-weight: 600;
38
41
  border-color: var(--td-graph-node-active-bg, #ed5c17);
39
- box-shadow: var(--td-graph-node-active-shadow, 0 4px 14px rgba(237, 92, 23, 0.35));
42
+ box-shadow: var(
43
+ --td-graph-node-active-shadow,
44
+ 0 4px 14px rgba(237, 92, 23, 0.35)
45
+ );
40
46
  cursor: default;
41
47
 
42
48
  .react-flow__handle {
@@ -1,3 +1,3 @@
1
1
  .CardGroupTitle {
2
- margin-top: 1rem;
2
+ margin-top: 1rem;
3
3
  }
@@ -45,7 +45,7 @@
45
45
  border-radius: 0 0 0.28571429rem 0.28571429rem;
46
46
  padding: 8px 10px;
47
47
 
48
- >div {
48
+ > div {
49
49
  flex: 1;
50
50
  min-height: 0;
51
51
  display: flex;
@@ -74,9 +74,7 @@
74
74
  }
75
75
 
76
76
  .ui[class*="top attached"].menu {
77
- margin-top: 0
77
+ margin-top: 0;
78
78
  }
79
79
  }
80
-
81
-
82
- }
80
+ }
@@ -10,7 +10,9 @@
10
10
  border-radius: 4px;
11
11
  padding: 0.5em 2.1em 0.5em 1em;
12
12
  min-height: 2.71428571em;
13
- transition: border-color 0.1s ease, box-shadow 0.1s ease;
13
+ transition:
14
+ border-color 0.1s ease,
15
+ box-shadow 0.1s ease;
14
16
 
15
17
  .dropdown.icon {
16
18
  position: absolute;
@@ -17,4 +17,4 @@ div.selectedFilters > a.resetFilters {
17
17
  }
18
18
  .ui.form .fields.date.filter .ui.input input[name="range"] {
19
19
  width: 16em;
20
- }
20
+ }
@@ -1,5 +1,5 @@
1
1
  .td-graph-container {
2
- height: var(--td-graph-container-height, 640px);
2
+ height: var(--td-graph-container-height, 760px);
3
3
 
4
4
  .react-flow {
5
5
  background: var(--td-graph-bg, #f7f8fa);