vccs 0.3.0 → 0.4.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.
- package/README.md +4 -0
- package/dist/cartesian/axis/XAxis.d.ts +3 -3
- package/dist/cartesian/cartesian-axis/CartesianAxis.d.ts +5 -5
- package/dist/chart/RechartsWrapper.d.ts +3 -3
- package/dist/chart/Sankey.d.ts +327 -0
- package/dist/chart/SunburstChart.d.ts +249 -0
- package/dist/chart/generateCategoricalChart.d.ts +2 -2
- package/dist/chart/index.d.ts +2 -0
- package/dist/chart/sankeyUtils.d.ts +36 -0
- package/dist/chart/sunburstUtils.d.ts +34 -0
- package/dist/components/Text.d.ts +16 -1
- package/dist/components/Tooltip.d.ts +46 -2
- package/dist/es/cartesian/axis/XAxis.mjs +2 -2
- package/dist/es/cartesian/axis/YAxis.mjs +1 -1
- package/dist/es/cartesian/cartesian-axis/CartesianAxis.mjs +2 -3
- package/dist/es/cartesian/cartesian-grid/const.mjs +6 -0
- package/dist/es/cartesian/utils/get-ticks.mjs +3 -2
- package/dist/es/chart/RechartsWrapper.mjs +8 -5
- package/dist/es/chart/Sankey.mjs +332 -0
- package/dist/es/chart/SunburstChart.mjs +229 -0
- package/dist/es/chart/generateCategoricalChart.mjs +5 -1
- package/dist/es/chart/sankeyUtils.mjs +28 -0
- package/dist/es/chart/sunburstUtils.mjs +67 -0
- package/dist/es/components/Text.vue_vue_type_script_setup_true_lang.mjs +3 -3
- package/dist/es/components/Tooltip.mjs +29 -13
- package/dist/es/container/ResponsiveContainer.vue_vue_type_script_setup_true_lang.mjs +15 -2
- package/dist/es/index.mjs +5 -2
- package/dist/es/polar/pie/Pie.mjs +1 -1
- package/dist/es/polar/pie/type.mjs +7 -0
- package/dist/es/polar/radar/Radar.mjs +9 -1
- package/dist/es/polar/radial-bar/RadialBar.mjs +1 -0
- package/dist/es/polar/radial-bar/type.mjs +7 -0
- package/dist/es/utils/Global.mjs +18 -0
- package/dist/es/utils/attrs.mjs +2 -2
- package/dist/es/utils/validate.mjs +1 -2
- package/dist/hooks/publicHooks.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/polar/pie/type.d.ts +8 -0
- package/dist/polar/radar/Radar.d.ts +16 -0
- package/dist/polar/radial-bar/type.d.ts +8 -0
- package/dist/state/selectors/combiners/combineActiveLabel.d.ts +1 -1
- package/dist/state/selectors/selectors.d.ts +1 -1
- package/dist/state/selectors/tooltipSelectors.d.ts +1 -1
- package/dist/types/common.d.ts +1 -1
- package/dist/utils/Global.d.ts +9 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/validate.d.ts +0 -1
- package/package.json +3 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SankeyLink, SankeyNode } from 'd3-sankey';
|
|
2
|
+
export interface SankeyInputNode {
|
|
3
|
+
name?: string;
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
export interface SankeyInputLink {
|
|
7
|
+
source: number | string;
|
|
8
|
+
target: number | string;
|
|
9
|
+
value: number;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
export type SankeyLayoutNode = SankeyNode<SankeyInputNode, SankeyInputLink>;
|
|
13
|
+
export type SankeyLayoutLink = SankeyLink<SankeyInputNode, SankeyInputLink>;
|
|
14
|
+
export interface ComputeSankeyLayoutArgs {
|
|
15
|
+
data: {
|
|
16
|
+
nodes: SankeyInputNode[];
|
|
17
|
+
links: SankeyInputLink[];
|
|
18
|
+
};
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
nodePadding: number;
|
|
22
|
+
nodeWidth: number;
|
|
23
|
+
iterations: number;
|
|
24
|
+
margin: {
|
|
25
|
+
top: number;
|
|
26
|
+
right: number;
|
|
27
|
+
bottom: number;
|
|
28
|
+
left: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface ComputeSankeyLayoutResult {
|
|
32
|
+
nodes: SankeyLayoutNode[];
|
|
33
|
+
links: SankeyLayoutLink[];
|
|
34
|
+
}
|
|
35
|
+
export declare function computeSankeyLayout(args: ComputeSankeyLayoutArgs): ComputeSankeyLayoutResult;
|
|
36
|
+
export declare const linkPathGenerator: (link: SankeyLayoutLink) => string | null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface SunburstData {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
name: string;
|
|
4
|
+
value?: number;
|
|
5
|
+
fill?: string;
|
|
6
|
+
children?: SunburstData[];
|
|
7
|
+
}
|
|
8
|
+
export interface SunburstLayoutNode {
|
|
9
|
+
cx: number;
|
|
10
|
+
cy: number;
|
|
11
|
+
innerRadius: number;
|
|
12
|
+
outerRadius: number;
|
|
13
|
+
startAngle: number;
|
|
14
|
+
endAngle: number;
|
|
15
|
+
depth: number;
|
|
16
|
+
name: string;
|
|
17
|
+
value: number;
|
|
18
|
+
fill?: string;
|
|
19
|
+
payload: SunburstData;
|
|
20
|
+
tooltipIndex: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SunburstLayoutOptions {
|
|
23
|
+
data: SunburstData;
|
|
24
|
+
cx: number;
|
|
25
|
+
cy: number;
|
|
26
|
+
innerRadius: number;
|
|
27
|
+
outerRadius: number;
|
|
28
|
+
startAngle: number;
|
|
29
|
+
endAngle: number;
|
|
30
|
+
dataKey: string;
|
|
31
|
+
ringPadding?: number;
|
|
32
|
+
padding?: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function computeSunburstLayout(options: SunburstLayoutOptions): SunburstLayoutNode[];
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
declare
|
|
1
|
+
declare function __VLS_template(): {
|
|
2
|
+
attrs: Partial<{}>;
|
|
3
|
+
slots: {
|
|
4
|
+
default?(_: {}): any;
|
|
5
|
+
};
|
|
6
|
+
refs: {};
|
|
7
|
+
rootEl: SVGTextElement;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
10
|
+
declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
|
|
2
11
|
x: {
|
|
3
12
|
type: (NumberConstructor | StringConstructor)[];
|
|
4
13
|
default: number;
|
|
@@ -146,4 +155,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
146
155
|
breakAll: boolean;
|
|
147
156
|
maxLines: number;
|
|
148
157
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, SVGTextElement>;
|
|
158
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
149
159
|
export default _default;
|
|
160
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
161
|
+
new (): {
|
|
162
|
+
$slots: S;
|
|
163
|
+
};
|
|
164
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { PropType, SlotsType } from 'vue';
|
|
2
2
|
import { TooltipIndex, TooltipPayload, TooltipPayloadEntry } from '../state/tooltipSlice';
|
|
3
3
|
import { AxisId } from '../state/cartesianAxisSlice';
|
|
4
|
-
import { ChartCoordinate, Coordinate } from '../types';
|
|
4
|
+
import { ChartCoordinate, Coordinate, LayoutType } from '../types';
|
|
5
5
|
import { TooltipTrigger } from '../types/tooltip';
|
|
6
|
+
import { Point } from '../shape';
|
|
6
7
|
export type ContentType = any | ((props: TooltipContentProps) => any);
|
|
7
8
|
export type TooltipContentProps = {
|
|
8
9
|
label?: string | number;
|
|
@@ -16,6 +17,49 @@ type AllowInDimension = {
|
|
|
16
17
|
x: boolean;
|
|
17
18
|
y: boolean;
|
|
18
19
|
};
|
|
20
|
+
type CursorSlotCommon = {
|
|
21
|
+
class: string | string[];
|
|
22
|
+
style: {
|
|
23
|
+
pointerEvents: 'none';
|
|
24
|
+
};
|
|
25
|
+
/** Chart area offset — same fields spread by Recharts: left, top, width, height */
|
|
26
|
+
left: number;
|
|
27
|
+
top: number;
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
payload: TooltipPayload;
|
|
31
|
+
/** Active tooltip index — named payloadIndex to match Recharts */
|
|
32
|
+
payloadIndex: string | undefined;
|
|
33
|
+
[key: string]: any;
|
|
34
|
+
};
|
|
35
|
+
export type CrossCursorSlotProps = CursorSlotCommon & {
|
|
36
|
+
stroke: string;
|
|
37
|
+
fill: string;
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
};
|
|
41
|
+
export type RectangleCursorSlotProps = CursorSlotCommon & {
|
|
42
|
+
stroke: string;
|
|
43
|
+
fill: string;
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
};
|
|
47
|
+
export type SectorCursorSlotProps = CursorSlotCommon & {
|
|
48
|
+
stroke: string;
|
|
49
|
+
fill: string;
|
|
50
|
+
cx: number;
|
|
51
|
+
cy: number;
|
|
52
|
+
startAngle: number;
|
|
53
|
+
endAngle: number;
|
|
54
|
+
innerRadius: number;
|
|
55
|
+
outerRadius: number;
|
|
56
|
+
};
|
|
57
|
+
export type CurveCursorSlotProps = CursorSlotCommon & {
|
|
58
|
+
stroke: string;
|
|
59
|
+
layout: LayoutType;
|
|
60
|
+
points: ReadonlyArray<Point>;
|
|
61
|
+
};
|
|
62
|
+
export type CursorSlotProps = CrossCursorSlotProps | RectangleCursorSlotProps | SectorCursorSlotProps | CurveCursorSlotProps;
|
|
19
63
|
type UniqueFunc<T> = (entry: T) => unknown;
|
|
20
64
|
export type UniqueOption<T> = boolean | UniqueFunc<T>;
|
|
21
65
|
export declare function getUniqPayload<T>(payload: ReadonlyArray<T>, option: UniqueOption<T>, defaultUniqBy: UniqueFunc<T>): ReadonlyArray<T>;
|
|
@@ -244,7 +288,7 @@ export declare const Tooltip: import('vue').DefineComponent<import('vue').Extrac
|
|
|
244
288
|
readonly filterNull: boolean;
|
|
245
289
|
}, SlotsType<{
|
|
246
290
|
content?: (props: TooltipContentProps) => any;
|
|
247
|
-
cursor?: (props:
|
|
291
|
+
cursor?: (props: CursorSlotProps) => any;
|
|
248
292
|
default?: () => any;
|
|
249
293
|
}>, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
250
294
|
export default Tooltip;
|
|
@@ -37,7 +37,7 @@ var XAxisImpl = /* @__PURE__ */ defineComponent({
|
|
|
37
37
|
"width": axisSize.value?.width,
|
|
38
38
|
"height": axisSize.value?.height,
|
|
39
39
|
"ticks": cartesianTickItems.value,
|
|
40
|
-
"class": ["v-charts-xAxis xAxis"
|
|
40
|
+
"class": ["v-charts-xAxis xAxis"]
|
|
41
41
|
}), { default: () => [slots.tick ? { tick: slots.tick } : void 0] });
|
|
42
42
|
};
|
|
43
43
|
}
|
|
@@ -178,7 +178,7 @@ var XAxis = /* @__PURE__ */ defineComponent({
|
|
|
178
178
|
},
|
|
179
179
|
domain: { type: Array },
|
|
180
180
|
axisLine: {
|
|
181
|
-
type: Boolean,
|
|
181
|
+
type: [Boolean, Object],
|
|
182
182
|
default: true
|
|
183
183
|
},
|
|
184
184
|
ticks: { type: Array },
|
|
@@ -31,7 +31,7 @@ var YAxisImpl = /* @__PURE__ */ defineComponent({
|
|
|
31
31
|
"width": axisSize.value?.width,
|
|
32
32
|
"height": axisSize.value?.height,
|
|
33
33
|
"ticks": cartesianTickItems.value,
|
|
34
|
-
"class": ["v-charts-yAxis yAxis"
|
|
34
|
+
"class": ["v-charts-yAxis yAxis"]
|
|
35
35
|
}), null);
|
|
36
36
|
};
|
|
37
37
|
}
|
|
@@ -92,8 +92,7 @@ var CartesianAxis = /* @__PURE__ */ defineComponent({
|
|
|
92
92
|
default: "#666"
|
|
93
93
|
}
|
|
94
94
|
},
|
|
95
|
-
|
|
96
|
-
setup(props, { attrs, slots }) {
|
|
95
|
+
setup(props, { slots }) {
|
|
97
96
|
const state = reactive({
|
|
98
97
|
fontSize: "",
|
|
99
98
|
letterSpacing: ""
|
|
@@ -269,7 +268,7 @@ var CartesianAxis = /* @__PURE__ */ defineComponent({
|
|
|
269
268
|
if (hide) return null;
|
|
270
269
|
if (width != null && width <= 0 || height != null && height <= 0) return null;
|
|
271
270
|
return createVNode(Layer, {
|
|
272
|
-
"class": ["v-charts-cartesian-axis"
|
|
271
|
+
"class": ["v-charts-cartesian-axis"],
|
|
273
272
|
"ref": (ref) => {
|
|
274
273
|
const elm = ref?.$el;
|
|
275
274
|
if (elm) {
|
|
@@ -266,11 +266,17 @@ var SVGElementPropKeys = [
|
|
|
266
266
|
"stroke",
|
|
267
267
|
"stroke-dasharray",
|
|
268
268
|
"strokeDashoffset",
|
|
269
|
+
"stroke-dashoffset",
|
|
269
270
|
"strokeLinecap",
|
|
271
|
+
"stroke-linecap",
|
|
270
272
|
"strokeLinejoin",
|
|
273
|
+
"stroke-linejoin",
|
|
271
274
|
"strokeMiterlimit",
|
|
275
|
+
"stroke-miterlimit",
|
|
272
276
|
"strokeOpacity",
|
|
277
|
+
"stroke-opacity",
|
|
273
278
|
"strokeWidth",
|
|
279
|
+
"stroke-width",
|
|
274
280
|
"surfaceScale",
|
|
275
281
|
"systemLanguage",
|
|
276
282
|
"tableValues",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { isNumber,
|
|
1
|
+
import { isNumber, isVisible } from "../../utils/validate.mjs";
|
|
2
|
+
import { Global } from "../../utils/Global.mjs";
|
|
2
3
|
import { mathSign } from "../../utils/data.mjs";
|
|
3
4
|
import { getStringSize } from "../../utils/attrs.mjs";
|
|
4
5
|
import { getAngledTickWidth, getNumberIntervalTicks, getTickBoundaries } from "../../utils/tick.mjs";
|
|
@@ -87,7 +88,7 @@ function getTicksStart(sign, boundaries, getTickSize, ticks, minTickGap, preserv
|
|
|
87
88
|
function getTicks(props, fontSize, letterSpacing) {
|
|
88
89
|
const { tick, ticks, viewBox, minTickGap, orientation, interval, tickFormatter, unit, angle } = props;
|
|
89
90
|
if (!ticks || !ticks.length || !tick) return [];
|
|
90
|
-
if (isNumber(interval) || isSsr) return getNumberIntervalTicks(ticks, isNumber(interval) ? interval : 0) ?? [];
|
|
91
|
+
if (isNumber(interval) || Global.isSsr) return getNumberIntervalTicks(ticks, isNumber(interval) ? interval : 0) ?? [];
|
|
91
92
|
let candidates = [];
|
|
92
93
|
const sizeKey = orientation === "top" || orientation === "bottom" ? "width" : "height";
|
|
93
94
|
const unitSize = unit && sizeKey === "width" ? getStringSize(unit, {
|
|
@@ -31,7 +31,11 @@ var RechartsWrapper = /* @__PURE__ */ defineComponent({
|
|
|
31
31
|
onTouchEnd: { type: Function },
|
|
32
32
|
onTouchMove: { type: Function },
|
|
33
33
|
onTouchStart: { type: Function },
|
|
34
|
-
style: { type:
|
|
34
|
+
style: { type: [
|
|
35
|
+
String,
|
|
36
|
+
Object,
|
|
37
|
+
Array
|
|
38
|
+
] },
|
|
35
39
|
width: {
|
|
36
40
|
type: Number,
|
|
37
41
|
required: true
|
|
@@ -132,13 +136,12 @@ var RechartsWrapper = /* @__PURE__ */ defineComponent({
|
|
|
132
136
|
};
|
|
133
137
|
return () => createVNode("div", {
|
|
134
138
|
"class": ["v-charts-wrapper", props.class],
|
|
135
|
-
"style": {
|
|
139
|
+
"style": [{
|
|
136
140
|
position: "relative",
|
|
137
141
|
cursor: "default",
|
|
138
142
|
width: `${props.width}px`,
|
|
139
|
-
height: `${props.height}px
|
|
140
|
-
|
|
141
|
-
},
|
|
143
|
+
height: `${props.height}px`
|
|
144
|
+
}, props.style],
|
|
142
145
|
"role": "application",
|
|
143
146
|
"onClick": myOnClick,
|
|
144
147
|
"onContextmenu": myOnContextMenu,
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { addTooltipEntrySettings, mouseLeaveItem, removeTooltipEntrySettings, setActiveClickItemIndex, setActiveMouseOverItemIndex } from "../state/tooltipSlice.mjs";
|
|
2
|
+
import { useAppDispatch } from "../state/hooks.mjs";
|
|
3
|
+
import { Layer } from "../container/Layer.mjs";
|
|
4
|
+
import { Animate } from "../animation/Animate.mjs";
|
|
5
|
+
import { createRechartsStore } from "../state/store.mjs";
|
|
6
|
+
import { RechartsWrapper } from "./RechartsWrapper.mjs";
|
|
7
|
+
import Surface from "../container/Surface.mjs";
|
|
8
|
+
import { computeSankeyLayout, linkPathGenerator } from "./sankeyUtils.mjs";
|
|
9
|
+
import { Fragment, computed, createVNode, defineComponent, watchEffect } from "vue";
|
|
10
|
+
import { provideStore } from "@reduxjs/vue-redux";
|
|
11
|
+
import { get } from "lodash-es";
|
|
12
|
+
//#region src/chart/Sankey.tsx
|
|
13
|
+
var sankeyPayloadSearcher = (data, activeIndex) => {
|
|
14
|
+
if (!data || activeIndex == null) return void 0;
|
|
15
|
+
return get(data, activeIndex);
|
|
16
|
+
};
|
|
17
|
+
var sankeyOptions = {
|
|
18
|
+
chartName: "Sankey",
|
|
19
|
+
defaultTooltipEventType: "item",
|
|
20
|
+
validateTooltipEventTypes: ["item"],
|
|
21
|
+
tooltipPayloadSearcher: sankeyPayloadSearcher,
|
|
22
|
+
eventEmitter: void 0
|
|
23
|
+
};
|
|
24
|
+
var SankeyVueProps = {
|
|
25
|
+
data: {
|
|
26
|
+
type: Object,
|
|
27
|
+
required: true
|
|
28
|
+
},
|
|
29
|
+
width: {
|
|
30
|
+
type: Number,
|
|
31
|
+
required: true
|
|
32
|
+
},
|
|
33
|
+
height: {
|
|
34
|
+
type: Number,
|
|
35
|
+
required: true
|
|
36
|
+
},
|
|
37
|
+
nameKey: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: "name"
|
|
40
|
+
},
|
|
41
|
+
dataKey: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: "value"
|
|
44
|
+
},
|
|
45
|
+
nodePadding: {
|
|
46
|
+
type: Number,
|
|
47
|
+
default: 10
|
|
48
|
+
},
|
|
49
|
+
nodeWidth: {
|
|
50
|
+
type: Number,
|
|
51
|
+
default: 10
|
|
52
|
+
},
|
|
53
|
+
iterations: {
|
|
54
|
+
type: Number,
|
|
55
|
+
default: 32
|
|
56
|
+
},
|
|
57
|
+
margin: {
|
|
58
|
+
type: Object,
|
|
59
|
+
default: () => ({
|
|
60
|
+
top: 5,
|
|
61
|
+
right: 5,
|
|
62
|
+
bottom: 5,
|
|
63
|
+
left: 5
|
|
64
|
+
})
|
|
65
|
+
},
|
|
66
|
+
nodeFill: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: "#0088fe"
|
|
69
|
+
},
|
|
70
|
+
nodeStroke: {
|
|
71
|
+
type: String,
|
|
72
|
+
default: "#fff"
|
|
73
|
+
},
|
|
74
|
+
linkFill: {
|
|
75
|
+
type: String,
|
|
76
|
+
default: "#0088fe"
|
|
77
|
+
},
|
|
78
|
+
linkStroke: {
|
|
79
|
+
type: String,
|
|
80
|
+
default: "none"
|
|
81
|
+
},
|
|
82
|
+
isAnimationActive: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: true
|
|
85
|
+
},
|
|
86
|
+
transition: {
|
|
87
|
+
type: Object,
|
|
88
|
+
default: () => ({
|
|
89
|
+
duration: .8,
|
|
90
|
+
ease: "easeOut"
|
|
91
|
+
})
|
|
92
|
+
},
|
|
93
|
+
onClick: {
|
|
94
|
+
type: Function,
|
|
95
|
+
default: void 0
|
|
96
|
+
},
|
|
97
|
+
onMouseEnter: {
|
|
98
|
+
type: Function,
|
|
99
|
+
default: void 0
|
|
100
|
+
},
|
|
101
|
+
onMouseLeave: {
|
|
102
|
+
type: Function,
|
|
103
|
+
default: void 0
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var SankeyInner = /* @__PURE__ */ defineComponent({
|
|
107
|
+
name: "SankeyInner",
|
|
108
|
+
props: SankeyVueProps,
|
|
109
|
+
slots: Object,
|
|
110
|
+
setup(props, { slots }) {
|
|
111
|
+
const dispatch = useAppDispatch();
|
|
112
|
+
const layout = computed(() => {
|
|
113
|
+
const m = props.margin;
|
|
114
|
+
return computeSankeyLayout({
|
|
115
|
+
data: props.data,
|
|
116
|
+
width: props.width,
|
|
117
|
+
height: props.height,
|
|
118
|
+
nodePadding: props.nodePadding,
|
|
119
|
+
nodeWidth: props.nodeWidth,
|
|
120
|
+
iterations: props.iterations,
|
|
121
|
+
margin: {
|
|
122
|
+
top: m.top ?? 5,
|
|
123
|
+
right: m.right ?? 5,
|
|
124
|
+
bottom: m.bottom ?? 5,
|
|
125
|
+
left: m.left ?? 5
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
const payloadTree = computed(() => {
|
|
130
|
+
return {
|
|
131
|
+
nodes: layout.value.nodes.map((n, i) => ({
|
|
132
|
+
tooltipIndex: `nodes[${i}]`,
|
|
133
|
+
name: n[props.nameKey] ?? n.name,
|
|
134
|
+
value: n.value,
|
|
135
|
+
x0: n.x0,
|
|
136
|
+
x1: n.x1,
|
|
137
|
+
y0: n.y0,
|
|
138
|
+
y1: n.y1
|
|
139
|
+
})),
|
|
140
|
+
links: layout.value.links.map((l, i) => {
|
|
141
|
+
const src = l.source;
|
|
142
|
+
const tgt = l.target;
|
|
143
|
+
return {
|
|
144
|
+
tooltipIndex: `links[${i}]`,
|
|
145
|
+
name: `${src[props.nameKey] ?? src.name} - ${tgt[props.nameKey] ?? tgt.name}`,
|
|
146
|
+
value: l.value
|
|
147
|
+
};
|
|
148
|
+
})
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
watchEffect((onCleanup) => {
|
|
152
|
+
const settings = {
|
|
153
|
+
dataDefinedOnItem: payloadTree.value,
|
|
154
|
+
positions: void 0,
|
|
155
|
+
settings: {
|
|
156
|
+
stroke: props.nodeStroke,
|
|
157
|
+
strokeWidth: void 0,
|
|
158
|
+
fill: props.nodeFill,
|
|
159
|
+
dataKey: props.dataKey,
|
|
160
|
+
nameKey: props.nameKey,
|
|
161
|
+
name: void 0,
|
|
162
|
+
hide: false,
|
|
163
|
+
type: void 0,
|
|
164
|
+
color: props.nodeFill,
|
|
165
|
+
unit: ""
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
dispatch(addTooltipEntrySettings(settings));
|
|
169
|
+
onCleanup(() => {
|
|
170
|
+
dispatch(removeTooltipEntrySettings(settings));
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
function handleNodeMouseEnter(node, index, e) {
|
|
174
|
+
const coord = {
|
|
175
|
+
x: ((node.x0 ?? 0) + (node.x1 ?? 0)) / 2,
|
|
176
|
+
y: ((node.y0 ?? 0) + (node.y1 ?? 0)) / 2
|
|
177
|
+
};
|
|
178
|
+
dispatch(setActiveMouseOverItemIndex({
|
|
179
|
+
activeIndex: `nodes[${index}]`,
|
|
180
|
+
activeDataKey: props.dataKey,
|
|
181
|
+
activeCoordinate: coord
|
|
182
|
+
}));
|
|
183
|
+
props.onMouseEnter?.(node, "node", e);
|
|
184
|
+
}
|
|
185
|
+
function handleLinkMouseEnter(link, index, e) {
|
|
186
|
+
const sx = link.source.x1 ?? 0;
|
|
187
|
+
const tx = link.target.x0 ?? 0;
|
|
188
|
+
const sy = link.y0 ?? 0;
|
|
189
|
+
const ty = link.y1 ?? 0;
|
|
190
|
+
const coord = {
|
|
191
|
+
x: (sx + tx) / 2,
|
|
192
|
+
y: (sy + ty) / 2
|
|
193
|
+
};
|
|
194
|
+
dispatch(setActiveMouseOverItemIndex({
|
|
195
|
+
activeIndex: `links[${index}]`,
|
|
196
|
+
activeDataKey: props.dataKey,
|
|
197
|
+
activeCoordinate: coord
|
|
198
|
+
}));
|
|
199
|
+
props.onMouseEnter?.(link, "link", e);
|
|
200
|
+
}
|
|
201
|
+
function handleMouseLeave(item, type, e) {
|
|
202
|
+
dispatch(mouseLeaveItem());
|
|
203
|
+
props.onMouseLeave?.(item, type, e);
|
|
204
|
+
}
|
|
205
|
+
function handleNodeClick(node, index, e) {
|
|
206
|
+
const coord = {
|
|
207
|
+
x: ((node.x0 ?? 0) + (node.x1 ?? 0)) / 2,
|
|
208
|
+
y: ((node.y0 ?? 0) + (node.y1 ?? 0)) / 2
|
|
209
|
+
};
|
|
210
|
+
dispatch(setActiveClickItemIndex({
|
|
211
|
+
activeIndex: `nodes[${index}]`,
|
|
212
|
+
activeDataKey: props.dataKey,
|
|
213
|
+
activeCoordinate: coord
|
|
214
|
+
}));
|
|
215
|
+
props.onClick?.(node, "node", e);
|
|
216
|
+
}
|
|
217
|
+
function handleLinkClick(link, index, e) {
|
|
218
|
+
const coord = {
|
|
219
|
+
x: ((link.source.x1 ?? 0) + (link.target.x0 ?? 0)) / 2,
|
|
220
|
+
y: ((link.y0 ?? 0) + (link.y1 ?? 0)) / 2
|
|
221
|
+
};
|
|
222
|
+
dispatch(setActiveClickItemIndex({
|
|
223
|
+
activeIndex: `links[${index}]`,
|
|
224
|
+
activeDataKey: props.dataKey,
|
|
225
|
+
activeCoordinate: coord
|
|
226
|
+
}));
|
|
227
|
+
props.onClick?.(link, "link", e);
|
|
228
|
+
}
|
|
229
|
+
function renderNode(node, index, opacity) {
|
|
230
|
+
const x = node.x0 ?? 0;
|
|
231
|
+
const y = node.y0 ?? 0;
|
|
232
|
+
const width = (node.x1 ?? 0) - x;
|
|
233
|
+
const height = (node.y1 ?? 0) - y;
|
|
234
|
+
if (slots.node) {
|
|
235
|
+
const slotProps = {
|
|
236
|
+
payload: node,
|
|
237
|
+
index,
|
|
238
|
+
x,
|
|
239
|
+
y,
|
|
240
|
+
width,
|
|
241
|
+
height,
|
|
242
|
+
fill: props.nodeFill
|
|
243
|
+
};
|
|
244
|
+
return createVNode("g", {
|
|
245
|
+
"key": `node-${index}`,
|
|
246
|
+
"class": "v-charts-sankey-node",
|
|
247
|
+
"style": { opacity },
|
|
248
|
+
"onClick": (e) => handleNodeClick(node, index, e),
|
|
249
|
+
"onMouseenter": (e) => handleNodeMouseEnter(node, index, e),
|
|
250
|
+
"onMouseleave": (e) => handleMouseLeave(node, "node", e)
|
|
251
|
+
}, [slots.node(slotProps)]);
|
|
252
|
+
}
|
|
253
|
+
return createVNode("g", {
|
|
254
|
+
"key": `node-${index}`,
|
|
255
|
+
"class": "v-charts-sankey-node",
|
|
256
|
+
"style": { opacity },
|
|
257
|
+
"onClick": (e) => handleNodeClick(node, index, e),
|
|
258
|
+
"onMouseenter": (e) => handleNodeMouseEnter(node, index, e),
|
|
259
|
+
"onMouseleave": (e) => handleMouseLeave(node, "node", e)
|
|
260
|
+
}, [createVNode("rect", {
|
|
261
|
+
"x": x,
|
|
262
|
+
"y": y,
|
|
263
|
+
"width": width,
|
|
264
|
+
"height": height,
|
|
265
|
+
"fill": props.nodeFill,
|
|
266
|
+
"stroke": props.nodeStroke
|
|
267
|
+
}, null)]);
|
|
268
|
+
}
|
|
269
|
+
function renderLink(link, index, opacity) {
|
|
270
|
+
const d = linkPathGenerator(link) ?? "";
|
|
271
|
+
const linkWidth = link.width ?? 0;
|
|
272
|
+
if (slots.link) {
|
|
273
|
+
const slotProps = {
|
|
274
|
+
payload: link,
|
|
275
|
+
index,
|
|
276
|
+
d,
|
|
277
|
+
linkWidth,
|
|
278
|
+
fill: props.linkFill
|
|
279
|
+
};
|
|
280
|
+
return createVNode("g", {
|
|
281
|
+
"key": `link-${index}`,
|
|
282
|
+
"style": { opacity },
|
|
283
|
+
"onClick": (e) => handleLinkClick(link, index, e),
|
|
284
|
+
"onMouseenter": (e) => handleLinkMouseEnter(link, index, e),
|
|
285
|
+
"onMouseleave": (e) => handleMouseLeave(link, "link", e)
|
|
286
|
+
}, [slots.link(slotProps)]);
|
|
287
|
+
}
|
|
288
|
+
return createVNode("path", {
|
|
289
|
+
"key": `link-${index}`,
|
|
290
|
+
"class": "v-charts-sankey-link",
|
|
291
|
+
"d": d,
|
|
292
|
+
"fill": "none",
|
|
293
|
+
"stroke": props.linkStroke === "none" ? props.linkFill : props.linkStroke,
|
|
294
|
+
"stroke-width": linkWidth,
|
|
295
|
+
"stroke-opacity": .2,
|
|
296
|
+
"style": { opacity },
|
|
297
|
+
"onClick": (e) => handleLinkClick(link, index, e),
|
|
298
|
+
"onMouseenter": (e) => handleLinkMouseEnter(link, index, e),
|
|
299
|
+
"onMouseleave": (e) => handleMouseLeave(link, "link", e)
|
|
300
|
+
}, null);
|
|
301
|
+
}
|
|
302
|
+
return () => createVNode(Surface, {
|
|
303
|
+
"width": props.width,
|
|
304
|
+
"height": props.height
|
|
305
|
+
}, { default: () => [createVNode(Layer, { "class": "v-charts-sankey" }, { default: () => [createVNode(Animate, {
|
|
306
|
+
"isActive": props.isAnimationActive,
|
|
307
|
+
"from": 0,
|
|
308
|
+
"to": 1,
|
|
309
|
+
"transition": props.transition
|
|
310
|
+
}, { default: (progress) => createVNode(Fragment, null, [createVNode("g", { "class": "v-charts-sankey-links" }, [layout.value.links.map((link, i) => renderLink(link, i, progress))]), createVNode("g", { "class": "v-charts-sankey-nodes" }, [layout.value.nodes.map((node, i) => renderNode(node, i, progress))])]) })] })] });
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
var Sankey = /* @__PURE__ */ defineComponent({
|
|
314
|
+
name: "Sankey",
|
|
315
|
+
props: SankeyVueProps,
|
|
316
|
+
slots: Object,
|
|
317
|
+
setup(props, { slots }) {
|
|
318
|
+
provideStore({ store: createRechartsStore({ options: sankeyOptions }, "Sankey") });
|
|
319
|
+
return () => {
|
|
320
|
+
if (!props.data || !props.data.nodes || props.data.nodes.length === 0) return null;
|
|
321
|
+
return createVNode(RechartsWrapper, {
|
|
322
|
+
"width": props.width,
|
|
323
|
+
"height": props.height
|
|
324
|
+
}, { default: () => [createVNode(SankeyInner, props, {
|
|
325
|
+
node: slots.node,
|
|
326
|
+
link: slots.link
|
|
327
|
+
}), slots.default?.()] });
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
//#endregion
|
|
332
|
+
export { Sankey, SankeyVueProps, sankeyPayloadSearcher };
|