Skip to content

Commit d6419e8

Browse files
committed
feat: support compare sankey chart
1 parent 7c0bf81 commit d6419e8

File tree

9 files changed

+477
-3
lines changed

9 files changed

+477
-3
lines changed

packages/vchart-extension/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
"@visactor/vrender-kits": "1.0.9",
2626
"@visactor/vrender-components": "1.0.9",
2727
"@visactor/vrender-animate": "1.0.9",
28-
"@visactor/vutils": "~1.0.6",
29-
"@visactor/vdataset": "~1.0.6",
30-
"@visactor/vlayouts": "~1.0.6",
28+
"@visactor/vutils": "~1.0.9",
29+
"@visactor/vdataset": "~1.0.9",
30+
"@visactor/vlayouts": "~1.0.9",
3131
"@visactor/vchart": "workspace:2.0.1"
3232
},
3333
"devDependencies": {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import type { DataView } from '@visactor/vdataset';
2+
import { field, isFunction } from '@visactor/vutils';
3+
import { computeNodeValues, computeHierarchicNodeLinks } from '@visactor/vlayouts/es/sankey/hierarchy';
4+
import type { SankeyNodeElement } from '@visactor/vlayouts/es/sankey/interface';
5+
6+
export interface ICompareSankeyLayoutOpt {
7+
rawData: () => DataView;
8+
nodeKey: string;
9+
subNodeGap: number;
10+
}
11+
12+
export const compareSankeySubData = (data: Array<DataView>, opt: ICompareSankeyLayoutOpt) => {
13+
const viewData = data[0] as DataView;
14+
if (!viewData.latestData?.length) {
15+
return {};
16+
}
17+
// 读取参数
18+
const rawDataTree = opt.rawData().latestData[0];
19+
const subNodeGap = opt.subNodeGap;
20+
const keyFunc = isFunction(opt.nodeKey) ? opt.nodeKey : opt.nodeKey ? field(opt.nodeKey as string) : null;
21+
22+
const subNodeMap: { [key: string]: any } = {};
23+
rawDataTree.subNode.forEach((sunGroup: any) => {
24+
subNodeMap[sunGroup.type] = computeHierarchicNodeLinks(sunGroup.nodes, keyFunc);
25+
computeNodeValues(subNodeMap[sunGroup.type].nodes);
26+
});
27+
const subCount = Object.keys(subNodeMap).length;
28+
29+
const subNodes: any[] = [];
30+
viewData.latestData[0].nodes.forEach((n: SankeyNodeElement) => {
31+
let path: (string | number)[] = [];
32+
if (n.targetLinks.length) {
33+
const link = n.targetLinks[0];
34+
path = [...link.parents];
35+
}
36+
path.push(n.key);
37+
// 根据path获取sub的节点
38+
// 当前已使用比例
39+
let currentY = n.y0;
40+
const totalSize = n.y1 - n.y0 - (subCount - 1) * subNodeGap;
41+
const totalValue = n.value;
42+
rawDataTree.subNode.forEach((sunGroup: any) => {
43+
const subNode = (subNodeMap[sunGroup.type].nodes as SankeyNodeElement[]).find(subN => subN.key === n.key);
44+
if (!subNode) {
45+
return;
46+
}
47+
const percent = subNode.value / totalValue;
48+
subNode.x0 = n.x0;
49+
subNode.x1 = n.x1;
50+
subNode.y0 = currentY;
51+
subNode.y1 = currentY + totalSize * percent;
52+
// @ts-ignore
53+
subNode.type = sunGroup.type;
54+
// @ts-ignore
55+
subNode.sourceNode = n;
56+
currentY += totalSize * percent + subNodeGap;
57+
subNodes.push(subNode);
58+
});
59+
});
60+
return subNodeMap;
61+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { DataView } from '@visactor/vdataset';
2+
3+
export const compareSankeySubNodes = (data: Array<DataView>) => {
4+
const viewData = data[0] as DataView;
5+
if (!viewData.latestData) {
6+
return [];
7+
}
8+
const subData = Object.keys(viewData.latestData);
9+
if (!subData.length) {
10+
return {};
11+
}
12+
const subNodes: any[] = [];
13+
subData.forEach(key => {
14+
subNodes.push(...viewData.latestData[key].nodes);
15+
});
16+
return [{ nodes: subNodes }];
17+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { ICompareSankeyChartSpecBase } from './interface';
2+
import { SankeyChartSpecTransformer } from '@visactor/vchart';
3+
4+
export class CompareSankeyChartSpecTransformer extends SankeyChartSpecTransformer<ICompareSankeyChartSpecBase> {
5+
transformSpec(spec: ICompareSankeyChartSpecBase): void {
6+
super.transformSpec(spec);
7+
}
8+
9+
_getDefaultSeriesSpec(spec: ICompareSankeyChartSpecBase) {
10+
const seriesSpec = super._getDefaultSeriesSpec(spec);
11+
(seriesSpec as ICompareSankeyChartSpecBase).subNodeGap = spec.subNodeGap;
12+
(seriesSpec as ICompareSankeyChartSpecBase).compareNodeColor = spec.compareNodeColor;
13+
(seriesSpec as ICompareSankeyChartSpecBase).compareLinkColor = spec.compareLinkColor;
14+
(seriesSpec as ICompareSankeyChartSpecBase).activeLink = spec.activeLink;
15+
return seriesSpec;
16+
}
17+
}

0 commit comments

Comments
 (0)