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.
Files changed (48) hide show
  1. package/README.md +4 -0
  2. package/dist/cartesian/axis/XAxis.d.ts +3 -3
  3. package/dist/cartesian/cartesian-axis/CartesianAxis.d.ts +5 -5
  4. package/dist/chart/RechartsWrapper.d.ts +3 -3
  5. package/dist/chart/Sankey.d.ts +327 -0
  6. package/dist/chart/SunburstChart.d.ts +249 -0
  7. package/dist/chart/generateCategoricalChart.d.ts +2 -2
  8. package/dist/chart/index.d.ts +2 -0
  9. package/dist/chart/sankeyUtils.d.ts +36 -0
  10. package/dist/chart/sunburstUtils.d.ts +34 -0
  11. package/dist/components/Text.d.ts +16 -1
  12. package/dist/components/Tooltip.d.ts +46 -2
  13. package/dist/es/cartesian/axis/XAxis.mjs +2 -2
  14. package/dist/es/cartesian/axis/YAxis.mjs +1 -1
  15. package/dist/es/cartesian/cartesian-axis/CartesianAxis.mjs +2 -3
  16. package/dist/es/cartesian/cartesian-grid/const.mjs +6 -0
  17. package/dist/es/cartesian/utils/get-ticks.mjs +3 -2
  18. package/dist/es/chart/RechartsWrapper.mjs +8 -5
  19. package/dist/es/chart/Sankey.mjs +332 -0
  20. package/dist/es/chart/SunburstChart.mjs +229 -0
  21. package/dist/es/chart/generateCategoricalChart.mjs +5 -1
  22. package/dist/es/chart/sankeyUtils.mjs +28 -0
  23. package/dist/es/chart/sunburstUtils.mjs +67 -0
  24. package/dist/es/components/Text.vue_vue_type_script_setup_true_lang.mjs +3 -3
  25. package/dist/es/components/Tooltip.mjs +29 -13
  26. package/dist/es/container/ResponsiveContainer.vue_vue_type_script_setup_true_lang.mjs +15 -2
  27. package/dist/es/index.mjs +5 -2
  28. package/dist/es/polar/pie/Pie.mjs +1 -1
  29. package/dist/es/polar/pie/type.mjs +7 -0
  30. package/dist/es/polar/radar/Radar.mjs +9 -1
  31. package/dist/es/polar/radial-bar/RadialBar.mjs +1 -0
  32. package/dist/es/polar/radial-bar/type.mjs +7 -0
  33. package/dist/es/utils/Global.mjs +18 -0
  34. package/dist/es/utils/attrs.mjs +2 -2
  35. package/dist/es/utils/validate.mjs +1 -2
  36. package/dist/hooks/publicHooks.d.ts +1 -1
  37. package/dist/index.d.ts +2 -0
  38. package/dist/polar/pie/type.d.ts +8 -0
  39. package/dist/polar/radar/Radar.d.ts +16 -0
  40. package/dist/polar/radial-bar/type.d.ts +8 -0
  41. package/dist/state/selectors/combiners/combineActiveLabel.d.ts +1 -1
  42. package/dist/state/selectors/selectors.d.ts +1 -1
  43. package/dist/state/selectors/tooltipSelectors.d.ts +1 -1
  44. package/dist/types/common.d.ts +1 -1
  45. package/dist/utils/Global.d.ts +9 -0
  46. package/dist/utils/index.d.ts +1 -0
  47. package/dist/utils/validate.d.ts +0 -1
  48. 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: Object },
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 { useElementBounding, useMagicKeys, usePreferredReducedMotion } from "@vueuse/core";
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 lastBoundingBox = useElementBounding(el, {});
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: lastBoundingBox.height.value,
165
- width: lastBoundingBox.width.value
167
+ height: tooltipSize.value.height,
168
+ width: tooltipSize.value.width
166
169
  },
167
170
  useTranslate3d: false,
168
171
  viewBox
169
172
  });
170
- transform = !lastBoundingBox.height.value && preTransform ? preTransform : 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
- class: ["v-charts-tooltip-cursor"],
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, createBlock, createElementBlock, defineComponent, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, ref, resolveDynamicComponent, toRef, useSlots } from "vue";
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
- }, [(openBlock(), createBlock(resolveDynamicComponent(() => renderChildren())))], 14, _hoisted_1);
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": { duration: 1.5 }
123
+ "transition": props.transition
124
124
  }, { default: (progress) => {
125
125
  let curAngle = sectorList[0]?.startAngle ?? 0;
126
126
  const sectorNodes = sectorList.map((sector, i) => {
@@ -85,6 +85,13 @@ var PieVueProps = {
85
85
  type: Boolean,
86
86
  default: true
87
87
  },
88
+ transition: {
89
+ type: Object,
90
+ default: () => ({
91
+ duration: 1.2,
92
+ ease: "easeOut"
93
+ })
94
+ },
88
95
  label: {
89
96
  type: Boolean,
90
97
  default: false
@@ -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 = void 0;
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
  },
@@ -165,6 +165,7 @@ var RadialBar = /* @__PURE__ */ defineComponent({
165
165
  createVNode(Animate, {
166
166
  "key": animationId,
167
167
  "isActive": true,
168
+ "transition": props.transition,
168
169
  "onAnimationStart": () => {
169
170
  isAnimating.value = true;
170
171
  },
@@ -64,6 +64,13 @@ var RadialBarVueProps = {
64
64
  type: Boolean,
65
65
  default: true
66
66
  },
67
+ transition: {
68
+ type: Object,
69
+ default: () => ({
70
+ duration: .4,
71
+ ease: "easeOut"
72
+ })
73
+ },
67
74
  minPointSize: {
68
75
  type: Number,
69
76
  default: 0
@@ -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 };
@@ -1,4 +1,4 @@
1
- import { isSsr } from "./validate.mjs";
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
  };