Skip to content

Commit 6635a0d

Browse files
authored
Merge pull request #245 from VisActor/feat/export-sankey-makeHierarchicNodes
Feat/export sankey make hierarchic nodes
2 parents 96f94b3 + e7bbc19 commit 6635a0d

File tree

3 files changed

+69
-45
lines changed

3 files changed

+69
-45
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "feat: export function makeHierarchicNodes about sankey\n\n",
5+
"type": "none",
6+
"packageName": "@visactor/vlayouts"
7+
}
8+
],
9+
"packageName": "@visactor/vlayouts",
10+
"email": "[email protected]"
11+
}

packages/vlayouts/src/sankey/hierarchy.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { isNil } from '@visactor/vutils';
2-
import type { HierarchyNodeDatum } from './interface';
1+
import { isNil, toValidNumber } from '@visactor/vutils';
2+
3+
import type { HierarchyNodeDatum, SankeyLinkDatum, SankeyLinkElement, SankeyNodeElement } from './interface';
34

45
export const calculateNodeValue = (subTree: HierarchyNodeDatum[]) => {
56
let sum = 0;
@@ -17,3 +18,56 @@ export const calculateNodeValue = (subTree: HierarchyNodeDatum[]) => {
1718

1819
return sum;
1920
};
21+
22+
export function makeHierarchicNodes(
23+
originalNodes: HierarchyNodeDatum[],
24+
nodeKeyFunc: (node: HierarchyNodeDatum) => string,
25+
nodes: SankeyNodeElement[] = [],
26+
nodeMap: Record<string | number, SankeyNodeElement> = {},
27+
originalLinks?: (SankeyLinkDatum & { parents?: SankeyNodeElement[] })[]
28+
) {
29+
calculateNodeValue(originalNodes);
30+
31+
const doSubTree = (subTree: HierarchyNodeDatum[], depth: number, parents?: SankeyNodeElement[]) => {
32+
subTree.forEach((node, index) => {
33+
const nodeKey = nodeKeyFunc
34+
? nodeKeyFunc(node)
35+
: parents
36+
? `${parents[parents.length - 1].key}-${index}`
37+
: `${depth}-${index}`;
38+
const nodeValue: number = (isNil(node.value) ? 0 : toValidNumber(node.value)) as number;
39+
40+
if (nodeMap[nodeKey]) {
41+
nodeMap[nodeKey].value = undefined;
42+
} else {
43+
const nodeElement: SankeyNodeElement = {
44+
depth,
45+
datum: node,
46+
index: index,
47+
key: nodeKey,
48+
value: nodeValue,
49+
sourceLinks: [] as SankeyLinkElement[],
50+
targetLinks: [] as SankeyLinkElement[]
51+
};
52+
53+
nodeMap[nodeKey] = nodeElement;
54+
nodes.push(nodeElement);
55+
}
56+
if (parents && originalLinks) {
57+
originalLinks.push({
58+
source: parents[parents.length - 1].key,
59+
target: nodeKey,
60+
value: nodeValue,
61+
parents
62+
});
63+
}
64+
65+
if (node.children && node.children.length) {
66+
doSubTree(node.children, depth + 1, parents ? parents.concat([nodeMap[nodeKey]]) : [nodeMap[nodeKey]]);
67+
}
68+
});
69+
};
70+
71+
doSubTree(originalNodes, 0, null);
72+
return nodes;
73+
}

packages/vlayouts/src/sankey/layout.ts

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
pickWithout,
1313
toValidNumber
1414
} from '@visactor/vutils';
15-
import { calculateNodeValue } from './hierarchy';
15+
import { makeHierarchicNodes } from './hierarchy';
1616
import type {
1717
SankeyData,
1818
SankeyOptions,
@@ -249,49 +249,8 @@ export class SankeyLayout {
249249
const linkMap: Record<string | number, SankeyLinkElement> = {};
250250
const originalLinks: (SankeyLinkDatum & { parents?: SankeyNodeElement[] })[] = [];
251251

252-
calculateNodeValue(originalNodes);
252+
makeHierarchicNodes(originalNodes, this._getNodeKey, nodes, nodeMap, originalLinks);
253253

254-
const doSubTree = (subTree: HierarchyNodeDatum[], depth: number, parents?: SankeyNodeElement[]) => {
255-
subTree.forEach((node, index) => {
256-
const nodeKey = this._getNodeKey
257-
? this._getNodeKey(node)
258-
: parents
259-
? `${parents[parents.length - 1].key}-${index}`
260-
: `${depth}-${index}`;
261-
const nodeValue = isNil(node.value) ? 0 : toValidNumber(node.value);
262-
263-
if (nodeMap[nodeKey]) {
264-
nodeMap[nodeKey].value = undefined;
265-
} else {
266-
const nodeElement: SankeyNodeElement = {
267-
depth,
268-
datum: node,
269-
index: index,
270-
key: nodeKey,
271-
value: nodeValue,
272-
sourceLinks: [] as SankeyLinkElement[],
273-
targetLinks: [] as SankeyLinkElement[]
274-
};
275-
276-
nodeMap[nodeKey] = nodeElement;
277-
nodes.push(nodeElement);
278-
}
279-
if (parents) {
280-
originalLinks.push({
281-
source: parents[parents.length - 1].key,
282-
target: nodeKey,
283-
value: nodeValue,
284-
parents
285-
});
286-
}
287-
288-
if (node.children && node.children.length) {
289-
doSubTree(node.children, depth + 1, parents ? parents.concat([nodeMap[nodeKey]]) : [nodeMap[nodeKey]]);
290-
}
291-
});
292-
};
293-
294-
doSubTree(originalNodes, 0, null);
295254
originalLinks.forEach((link, index) => {
296255
const key = `${link.source}-${link.target}`;
297256
const linkDatum = pickWithout(link, ['parents']);

0 commit comments

Comments
 (0)