vccs 0.2.0 → 0.4.0
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 +151 -0
- package/dist/animation/Animate.d.ts +1 -1
- package/dist/cartesian/area/type.d.ts +3 -3
- package/dist/cartesian/axis/XAxis.d.ts +3 -3
- package/dist/cartesian/bar/type.d.ts +1 -13
- package/dist/cartesian/brush/components/Slide.d.ts +1 -1
- package/dist/cartesian/brush/components/TravellerLayer.d.ts +1 -1
- package/dist/cartesian/brush/type.d.ts +2 -1
- package/dist/cartesian/cartesian-axis/CartesianAxis.d.ts +7 -6
- package/dist/cartesian/funnel/type.d.ts +4 -5
- package/dist/cartesian/index.d.ts +1 -0
- package/dist/cartesian/line/Line.d.ts +7 -13
- package/dist/cartesian/line/type.d.ts +4 -17
- package/dist/cartesian/reference-area/ReferenceArea.d.ts +16 -16
- package/dist/cartesian/reference-dot/ReferenceDot.d.ts +143 -0
- package/dist/cartesian/reference-dot/index.d.ts +2 -0
- package/dist/cartesian/reference-line/ReferenceLine.d.ts +8 -8
- package/dist/cartesian/scatter/Scatter.d.ts +1 -1
- package/dist/chart/RechartsWrapper.d.ts +7 -3
- package/dist/chart/Surface.d.ts +2 -1
- package/dist/chart/Treemap.d.ts +237 -0
- package/dist/chart/generateCategoricalChart.d.ts +2 -1
- package/dist/chart/index.d.ts +1 -0
- package/dist/chart/treemapUtils.d.ts +22 -0
- package/dist/components/Customized.d.ts +23 -0
- package/dist/components/Text.d.ts +20 -5
- package/dist/components/Tooltip.d.ts +47 -3
- package/dist/components/index.d.ts +2 -0
- package/dist/components/label/Label.d.ts +3 -3
- package/dist/components/label/types.d.ts +1 -1
- package/dist/container/Surface.d.ts +3 -2
- package/dist/es/cartesian/area/type.mjs +2 -4
- package/dist/es/cartesian/axis/XAxis.mjs +2 -2
- package/dist/es/cartesian/axis/YAxis.mjs +1 -1
- package/dist/es/cartesian/bar/Bar.mjs +2 -17
- package/dist/es/cartesian/bar/type.mjs +2 -16
- package/dist/es/cartesian/cartesian-axis/CartesianAxis.mjs +2 -3
- package/dist/es/cartesian/cartesian-grid/const.mjs +7 -1
- package/dist/es/cartesian/funnel/Funnel.mjs +3 -18
- package/dist/es/cartesian/funnel/type.mjs +3 -5
- package/dist/es/cartesian/line/type.mjs +2 -7
- package/dist/es/cartesian/reference-area/ReferenceArea.mjs +6 -22
- package/dist/es/cartesian/reference-dot/ReferenceDot.mjs +134 -0
- package/dist/es/cartesian/reference-line/ReferenceLine.mjs +6 -19
- package/dist/es/chart/RechartsWrapper.mjs +2 -1
- package/dist/es/chart/Treemap.mjs +379 -0
- package/dist/es/chart/generateCategoricalChart.mjs +3 -2
- package/dist/es/chart/treemapUtils.mjs +32 -0
- package/dist/es/components/Customized.mjs +43 -0
- package/dist/es/components/Text.vue_vue_type_script_setup_true_lang.mjs +3 -3
- package/dist/es/components/Tooltip.mjs +14 -7
- package/dist/es/components/label/types.mjs +2 -1
- package/dist/es/components/legend/Legend.mjs +1 -1
- package/dist/es/components/legend/hooks/useLegend.mjs +8 -3
- package/dist/es/container/Surface.mjs +2 -4
- package/dist/es/hooks/publicHooks.mjs +207 -0
- package/dist/es/index.mjs +9 -1
- package/dist/es/polar/pie/Pie.mjs +1 -1
- package/dist/es/polar/pie/type.mjs +2 -4
- package/dist/es/shape/Curve.mjs +2 -1
- package/dist/es/shape/Polygon.mjs +19 -0
- package/dist/es/shape/Rectangle.mjs +0 -4
- package/dist/es/shape/Sector.mjs +4 -6
- package/dist/es/shape/Symbols.mjs +1 -1
- package/dist/es/shape/Trapezoid.mjs +5 -7
- package/dist/es/state/ReportChartProps.mjs +2 -4
- package/dist/es/state/hooks.mjs +21 -1
- package/dist/es/state/referenceElementsSlice.mjs +1 -1
- package/dist/es/state/selectors/axisSelectors.mjs +30 -1
- package/dist/es/state/selectors/tooltipSelectors.mjs +2 -2
- package/dist/es/types/common.mjs +12 -0
- package/dist/es/utils/VueUtils.mjs +1 -1
- package/dist/es/utils/cell.mjs +28 -0
- package/dist/es/utils/createCategoricalInverse.mjs +46 -0
- package/dist/es/utils/scale.mjs +46 -0
- package/dist/hooks/publicHooks.d.ts +143 -0
- package/dist/index.d.ts +1 -0
- package/dist/polar/pie/type.d.ts +2 -2
- package/dist/polar/radar/Radar.d.ts +4 -4
- package/dist/shape/Curve.d.ts +2 -1
- package/dist/shape/Polygon.d.ts +9 -0
- package/dist/shape/Rectangle.d.ts +0 -4
- package/dist/shape/Sector.d.ts +2 -2
- package/dist/shape/Symbols.d.ts +2 -1
- package/dist/shape/Trapezoid.d.ts +9 -10
- package/dist/shape/index.d.ts +1 -0
- package/dist/shape/types.d.ts +4 -5
- package/dist/state/ReportChartProps.d.ts +3 -3
- package/dist/state/rootPropsSlice.d.ts +2 -2
- package/dist/state/selectors/axisSelectors.d.ts +5 -0
- package/dist/types/axis.d.ts +2 -2
- package/dist/types/bar.d.ts +2 -6
- package/dist/types/categorical.d.ts +2 -2
- package/dist/types/common.d.ts +7 -1
- package/dist/types/tooltip.d.ts +2 -2
- package/dist/utils/cell.d.ts +11 -0
- package/dist/utils/createCategoricalInverse.d.ts +16 -0
- package/dist/utils/scale.d.ts +23 -0
- package/package.json +2 -1
|
@@ -0,0 +1,379 @@
|
|
|
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 { getStringSize } from "../utils/attrs.mjs";
|
|
5
|
+
import { Animate } from "../animation/Animate.mjs";
|
|
6
|
+
import { createRechartsStore } from "../state/store.mjs";
|
|
7
|
+
import { RechartsWrapper } from "./RechartsWrapper.mjs";
|
|
8
|
+
import Surface from "../container/Surface.mjs";
|
|
9
|
+
import { computeTreemapLayout } from "./treemapUtils.mjs";
|
|
10
|
+
import { Fragment, computed, createTextVNode, createVNode, defineComponent, ref, watchEffect } from "vue";
|
|
11
|
+
import { provideStore } from "@reduxjs/vue-redux";
|
|
12
|
+
import { get } from "lodash-es";
|
|
13
|
+
//#region src/chart/Treemap.tsx
|
|
14
|
+
var DEFAULT_COLORS = [
|
|
15
|
+
"#8889DD",
|
|
16
|
+
"#9597E4",
|
|
17
|
+
"#8DC77B",
|
|
18
|
+
"#A5D297",
|
|
19
|
+
"#E2CF45",
|
|
20
|
+
"#F8C12D",
|
|
21
|
+
"#F89C24",
|
|
22
|
+
"#F56E1A"
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Recursively sum all descendant values for a given dataKey.
|
|
26
|
+
*/
|
|
27
|
+
function sumValues(item, dataKey) {
|
|
28
|
+
if (item.children && item.children.length > 0) return item.children.reduce((sum, child) => sum + sumValues(child, dataKey), 0);
|
|
29
|
+
const val = item[dataKey];
|
|
30
|
+
return typeof val === "number" && val > 0 ? val : 0;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Tooltip payload searcher for Treemap — navigates nested node structure
|
|
34
|
+
* using a path string like 'children[0].children[1]'.
|
|
35
|
+
*/
|
|
36
|
+
var treemapPayloadSearcher = (data, activeIndex) => {
|
|
37
|
+
if (!data || !activeIndex) return void 0;
|
|
38
|
+
return get(data, activeIndex);
|
|
39
|
+
};
|
|
40
|
+
var treemapOptions = {
|
|
41
|
+
chartName: "Treemap",
|
|
42
|
+
defaultTooltipEventType: "item",
|
|
43
|
+
validateTooltipEventTypes: ["item"],
|
|
44
|
+
tooltipPayloadSearcher: treemapPayloadSearcher,
|
|
45
|
+
eventEmitter: void 0
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Build a hierarchical node structure with tooltipIndex paths for tooltip lookup.
|
|
49
|
+
*/
|
|
50
|
+
function buildNodeTree(data, dataKey, nameKey, parentIndex = "") {
|
|
51
|
+
return {
|
|
52
|
+
children: data.map((item, i) => {
|
|
53
|
+
const tooltipIndex = `${parentIndex}children[${i}]`;
|
|
54
|
+
if (item.children && item.children.length > 0) {
|
|
55
|
+
const childTree = buildNodeTree(item.children, dataKey, nameKey, `${tooltipIndex}.`);
|
|
56
|
+
return {
|
|
57
|
+
...item,
|
|
58
|
+
tooltipIndex,
|
|
59
|
+
...childTree
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
...item,
|
|
64
|
+
tooltipIndex,
|
|
65
|
+
value: sumValues(item, dataKey)
|
|
66
|
+
};
|
|
67
|
+
}),
|
|
68
|
+
name: "root",
|
|
69
|
+
tooltipIndex: parentIndex
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
var TreemapVueProps = {
|
|
73
|
+
data: {
|
|
74
|
+
type: Array,
|
|
75
|
+
required: true
|
|
76
|
+
},
|
|
77
|
+
dataKey: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: "value"
|
|
80
|
+
},
|
|
81
|
+
nameKey: {
|
|
82
|
+
type: String,
|
|
83
|
+
default: "name"
|
|
84
|
+
},
|
|
85
|
+
width: {
|
|
86
|
+
type: Number,
|
|
87
|
+
required: true
|
|
88
|
+
},
|
|
89
|
+
height: {
|
|
90
|
+
type: Number,
|
|
91
|
+
required: true
|
|
92
|
+
},
|
|
93
|
+
aspectRatio: {
|
|
94
|
+
type: Number,
|
|
95
|
+
default: 4 / 3
|
|
96
|
+
},
|
|
97
|
+
fill: {
|
|
98
|
+
type: String,
|
|
99
|
+
default: "#808080"
|
|
100
|
+
},
|
|
101
|
+
stroke: {
|
|
102
|
+
type: String,
|
|
103
|
+
default: "#fff"
|
|
104
|
+
},
|
|
105
|
+
type: {
|
|
106
|
+
type: String,
|
|
107
|
+
default: "flat"
|
|
108
|
+
},
|
|
109
|
+
colorPanel: {
|
|
110
|
+
type: Array,
|
|
111
|
+
default: void 0
|
|
112
|
+
},
|
|
113
|
+
isAnimationActive: {
|
|
114
|
+
type: Boolean,
|
|
115
|
+
default: true
|
|
116
|
+
},
|
|
117
|
+
transition: {
|
|
118
|
+
type: Object,
|
|
119
|
+
default: () => ({
|
|
120
|
+
duration: .8,
|
|
121
|
+
ease: "easeOut"
|
|
122
|
+
})
|
|
123
|
+
},
|
|
124
|
+
onClick: {
|
|
125
|
+
type: Function,
|
|
126
|
+
default: void 0
|
|
127
|
+
},
|
|
128
|
+
onMouseEnter: {
|
|
129
|
+
type: Function,
|
|
130
|
+
default: void 0
|
|
131
|
+
},
|
|
132
|
+
onMouseLeave: {
|
|
133
|
+
type: Function,
|
|
134
|
+
default: void 0
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Inner component that has access to the Redux store (provided by Treemap wrapper).
|
|
139
|
+
*/
|
|
140
|
+
var TreemapInner = /* @__PURE__ */ defineComponent({
|
|
141
|
+
name: "TreemapInner",
|
|
142
|
+
props: TreemapVueProps,
|
|
143
|
+
slots: Object,
|
|
144
|
+
setup(props, { slots }) {
|
|
145
|
+
const dispatch = useAppDispatch();
|
|
146
|
+
const colors = computed(() => props.colorPanel ?? DEFAULT_COLORS);
|
|
147
|
+
const breadcrumbTrail = ref([]);
|
|
148
|
+
const currentData = ref(null);
|
|
149
|
+
const animationKey = ref(0);
|
|
150
|
+
const isNestMode = computed(() => props.type === "nest");
|
|
151
|
+
const nestCurrentData = computed(() => {
|
|
152
|
+
if (!isNestMode.value) return null;
|
|
153
|
+
return currentData.value ?? props.data;
|
|
154
|
+
});
|
|
155
|
+
function computeNestLevelData(data) {
|
|
156
|
+
return data.map((item) => {
|
|
157
|
+
const aggregatedValue = sumValues(item, props.dataKey);
|
|
158
|
+
const { children: _, ...rest } = item;
|
|
159
|
+
return {
|
|
160
|
+
...rest,
|
|
161
|
+
[props.dataKey]: aggregatedValue
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
const nodes = computed(() => {
|
|
166
|
+
return computeTreemapLayout({
|
|
167
|
+
data: isNestMode.value ? computeNestLevelData(nestCurrentData.value ?? props.data) : props.data,
|
|
168
|
+
width: props.width,
|
|
169
|
+
height: props.height,
|
|
170
|
+
dataKey: props.dataKey,
|
|
171
|
+
nameKey: props.nameKey,
|
|
172
|
+
aspectRatio: props.aspectRatio,
|
|
173
|
+
colorPanel: colors.value
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
const nodeTree = computed(() => {
|
|
177
|
+
return buildNodeTree(isNestMode.value ? nestCurrentData.value ?? props.data : props.data, props.dataKey, props.nameKey);
|
|
178
|
+
});
|
|
179
|
+
watchEffect((onCleanup) => {
|
|
180
|
+
const tooltipEntrySettings = {
|
|
181
|
+
dataDefinedOnItem: nodeTree.value,
|
|
182
|
+
positions: void 0,
|
|
183
|
+
settings: {
|
|
184
|
+
stroke: props.stroke,
|
|
185
|
+
strokeWidth: void 0,
|
|
186
|
+
fill: props.fill,
|
|
187
|
+
dataKey: props.dataKey,
|
|
188
|
+
nameKey: props.nameKey,
|
|
189
|
+
name: void 0,
|
|
190
|
+
hide: false,
|
|
191
|
+
type: void 0,
|
|
192
|
+
color: props.fill,
|
|
193
|
+
unit: ""
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
dispatch(addTooltipEntrySettings(tooltipEntrySettings));
|
|
197
|
+
onCleanup(() => {
|
|
198
|
+
dispatch(removeTooltipEntrySettings(tooltipEntrySettings));
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
function getTooltipIndex(node) {
|
|
202
|
+
const data = isNestMode.value ? nestCurrentData.value ?? props.data : props.data;
|
|
203
|
+
const idx = data.findIndex((item) => item[props.nameKey] === node.name);
|
|
204
|
+
if (idx >= 0) return `children[${idx}]`;
|
|
205
|
+
for (let i = 0; i < data.length; i++) if (data[i].children) {
|
|
206
|
+
const childIdx = data[i].children.findIndex((c) => c[props.nameKey] === node.name);
|
|
207
|
+
if (childIdx >= 0) return `children[${i}].children[${childIdx}]`;
|
|
208
|
+
}
|
|
209
|
+
return `children[0]`;
|
|
210
|
+
}
|
|
211
|
+
function handleNestClick(node, e) {
|
|
212
|
+
const sourceData = nestCurrentData.value ?? props.data;
|
|
213
|
+
const clickedItem = sourceData.find((item) => item[props.nameKey] === node.name);
|
|
214
|
+
if (clickedItem?.children && clickedItem.children.length > 0) {
|
|
215
|
+
breadcrumbTrail.value = [...breadcrumbTrail.value, {
|
|
216
|
+
name: clickedItem[props.nameKey] ?? clickedItem.name,
|
|
217
|
+
data: sourceData
|
|
218
|
+
}];
|
|
219
|
+
currentData.value = clickedItem.children;
|
|
220
|
+
animationKey.value++;
|
|
221
|
+
}
|
|
222
|
+
props.onClick?.(node, e);
|
|
223
|
+
}
|
|
224
|
+
function navigateToBreadcrumb(index) {
|
|
225
|
+
if (index < 0) {
|
|
226
|
+
currentData.value = null;
|
|
227
|
+
breadcrumbTrail.value = [];
|
|
228
|
+
} else {
|
|
229
|
+
currentData.value = breadcrumbTrail.value[index].data;
|
|
230
|
+
breadcrumbTrail.value = breadcrumbTrail.value.slice(0, index);
|
|
231
|
+
}
|
|
232
|
+
animationKey.value++;
|
|
233
|
+
}
|
|
234
|
+
function getNodeFill(node) {
|
|
235
|
+
return node.color ?? props.fill;
|
|
236
|
+
}
|
|
237
|
+
function handleNodeMouseEnter(node, e) {
|
|
238
|
+
const tooltipIndex = getTooltipIndex(node);
|
|
239
|
+
const activeCoordinate = {
|
|
240
|
+
x: node.x + node.width / 2,
|
|
241
|
+
y: node.y + node.height / 2
|
|
242
|
+
};
|
|
243
|
+
dispatch(setActiveMouseOverItemIndex({
|
|
244
|
+
activeIndex: tooltipIndex,
|
|
245
|
+
activeDataKey: props.dataKey,
|
|
246
|
+
activeCoordinate
|
|
247
|
+
}));
|
|
248
|
+
props.onMouseEnter?.(node, e);
|
|
249
|
+
}
|
|
250
|
+
function handleNodeMouseLeave(node, e) {
|
|
251
|
+
dispatch(mouseLeaveItem());
|
|
252
|
+
props.onMouseLeave?.(node, e);
|
|
253
|
+
}
|
|
254
|
+
function handleNodeClick(node, e) {
|
|
255
|
+
if (isNestMode.value) handleNestClick(node, e);
|
|
256
|
+
else {
|
|
257
|
+
const tooltipIndex = getTooltipIndex(node);
|
|
258
|
+
const activeCoordinate = {
|
|
259
|
+
x: node.x + node.width / 2,
|
|
260
|
+
y: node.y + node.height / 2
|
|
261
|
+
};
|
|
262
|
+
dispatch(setActiveClickItemIndex({
|
|
263
|
+
activeIndex: tooltipIndex,
|
|
264
|
+
activeDataKey: props.dataKey,
|
|
265
|
+
activeCoordinate
|
|
266
|
+
}));
|
|
267
|
+
props.onClick?.(node, e);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function renderNodeAtProgress(node, index, progress) {
|
|
271
|
+
const nodeFill = getNodeFill(node);
|
|
272
|
+
const translateX = (-node.x - node.width) * (1 - progress);
|
|
273
|
+
const transform = progress < 1 ? `translate(${translateX}, 0)` : void 0;
|
|
274
|
+
const nodeProps = {
|
|
275
|
+
...node,
|
|
276
|
+
index,
|
|
277
|
+
fill: nodeFill,
|
|
278
|
+
stroke: props.stroke
|
|
279
|
+
};
|
|
280
|
+
if (slots.content) return createVNode("g", {
|
|
281
|
+
"key": `node-${index}`,
|
|
282
|
+
"class": "v-charts-treemap-node",
|
|
283
|
+
"style": { transformOrigin: `${node.x}px ${node.y}px` },
|
|
284
|
+
"transform": transform,
|
|
285
|
+
"onClick": (e) => handleNodeClick(node, e),
|
|
286
|
+
"onMouseenter": (e) => handleNodeMouseEnter(node, e),
|
|
287
|
+
"onMouseleave": (e) => handleNodeMouseLeave(node, e)
|
|
288
|
+
}, [slots.content(nodeProps)]);
|
|
289
|
+
const arrow = isNestMode.value && (() => {
|
|
290
|
+
const item = (nestCurrentData.value ?? props.data).find((d) => d[props.nameKey] === node.name);
|
|
291
|
+
return item?.children && item.children.length > 0;
|
|
292
|
+
})() && node.width > 10 && node.height > 10 ? createVNode("polygon", {
|
|
293
|
+
"points": `${node.x + 2},${node.y + node.height / 2} ${node.x + 6},${node.y + node.height / 2 + 3} ${node.x + 2},${node.y + node.height / 2 + 6}`,
|
|
294
|
+
"fill": "#fff"
|
|
295
|
+
}, null) : null;
|
|
296
|
+
const nameSize = node.width > 20 && node.height > 20 ? getStringSize(node.name, { fontSize: "14px" }) : {
|
|
297
|
+
width: Infinity,
|
|
298
|
+
height: Infinity
|
|
299
|
+
};
|
|
300
|
+
const text = node.width > 20 && node.height > 20 && nameSize.width < node.width && nameSize.height < node.height ? createVNode("text", {
|
|
301
|
+
"x": node.x + 8,
|
|
302
|
+
"y": node.y + node.height / 2 + 7,
|
|
303
|
+
"fill": "#fff",
|
|
304
|
+
"font-size": 14
|
|
305
|
+
}, [node.name]) : null;
|
|
306
|
+
return createVNode("g", {
|
|
307
|
+
"key": `node-${index}`,
|
|
308
|
+
"class": "v-charts-treemap-node",
|
|
309
|
+
"style": { transformOrigin: `${node.x}px ${node.y}px` },
|
|
310
|
+
"transform": transform,
|
|
311
|
+
"onClick": (e) => handleNodeClick(node, e),
|
|
312
|
+
"onMouseenter": (e) => handleNodeMouseEnter(node, e),
|
|
313
|
+
"onMouseleave": (e) => handleNodeMouseLeave(node, e)
|
|
314
|
+
}, [
|
|
315
|
+
createVNode("rect", {
|
|
316
|
+
"x": node.x,
|
|
317
|
+
"y": node.y,
|
|
318
|
+
"width": node.width,
|
|
319
|
+
"height": node.height,
|
|
320
|
+
"fill": nodeFill,
|
|
321
|
+
"stroke": props.stroke
|
|
322
|
+
}, null),
|
|
323
|
+
arrow,
|
|
324
|
+
text
|
|
325
|
+
]);
|
|
326
|
+
}
|
|
327
|
+
function renderBreadcrumb() {
|
|
328
|
+
if (!isNestMode.value || breadcrumbTrail.value.length === 0) return null;
|
|
329
|
+
return createVNode("div", { "class": "v-charts-treemap-breadcrumb" }, [createVNode("span", {
|
|
330
|
+
"class": "v-charts-treemap-breadcrumb-item",
|
|
331
|
+
"style": { cursor: "pointer" },
|
|
332
|
+
"onClick": () => navigateToBreadcrumb(-1)
|
|
333
|
+
}, [createTextVNode("Root")]), breadcrumbTrail.value.map((entry, i) => createVNode("span", { "key": i }, [createVNode("span", { "style": { margin: "0 4px" } }, [createTextVNode("/")]), createVNode("span", {
|
|
334
|
+
"class": "v-charts-treemap-breadcrumb-item",
|
|
335
|
+
"style": { cursor: "pointer" },
|
|
336
|
+
"onClick": () => navigateToBreadcrumb(i)
|
|
337
|
+
}, [entry.name])]))]);
|
|
338
|
+
}
|
|
339
|
+
return () => createVNode(Fragment, null, [renderBreadcrumb(), createVNode(Surface, {
|
|
340
|
+
"width": props.width,
|
|
341
|
+
"height": props.height
|
|
342
|
+
}, { default: () => [createVNode(Layer, { "class": "v-charts-treemap" }, { default: () => [createVNode(Animate, {
|
|
343
|
+
"key": animationKey.value,
|
|
344
|
+
"isActive": props.isAnimationActive,
|
|
345
|
+
"from": 0,
|
|
346
|
+
"to": 1,
|
|
347
|
+
"transition": props.transition
|
|
348
|
+
}, { default: (progress) => nodes.value.map((node, index) => renderNodeAtProgress(node, index, progress)) })] })] })]);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
/**
|
|
352
|
+
* Treemap chart — hierarchical data visualization using nested rectangles.
|
|
353
|
+
*
|
|
354
|
+
* Supports `<Tooltip>` as a child component (same pattern as BarChart, LineChart, etc.).
|
|
355
|
+
*
|
|
356
|
+
* Usage:
|
|
357
|
+
* ```vue
|
|
358
|
+
* <Treemap :data="data" data-key="value" :width="600" :height="400">
|
|
359
|
+
* <Tooltip />
|
|
360
|
+
* </Treemap>
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
var Treemap = /* @__PURE__ */ defineComponent({
|
|
364
|
+
name: "Treemap",
|
|
365
|
+
props: TreemapVueProps,
|
|
366
|
+
slots: Object,
|
|
367
|
+
setup(props, { slots }) {
|
|
368
|
+
provideStore({ store: createRechartsStore({ options: treemapOptions }, "Treemap") });
|
|
369
|
+
return () => {
|
|
370
|
+
if (!props.data || props.data.length === 0) return null;
|
|
371
|
+
return createVNode(RechartsWrapper, {
|
|
372
|
+
"width": props.width,
|
|
373
|
+
"height": props.height
|
|
374
|
+
}, { default: () => [createVNode(TreemapInner, props, { content: slots.content }), slots.default?.()] });
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
//#endregion
|
|
379
|
+
export { Treemap, TreemapVueProps, treemapPayloadSearcher };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classProp } from "../types/common.mjs";
|
|
1
2
|
import { validateWidthHeight } from "../utils/validate.mjs";
|
|
2
3
|
import { provideClipPathId } from "./provideClipPathId.mjs";
|
|
3
4
|
import { createRechartsStore } from "../state/store.mjs";
|
|
@@ -34,7 +35,7 @@ var CategoricalProps = {
|
|
|
34
35
|
default: 4
|
|
35
36
|
},
|
|
36
37
|
barSize: { type: [Number, String] },
|
|
37
|
-
class:
|
|
38
|
+
class: classProp,
|
|
38
39
|
compact: { type: Boolean },
|
|
39
40
|
cx: { type: [Number, String] },
|
|
40
41
|
cy: { type: [Number, String] },
|
|
@@ -130,7 +131,7 @@ function generateCategoricalChart({ chartName, defaultProps = {}, defaultTooltip
|
|
|
130
131
|
}), { default: () => [createVNode(ClipPath_default, { "clipPathId": clipPathId }, null), slots.default?.()] })
|
|
131
132
|
]);
|
|
132
133
|
if (props.accessibilityLayer) {
|
|
133
|
-
attributes.
|
|
134
|
+
attributes.tabindex = props.tabIndex ?? 0;
|
|
134
135
|
attributes.role = props.role ?? "application";
|
|
135
136
|
}
|
|
136
137
|
const eventHandlerAttrs = {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { hierarchy, treemap, treemapSquarify } from "d3-hierarchy";
|
|
2
|
+
//#region src/chart/treemapUtils.ts
|
|
3
|
+
function computeTreemapLayout(options) {
|
|
4
|
+
const { data, width, height, dataKey, aspectRatio = 4 / 3, nameKey = "name", colorPanel } = options;
|
|
5
|
+
if (!data || data.length === 0 || width <= 0 || height <= 0) return [];
|
|
6
|
+
const root = hierarchy({ children: data }).sum((d) => {
|
|
7
|
+
if (d.children && d.children.length > 0) return 0;
|
|
8
|
+
const val = d[dataKey];
|
|
9
|
+
return typeof val === "number" && val > 0 ? val : 0;
|
|
10
|
+
}).sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
|
|
11
|
+
treemap().size([width, height]).tile(treemapSquarify.ratio(aspectRatio)).round(true)(root);
|
|
12
|
+
return root.leaves().map((leaf) => {
|
|
13
|
+
const d = leaf.data;
|
|
14
|
+
let ancestor = leaf;
|
|
15
|
+
while (ancestor.depth > 1 && ancestor.parent) ancestor = ancestor.parent;
|
|
16
|
+
const rootIndex = ancestor.parent ? ancestor.parent.children.indexOf(ancestor) : 0;
|
|
17
|
+
return {
|
|
18
|
+
x: leaf.x0,
|
|
19
|
+
y: leaf.y0,
|
|
20
|
+
width: leaf.x1 - leaf.x0,
|
|
21
|
+
height: leaf.y1 - leaf.y0,
|
|
22
|
+
depth: leaf.depth,
|
|
23
|
+
name: d[nameKey] ?? "",
|
|
24
|
+
value: leaf.value ?? 0,
|
|
25
|
+
payload: d,
|
|
26
|
+
root: rootIndex,
|
|
27
|
+
color: colorPanel ? colorPanel[rootIndex % colorPanel.length] : void 0
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { computeTreemapLayout };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { selectChartOffset } from "../state/selectors/selectChartOffset.mjs";
|
|
2
|
+
import { selectUnfilteredCartesianItems } from "../state/selectors/axisSelectors.mjs";
|
|
3
|
+
import { useAppSelector } from "../state/hooks.mjs";
|
|
4
|
+
import { useChartHeight, useChartWidth } from "../context/chartLayoutContext.mjs";
|
|
5
|
+
import { computed, defineComponent } from "vue";
|
|
6
|
+
//#region src/components/Customized.tsx
|
|
7
|
+
var Customized = /* @__PURE__ */ defineComponent({
|
|
8
|
+
name: "Customized",
|
|
9
|
+
inheritAttrs: false,
|
|
10
|
+
slots: Object,
|
|
11
|
+
setup(_props, { slots }) {
|
|
12
|
+
const chartWidth = useChartWidth();
|
|
13
|
+
const chartHeight = useChartHeight();
|
|
14
|
+
const offset = useAppSelector(selectChartOffset);
|
|
15
|
+
const cartesianItems = useAppSelector(selectUnfilteredCartesianItems);
|
|
16
|
+
const polarItems = useAppSelector((state) => state.graphicalItems.polarItems);
|
|
17
|
+
const formattedGraphicalItems = computed(() => {
|
|
18
|
+
const items = [];
|
|
19
|
+
for (const item of cartesianItems.value) items.push({
|
|
20
|
+
type: item.type,
|
|
21
|
+
dataKey: item.dataKey,
|
|
22
|
+
props: item
|
|
23
|
+
});
|
|
24
|
+
for (const item of polarItems.value) items.push({
|
|
25
|
+
type: item.type,
|
|
26
|
+
dataKey: item.dataKey,
|
|
27
|
+
props: item
|
|
28
|
+
});
|
|
29
|
+
return items;
|
|
30
|
+
});
|
|
31
|
+
return () => {
|
|
32
|
+
if (!slots.default) return null;
|
|
33
|
+
return slots.default({
|
|
34
|
+
formattedGraphicalItems: formattedGraphicalItems.value,
|
|
35
|
+
chartWidth: chartWidth.value,
|
|
36
|
+
chartHeight: chartHeight.value,
|
|
37
|
+
offset: offset.value
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//#endregion
|
|
43
|
+
export { Customized };
|
|
@@ -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
|
});
|
|
@@ -235,17 +235,15 @@ var Cursor = /* @__PURE__ */ defineComponent({
|
|
|
235
235
|
let cursorElement;
|
|
236
236
|
if (isScatterChart) {
|
|
237
237
|
const { offset: _offset, ...coord } = props.coordinate;
|
|
238
|
-
const { top, left, width, height } = offset.value;
|
|
239
238
|
const crossProps = {
|
|
240
239
|
stroke: "#ccc",
|
|
241
240
|
fill: "none",
|
|
241
|
+
...offset.value,
|
|
242
242
|
...coord,
|
|
243
|
-
top,
|
|
244
|
-
left,
|
|
245
|
-
width,
|
|
246
|
-
height,
|
|
247
243
|
class: "v-charts-tooltip-cursor",
|
|
248
244
|
style: { pointerEvents: "none" },
|
|
245
|
+
payload: props.payload ?? [],
|
|
246
|
+
payloadIndex: props.index,
|
|
249
247
|
...cursorSvgProps
|
|
250
248
|
};
|
|
251
249
|
cursorElement = props.cursorSlot ? props.cursorSlot(crossProps) : createVNode(Cross, crossProps, null);
|
|
@@ -255,6 +253,7 @@ var Cursor = /* @__PURE__ */ defineComponent({
|
|
|
255
253
|
const coord = props.coordinate;
|
|
256
254
|
const off = offset.value;
|
|
257
255
|
const rectProps = {
|
|
256
|
+
...off,
|
|
258
257
|
stroke: "none",
|
|
259
258
|
fill: "#ccc",
|
|
260
259
|
x: layout.value === "horizontal" ? coord.x - halfSize : off.left + .5,
|
|
@@ -263,32 +262,40 @@ var Cursor = /* @__PURE__ */ defineComponent({
|
|
|
263
262
|
height: layout.value === "horizontal" ? off.height - 1 : bandSize,
|
|
264
263
|
class: "v-charts-tooltip-cursor",
|
|
265
264
|
style: { pointerEvents: "none" },
|
|
265
|
+
payload: props.payload ?? [],
|
|
266
|
+
payloadIndex: props.index,
|
|
266
267
|
...cursorSvgProps
|
|
267
268
|
};
|
|
268
269
|
cursorElement = props.cursorSlot ? props.cursorSlot(rectProps) : createVNode(Rectangle, rectProps, null);
|
|
269
270
|
} else if (layout.value === "radial" && props.coordinate?.cx != null) {
|
|
270
271
|
const radialPoints = points.value;
|
|
271
272
|
const sectorProps = {
|
|
273
|
+
stroke: "#ccc",
|
|
274
|
+
...offset.value,
|
|
272
275
|
cx: radialPoints.cx,
|
|
273
276
|
cy: radialPoints.cy,
|
|
274
277
|
startAngle: radialPoints.startAngle,
|
|
275
278
|
endAngle: radialPoints.endAngle,
|
|
276
279
|
innerRadius: radialPoints.radius,
|
|
277
280
|
outerRadius: radialPoints.radius,
|
|
278
|
-
stroke: "#ccc",
|
|
279
281
|
fill: "none",
|
|
280
282
|
class: "v-charts-tooltip-cursor",
|
|
281
283
|
style: { pointerEvents: "none" },
|
|
284
|
+
payload: props.payload ?? [],
|
|
285
|
+
payloadIndex: props.index,
|
|
282
286
|
...cursorSvgProps
|
|
283
287
|
};
|
|
284
288
|
cursorElement = props.cursorSlot ? props.cursorSlot(sectorProps) : createVNode(Sector, sectorProps, null);
|
|
285
289
|
} else {
|
|
286
290
|
const cursorProps = {
|
|
287
291
|
stroke: "#ccc",
|
|
288
|
-
|
|
292
|
+
...offset.value,
|
|
289
293
|
layout: layout.value,
|
|
290
294
|
points: points.value,
|
|
295
|
+
class: ["v-charts-tooltip-cursor"],
|
|
291
296
|
style: { pointerEvents: "none" },
|
|
297
|
+
payload: props.payload ?? [],
|
|
298
|
+
payloadIndex: props.index,
|
|
292
299
|
...cursorSvgProps
|
|
293
300
|
};
|
|
294
301
|
cursorElement = props.cursorSlot ? props.cursorSlot(cursorProps) : createVNode(Curve, cursorProps, null);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classProp } from "../../types/common.mjs";
|
|
1
2
|
import { last } from "es-toolkit/compat";
|
|
2
3
|
//#region src/components/label/types.ts
|
|
3
4
|
var defaultAccessor = (entry) => Array.isArray(entry.value) ? last(entry.value) : entry.value;
|
|
@@ -18,7 +19,7 @@ var LabelListVueProps = {
|
|
|
18
19
|
var LabelVueProps = {
|
|
19
20
|
id: { type: String },
|
|
20
21
|
class: {
|
|
21
|
-
|
|
22
|
+
...classProp,
|
|
22
23
|
default: ""
|
|
23
24
|
},
|
|
24
25
|
viewBox: { type: Object },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import Surface from "../../container/Surface.mjs";
|
|
1
2
|
import { LegendVueProps } from "./type.mjs";
|
|
2
3
|
import { useLegend } from "./hooks/useLegend.mjs";
|
|
3
4
|
import { useLegendContent } from "./hooks/useLegendContent.mjs";
|
|
4
|
-
import Surface from "../../container/Surface.mjs";
|
|
5
5
|
import { LegendSymbol } from "./LegendSymbol.mjs";
|
|
6
6
|
import { Teleport, createVNode, defineComponent, isVNode, watchEffect } from "vue";
|
|
7
7
|
//#region src/components/legend/Legend.tsx
|
|
@@ -34,14 +34,19 @@ function useLegend(props) {
|
|
|
34
34
|
return Array.from(finalPayload);
|
|
35
35
|
});
|
|
36
36
|
const outerStyle = computed(() => {
|
|
37
|
-
|
|
37
|
+
const userStyle = props.wrapperStyle ? { ...props.wrapperStyle } : {};
|
|
38
|
+
if (props.portal) return userStyle;
|
|
38
39
|
const baseStyle = {
|
|
39
40
|
position: "absolute",
|
|
40
41
|
width: widthOrHeight.value?.width ? `${widthOrHeight.value.width}px` : props.width ? `${props.width}px` : "auto",
|
|
41
42
|
height: widthOrHeight.value?.height ? `${widthOrHeight.value.height}px` : props.height ? `${props.height}px` : "auto"
|
|
42
43
|
};
|
|
43
|
-
const positionStyle = getDefaultPosition(
|
|
44
|
-
return
|
|
44
|
+
const positionStyle = getDefaultPosition(userStyle, props, margin.value, chartWidth.value, chartHeight.value, boundingBox.value);
|
|
45
|
+
return {
|
|
46
|
+
...baseStyle,
|
|
47
|
+
...positionStyle,
|
|
48
|
+
...userStyle
|
|
49
|
+
};
|
|
45
50
|
});
|
|
46
51
|
const legendPortal = computed(() => props.portal ?? legendPortalFromContext?.value);
|
|
47
52
|
const syncSettings = () => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classProp } from "../types/common.mjs";
|
|
1
2
|
import { createVNode, defineComponent, mergeProps } from "vue";
|
|
2
3
|
//#region src/container/Surface.tsx
|
|
3
4
|
/**
|
|
@@ -18,10 +19,7 @@ var Surface = /* @__PURE__ */ defineComponent({
|
|
|
18
19
|
type: Object,
|
|
19
20
|
default: void 0
|
|
20
21
|
},
|
|
21
|
-
class:
|
|
22
|
-
type: String,
|
|
23
|
-
default: void 0
|
|
24
|
-
},
|
|
22
|
+
class: classProp,
|
|
25
23
|
style: {
|
|
26
24
|
type: Object,
|
|
27
25
|
default: void 0
|