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,229 @@
|
|
|
1
|
+
import { polarToCartesian } from "../utils/polar.mjs";
|
|
2
|
+
import { addTooltipEntrySettings, mouseLeaveItem, removeTooltipEntrySettings, setActiveClickItemIndex, setActiveMouseOverItemIndex } from "../state/tooltipSlice.mjs";
|
|
3
|
+
import { useAppDispatch } from "../state/hooks.mjs";
|
|
4
|
+
import { Layer } from "../container/Layer.mjs";
|
|
5
|
+
import { createRechartsStore } from "../state/store.mjs";
|
|
6
|
+
import { RechartsWrapper } from "./RechartsWrapper.mjs";
|
|
7
|
+
import Surface from "../container/Surface.mjs";
|
|
8
|
+
import { Sector } from "../shape/Sector.mjs";
|
|
9
|
+
import { computeSunburstLayout } from "./sunburstUtils.mjs";
|
|
10
|
+
import { computed, createVNode, defineComponent, isVNode, watchEffect } from "vue";
|
|
11
|
+
import { provideStore } from "@reduxjs/vue-redux";
|
|
12
|
+
import { get } from "lodash-es";
|
|
13
|
+
//#region src/chart/SunburstChart.tsx
|
|
14
|
+
function _isSlot(s) {
|
|
15
|
+
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
16
|
+
}
|
|
17
|
+
var sunburstPayloadSearcher = (data, activeIndex) => {
|
|
18
|
+
if (!data || !activeIndex) return void 0;
|
|
19
|
+
return get(data, activeIndex);
|
|
20
|
+
};
|
|
21
|
+
var sunburstOptions = {
|
|
22
|
+
chartName: "SunburstChart",
|
|
23
|
+
defaultTooltipEventType: "item",
|
|
24
|
+
validateTooltipEventTypes: ["item"],
|
|
25
|
+
tooltipPayloadSearcher: sunburstPayloadSearcher,
|
|
26
|
+
eventEmitter: void 0
|
|
27
|
+
};
|
|
28
|
+
var SunburstChartVueProps = {
|
|
29
|
+
data: {
|
|
30
|
+
type: Object,
|
|
31
|
+
required: true
|
|
32
|
+
},
|
|
33
|
+
dataKey: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: "value"
|
|
36
|
+
},
|
|
37
|
+
nameKey: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: "name"
|
|
40
|
+
},
|
|
41
|
+
width: {
|
|
42
|
+
type: Number,
|
|
43
|
+
required: true
|
|
44
|
+
},
|
|
45
|
+
height: {
|
|
46
|
+
type: Number,
|
|
47
|
+
required: true
|
|
48
|
+
},
|
|
49
|
+
cx: {
|
|
50
|
+
type: Number,
|
|
51
|
+
default: void 0
|
|
52
|
+
},
|
|
53
|
+
cy: {
|
|
54
|
+
type: Number,
|
|
55
|
+
default: void 0
|
|
56
|
+
},
|
|
57
|
+
innerRadius: {
|
|
58
|
+
type: Number,
|
|
59
|
+
default: 50
|
|
60
|
+
},
|
|
61
|
+
outerRadius: {
|
|
62
|
+
type: Number,
|
|
63
|
+
default: void 0
|
|
64
|
+
},
|
|
65
|
+
startAngle: {
|
|
66
|
+
type: Number,
|
|
67
|
+
default: 0
|
|
68
|
+
},
|
|
69
|
+
endAngle: {
|
|
70
|
+
type: Number,
|
|
71
|
+
default: 360
|
|
72
|
+
},
|
|
73
|
+
ringPadding: {
|
|
74
|
+
type: Number,
|
|
75
|
+
default: 2
|
|
76
|
+
},
|
|
77
|
+
padding: {
|
|
78
|
+
type: Number,
|
|
79
|
+
default: 2
|
|
80
|
+
},
|
|
81
|
+
fill: {
|
|
82
|
+
type: String,
|
|
83
|
+
default: "#333"
|
|
84
|
+
},
|
|
85
|
+
stroke: {
|
|
86
|
+
type: String,
|
|
87
|
+
default: "#fff"
|
|
88
|
+
},
|
|
89
|
+
onClick: {
|
|
90
|
+
type: Function,
|
|
91
|
+
default: void 0
|
|
92
|
+
},
|
|
93
|
+
onMouseEnter: {
|
|
94
|
+
type: Function,
|
|
95
|
+
default: void 0
|
|
96
|
+
},
|
|
97
|
+
onMouseLeave: {
|
|
98
|
+
type: Function,
|
|
99
|
+
default: void 0
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var SunburstInner = /* @__PURE__ */ defineComponent({
|
|
103
|
+
name: "SunburstInner",
|
|
104
|
+
props: SunburstChartVueProps,
|
|
105
|
+
slots: Object,
|
|
106
|
+
setup(props, { slots }) {
|
|
107
|
+
const dispatch = useAppDispatch();
|
|
108
|
+
const resolvedCx = computed(() => props.cx ?? props.width / 2);
|
|
109
|
+
const resolvedCy = computed(() => props.cy ?? props.height / 2);
|
|
110
|
+
const resolvedOuterRadius = computed(() => props.outerRadius ?? Math.min(props.width, props.height) / 2);
|
|
111
|
+
const nodes = computed(() => computeSunburstLayout({
|
|
112
|
+
data: props.data,
|
|
113
|
+
cx: resolvedCx.value,
|
|
114
|
+
cy: resolvedCy.value,
|
|
115
|
+
innerRadius: props.innerRadius,
|
|
116
|
+
outerRadius: resolvedOuterRadius.value,
|
|
117
|
+
startAngle: props.startAngle,
|
|
118
|
+
endAngle: props.endAngle,
|
|
119
|
+
dataKey: props.dataKey,
|
|
120
|
+
ringPadding: props.ringPadding,
|
|
121
|
+
padding: props.padding
|
|
122
|
+
}));
|
|
123
|
+
watchEffect((onCleanup) => {
|
|
124
|
+
const tooltipEntrySettings = {
|
|
125
|
+
dataDefinedOnItem: props.data,
|
|
126
|
+
positions: void 0,
|
|
127
|
+
settings: {
|
|
128
|
+
stroke: props.stroke,
|
|
129
|
+
strokeWidth: void 0,
|
|
130
|
+
fill: props.fill,
|
|
131
|
+
dataKey: props.dataKey,
|
|
132
|
+
nameKey: props.nameKey,
|
|
133
|
+
name: void 0,
|
|
134
|
+
hide: false,
|
|
135
|
+
type: void 0,
|
|
136
|
+
color: props.fill,
|
|
137
|
+
unit: ""
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
dispatch(addTooltipEntrySettings(tooltipEntrySettings));
|
|
141
|
+
onCleanup(() => {
|
|
142
|
+
dispatch(removeTooltipEntrySettings(tooltipEntrySettings));
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
function getNodeFill(node) {
|
|
146
|
+
if (node.fill) return node.fill;
|
|
147
|
+
return props.fill;
|
|
148
|
+
}
|
|
149
|
+
function getTooltipCoordinate(node) {
|
|
150
|
+
const midAngle = (node.startAngle + node.endAngle) / 2;
|
|
151
|
+
const midRadius = (node.innerRadius + node.outerRadius) / 2;
|
|
152
|
+
return polarToCartesian(node.cx, node.cy, midRadius, midAngle);
|
|
153
|
+
}
|
|
154
|
+
function handleMouseEnter(node, e) {
|
|
155
|
+
dispatch(setActiveMouseOverItemIndex({
|
|
156
|
+
activeIndex: node.tooltipIndex,
|
|
157
|
+
activeDataKey: props.dataKey,
|
|
158
|
+
activeCoordinate: getTooltipCoordinate(node)
|
|
159
|
+
}));
|
|
160
|
+
props.onMouseEnter?.(node.payload, e);
|
|
161
|
+
}
|
|
162
|
+
function handleMouseLeave(node, e) {
|
|
163
|
+
dispatch(mouseLeaveItem());
|
|
164
|
+
props.onMouseLeave?.(node.payload, e);
|
|
165
|
+
}
|
|
166
|
+
function handleClick(node, e) {
|
|
167
|
+
dispatch(setActiveClickItemIndex({
|
|
168
|
+
activeIndex: node.tooltipIndex,
|
|
169
|
+
activeDataKey: props.dataKey,
|
|
170
|
+
activeCoordinate: getTooltipCoordinate(node)
|
|
171
|
+
}));
|
|
172
|
+
props.onClick?.(node.payload, e);
|
|
173
|
+
}
|
|
174
|
+
function renderSector(node, index) {
|
|
175
|
+
const nodeFill = getNodeFill(node);
|
|
176
|
+
const slotProps = {
|
|
177
|
+
...node,
|
|
178
|
+
index
|
|
179
|
+
};
|
|
180
|
+
if (slots.content) return createVNode("g", {
|
|
181
|
+
"key": `sector-${index}`,
|
|
182
|
+
"class": "v-charts-sunburst-sector",
|
|
183
|
+
"onClick": (e) => handleClick(node, e),
|
|
184
|
+
"onMouseenter": (e) => handleMouseEnter(node, e),
|
|
185
|
+
"onMouseleave": (e) => handleMouseLeave(node, e)
|
|
186
|
+
}, [slots.content(slotProps)]);
|
|
187
|
+
return createVNode("g", {
|
|
188
|
+
"key": `sector-${index}`,
|
|
189
|
+
"class": "v-charts-sunburst-sector",
|
|
190
|
+
"onClick": (e) => handleClick(node, e),
|
|
191
|
+
"onMouseenter": (e) => handleMouseEnter(node, e),
|
|
192
|
+
"onMouseleave": (e) => handleMouseLeave(node, e)
|
|
193
|
+
}, [createVNode(Sector, {
|
|
194
|
+
"cx": node.cx,
|
|
195
|
+
"cy": node.cy,
|
|
196
|
+
"innerRadius": node.innerRadius,
|
|
197
|
+
"outerRadius": node.outerRadius,
|
|
198
|
+
"startAngle": node.startAngle,
|
|
199
|
+
"endAngle": node.endAngle,
|
|
200
|
+
"fill": nodeFill,
|
|
201
|
+
"stroke": props.stroke
|
|
202
|
+
}, null)]);
|
|
203
|
+
}
|
|
204
|
+
return () => {
|
|
205
|
+
let _slot;
|
|
206
|
+
return createVNode(Surface, {
|
|
207
|
+
"width": props.width,
|
|
208
|
+
"height": props.height
|
|
209
|
+
}, { default: () => [createVNode(Layer, { "class": "v-charts-sunburst" }, _isSlot(_slot = nodes.value.map((node, index) => renderSector(node, index))) ? _slot : { default: () => [_slot] })] });
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
var SunburstChart = /* @__PURE__ */ defineComponent({
|
|
214
|
+
name: "SunburstChart",
|
|
215
|
+
props: SunburstChartVueProps,
|
|
216
|
+
slots: Object,
|
|
217
|
+
setup(props, { slots }) {
|
|
218
|
+
provideStore({ store: createRechartsStore({ options: sunburstOptions }, "SunburstChart") });
|
|
219
|
+
return () => {
|
|
220
|
+
if (!props.data?.children || props.data.children.length === 0) return null;
|
|
221
|
+
return createVNode(RechartsWrapper, {
|
|
222
|
+
"width": props.width,
|
|
223
|
+
"height": props.height
|
|
224
|
+
}, { default: () => [createVNode(SunburstInner, props, { content: slots.content }), slots.default?.()] });
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
//#endregion
|
|
229
|
+
export { SunburstChart, SunburstChartVueProps, sunburstPayloadSearcher };
|
|
@@ -73,7 +73,11 @@ var CategoricalProps = {
|
|
|
73
73
|
default: "none"
|
|
74
74
|
},
|
|
75
75
|
startAngle: { type: Number },
|
|
76
|
-
style: { type:
|
|
76
|
+
style: { type: [
|
|
77
|
+
String,
|
|
78
|
+
Object,
|
|
79
|
+
Array
|
|
80
|
+
] },
|
|
77
81
|
syncId: { type: [Number, String] },
|
|
78
82
|
syncMethod: {
|
|
79
83
|
type: [String, Function],
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { toRaw } from "vue";
|
|
2
|
+
import { sankey, sankeyLinkHorizontal } from "d3-sankey";
|
|
3
|
+
//#region src/chart/sankeyUtils.ts
|
|
4
|
+
function computeSankeyLayout(args) {
|
|
5
|
+
const { data, width, height, nodePadding, nodeWidth, iterations, margin } = args;
|
|
6
|
+
const cloned = {
|
|
7
|
+
nodes: data.nodes.map((n) => ({ ...toRaw(n) })),
|
|
8
|
+
links: data.links.map((l) => ({ ...toRaw(l) }))
|
|
9
|
+
};
|
|
10
|
+
const result = sankey().nodeWidth(nodeWidth).nodePadding(nodePadding).extent([[margin.left, margin.top], [Math.max(margin.left + 1, width - margin.right), Math.max(margin.top + 1, height - margin.bottom)]]).iterations(iterations)(cloned);
|
|
11
|
+
const x0Min = margin.left;
|
|
12
|
+
const x1Max = Math.max(margin.left + 1, width - margin.right);
|
|
13
|
+
const y0Min = margin.top;
|
|
14
|
+
const y1Max = Math.max(margin.top + 1, height - margin.bottom);
|
|
15
|
+
for (const n of result.nodes) {
|
|
16
|
+
if (n.x0 != null && n.x0 < x0Min) n.x0 = x0Min;
|
|
17
|
+
if (n.x1 != null && n.x1 > x1Max) n.x1 = x1Max;
|
|
18
|
+
if (n.y0 != null && n.y0 < y0Min) n.y0 = y0Min;
|
|
19
|
+
if (n.y1 != null && n.y1 > y1Max) n.y1 = y1Max;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
nodes: result.nodes,
|
|
23
|
+
links: result.links
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
var linkPathGenerator = sankeyLinkHorizontal();
|
|
27
|
+
//#endregion
|
|
28
|
+
export { computeSankeyLayout, linkPathGenerator };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { hierarchy, partition } from "d3-hierarchy";
|
|
2
|
+
//#region src/chart/sunburstUtils.ts
|
|
3
|
+
/**
|
|
4
|
+
* Record each node's original child index before sorting mutates the order.
|
|
5
|
+
* This ensures tooltipIndex paths point into the original data.children order.
|
|
6
|
+
*/
|
|
7
|
+
function recordOriginalIndices(node) {
|
|
8
|
+
if (node.children) node.children.forEach((child, i) => {
|
|
9
|
+
child._originalIndex = i;
|
|
10
|
+
recordOriginalIndices(child);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build a hierarchical tooltip index path string for a d3 hierarchy node.
|
|
15
|
+
* Uses _originalIndex (pre-sort) so the path matches the original data structure.
|
|
16
|
+
* E.g. 'children[0].children[1]'
|
|
17
|
+
*/
|
|
18
|
+
function buildTooltipIndex(node) {
|
|
19
|
+
const parts = [];
|
|
20
|
+
let current = node;
|
|
21
|
+
while (current.parent) {
|
|
22
|
+
const idx = current._originalIndex ?? current.parent.children.indexOf(current);
|
|
23
|
+
parts.unshift(`children[${idx}]`);
|
|
24
|
+
current = current.parent;
|
|
25
|
+
}
|
|
26
|
+
return parts.join(".");
|
|
27
|
+
}
|
|
28
|
+
function computeSunburstLayout(options) {
|
|
29
|
+
const { data, cx, cy, innerRadius, outerRadius, startAngle, endAngle, dataKey, ringPadding = 0, padding = 0 } = options;
|
|
30
|
+
if (!data.children || data.children.length === 0) return [];
|
|
31
|
+
const root = hierarchy(data).sum((d) => {
|
|
32
|
+
if (d.children && d.children.length > 0) return 0;
|
|
33
|
+
const val = d[dataKey];
|
|
34
|
+
return typeof val === "number" && val > 0 ? val : 0;
|
|
35
|
+
});
|
|
36
|
+
recordOriginalIndices(root);
|
|
37
|
+
root.sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
|
|
38
|
+
partition().size([1, 1])(root);
|
|
39
|
+
const angleRange = endAngle - startAngle;
|
|
40
|
+
const radiusRange = outerRadius - innerRadius;
|
|
41
|
+
const nodes = [];
|
|
42
|
+
root.descendants().forEach((d) => {
|
|
43
|
+
if (d.depth === 0) return;
|
|
44
|
+
const nodeStartAngle = startAngle + d.x0 * angleRange + padding / 2;
|
|
45
|
+
const nodeEndAngle = startAngle + d.x1 * angleRange - padding / 2;
|
|
46
|
+
const nodeInnerRadius = innerRadius + d.y0 * radiusRange + ringPadding / 2;
|
|
47
|
+
const nodeOuterRadius = innerRadius + d.y1 * radiusRange - ringPadding / 2;
|
|
48
|
+
if (nodeEndAngle <= nodeStartAngle || nodeOuterRadius <= nodeInnerRadius) return;
|
|
49
|
+
nodes.push({
|
|
50
|
+
cx,
|
|
51
|
+
cy,
|
|
52
|
+
innerRadius: nodeInnerRadius,
|
|
53
|
+
outerRadius: nodeOuterRadius,
|
|
54
|
+
startAngle: nodeStartAngle,
|
|
55
|
+
endAngle: nodeEndAngle,
|
|
56
|
+
depth: d.depth,
|
|
57
|
+
name: d.data.name,
|
|
58
|
+
value: d.value ?? 0,
|
|
59
|
+
fill: d.data.fill,
|
|
60
|
+
payload: d.data,
|
|
61
|
+
tooltipIndex: buildTooltipIndex(d)
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
return nodes;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { computeSunburstLayout };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getStringSize } from "../utils/attrs.mjs";
|
|
2
2
|
import { reduceCSSCalc } from "../utils/ReduceCSSCalc.mjs";
|
|
3
|
-
import { Fragment, computed, createElementBlock, defineComponent, normalizeStyle, openBlock, renderList, toDisplayString } from "vue";
|
|
3
|
+
import { Fragment, computed, createElementBlock, defineComponent, normalizeStyle, openBlock, renderList, renderSlot, toDisplayString } from "vue";
|
|
4
4
|
//#region src/components/Text.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var _hoisted_1 = [
|
|
6
6
|
"x",
|
|
@@ -177,13 +177,13 @@ var Text_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
177
177
|
fill: props.fill && props.fill.includes("url") ? "#808080" : props.fill,
|
|
178
178
|
class: "v-charts-text",
|
|
179
179
|
style: normalizeStyle(props.style)
|
|
180
|
-
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(wordsByLines.value, (line, index) => {
|
|
180
|
+
}, [renderSlot(_ctx.$slots, "default", {}, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(wordsByLines.value, (line, index) => {
|
|
181
181
|
return openBlock(), createElementBlock("tspan", {
|
|
182
182
|
key: index,
|
|
183
183
|
x: x.value,
|
|
184
184
|
dy: index === 0 ? startDy.value : props.lineHeight
|
|
185
185
|
}, toDisplayString(line.words.join(props.breakAll ? "" : " ")), 9, _hoisted_2);
|
|
186
|
-
}), 128))], 12, _hoisted_1);
|
|
186
|
+
}), 128))])], 12, _hoisted_1);
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
189
|
});
|
|
@@ -8,17 +8,17 @@ import { selectActiveCoordinate, selectActiveLabel, selectIsTooltipActive, selec
|
|
|
8
8
|
import { Rectangle } from "../shape/Rectangle.mjs";
|
|
9
9
|
import { useCursorLayerRef } from "../context/cursorLayerContext.mjs";
|
|
10
10
|
import { usePortal } from "../chart/TooltipPortalContext.mjs";
|
|
11
|
+
import { Sector } from "../shape/Sector.mjs";
|
|
11
12
|
import { useAccessibilityLayer } from "../context/accessibilityContext.mjs";
|
|
12
13
|
import { getTooltipTranslate } from "../utils/tooltip/translate.mjs";
|
|
13
14
|
import { Cross } from "../shape/Cross.mjs";
|
|
14
|
-
import { Sector } from "../shape/Sector.mjs";
|
|
15
15
|
import { getCursorPoints } from "./utils.mjs";
|
|
16
16
|
import { useTooltipAxisBandSize } from "../context/useTooltipAxis.mjs";
|
|
17
17
|
import { useTooltipChartSynchronisation } from "../synchronisation/useChartSynchronisation.mjs";
|
|
18
18
|
import { Fragment, Teleport, computed, createVNode, defineComponent, isVNode, reactive, ref, watch, watchEffect, watchPostEffect } from "vue";
|
|
19
19
|
import { sortBy, uniqBy } from "es-toolkit/compat";
|
|
20
20
|
import { animate } from "motion-v";
|
|
21
|
-
import {
|
|
21
|
+
import { useMagicKeys, usePreferredReducedMotion } from "@vueuse/core";
|
|
22
22
|
//#region src/components/Tooltip.tsx
|
|
23
23
|
function _isSlot(s) {
|
|
24
24
|
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
@@ -148,7 +148,10 @@ var TooltipBoundingBox = /* @__PURE__ */ defineComponent({
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
const el = ref();
|
|
151
|
-
const
|
|
151
|
+
const tooltipSize = ref({
|
|
152
|
+
width: 0,
|
|
153
|
+
height: 0
|
|
154
|
+
});
|
|
152
155
|
let preTransform;
|
|
153
156
|
let animationControls;
|
|
154
157
|
const reducedMotion = usePreferredReducedMotion();
|
|
@@ -161,13 +164,13 @@ var TooltipBoundingBox = /* @__PURE__ */ defineComponent({
|
|
|
161
164
|
position,
|
|
162
165
|
reverseDirection,
|
|
163
166
|
tooltipBox: {
|
|
164
|
-
height:
|
|
165
|
-
width:
|
|
167
|
+
height: tooltipSize.value.height,
|
|
168
|
+
width: tooltipSize.value.width
|
|
166
169
|
},
|
|
167
170
|
useTranslate3d: false,
|
|
168
171
|
viewBox
|
|
169
172
|
});
|
|
170
|
-
transform = !
|
|
173
|
+
transform = !tooltipSize.value.height && preTransform ? preTransform : transform;
|
|
171
174
|
preTransform = transform || preTransform;
|
|
172
175
|
return {
|
|
173
176
|
cssClasses,
|
|
@@ -181,6 +184,12 @@ var TooltipBoundingBox = /* @__PURE__ */ defineComponent({
|
|
|
181
184
|
if (!element || !transform?.transform) return;
|
|
182
185
|
if (props.isAnimationActive && reducedMotion.value !== "reduce") animationControls = animate(element, { transform: transform.transform }, props.transition);
|
|
183
186
|
else element.style.transform = transform.transform;
|
|
187
|
+
const width = element.offsetWidth;
|
|
188
|
+
const height = element.offsetHeight;
|
|
189
|
+
if (height > 0 && (width !== tooltipSize.value.width || height !== tooltipSize.value.height)) tooltipSize.value = {
|
|
190
|
+
width,
|
|
191
|
+
height
|
|
192
|
+
};
|
|
184
193
|
onCleanup(() => {
|
|
185
194
|
animationControls?.stop();
|
|
186
195
|
animationControls = void 0;
|
|
@@ -235,17 +244,15 @@ var Cursor = /* @__PURE__ */ defineComponent({
|
|
|
235
244
|
let cursorElement;
|
|
236
245
|
if (isScatterChart) {
|
|
237
246
|
const { offset: _offset, ...coord } = props.coordinate;
|
|
238
|
-
const { top, left, width, height } = offset.value;
|
|
239
247
|
const crossProps = {
|
|
240
248
|
stroke: "#ccc",
|
|
241
249
|
fill: "none",
|
|
250
|
+
...offset.value,
|
|
242
251
|
...coord,
|
|
243
|
-
top,
|
|
244
|
-
left,
|
|
245
|
-
width,
|
|
246
|
-
height,
|
|
247
252
|
class: "v-charts-tooltip-cursor",
|
|
248
253
|
style: { pointerEvents: "none" },
|
|
254
|
+
payload: props.payload ?? [],
|
|
255
|
+
payloadIndex: props.index,
|
|
249
256
|
...cursorSvgProps
|
|
250
257
|
};
|
|
251
258
|
cursorElement = props.cursorSlot ? props.cursorSlot(crossProps) : createVNode(Cross, crossProps, null);
|
|
@@ -255,6 +262,7 @@ var Cursor = /* @__PURE__ */ defineComponent({
|
|
|
255
262
|
const coord = props.coordinate;
|
|
256
263
|
const off = offset.value;
|
|
257
264
|
const rectProps = {
|
|
265
|
+
...off,
|
|
258
266
|
stroke: "none",
|
|
259
267
|
fill: "#ccc",
|
|
260
268
|
x: layout.value === "horizontal" ? coord.x - halfSize : off.left + .5,
|
|
@@ -263,32 +271,40 @@ var Cursor = /* @__PURE__ */ defineComponent({
|
|
|
263
271
|
height: layout.value === "horizontal" ? off.height - 1 : bandSize,
|
|
264
272
|
class: "v-charts-tooltip-cursor",
|
|
265
273
|
style: { pointerEvents: "none" },
|
|
274
|
+
payload: props.payload ?? [],
|
|
275
|
+
payloadIndex: props.index,
|
|
266
276
|
...cursorSvgProps
|
|
267
277
|
};
|
|
268
278
|
cursorElement = props.cursorSlot ? props.cursorSlot(rectProps) : createVNode(Rectangle, rectProps, null);
|
|
269
279
|
} else if (layout.value === "radial" && props.coordinate?.cx != null) {
|
|
270
280
|
const radialPoints = points.value;
|
|
271
281
|
const sectorProps = {
|
|
282
|
+
stroke: "#ccc",
|
|
283
|
+
...offset.value,
|
|
272
284
|
cx: radialPoints.cx,
|
|
273
285
|
cy: radialPoints.cy,
|
|
274
286
|
startAngle: radialPoints.startAngle,
|
|
275
287
|
endAngle: radialPoints.endAngle,
|
|
276
288
|
innerRadius: radialPoints.radius,
|
|
277
289
|
outerRadius: radialPoints.radius,
|
|
278
|
-
stroke: "#ccc",
|
|
279
290
|
fill: "none",
|
|
280
291
|
class: "v-charts-tooltip-cursor",
|
|
281
292
|
style: { pointerEvents: "none" },
|
|
293
|
+
payload: props.payload ?? [],
|
|
294
|
+
payloadIndex: props.index,
|
|
282
295
|
...cursorSvgProps
|
|
283
296
|
};
|
|
284
297
|
cursorElement = props.cursorSlot ? props.cursorSlot(sectorProps) : createVNode(Sector, sectorProps, null);
|
|
285
298
|
} else {
|
|
286
299
|
const cursorProps = {
|
|
287
300
|
stroke: "#ccc",
|
|
288
|
-
|
|
301
|
+
...offset.value,
|
|
289
302
|
layout: layout.value,
|
|
290
303
|
points: points.value,
|
|
304
|
+
class: ["v-charts-tooltip-cursor"],
|
|
291
305
|
style: { pointerEvents: "none" },
|
|
306
|
+
payload: props.payload ?? [],
|
|
307
|
+
payloadIndex: props.index,
|
|
292
308
|
...cursorSvgProps
|
|
293
309
|
};
|
|
294
310
|
cursorElement = props.cursorSlot ? props.cursorSlot(cursorProps) : createVNode(Curve, cursorProps, null);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isPercent } from "../utils/validate.mjs";
|
|
2
2
|
import { normalizeStyle as normalizeStyle$1 } from "../utils/style.mjs";
|
|
3
3
|
import { provideSizeContext } from "./useSizeContext.mjs";
|
|
4
|
-
import { Fragment, cloneVNode, computed,
|
|
4
|
+
import { Fragment, cloneVNode, computed, createElementBlock, createVNode, defineComponent, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, ref, toRef, useSlots } from "vue";
|
|
5
5
|
import { useThrottleFn } from "@vueuse/core";
|
|
6
6
|
//#region src/container/ResponsiveContainer.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var _hoisted_1 = ["id"];
|
|
@@ -119,6 +119,19 @@ var ResponsiveContainer_vue_vue_type_script_setup_true_lang_default = /* @__PURE
|
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Rendering the children through `<component :is="() => renderChildren()" />` would
|
|
124
|
+
* create a new component type on every render, so Vue unmounts and remounts the whole
|
|
125
|
+
* chart subtree each time. Charts that dispatch on `mouseenter` (radial bar, radar) then
|
|
126
|
+
* loop forever: the remount recreates the element under the cursor, which fires
|
|
127
|
+
* `mouseenter` again. This renderer keeps a stable type, so the subtree is patched.
|
|
128
|
+
*/
|
|
129
|
+
const ChildrenRenderer = (rendererProps) => rendererProps.nodes;
|
|
130
|
+
ChildrenRenderer.props = { nodes: {
|
|
131
|
+
type: Array,
|
|
132
|
+
required: true
|
|
133
|
+
} };
|
|
134
|
+
ChildrenRenderer.inheritAttrs = false;
|
|
122
135
|
const containerStyle = computed(() => ({
|
|
123
136
|
...props.style,
|
|
124
137
|
...normalizeStyle$1({
|
|
@@ -136,7 +149,7 @@ var ResponsiveContainer_vue_vue_type_script_setup_true_lang_default = /* @__PURE
|
|
|
136
149
|
ref: containerRef,
|
|
137
150
|
class: normalizeClass(["vcharts-responsive-container", [props.class]]),
|
|
138
151
|
style: normalizeStyle(containerStyle.value)
|
|
139
|
-
}, [(
|
|
152
|
+
}, [createVNode(ChildrenRenderer, { nodes: renderChildren() ?? [] }, null, 8, ["nodes"])], 14, _hoisted_1);
|
|
140
153
|
};
|
|
141
154
|
}
|
|
142
155
|
});
|
package/dist/es/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Global } from "./utils/Global.mjs";
|
|
1
2
|
import { Curve, CurveVueProps, getPath } from "./shape/Curve.mjs";
|
|
2
3
|
import { useActiveTooltipDataPoints } from "./state/hooks.mjs";
|
|
3
4
|
import { useChartHeight, useChartWidth, useMargin, useOffset } from "./context/chartLayoutContext.mjs";
|
|
@@ -36,11 +37,13 @@ import { ScatterChart } from "./chart/ScatterChart.mjs";
|
|
|
36
37
|
import { RadialBarChart } from "./chart/RadialBarChart.mjs";
|
|
37
38
|
import { FunnelChart } from "./chart/FunnelChart.mjs";
|
|
38
39
|
import { Treemap, TreemapVueProps, treemapPayloadSearcher } from "./chart/Treemap.mjs";
|
|
40
|
+
import { Sankey, SankeyVueProps, sankeyPayloadSearcher } from "./chart/Sankey.mjs";
|
|
41
|
+
import { Sector } from "./shape/Sector.mjs";
|
|
42
|
+
import { SunburstChart, SunburstChartVueProps, sunburstPayloadSearcher } from "./chart/SunburstChart.mjs";
|
|
39
43
|
import ResponsiveContainer_default from "./container/ResponsiveContainer.mjs";
|
|
40
44
|
import { Customized } from "./components/Customized.mjs";
|
|
41
45
|
import Legend_default from "./components/legend/Legend.mjs";
|
|
42
46
|
import { Cross } from "./shape/Cross.mjs";
|
|
43
|
-
import { Sector } from "./shape/Sector.mjs";
|
|
44
47
|
import Tooltip, { getUniqPayload } from "./components/Tooltip.mjs";
|
|
45
48
|
import { PieVueProps } from "./polar/pie/type.mjs";
|
|
46
49
|
import { Pie } from "./polar/pie/Pie.mjs";
|
|
@@ -51,4 +54,4 @@ import { PolarRadiusAxis } from "./polar/radar/PolarRadiusAxis.mjs";
|
|
|
51
54
|
import { RadialBar } from "./polar/radial-bar/RadialBar.mjs";
|
|
52
55
|
import { Polygon } from "./shape/Polygon.mjs";
|
|
53
56
|
import { useActiveTooltipCoordinate, useActiveTooltipLabel, useCartesianScale, useIsTooltipActive, usePlotArea, useXAxisDomain, useXAxisInverseDataSnapScale, useXAxisInverseScale, useXAxisInverseTickSnapScale, useXAxisScale, useXAxisTicks, useYAxisDomain, useYAxisInverseDataSnapScale, useYAxisInverseScale, useYAxisInverseTickSnapScale, useYAxisScale, useYAxisTicks } from "./hooks/publicHooks.mjs";
|
|
54
|
-
export { Area, AreaChart, Bar, BarChart, CartesianAxis, CartesianGrid, Cell, ComposedChart, Cross, Curve, CurveVueProps, Customized, Dot, ErrorBar, ErrorBarVueProps, Funnel, FunnelChart, FunnelVueProps, Label, LabelList, Legend_default as Legend, Line, LineChart, LineContextKey, Pie, PieChart, PieVueProps, PolarAngleAxis, PolarGrid, PolarRadiusAxis, Polygon, Radar, RadarChart, RadialBar, RadialBarChart, Rectangle, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer_default as ResponsiveContainer, Scatter, ScatterChart, Sector, Symbols, Text_default as Text, Tooltip, Trapezoid, Treemap, TreemapVueProps, XAxis, YAxis, ZAxis, createErrorBarRegistry, getPath, getUniqPayload, provideErrorBarContext, provideErrorBarRegistry, provideLineContext, treemapPayloadSearcher, useActiveTooltipCoordinate, useActiveTooltipDataPoints, useActiveTooltipLabel, useCartesianScale, useChartHeight, useChartWidth, useErrorBarContext, useErrorBarRegistry, useIsTooltipActive, useLine, useLineContext, useMargin, useOffset, usePlotArea, useXAxisDomain, useXAxisInverseDataSnapScale, useXAxisInverseScale, useXAxisInverseTickSnapScale, useXAxisScale, useXAxisTicks, useYAxisDomain, useYAxisInverseDataSnapScale, useYAxisInverseScale, useYAxisInverseTickSnapScale, useYAxisScale, useYAxisTicks };
|
|
57
|
+
export { Area, AreaChart, Bar, BarChart, CartesianAxis, CartesianGrid, Cell, ComposedChart, Cross, Curve, CurveVueProps, Customized, Dot, ErrorBar, ErrorBarVueProps, Funnel, FunnelChart, FunnelVueProps, Global, Label, LabelList, Legend_default as Legend, Line, LineChart, LineContextKey, Pie, PieChart, PieVueProps, PolarAngleAxis, PolarGrid, PolarRadiusAxis, Polygon, Radar, RadarChart, RadialBar, RadialBarChart, Rectangle, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer_default as ResponsiveContainer, Sankey, SankeyVueProps, Scatter, ScatterChart, Sector, SunburstChart, SunburstChartVueProps, Symbols, Text_default as Text, Tooltip, Trapezoid, Treemap, TreemapVueProps, XAxis, YAxis, ZAxis, createErrorBarRegistry, getPath, getUniqPayload, provideErrorBarContext, provideErrorBarRegistry, provideLineContext, sankeyPayloadSearcher, sunburstPayloadSearcher, treemapPayloadSearcher, useActiveTooltipCoordinate, useActiveTooltipDataPoints, useActiveTooltipLabel, useCartesianScale, useChartHeight, useChartWidth, useErrorBarContext, useErrorBarRegistry, useIsTooltipActive, useLine, useLineContext, useMargin, useOffset, usePlotArea, useXAxisDomain, useXAxisInverseDataSnapScale, useXAxisInverseScale, useXAxisInverseTickSnapScale, useXAxisScale, useXAxisTicks, useYAxisDomain, useYAxisInverseDataSnapScale, useYAxisInverseScale, useYAxisInverseTickSnapScale, useYAxisScale, useYAxisTicks };
|
|
@@ -120,7 +120,7 @@ var Pie = /* @__PURE__ */ defineComponent({
|
|
|
120
120
|
"isActive": props.isAnimationActive,
|
|
121
121
|
"from": 0,
|
|
122
122
|
"to": 1,
|
|
123
|
-
"transition":
|
|
123
|
+
"transition": props.transition
|
|
124
124
|
}, { default: (progress) => {
|
|
125
125
|
let curAngle = sectorList[0]?.startAngle ?? 0;
|
|
126
126
|
const sectorNodes = sectorList.map((sector, i) => {
|
|
@@ -115,6 +115,13 @@ var Radar = /* @__PURE__ */ defineComponent({
|
|
|
115
115
|
type: Boolean,
|
|
116
116
|
default: true
|
|
117
117
|
},
|
|
118
|
+
transition: {
|
|
119
|
+
type: Object,
|
|
120
|
+
default: () => ({
|
|
121
|
+
duration: .8,
|
|
122
|
+
ease: "easeOut"
|
|
123
|
+
})
|
|
124
|
+
},
|
|
118
125
|
activeDot: {
|
|
119
126
|
type: [Object, Boolean],
|
|
120
127
|
default: true
|
|
@@ -175,7 +182,7 @@ var Radar = /* @__PURE__ */ defineComponent({
|
|
|
175
182
|
let prevPoints = null;
|
|
176
183
|
let prevBaseLinePoints = null;
|
|
177
184
|
let animationId = 0;
|
|
178
|
-
let lastData
|
|
185
|
+
let lastData;
|
|
179
186
|
const renderPolygon = (points, baseLinePoints, isRange) => {
|
|
180
187
|
const stroke = props.stroke ?? props.fill;
|
|
181
188
|
const hasStroke = stroke && stroke !== "none";
|
|
@@ -259,6 +266,7 @@ var Radar = /* @__PURE__ */ defineComponent({
|
|
|
259
266
|
createVNode(Animate, {
|
|
260
267
|
"key": animationId,
|
|
261
268
|
"isActive": true,
|
|
269
|
+
"transition": props.transition,
|
|
262
270
|
"onAnimationStart": () => {
|
|
263
271
|
isAnimating.value = true;
|
|
264
272
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/utils/Global.ts
|
|
2
|
+
function parseIsSsrByDefault() {
|
|
3
|
+
return typeof window === "undefined";
|
|
4
|
+
}
|
|
5
|
+
var Global = {
|
|
6
|
+
isSsr: parseIsSsrByDefault(),
|
|
7
|
+
get(key) {
|
|
8
|
+
return Global[key];
|
|
9
|
+
},
|
|
10
|
+
set(key, value) {
|
|
11
|
+
if (typeof key === "string") Global[key] = value;
|
|
12
|
+
else Object.keys(key).forEach((k) => {
|
|
13
|
+
Global[k] = key[k];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Global };
|
package/dist/es/utils/attrs.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Global } from "./Global.mjs";
|
|
2
2
|
//#region src/utils/attrs.ts
|
|
3
3
|
var stringCache = {
|
|
4
4
|
widthCache: {},
|
|
@@ -23,7 +23,7 @@ function removeInvalidKeys(obj) {
|
|
|
23
23
|
return copyObj;
|
|
24
24
|
}
|
|
25
25
|
function getStringSize(text, style = {}) {
|
|
26
|
-
if (text === void 0 || text === null || isSsr) return {
|
|
26
|
+
if (text === void 0 || text === null || Global.isSsr) return {
|
|
27
27
|
width: 0,
|
|
28
28
|
height: 0
|
|
29
29
|
};
|