@automattic/charts 0.27.0 → 0.29.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/CHANGELOG.md +11 -0
- package/dist/cjs/components/bar-chart/bar-chart.js +16 -6
- package/dist/cjs/components/leaderboard-chart/leaderboard-chart.js +6 -2
- package/dist/cjs/components/legend/base-legend.js +6 -2
- package/dist/cjs/components/legend/use-chart-legend-data.js +6 -2
- package/dist/cjs/components/line-chart/line-chart-annotation.js +7 -4
- package/dist/cjs/components/line-chart/line-chart.js +16 -6
- package/dist/cjs/components/pie-chart/index.js +1 -0
- package/dist/cjs/components/pie-chart/pie-chart.js +61 -31
- package/dist/cjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js +57 -19
- package/dist/cjs/components/shared/chart-composition/chart-html.js +22 -0
- package/dist/cjs/components/shared/chart-composition/chart-svg.js +22 -0
- package/dist/cjs/components/shared/chart-composition/use-chart-children.js +55 -0
- package/dist/cjs/hooks/use-chart-mouse-handler.js +1 -3
- package/dist/cjs/hooks/use-deep-memo.js +21 -0
- package/dist/cjs/hooks/use-global-chart-theme.js +28 -0
- package/dist/cjs/hooks/use-xychart-theme.js +20 -0
- package/dist/cjs/index.js +9 -1
- package/dist/cjs/providers/chart-context/global-charts-provider.js +5 -2
- package/dist/cjs/providers/chart-context/utils.js +11 -5
- package/dist/cjs/providers/theme/index.js +0 -1
- package/dist/cjs/providers/theme/theme-provider.js +2 -18
- package/dist/cjs/utils/merge-themes.js +21 -0
- package/dist/mjs/components/bar-chart/bar-chart.js +15 -5
- package/dist/mjs/components/leaderboard-chart/leaderboard-chart.js +6 -2
- package/dist/mjs/components/legend/base-legend.js +6 -2
- package/dist/mjs/components/legend/use-chart-legend-data.js +6 -2
- package/dist/mjs/components/line-chart/line-chart-annotation.js +7 -4
- package/dist/mjs/components/line-chart/line-chart.js +15 -5
- package/dist/mjs/components/pie-chart/index.js +1 -1
- package/dist/mjs/components/pie-chart/pie-chart.js +60 -31
- package/dist/mjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js +59 -21
- package/dist/mjs/components/shared/chart-composition/chart-html.js +20 -0
- package/dist/mjs/components/shared/chart-composition/chart-svg.js +20 -0
- package/dist/mjs/components/shared/chart-composition/use-chart-children.js +53 -0
- package/dist/mjs/hooks/use-chart-mouse-handler.js +1 -1
- package/dist/mjs/hooks/use-deep-memo.js +19 -0
- package/dist/mjs/hooks/use-global-chart-theme.js +26 -0
- package/dist/mjs/hooks/use-xychart-theme.js +18 -0
- package/dist/mjs/index.js +5 -1
- package/dist/mjs/providers/chart-context/global-charts-provider.js +6 -3
- package/dist/mjs/providers/chart-context/utils.js +11 -5
- package/dist/mjs/providers/theme/index.js +1 -1
- package/dist/mjs/providers/theme/theme-provider.js +4 -19
- package/dist/mjs/utils/merge-themes.js +19 -0
- package/dist/types/components/bar-list-chart/bar-list-chart.d.ts +1 -1
- package/dist/types/components/legend/base-legend.d.ts +9 -9
- package/dist/types/components/legend/use-chart-legend-data.d.ts +2 -3
- package/dist/types/components/pie-chart/index.d.ts +1 -1
- package/dist/types/components/pie-chart/pie-chart.d.ts +9 -5
- package/dist/types/components/pie-semi-circle-chart/pie-semi-circle-chart.d.ts +11 -4
- package/dist/types/components/shared/chart-composition/types.d.ts +19 -0
- package/dist/types/hooks/use-chart-mouse-handler.d.ts +1 -1
- package/dist/types/hooks/use-deep-memo.d.ts +10 -0
- package/dist/types/hooks/use-global-chart-theme.d.ts +14 -0
- package/dist/types/hooks/use-xychart-theme.d.ts +6 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/providers/chart-context/global-charts-provider.d.ts +3 -0
- package/dist/types/providers/chart-context/types.d.ts +2 -1
- package/dist/types/providers/chart-context/utils.d.ts +7 -2
- package/dist/types/providers/theme/index.d.ts +1 -1
- package/dist/types/providers/theme/theme-provider.d.ts +3 -5
- package/dist/types/utils/merge-themes.d.ts +13 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.29.0] - 2025-08-25
|
|
9
|
+
### Changed
|
|
10
|
+
- Charts: consolidate and clean up pie chart composition api. [#44856]
|
|
11
|
+
|
|
12
|
+
## [0.28.0] - 2025-08-21
|
|
13
|
+
### Added
|
|
14
|
+
- Charts: adds composition legend to pie family charts [#44796]
|
|
15
|
+
- Charts: Add theme to global context and use instead of that from theme provider [#44809]
|
|
16
|
+
|
|
8
17
|
## [0.27.0] - 2025-08-18
|
|
9
18
|
### Added
|
|
10
19
|
- Add support for custom labels in the leaderboard chart for greater flexibility. [#44751]
|
|
@@ -375,6 +384,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
375
384
|
- Fixed lints following ESLint rule changes for TS [#40584]
|
|
376
385
|
- Fixing a bug in Chart storybook data. [#40640]
|
|
377
386
|
|
|
387
|
+
[0.29.0]: https://github.com/Automattic/charts/compare/v0.28.0...v0.29.0
|
|
388
|
+
[0.28.0]: https://github.com/Automattic/charts/compare/v0.27.0...v0.28.0
|
|
378
389
|
[0.27.0]: https://github.com/Automattic/charts/compare/v0.26.0...v0.27.0
|
|
379
390
|
[0.26.0]: https://github.com/Automattic/charts/compare/v0.25.0...v0.26.0
|
|
380
391
|
[0.25.0]: https://github.com/Automattic/charts/compare/v0.24.0...v0.25.0
|
|
@@ -8,9 +8,13 @@ var xychart = require('@visx/xychart');
|
|
|
8
8
|
var i18n = require('@wordpress/i18n');
|
|
9
9
|
var clsx = require('clsx');
|
|
10
10
|
var react = require('react');
|
|
11
|
+
require('fast-deep-equal');
|
|
12
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
13
|
+
require('@visx/event');
|
|
14
|
+
require('@visx/tooltip');
|
|
15
|
+
var useXychartTheme = require('../../hooks/use-xychart-theme.js');
|
|
11
16
|
var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
|
|
12
17
|
var utils = require('../../providers/chart-context/utils.js');
|
|
13
|
-
var themeProvider = require('../../providers/theme/theme-provider.js');
|
|
14
18
|
var createComposition = require('../../utils/create-composition.js');
|
|
15
19
|
var legend = require('../legend/legend.js');
|
|
16
20
|
require('../legend/base-legend.js');
|
|
@@ -42,15 +46,15 @@ const getPatternId = (chartId, index) => `bar-pattern-${chartId}-${index}`;
|
|
|
42
46
|
const BarChartInternal = ({ data, chartId: providedChartId, width, height = 400, className, margin, withTooltips = false, showLegend = false, legendOrientation = 'horizontal', legendPosition = 'bottom', legendAlignment = 'center', legendShape = 'rect', gridVisibility: gridVisibilityProp, renderTooltip, options = {}, orientation = 'vertical', withPatterns = false, showZeroValues = false, children, }) => {
|
|
43
47
|
const horizontal = orientation === 'horizontal';
|
|
44
48
|
const chartId = utils.useChartId(providedChartId);
|
|
45
|
-
const providerTheme =
|
|
46
|
-
const theme =
|
|
49
|
+
const providerTheme = useGlobalChartTheme.useGlobalChartTheme();
|
|
50
|
+
const theme = useXychartTheme.useXYChartTheme(data);
|
|
47
51
|
const dataSorted = useChartDataTransform.useChartDataTransform(data);
|
|
48
52
|
// Transform data to add a small value for zero bars to make them visible
|
|
49
53
|
const dataWithVisibleZeros = useZeroValueDisplay.useZeroValueDisplay(dataSorted, {
|
|
50
54
|
enabled: showZeroValues,
|
|
51
55
|
});
|
|
52
56
|
// Create legend items using the reusable hook
|
|
53
|
-
const legendItems = useChartLegendData.useChartLegendData(dataSorted
|
|
57
|
+
const legendItems = useChartLegendData.useChartLegendData(dataSorted);
|
|
54
58
|
const chartOptions = useBarChartOptions.useBarChartOptions(dataWithVisibleZeros, horizontal, options);
|
|
55
59
|
const defaultMargin = useChartMargin.useChartMargin(height, chartOptions, dataSorted, theme, horizontal);
|
|
56
60
|
const [legendRef, legendHeight] = useElementHeight.useElementHeight();
|
|
@@ -67,7 +71,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height = 400,
|
|
|
67
71
|
chartRef,
|
|
68
72
|
totalPoints,
|
|
69
73
|
});
|
|
70
|
-
const getColor = react.useCallback((seriesData, index) => seriesData?.options?.stroke ||
|
|
74
|
+
const getColor = react.useCallback((seriesData, index) => seriesData?.options?.stroke || providerTheme.colors[index % providerTheme.colors.length], [providerTheme]);
|
|
71
75
|
const getBarBackground = react.useCallback((index) => () => withPatterns
|
|
72
76
|
? `url(#${getPatternId(chartId, index)})`
|
|
73
77
|
: getColor(dataSorted[index], index), [withPatterns, getColor, dataSorted, chartId]);
|
|
@@ -146,7 +150,13 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height = 400,
|
|
|
146
150
|
withPatterns,
|
|
147
151
|
}), [orientation, withPatterns]);
|
|
148
152
|
// Register chart with context only if data is valid
|
|
149
|
-
utils.useChartRegistration(
|
|
153
|
+
utils.useChartRegistration({
|
|
154
|
+
chartId,
|
|
155
|
+
legendItems,
|
|
156
|
+
chartType: 'bar',
|
|
157
|
+
isDataValid,
|
|
158
|
+
metadata: chartMetadata,
|
|
159
|
+
});
|
|
150
160
|
if (error) {
|
|
151
161
|
return jsxRuntime.jsx("div", { className: clsx('bar-chart', barChart_module.default['bar-chart']), children: error });
|
|
152
162
|
}
|
|
@@ -7,7 +7,11 @@ var components = require('@wordpress/components');
|
|
|
7
7
|
var element = require('@wordpress/element');
|
|
8
8
|
var clsx = require('clsx');
|
|
9
9
|
require('react');
|
|
10
|
-
|
|
10
|
+
require('fast-deep-equal');
|
|
11
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
12
|
+
require('@visx/event');
|
|
13
|
+
require('@visx/tooltip');
|
|
14
|
+
require('@visx/xychart');
|
|
11
15
|
var formatMetricValue = require('../shared/format-metric-value.js');
|
|
12
16
|
var leaderboardChart_module = require('./leaderboard-chart.module.scss.js');
|
|
13
17
|
|
|
@@ -66,7 +70,7 @@ const ProgressBarWithLabel = ({ entry, withComparison, }) => (jsxRuntime.jsxs(js
|
|
|
66
70
|
* @return JSX element representing the leaderboard chart
|
|
67
71
|
*/
|
|
68
72
|
const LeaderboardChart = ({ data, withComparison = false, withOverlayLabel = false, primaryColor, secondaryColor, valueFormatter = defaultValueFormatter, deltaFormatter = defaultDeltaFormatter, loading = false, className, style, }) => {
|
|
69
|
-
const theme =
|
|
73
|
+
const theme = useGlobalChartTheme.useGlobalChartTheme();
|
|
70
74
|
// Get component settings from theme with fallbacks
|
|
71
75
|
const leaderboardSettings = theme.leaderboardChart;
|
|
72
76
|
const labelSpacing = leaderboardSettings?.labelSpacing ?? DEFAULT_LEADERBOARD_SETTINGS.labelSpacing;
|
|
@@ -6,7 +6,11 @@ var legend = require('@visx/legend');
|
|
|
6
6
|
var scale = require('@visx/scale');
|
|
7
7
|
var clsx = require('clsx');
|
|
8
8
|
var react = require('react');
|
|
9
|
-
|
|
9
|
+
require('fast-deep-equal');
|
|
10
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
11
|
+
require('@visx/event');
|
|
12
|
+
require('@visx/tooltip');
|
|
13
|
+
require('@visx/xychart');
|
|
10
14
|
var legend_module = require('./legend.module.scss.js');
|
|
11
15
|
var utils = require('./utils.js');
|
|
12
16
|
|
|
@@ -20,7 +24,7 @@ const orientationToFlexDirection = {
|
|
|
20
24
|
*/
|
|
21
25
|
const BaseLegend = react.forwardRef(({ items, className, orientation = 'horizontal', position = 'bottom', alignment = 'center', shape = 'rect', fill = utils.valueOrIdentityString, size = utils.valueOrIdentityString, labelFormat = utils.valueOrIdentity, labelTransform = utils.labelTransformFactory, shapeWidth = 16, shapeHeight = 16, shapeMargin = '2px 4px 2px 0', labelAlign = 'left', labelFlex = '0 0 auto', // Use natural width instead of expanding to fill space
|
|
22
26
|
labelMargin = '0 4px', itemMargin = '0', itemDirection = 'row', legendLabelProps, ...legendItemProps }, ref) => {
|
|
23
|
-
const theme =
|
|
27
|
+
const theme = useGlobalChartTheme.useGlobalChartTheme();
|
|
24
28
|
const legendScale = scale.scaleOrdinal({
|
|
25
29
|
domain: items.map(item => item.label),
|
|
26
30
|
range: items.map(item => item.color),
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require('@visx/xychart');
|
|
4
4
|
var react = require('react');
|
|
5
|
+
require('fast-deep-equal');
|
|
6
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
7
|
+
require('@visx/event');
|
|
8
|
+
require('@visx/tooltip');
|
|
5
9
|
var getStyles = require('../../utils/get-styles.js');
|
|
6
10
|
|
|
7
11
|
/**
|
|
@@ -92,13 +96,13 @@ function processPointData(pointData, theme, showValues, withGlyph, glyphSize, re
|
|
|
92
96
|
/**
|
|
93
97
|
* Hook to transform chart data into legend items
|
|
94
98
|
* @param data - The chart data to transform
|
|
95
|
-
* @param theme - The chart theme for colors
|
|
96
99
|
* @param options - Configuration options for legend generation
|
|
97
100
|
* @param legendShape - The shape type for legend items (string literal or React component)
|
|
98
101
|
* @return Array of legend items ready for display
|
|
99
102
|
*/
|
|
100
|
-
function useChartLegendData(data,
|
|
103
|
+
function useChartLegendData(data, options = {}, legendShape) {
|
|
101
104
|
const { showValues = false, withGlyph = false, glyphSize = 8, renderGlyph } = options;
|
|
105
|
+
const theme = useGlobalChartTheme.useGlobalChartTheme();
|
|
102
106
|
return react.useMemo(() => {
|
|
103
107
|
if (!data || !Array.isArray(data) || data.length === 0) {
|
|
104
108
|
return [];
|
|
@@ -5,9 +5,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var annotation = require('@visx/annotation');
|
|
7
7
|
var xychart = require('@visx/xychart');
|
|
8
|
-
var
|
|
8
|
+
var deepmerge = require('deepmerge');
|
|
9
9
|
var react = require('react');
|
|
10
|
-
|
|
10
|
+
require('fast-deep-equal');
|
|
11
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
12
|
+
require('@visx/event');
|
|
13
|
+
require('@visx/tooltip');
|
|
11
14
|
var utils = require('../shared/utils.js');
|
|
12
15
|
var lineChartAnnotationLabelPopover = require('./line-chart-annotation-label-popover.js');
|
|
13
16
|
|
|
@@ -91,12 +94,12 @@ const getVerticalAnchor = (subjectType, isFlippedVertically, y, yMax, height) =>
|
|
|
91
94
|
return undefined;
|
|
92
95
|
};
|
|
93
96
|
const LineChartAnnotation = ({ datum, title, subtitle, subjectType = 'circle', styles: datumStyles, testId, renderLabel, renderLabelPopover, }) => {
|
|
94
|
-
const providerTheme =
|
|
97
|
+
const providerTheme = useGlobalChartTheme.useGlobalChartTheme();
|
|
95
98
|
const { xScale, yScale } = react.useContext(xychart.DataContext) || {};
|
|
96
99
|
const labelRef = react.useRef(null);
|
|
97
100
|
const [height, setHeight] = react.useState(null);
|
|
98
101
|
// Deep merge styles to preserve nested object properties
|
|
99
|
-
const styles =
|
|
102
|
+
const styles = deepmerge(providerTheme.annotationStyles ?? {}, datumStyles ?? {});
|
|
100
103
|
// Measure the label height once after initial render
|
|
101
104
|
react.useEffect(() => {
|
|
102
105
|
if (labelRef.current?.getBBox) {
|
|
@@ -10,9 +10,13 @@ var gradient = require('@visx/gradient');
|
|
|
10
10
|
var xychart = require('@visx/xychart');
|
|
11
11
|
var i18n = require('@wordpress/i18n');
|
|
12
12
|
var clsx = require('clsx');
|
|
13
|
+
require('fast-deep-equal');
|
|
14
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
15
|
+
require('@visx/event');
|
|
16
|
+
require('@visx/tooltip');
|
|
17
|
+
var useXychartTheme = require('../../hooks/use-xychart-theme.js');
|
|
13
18
|
var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
|
|
14
19
|
var utils = require('../../providers/chart-context/utils.js');
|
|
15
|
-
var themeProvider = require('../../providers/theme/theme-provider.js');
|
|
16
20
|
var createComposition = require('../../utils/create-composition.js');
|
|
17
21
|
var getStyles = require('../../utils/get-styles.js');
|
|
18
22
|
var legend = require('../legend/legend.js');
|
|
@@ -137,8 +141,8 @@ const LineChartScalesRef = ({ chartRef, width, height, margin }) => {
|
|
|
137
141
|
return null; // This component only provides the ref interface
|
|
138
142
|
};
|
|
139
143
|
const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legendOrientation = 'horizontal', legendAlignment = 'center', legendPosition = 'bottom', renderGlyph = defaultRenderGlyph, glyphStyle = {}, legendShape = 'line', withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, withStartGlyphs = false, options = {}, onPointerDown = undefined, onPointerUp = undefined, onPointerMove = undefined, onPointerOut = undefined, children, }, ref) => {
|
|
140
|
-
const providerTheme =
|
|
141
|
-
const theme =
|
|
144
|
+
const providerTheme = useGlobalChartTheme.useGlobalChartTheme();
|
|
145
|
+
const theme = useXychartTheme.useXYChartTheme(data);
|
|
142
146
|
const chartId = utils.useChartId(providedChartId);
|
|
143
147
|
const [legendRef, legendHeight] = useElementHeight.useElementHeight();
|
|
144
148
|
const chartRef = react.useRef(null);
|
|
@@ -206,7 +210,7 @@ const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, wi
|
|
|
206
210
|
renderGlyph,
|
|
207
211
|
}), [withLegendGlyph, glyphStyle?.radius, renderGlyph]);
|
|
208
212
|
// Create legend items using the reusable hook
|
|
209
|
-
const legendItems = useChartLegendData.useChartLegendData(dataSorted,
|
|
213
|
+
const legendItems = useChartLegendData.useChartLegendData(dataSorted, legendOptions, legendShape);
|
|
210
214
|
// Memoize metadata to prevent unnecessary re-registration
|
|
211
215
|
const chartMetadata = react.useMemo(() => ({
|
|
212
216
|
withGradientFill,
|
|
@@ -216,7 +220,13 @@ const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, wi
|
|
|
216
220
|
withLegendGlyph,
|
|
217
221
|
}), [withGradientFill, smoothing, curveType, withStartGlyphs, withLegendGlyph]);
|
|
218
222
|
// Register chart with context only if data is valid
|
|
219
|
-
utils.useChartRegistration(
|
|
223
|
+
utils.useChartRegistration({
|
|
224
|
+
chartId,
|
|
225
|
+
legendItems,
|
|
226
|
+
chartType: 'line',
|
|
227
|
+
isDataValid,
|
|
228
|
+
metadata: chartMetadata,
|
|
229
|
+
});
|
|
220
230
|
const accessors = {
|
|
221
231
|
xAccessor: (d) => d?.date,
|
|
222
232
|
yAccessor: (d) => d?.value,
|
|
@@ -250,7 +260,7 @@ const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, wi
|
|
|
250
260
|
stroke,
|
|
251
261
|
...lineStyles,
|
|
252
262
|
};
|
|
253
|
-
return (jsxRuntime.jsxs("g", { children: [withStartGlyphs && (jsxRuntime.jsx(StartGlyph, { index: index, data: seriesData, color: stroke, renderGlyph: providerTheme.glyphs?.[index] ?? renderGlyph, accessors: accessors, glyphStyle: glyphStyle })), withGradientFill && (jsxRuntime.jsx(gradient.LinearGradient, { id: `area-gradient-${chartId}-${index + 1}`, from: stroke, fromOpacity: 0.4, toOpacity: 0.1, to:
|
|
263
|
+
return (jsxRuntime.jsxs("g", { children: [withStartGlyphs && (jsxRuntime.jsx(StartGlyph, { index: index, data: seriesData, color: stroke, renderGlyph: providerTheme.glyphs?.[index] ?? renderGlyph, accessors: accessors, glyphStyle: glyphStyle })), withGradientFill && (jsxRuntime.jsx(gradient.LinearGradient, { id: `area-gradient-${chartId}-${index + 1}`, from: stroke, fromOpacity: 0.4, toOpacity: 0.1, to: providerTheme.backgroundColor, ...seriesData.options?.gradient, "data-testid": "line-gradient" })), jsxRuntime.jsx(xychart.AreaSeries, { dataKey: seriesData?.label, data: seriesData.data, ...accessors, fill: withGradientFill
|
|
254
264
|
? `url(#area-gradient-${chartId}-${index + 1})`
|
|
255
265
|
: 'transparent', renderLine: true, curve: getCurveType(curveType, smoothing), lineProps: lineProps }, seriesData?.label)] }, seriesData?.label || index));
|
|
256
266
|
}), withTooltips && (jsxRuntime.jsx(accessibleTooltip.AccessibleTooltip, { detectBounds: true, snapTooltipToDatumX: true, snapTooltipToDatumY: true, showSeriesGlyphs: true, renderTooltip: renderTooltip, renderGlyph: tooltipRenderGlyph, glyphStyle: glyphStyle, showVerticalCrosshair: withTooltipCrosshairs?.showVertical, showHorizontalCrosshair: withTooltipCrosshairs?.showHorizontal, selectedIndex: selectedIndex, tooltipRef: tooltipRef, keyboardFocusedClassName: lineChart_module.default['line-chart__tooltip--keyboard-focused'], series: dataSorted })), jsxRuntime.jsx(LineChartScalesRef, { chartRef: internalChartRef, width: width, height: height, margin: margin })] }) }), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, alignment: legendAlignment, position: legendPosition, className: lineChart_module.default['line-chart-legend'], shape: legendShape, chartId: chartId, ref: legendRef })), children] }) }));
|
|
@@ -7,14 +7,20 @@ var group = require('@visx/group');
|
|
|
7
7
|
var shape = require('@visx/shape');
|
|
8
8
|
var clsx = require('clsx');
|
|
9
9
|
var react = require('react');
|
|
10
|
+
require('fast-deep-equal');
|
|
11
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
10
12
|
var useChartMouseHandler = require('../../hooks/use-chart-mouse-handler.js');
|
|
13
|
+
require('@visx/xychart');
|
|
11
14
|
var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
|
|
12
15
|
var utils = require('../../providers/chart-context/utils.js');
|
|
13
|
-
var
|
|
14
|
-
var themes = require('../../providers/theme/themes.js');
|
|
16
|
+
var createComposition = require('../../utils/create-composition.js');
|
|
15
17
|
var legend = require('../legend/legend.js');
|
|
16
18
|
require('../legend/base-legend.js');
|
|
17
19
|
var useChartLegendData = require('../legend/use-chart-legend-data.js');
|
|
20
|
+
var chartSvg = require('../shared/chart-composition/chart-svg.js');
|
|
21
|
+
var chartHtml = require('../shared/chart-composition/chart-html.js');
|
|
22
|
+
var useChartChildren = require('../shared/chart-composition/use-chart-children.js');
|
|
23
|
+
var singleChartContext = require('../shared/single-chart-context.js');
|
|
18
24
|
var useElementHeight = require('../shared/use-element-height.js');
|
|
19
25
|
var withResponsive = require('../shared/with-responsive.js');
|
|
20
26
|
var baseTooltip = require('../tooltip/base-tooltip.js');
|
|
@@ -49,17 +55,19 @@ const validateData = (data) => {
|
|
|
49
55
|
* @return {JSX.Element} The rendered chart component
|
|
50
56
|
*/
|
|
51
57
|
const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false, className, showLegend = false, legendOrientation = 'horizontal', legendPosition = 'bottom', legendAlignment = 'center', legendShape = 'circle', size, thickness = 1, padding = 20, gapScale = 0, cornerScale = 0, children = null, }) => {
|
|
52
|
-
const providerTheme =
|
|
58
|
+
const providerTheme = useGlobalChartTheme.useGlobalChartTheme();
|
|
53
59
|
const chartId = utils.useChartId(providedChartId);
|
|
54
60
|
const [legendRef, legendHeight] = useElementHeight.useElementHeight();
|
|
55
|
-
const { onMouseMove, onMouseLeave, tooltipOpen, tooltipData, tooltipLeft, tooltipTop } = useChartMouseHandler.
|
|
61
|
+
const { onMouseMove, onMouseLeave, tooltipOpen, tooltipData, tooltipLeft, tooltipTop } = useChartMouseHandler.useChartMouseHandler({
|
|
56
62
|
withTooltips,
|
|
57
63
|
});
|
|
58
64
|
// Memoize legend options to prevent unnecessary re-calculations
|
|
59
65
|
const legendOptions = react.useMemo(() => ({ showValues: true }), []);
|
|
60
66
|
// Create legend items using the reusable hook
|
|
61
|
-
const legendItems = useChartLegendData.useChartLegendData(data,
|
|
67
|
+
const legendItems = useChartLegendData.useChartLegendData(data, legendOptions);
|
|
62
68
|
const { isValid, message } = validateData(data);
|
|
69
|
+
// Process children to extract compound components
|
|
70
|
+
const { svgChildren, htmlChildren, otherChildren } = useChartChildren.useChartChildren(children, 'PieChart');
|
|
63
71
|
// Memoize metadata to prevent unnecessary re-registration
|
|
64
72
|
const chartMetadata = react.useMemo(() => ({
|
|
65
73
|
thickness,
|
|
@@ -67,7 +75,13 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
67
75
|
cornerScale,
|
|
68
76
|
}), [thickness, gapScale, cornerScale]);
|
|
69
77
|
// Register chart with context only if data is valid
|
|
70
|
-
utils.useChartRegistration(
|
|
78
|
+
utils.useChartRegistration({
|
|
79
|
+
chartId,
|
|
80
|
+
legendItems,
|
|
81
|
+
chartType: 'pie',
|
|
82
|
+
isDataValid: isValid,
|
|
83
|
+
metadata: chartMetadata,
|
|
84
|
+
});
|
|
71
85
|
if (!isValid) {
|
|
72
86
|
return (jsxRuntime.jsx("div", { className: clsx('pie-chart', pieChart_module.default['pie-chart'], className), children: jsxRuntime.jsx("div", { className: pieChart_module.default['error-message'], children: message }) }));
|
|
73
87
|
}
|
|
@@ -95,29 +109,33 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
95
109
|
// Use the color property from the data object as a last resort. The theme provides colours by default.
|
|
96
110
|
fill: (d) => d?.color || providerTheme.colors[d.index],
|
|
97
111
|
};
|
|
98
|
-
return (jsxRuntime.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
return (jsxRuntime.jsx(singleChartContext.SingleChartContext.Provider, { value: {
|
|
113
|
+
chartId,
|
|
114
|
+
chartWidth: size,
|
|
115
|
+
chartHeight: adjustedHeight,
|
|
116
|
+
}, children: jsxRuntime.jsxs("div", { className: clsx('pie-chart', pieChart_module.default['pie-chart'], className), style: {
|
|
117
|
+
display: 'flex',
|
|
118
|
+
flexDirection: showLegend && legendPosition === 'top' ? 'column-reverse' : 'column',
|
|
119
|
+
}, children: [jsxRuntime.jsx("svg", { viewBox: `0 0 ${size} ${adjustedHeight}`, preserveAspectRatio: "xMidYMid meet", width: size, height: adjustedHeight, children: jsxRuntime.jsxs(group.Group, { top: centerY, left: centerX, children: [jsxRuntime.jsx(shape.Pie, { data: dataWithIndex, pieValue: accessors.value, outerRadius: outerRadius, innerRadius: innerRadius, padAngle: padAngle, cornerRadius: cornerRadius, children: pie => {
|
|
120
|
+
return pie.arcs.map((arc, index) => {
|
|
121
|
+
const [centroidX, centroidY] = pie.path.centroid(arc);
|
|
122
|
+
const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.25;
|
|
123
|
+
const handleMouseMove = (event) => onMouseMove(event, arc.data);
|
|
124
|
+
const pathProps = {
|
|
125
|
+
d: pie.path(arc) || '',
|
|
126
|
+
fill: accessors.fill(arc.data),
|
|
127
|
+
};
|
|
128
|
+
if (withTooltips) {
|
|
129
|
+
pathProps.onMouseMove = handleMouseMove;
|
|
130
|
+
pathProps.onMouseLeave = onMouseLeave;
|
|
131
|
+
}
|
|
132
|
+
return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("path", { ...pathProps }), hasSpaceForLabel && (jsxRuntime.jsx("text", { x: centroidX, y: centroidY, dy: ".33em", fill: providerTheme.labelBackgroundColor || '#333', fontSize: 12, textAnchor: "middle", pointerEvents: "none", children: arc.data.label }))] }, `arc-${index}`));
|
|
133
|
+
});
|
|
134
|
+
} }), svgChildren] }) }), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, position: legendPosition, alignment: legendAlignment, className: pieChart_module.default['pie-chart-legend'], shape: legendShape, ref: legendRef, chartId: chartId })), withTooltips && tooltipOpen && tooltipData && (jsxRuntime.jsx(baseTooltip.BaseTooltip, { data: tooltipData, top: tooltipTop || 0, left: tooltipLeft || 0, style: {
|
|
135
|
+
transform: 'translate(-50%, -100%)',
|
|
136
|
+
} })), htmlChildren, otherChildren] }) }));
|
|
119
137
|
};
|
|
120
|
-
const
|
|
138
|
+
const PieChartWithProvider = props => {
|
|
121
139
|
const existingContext = react.useContext(globalChartsProvider.GlobalChartsContext);
|
|
122
140
|
// If we're already in a GlobalChartsProvider context, don't create a new one
|
|
123
141
|
if (existingContext) {
|
|
@@ -126,7 +144,19 @@ const PieChart = (props) => {
|
|
|
126
144
|
// Otherwise, create our own GlobalChartsProvider
|
|
127
145
|
return (jsxRuntime.jsx(globalChartsProvider.GlobalChartsProvider, { children: jsxRuntime.jsx(PieChartInternal, { ...props }) }));
|
|
128
146
|
};
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
PieChartWithProvider.displayName = 'PieChart';
|
|
148
|
+
// Create PieChart with composition API
|
|
149
|
+
const PieChart = createComposition.attachSubComponents(PieChartWithProvider, {
|
|
150
|
+
Legend: legend.Legend,
|
|
151
|
+
SVG: chartSvg.ChartSVG,
|
|
152
|
+
HTML: chartHtml.ChartHTML,
|
|
153
|
+
});
|
|
154
|
+
// Create responsive PieChart with composition API
|
|
155
|
+
const PieChartResponsive = createComposition.attachSubComponents(withResponsive.withResponsive(PieChartWithProvider), {
|
|
156
|
+
Legend: legend.Legend,
|
|
157
|
+
SVG: chartSvg.ChartSVG,
|
|
158
|
+
HTML: chartHtml.ChartHTML,
|
|
159
|
+
});
|
|
131
160
|
|
|
132
|
-
exports.
|
|
161
|
+
exports.PieChartUnresponsive = PieChart;
|
|
162
|
+
exports.default = PieChartResponsive;
|
|
@@ -10,12 +10,19 @@ var text = require('@visx/text');
|
|
|
10
10
|
var tooltip = require('@visx/tooltip');
|
|
11
11
|
var clsx = require('clsx');
|
|
12
12
|
var react = require('react');
|
|
13
|
+
require('fast-deep-equal');
|
|
14
|
+
var useGlobalChartTheme = require('../../hooks/use-global-chart-theme.js');
|
|
15
|
+
require('@visx/xychart');
|
|
13
16
|
var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
|
|
14
17
|
var utils = require('../../providers/chart-context/utils.js');
|
|
15
|
-
var
|
|
18
|
+
var createComposition = require('../../utils/create-composition.js');
|
|
16
19
|
var legend = require('../legend/legend.js');
|
|
17
20
|
require('../legend/base-legend.js');
|
|
18
21
|
var useChartLegendData = require('../legend/use-chart-legend-data.js');
|
|
22
|
+
var chartSvg = require('../shared/chart-composition/chart-svg.js');
|
|
23
|
+
var chartHtml = require('../shared/chart-composition/chart-html.js');
|
|
24
|
+
var useChartChildren = require('../shared/chart-composition/use-chart-children.js');
|
|
25
|
+
var singleChartContext = require('../shared/single-chart-context.js');
|
|
19
26
|
var useElementHeight = require('../shared/use-element-height.js');
|
|
20
27
|
var withResponsive = require('../shared/with-responsive.js');
|
|
21
28
|
var baseTooltip = require('../tooltip/base-tooltip.js');
|
|
@@ -43,8 +50,8 @@ const validateData = (data) => {
|
|
|
43
50
|
}
|
|
44
51
|
return { isValid: true, message: '' };
|
|
45
52
|
};
|
|
46
|
-
const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 400, thickness = 0.4, clockwise = true, withTooltips = false, showLegend = false, legendOrientation = 'horizontal', legendPosition = 'bottom', legendAlignment = 'center', legendShape = 'circle', label, note, className, }) => {
|
|
47
|
-
const providerTheme =
|
|
53
|
+
const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 400, thickness = 0.4, clockwise = true, withTooltips = false, showLegend = false, legendOrientation = 'horizontal', legendPosition = 'bottom', legendAlignment = 'center', legendShape = 'circle', label, note, className, children, }) => {
|
|
54
|
+
const providerTheme = useGlobalChartTheme.useGlobalChartTheme();
|
|
48
55
|
const chartId = utils.useChartId(providedChartId);
|
|
49
56
|
const [legendRef, legendHeight] = useElementHeight.useElementHeight();
|
|
50
57
|
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = tooltip.useTooltip();
|
|
@@ -76,14 +83,22 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 40
|
|
|
76
83
|
// Memoize legend options to prevent unnecessary re-calculations
|
|
77
84
|
const legendOptions = react.useMemo(() => ({ showValues: true }), []);
|
|
78
85
|
// Create legend items using the reusable hook
|
|
79
|
-
const legendItems = useChartLegendData.useChartLegendData(data,
|
|
86
|
+
const legendItems = useChartLegendData.useChartLegendData(data, legendOptions);
|
|
87
|
+
// Process children to extract compound components
|
|
88
|
+
const { svgChildren, htmlChildren, otherChildren } = useChartChildren.useChartChildren(children, 'PieSemiCircleChart');
|
|
80
89
|
// Memoize metadata to prevent unnecessary re-registration
|
|
81
90
|
const chartMetadata = react.useMemo(() => ({
|
|
82
91
|
thickness,
|
|
83
92
|
clockwise,
|
|
84
93
|
}), [thickness, clockwise]);
|
|
85
94
|
// Register chart with context only if data is valid
|
|
86
|
-
utils.useChartRegistration(
|
|
95
|
+
utils.useChartRegistration({
|
|
96
|
+
chartId,
|
|
97
|
+
legendItems,
|
|
98
|
+
chartType: 'pie-semi-circle',
|
|
99
|
+
isDataValid: isValid,
|
|
100
|
+
metadata: chartMetadata,
|
|
101
|
+
});
|
|
87
102
|
if (!isValid) {
|
|
88
103
|
return (jsxRuntime.jsx("div", { className: pieSemiCircleChart_module.default['pie-semi-circle-chart'], children: jsxRuntime.jsx("svg", { width: width, height: width / 2, "data-testid": "pie-chart-svg", children: jsxRuntime.jsx("text", { x: "50%", y: "50%", textAnchor: "middle", className: pieSemiCircleChart_module.default.error, children: message }) }) }));
|
|
89
104
|
}
|
|
@@ -102,19 +117,42 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 40
|
|
|
102
117
|
// Configure pie angles based on clockwise direction
|
|
103
118
|
const startAngle = clockwise ? -Math.PI / 2 : Math.PI / 2;
|
|
104
119
|
const endAngle = clockwise ? Math.PI / 2 : -Math.PI / 2;
|
|
105
|
-
return (jsxRuntime.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
return (jsxRuntime.jsx(singleChartContext.SingleChartContext.Provider, { value: {
|
|
121
|
+
chartId,
|
|
122
|
+
chartWidth: width,
|
|
123
|
+
chartHeight: radius,
|
|
124
|
+
}, children: jsxRuntime.jsxs("div", { className: clsx('pie-semi-circle-chart', pieSemiCircleChart_module.default['pie-semi-circle-chart'], className), "data-testid": "pie-chart-container", style: {
|
|
125
|
+
display: 'flex',
|
|
126
|
+
flexDirection: showLegend && legendPosition === 'top' ? 'column-reverse' : 'column',
|
|
127
|
+
}, children: [jsxRuntime.jsx("svg", { width: width, height: radius, viewBox: `0 0 ${width} ${chartHeight}`, "data-testid": "pie-chart-svg", children: jsxRuntime.jsxs(group.Group, { top: chartHeight, left: width / 2, children: [jsxRuntime.jsx(shape.Pie, { data: dataWithIndex, pieValue: accessors.value, outerRadius: radius, innerRadius: innerRadius, cornerRadius: 3, padAngle: PAD_ANGLE, startAngle: startAngle, endAngle: endAngle, pieSort: accessors.sort, children: pie => {
|
|
128
|
+
return pie.arcs.map(arc => (jsxRuntime.jsx("g", { onMouseMove: handleArcMouseMove(arc), onMouseLeave: handleMouseLeave, children: jsxRuntime.jsx("path", { d: pie.path(arc) || '', fill: accessors.fill(arc.data), "data-testid": "pie-segment" }) }, arc.data.label)));
|
|
129
|
+
} }), jsxRuntime.jsxs(group.Group, { children: [jsxRuntime.jsx(text.Text, { textAnchor: "middle", verticalAnchor: "start", y: -40, className: pieSemiCircleChart_module.default.label, children: label }), jsxRuntime.jsx(text.Text, { textAnchor: "middle", verticalAnchor: "start", y: -20, className: pieSemiCircleChart_module.default.note, children: note })] }), svgChildren] }) }), withTooltips && tooltipOpen && tooltipData && (jsxRuntime.jsx(baseTooltip.BaseTooltip, { data: {
|
|
130
|
+
label: tooltipData.label,
|
|
131
|
+
value: tooltipData.value,
|
|
132
|
+
valueDisplay: tooltipData.valueDisplay,
|
|
133
|
+
}, top: tooltipTop || 0, left: tooltipLeft || 0 })), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, position: legendPosition, alignment: legendAlignment, shape: legendShape, ref: legendRef, chartId: chartId })), htmlChildren, otherChildren] }) }));
|
|
115
134
|
};
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
135
|
+
const PieSemiCircleChartWithProvider = props => {
|
|
136
|
+
const existingContext = react.useContext(globalChartsProvider.GlobalChartsContext);
|
|
137
|
+
// If we're already in a GlobalChartsProvider context, don't create a new one
|
|
138
|
+
if (existingContext) {
|
|
139
|
+
return jsxRuntime.jsx(PieSemiCircleChartInternal, { ...props });
|
|
140
|
+
}
|
|
141
|
+
// Otherwise, create our own GlobalChartsProvider
|
|
142
|
+
return (jsxRuntime.jsx(globalChartsProvider.GlobalChartsProvider, { children: jsxRuntime.jsx(PieSemiCircleChartInternal, { ...props }) }));
|
|
143
|
+
};
|
|
144
|
+
PieSemiCircleChartWithProvider.displayName = 'PieSemiCircleChart';
|
|
145
|
+
// Create PieSemiCircleChart with composition API
|
|
146
|
+
createComposition.attachSubComponents(PieSemiCircleChartWithProvider, {
|
|
147
|
+
Legend: legend.Legend,
|
|
148
|
+
SVG: chartSvg.ChartSVG,
|
|
149
|
+
HTML: chartHtml.ChartHTML,
|
|
150
|
+
});
|
|
151
|
+
// Create responsive PieSemiCircleChart with composition API
|
|
152
|
+
const PieSemiCircleChartResponsive = createComposition.attachSubComponents(withResponsive.withResponsive(PieSemiCircleChartWithProvider), {
|
|
153
|
+
Legend: legend.Legend,
|
|
154
|
+
SVG: chartSvg.ChartSVG,
|
|
155
|
+
HTML: chartHtml.ChartHTML,
|
|
156
|
+
});
|
|
119
157
|
|
|
120
|
-
exports.default =
|
|
158
|
+
exports.default = PieSemiCircleChartResponsive;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compound component for HTML children in charts.
|
|
7
|
+
* This component serves as a marker for HTML content that should be rendered
|
|
8
|
+
* outside the chart's SVG element. The actual rendering is handled by the parent chart.
|
|
9
|
+
*
|
|
10
|
+
* @param {PropsWithChildren} props - Component props
|
|
11
|
+
* @param {ReactNode} props.children - Child elements to render outside the SVG
|
|
12
|
+
* @return {JSX.Element} The children wrapped in a fragment
|
|
13
|
+
*/
|
|
14
|
+
const ChartHTML = ({ children }) => {
|
|
15
|
+
// This component doesn't render directly - its children are extracted by the parent chart
|
|
16
|
+
// We just return the children as-is
|
|
17
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: children });
|
|
18
|
+
};
|
|
19
|
+
// Set displayName for better debugging and type checking
|
|
20
|
+
ChartHTML.displayName = 'Chart.HTML';
|
|
21
|
+
|
|
22
|
+
exports.ChartHTML = ChartHTML;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compound component for SVG children in charts.
|
|
7
|
+
* This component serves as a marker for SVG content that should be rendered
|
|
8
|
+
* inside the chart's SVG element. The actual rendering is handled by the parent chart.
|
|
9
|
+
*
|
|
10
|
+
* @param {PropsWithChildren} props - Component props
|
|
11
|
+
* @param {ReactNode} props.children - Child elements to render inside the SVG
|
|
12
|
+
* @return {JSX.Element} The children wrapped in a fragment
|
|
13
|
+
*/
|
|
14
|
+
const ChartSVG = ({ children }) => {
|
|
15
|
+
// This component doesn't render directly - its children are extracted by the parent chart
|
|
16
|
+
// We just return the children as-is
|
|
17
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: children });
|
|
18
|
+
};
|
|
19
|
+
// Set displayName for better debugging and type checking
|
|
20
|
+
ChartSVG.displayName = 'Chart.SVG';
|
|
21
|
+
|
|
22
|
+
exports.ChartSVG = ChartSVG;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var group = require('@visx/group');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Custom hook to process and categorize chart children for composition API.
|
|
8
|
+
* Extracts children from compound components (Chart.SVG, Chart.HTML) and
|
|
9
|
+
* maintains backward compatibility with legacy Group components.
|
|
10
|
+
*
|
|
11
|
+
* @param {ReactNode} children - The children prop from the chart component
|
|
12
|
+
* @param {string} chartType - The type of chart (e.g., 'PieChart', 'BarChart')
|
|
13
|
+
* @return {ChartChildren} Categorized children for rendering
|
|
14
|
+
*/
|
|
15
|
+
function useChartChildren(children, chartType) {
|
|
16
|
+
return react.useMemo(() => {
|
|
17
|
+
const svg = [];
|
|
18
|
+
const html = [];
|
|
19
|
+
const other = [];
|
|
20
|
+
react.Children.forEach(children, child => {
|
|
21
|
+
if (react.isValidElement(child)) {
|
|
22
|
+
// Check displayName for compound components
|
|
23
|
+
const childType = child.type;
|
|
24
|
+
const displayName = childType?.displayName;
|
|
25
|
+
// Handle chart-specific compound components (e.g., PieChart.SVG)
|
|
26
|
+
if (displayName === `${chartType}.SVG` || displayName === 'Chart.SVG') {
|
|
27
|
+
// Extract children from Chart.SVG with safety checks
|
|
28
|
+
if (child.props?.children) {
|
|
29
|
+
react.Children.forEach(child.props.children, svgChild => {
|
|
30
|
+
svg.push(svgChild);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (displayName === `${chartType}.HTML` || displayName === 'Chart.HTML') {
|
|
35
|
+
// Extract children from Chart.HTML with safety checks
|
|
36
|
+
if (child.props?.children) {
|
|
37
|
+
react.Children.forEach(child.props.children, htmlChild => {
|
|
38
|
+
html.push(htmlChild);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (child.type === group.Group) {
|
|
43
|
+
// Legacy support: still check for Group type for backward compatibility
|
|
44
|
+
svg.push(child);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
other.push(child);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return { svgChildren: svg, htmlChildren: html, otherChildren: other };
|
|
52
|
+
}, [children, chartType]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
exports.useChartChildren = useChartChildren;
|