@automattic/charts 0.25.0 → 0.26.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/components/bar-chart/bar-chart.js +35 -22
  3. package/dist/cjs/components/legend/base-legend.js +4 -8
  4. package/dist/cjs/components/legend/legend.js +13 -6
  5. package/dist/cjs/components/legend/legend.module.scss.js +1 -1
  6. package/dist/cjs/components/legend/use-chart-legend-data.js +20 -12
  7. package/dist/cjs/components/line-chart/line-chart-annotations-overlay.js +2 -2
  8. package/dist/cjs/components/line-chart/line-chart.js +29 -23
  9. package/dist/cjs/components/pie-chart/pie-chart.js +9 -9
  10. package/dist/cjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js +6 -6
  11. package/dist/cjs/components/shared/single-chart-context.js +20 -0
  12. package/dist/cjs/providers/chart-context/{chart-context.js → global-charts-provider.js} +9 -9
  13. package/dist/cjs/providers/chart-context/index.js +4 -4
  14. package/dist/cjs/providers/chart-context/utils.js +2 -2
  15. package/dist/cjs/providers/theme/themes.js +25 -0
  16. package/dist/cjs/style.css +1 -1
  17. package/dist/cjs/utils/create-composition.js +17 -0
  18. package/dist/cjs/utils/get-styles.js +75 -0
  19. package/dist/mjs/components/bar-chart/bar-chart.js +35 -22
  20. package/dist/mjs/components/bar-list-chart/bar-list-chart.js +2 -2
  21. package/dist/mjs/components/legend/base-legend.js +4 -8
  22. package/dist/mjs/components/legend/legend.js +13 -6
  23. package/dist/mjs/components/legend/legend.module.scss.js +1 -1
  24. package/dist/mjs/components/legend/use-chart-legend-data.js +20 -12
  25. package/dist/mjs/components/line-chart/line-chart-annotations-overlay.js +2 -2
  26. package/dist/mjs/components/line-chart/line-chart.js +29 -22
  27. package/dist/mjs/components/pie-chart/pie-chart.js +9 -9
  28. package/dist/mjs/components/pie-semi-circle-chart/pie-semi-circle-chart.js +6 -6
  29. package/dist/mjs/components/shared/single-chart-context.js +15 -0
  30. package/dist/mjs/providers/chart-context/{chart-context.js → global-charts-provider.js} +7 -7
  31. package/dist/mjs/providers/chart-context/index.js +1 -1
  32. package/dist/mjs/providers/chart-context/utils.js +2 -2
  33. package/dist/mjs/providers/theme/themes.js +25 -0
  34. package/dist/mjs/style.css +1 -1
  35. package/dist/mjs/utils/create-composition.js +15 -0
  36. package/dist/mjs/utils/get-styles.js +70 -0
  37. package/dist/types/components/bar-chart/bar-chart.d.ts +11 -5
  38. package/dist/types/components/bar-list-chart/bar-list-chart.d.ts +1 -1
  39. package/dist/types/components/legend/base-legend.d.ts +2 -2
  40. package/dist/types/components/legend/types.d.ts +7 -4
  41. package/dist/types/components/legend/use-chart-legend-data.d.ts +6 -4
  42. package/dist/types/components/line-chart/line-chart.d.ts +9 -7
  43. package/dist/types/components/{line-chart/line-chart-context.d.ts → shared/single-chart-context.d.ts} +3 -2
  44. package/dist/types/index.d.ts +1 -1
  45. package/dist/types/providers/chart-context/global-charts-provider.d.ts +12 -0
  46. package/dist/types/providers/chart-context/index.d.ts +1 -1
  47. package/dist/types/types.d.ts +23 -17
  48. package/package.json +3 -3
  49. package/dist/cjs/components/line-chart/line-chart-context.js +0 -15
  50. package/dist/mjs/components/line-chart/line-chart-context.js +0 -12
  51. package/dist/types/providers/chart-context/chart-context.d.ts +0 -12
package/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ 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.26.0] - 2025-08-14
9
+ ### Added
10
+ - Bar Chart: Add composition API. [#44771]
11
+ - Line Chart: Add composition legends. [#44691]
12
+ - Line Chart: Add comparison style to theme. [#44676]
13
+
14
+ ### Changed
15
+ - Updated legend positioning and alignment. [#44747]
16
+ - Update package dependencies. [#44701]
17
+
8
18
  ## [0.25.0] - 2025-08-11
9
19
  ### Added
10
20
  - Add internationalization. [#44652]
@@ -361,6 +371,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
361
371
  - Fixed lints following ESLint rule changes for TS [#40584]
362
372
  - Fixing a bug in Chart storybook data. [#40640]
363
373
 
374
+ [0.26.0]: https://github.com/Automattic/charts/compare/v0.25.0...v0.26.0
364
375
  [0.25.0]: https://github.com/Automattic/charts/compare/v0.24.0...v0.25.0
365
376
  [0.24.0]: https://github.com/Automattic/charts/compare/v0.23.1...v0.24.0
366
377
  [0.23.1]: https://github.com/Automattic/charts/compare/v0.23.0...v0.23.1
@@ -8,12 +8,14 @@ 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
- var chartContext = require('../../providers/chart-context/chart-context.js');
11
+ var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
12
12
  var utils = require('../../providers/chart-context/utils.js');
13
13
  var themeProvider = require('../../providers/theme/theme-provider.js');
14
+ var createComposition = require('../../utils/create-composition.js');
14
15
  var legend = require('../legend/legend.js');
15
16
  require('../legend/base-legend.js');
16
17
  var useChartLegendData = require('../legend/use-chart-legend-data.js');
18
+ var singleChartContext = require('../shared/single-chart-context.js');
17
19
  var useChartDataTransform = require('../shared/use-chart-data-transform.js');
18
20
  var useChartMargin = require('../shared/use-chart-margin.js');
19
21
  var useElementHeight = require('../shared/use-element-height.js');
@@ -37,7 +39,7 @@ const validateData = (data) => {
37
39
  return null;
38
40
  };
39
41
  const getPatternId = (chartId, index) => `bar-pattern-${chartId}-${index}`;
40
- const BarChartInternal = ({ data, chartId: providedChartId, width, height = 400, className, margin, withTooltips = false, showLegend = false, legendOrientation = 'horizontal', legendAlignmentHorizontal = 'center', legendAlignmentVertical = 'bottom', legendShape = 'rect', gridVisibility: gridVisibilityProp, renderTooltip, options = {}, orientation = 'vertical', withPatterns = false, showZeroValues = false, }) => {
42
+ 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, }) => {
41
43
  const horizontal = orientation === 'horizontal';
42
44
  const chartId = utils.useChartId(providedChartId);
43
45
  const providerTheme = themeProvider.useChartTheme();
@@ -150,29 +152,40 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height = 400,
150
152
  }
151
153
  const gridVisibility = gridVisibilityProp ?? chartOptions.gridVisibility;
152
154
  const highlightedBarStyle = createKeyboardHighlightStyle();
153
- return (jsxRuntime.jsxs("div", { className: clsx('bar-chart', barChart_module.default['bar-chart'], className), "data-testid": "bar-chart", role: "grid", "aria-label": i18n.__('Bar chart', 'jetpack-charts'), style: {
154
- width,
155
- height,
156
- display: 'flex',
157
- flexDirection: showLegend && legendAlignmentVertical === 'top' ? 'column-reverse' : 'column',
158
- }, tabIndex: 0, onKeyDown: onChartKeyDown, onFocus: onChartFocus, onBlur: onChartBlur, ref: chartRef, "data-chart-id": `bar-chart-${chartId}`, children: [jsxRuntime.jsxs(xychart.XYChart, { theme: theme, width: width, height: height - (showLegend ? legendHeight : 0), margin: {
159
- ...defaultMargin,
160
- ...margin,
161
- ...(showLegend && legendAlignmentVertical === 'top'
162
- ? { top: (defaultMargin.top || 0) + legendHeight }
163
- : {}),
164
- }, xScale: chartOptions.xScale, yScale: chartOptions.yScale, horizontal: horizontal, pointerEventsDataKey: "nearest", children: [jsxRuntime.jsx(xychart.Grid, { columns: gridVisibility.includes('y'), rows: gridVisibility.includes('x'), numTicks: 4 }), withPatterns && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("defs", { "data-testid": "bar-chart-patterns", children: dataSorted.map((seriesData, index) => renderPattern(index, getColor(seriesData, index))) }), jsxRuntime.jsx("style", { children: dataSorted.map((seriesData, index) => createPatternBorderStyle(index, getColor(seriesData, index))) })] })), highlightedBarStyle && jsxRuntime.jsx("style", { children: highlightedBarStyle }), jsxRuntime.jsx(xychart.BarGroup, { padding: chartOptions.barGroup.padding, children: dataWithVisibleZeros.map((seriesData, index) => (jsxRuntime.jsx(xychart.BarSeries, { dataKey: seriesData?.label, data: seriesData.data, yAccessor: chartOptions.accessors.yAccessor, xAccessor: chartOptions.accessors.xAccessor, colorAccessor: getBarBackground(index) }, seriesData?.label))) }), jsxRuntime.jsx(xychart.Axis, { ...chartOptions.axis.x }), jsxRuntime.jsx(xychart.Axis, { ...chartOptions.axis.y }), withTooltips && (jsxRuntime.jsx(accessibleTooltip.AccessibleTooltip, { detectBounds: true, snapTooltipToDatumX: true, snapTooltipToDatumY: true, renderTooltip: renderTooltip || renderDefaultTooltip, selectedIndex: selectedIndex, tooltipRef: tooltipRef, keyboardFocusedClassName: barChart_module.default['bar-chart__tooltip--keyboard-focused'], series: data, mode: "individual" }))] }), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, alignmentHorizontal: legendAlignmentHorizontal, alignmentVertical: legendAlignmentVertical, className: barChart_module.default['bar-chart__legend'], shape: legendShape, ref: legendRef, chartId: chartId }))] }));
155
+ return (jsxRuntime.jsx(singleChartContext.SingleChartContext.Provider, { value: {
156
+ chartId,
157
+ chartWidth: width,
158
+ chartHeight: height - (showLegend ? legendHeight : 0),
159
+ }, children: jsxRuntime.jsxs("div", { className: clsx('bar-chart', barChart_module.default['bar-chart'], className), "data-testid": "bar-chart", role: "grid", "aria-label": i18n.__('Bar chart', 'jetpack-charts'), style: {
160
+ width,
161
+ height,
162
+ display: 'flex',
163
+ flexDirection: showLegend && legendPosition === 'top' ? 'column-reverse' : 'column',
164
+ }, tabIndex: 0, onKeyDown: onChartKeyDown, onFocus: onChartFocus, onBlur: onChartBlur, ref: chartRef, "data-chart-id": `bar-chart-${chartId}`, children: [jsxRuntime.jsxs(xychart.XYChart, { theme: theme, width: width, height: height - (showLegend ? legendHeight : 0), margin: {
165
+ ...defaultMargin,
166
+ ...margin,
167
+ ...(showLegend && legendPosition === 'top'
168
+ ? { top: (defaultMargin.top || 0) + legendHeight }
169
+ : {}),
170
+ }, xScale: chartOptions.xScale, yScale: chartOptions.yScale, horizontal: horizontal, pointerEventsDataKey: "nearest", children: [jsxRuntime.jsx(xychart.Grid, { columns: gridVisibility.includes('y'), rows: gridVisibility.includes('x'), numTicks: 4 }), withPatterns && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("defs", { "data-testid": "bar-chart-patterns", children: dataSorted.map((seriesData, index) => renderPattern(index, getColor(seriesData, index))) }), jsxRuntime.jsx("style", { children: dataSorted.map((seriesData, index) => createPatternBorderStyle(index, getColor(seriesData, index))) })] })), highlightedBarStyle && jsxRuntime.jsx("style", { children: highlightedBarStyle }), jsxRuntime.jsx(xychart.BarGroup, { padding: chartOptions.barGroup.padding, children: dataWithVisibleZeros.map((seriesData, index) => (jsxRuntime.jsx(xychart.BarSeries, { dataKey: seriesData?.label, data: seriesData.data, yAccessor: chartOptions.accessors.yAccessor, xAccessor: chartOptions.accessors.xAccessor, colorAccessor: getBarBackground(index) }, seriesData?.label))) }), jsxRuntime.jsx(xychart.Axis, { ...chartOptions.axis.x }), jsxRuntime.jsx(xychart.Axis, { ...chartOptions.axis.y }), withTooltips && (jsxRuntime.jsx(accessibleTooltip.AccessibleTooltip, { detectBounds: true, snapTooltipToDatumX: true, snapTooltipToDatumY: true, renderTooltip: renderTooltip || renderDefaultTooltip, selectedIndex: selectedIndex, tooltipRef: tooltipRef, keyboardFocusedClassName: barChart_module.default['bar-chart__tooltip--keyboard-focused'], series: data, mode: "individual" }))] }), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, position: legendPosition, alignment: legendAlignment, className: barChart_module.default['bar-chart__legend'], shape: legendShape, ref: legendRef, chartId: chartId })), children] }) }));
165
171
  };
166
- const BarChart = props => {
167
- const existingContext = react.useContext(chartContext.ChartContext);
168
- // If we're already in a ChartProvider context, don't create a new one
172
+ const BarChartWithProvider = props => {
173
+ const existingContext = react.useContext(globalChartsProvider.GlobalChartsContext);
174
+ // If we're already in a GlobalChartsProvider context, don't create a new one
169
175
  if (existingContext) {
170
176
  return jsxRuntime.jsx(BarChartInternal, { ...props });
171
177
  }
172
- // Otherwise, create our own ChartProvider
173
- return (jsxRuntime.jsx(chartContext.ChartProvider, { children: jsxRuntime.jsx(BarChartInternal, { ...props }) }));
178
+ // Otherwise, create our own GlobalChartsProvider
179
+ return (jsxRuntime.jsx(globalChartsProvider.GlobalChartsProvider, { children: jsxRuntime.jsx(BarChartInternal, { ...props }) }));
174
180
  };
175
- BarChart.displayName = 'BarChart';
176
- var BarChart$1 = withResponsive.withResponsive(BarChart);
181
+ BarChartWithProvider.displayName = 'BarChart';
182
+ // Create BarChart with composition API
183
+ createComposition.attachSubComponents(BarChartWithProvider, {
184
+ Legend: legend.Legend,
185
+ });
186
+ // Create responsive BarChart with composition API
187
+ const BarChartResponsive = createComposition.attachSubComponents(withResponsive.withResponsive(BarChartWithProvider), {
188
+ Legend: legend.Legend,
189
+ });
177
190
 
178
- exports.default = BarChart$1;
191
+ exports.default = BarChartResponsive;
@@ -18,7 +18,7 @@ const orientationToFlexDirection = {
18
18
  * Base legend component that displays color-coded items with labels based on visx LegendOrdinal.
19
19
  * We avoid using LegendOrdinal directly to enable support for advanced features such as interactivity.
20
20
  */
21
- const BaseLegend = react.forwardRef(({ items, className, orientation = 'horizontal', alignmentHorizontal = 'center', alignmentVertical = 'bottom', 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
21
+ 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
22
  labelMargin = '0 4px', itemMargin = '0', itemDirection = 'row', legendLabelProps, ...legendItemProps }, ref) => {
23
23
  const theme = themeProvider.useChartTheme();
24
24
  const legendScale = scale.scaleOrdinal({
@@ -27,15 +27,11 @@ labelMargin = '0 4px', itemMargin = '0', itemDirection = 'row', legendLabelProps
27
27
  });
28
28
  const domain = legendScale.domain();
29
29
  // For right-aligned vertical legends, use row-reverse to align text consistently
30
- const getShapeStyle = react.useCallback(({ index }) => {
31
- return items[index]?.shapeStyle ?? theme.legendShapeStyles?.[index] ?? {};
32
- }, [items, theme]);
33
- return (jsxRuntime.jsx(legend.LegendOrdinal, { scale: legendScale, labelFormat: labelFormat, labelTransform: labelTransform, children: labels => (jsxRuntime.jsx("div", { ref: ref, role: "list", "data-testid": `legend-${orientation}`, className: clsx(legend_module.default.legend, legend_module.default[`legend--${orientation}`], legend_module.default[`legend--horizontal-align-${alignmentHorizontal}`], legend_module.default[`legend--vertical-align-${alignmentVertical}`], className), style: {
30
+ const getShapeStyle = react.useCallback(({ index }) => items[index]?.shapeStyle, [items]);
31
+ return (jsxRuntime.jsx(legend.LegendOrdinal, { scale: legendScale, labelFormat: labelFormat, labelTransform: labelTransform, children: labels => (jsxRuntime.jsx("div", { ref: ref, role: "list", "data-testid": `legend-${orientation}`, className: clsx(legend_module.default.legend, legend_module.default[`legend--${orientation}`], legend_module.default[`legend--alignment-${alignment}`], legend_module.default[`legend--position-${position}`], className), style: {
34
32
  flexDirection: orientationToFlexDirection[orientation],
35
33
  ...theme.legendContainerStyles,
36
- }, children: labels.map((label, i) => (jsxRuntime.jsxs(legend.LegendItem, { className: legend_module.default['legend-item'], "data-testid": "legend-item", margin: itemMargin, flexDirection: orientation === 'vertical' && alignmentHorizontal === 'right'
37
- ? 'row-reverse'
38
- : itemDirection, ...legendItemProps, children: [items[i]?.renderGlyph ? (jsxRuntime.jsx("svg", { width: items[i]?.glyphSize * 2, height: items[i]?.glyphSize * 2, "data-testid": "legend-glyph", children: jsxRuntime.jsx(group.Group, { children: items[i]?.renderGlyph({
34
+ }, children: labels.map((label, i) => (jsxRuntime.jsxs(legend.LegendItem, { className: legend_module.default['legend-item'], "data-testid": "legend-item", margin: itemMargin, flexDirection: orientation === 'vertical' && alignment === 'end' ? 'row-reverse' : itemDirection, ...legendItemProps, children: [items[i]?.renderGlyph ? (jsxRuntime.jsx("svg", { width: items[i]?.glyphSize * 2, height: items[i]?.glyphSize * 2, "data-testid": "legend-glyph", children: jsxRuntime.jsx(group.Group, { children: items[i]?.renderGlyph({
39
35
  key: `legend-glyph-${label.text}`,
40
36
  datum: {},
41
37
  index: i,
@@ -2,18 +2,25 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var react = require('react');
5
- var chartContext = require('../../providers/chart-context/chart-context.js');
5
+ var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
6
+ var singleChartContext = require('../shared/single-chart-context.js');
6
7
  var baseLegend = require('./base-legend.js');
7
8
 
8
9
  const Legend = react.forwardRef(({ chartId, items, ...props }, ref) => {
9
10
  // Get context but don't throw if it doesn't exist
10
- const context = react.useContext(chartContext.ChartContext);
11
+ const context = react.useContext(globalChartsProvider.GlobalChartsContext);
12
+ const singleChartContext$1 = react.useContext(singleChartContext.SingleChartContext);
13
+ // When chartId is used, it is standalone mode
14
+ // When chartId is not provided, we use the context's chartId, meaning it is in a single chart context
15
+ const contextChartId = chartId ?? singleChartContext$1?.chartId;
11
16
  // Use useMemo to ensure re-rendering when context changes
12
17
  const contextItems = react.useMemo(() => {
13
- return chartId && context ? context.getChartData(chartId)?.legendItems : undefined;
14
- }, [chartId, context]);
15
- // Use context items if available, otherwise fall back to provided items
16
- const legendItems = (contextItems || items);
18
+ return contextChartId && context
19
+ ? context.getChartData(contextChartId)?.legendItems
20
+ : undefined;
21
+ }, [contextChartId, context]);
22
+ // Provided items take precedence over context items
23
+ const legendItems = (items || contextItems);
17
24
  if (!legendItems) {
18
25
  return null;
19
26
  }
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var styles = {"legend--horizontal":"legend-module_legend--horizontal__IUN13","legend--vertical":"legend-module_legend--vertical__Scfzo","legend--horizontal-align-left":"legend-module_legend--horizontal-align-left__w2O7z","legend--horizontal-align-center":"legend-module_legend--horizontal-align-center__Fmcxd","legend--horizontal-align-right":"legend-module_legend--horizontal-align-right__tKgER","legend--vertical-align-top":"legend-module_legend--vertical-align-top__l6G1I","legend--vertical-align-bottom":"legend-module_legend--vertical-align-bottom__UzHCY","legend-item":"legend-module_legend-item__feemn","legend-item-label":"legend-module_legend-item-label__ksx6I","legend-item-value":"legend-module_legend-item-value__d9x1j"};
5
+ var styles = {"legend--horizontal":"legend-module_legend--horizontal__IUN13","legend--vertical":"legend-module_legend--vertical__Scfzo","legend--alignment-start":"legend-module_legend--alignment-start__Na2Qp","legend--alignment-center":"legend-module_legend--alignment-center__FVB2r","legend--alignment-end":"legend-module_legend--alignment-end__6Vuay","legend--position-top":"legend-module_legend--position-top__uh7-2","legend--position-bottom":"legend-module_legend--position-bottom__6Q3j-","legend-item":"legend-module_legend-item__feemn","legend-item-label":"legend-module_legend-item-label__ksx6I","legend-item-value":"legend-module_legend-item-value__d9x1j"};
6
6
 
7
7
  exports.default = styles;
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ require('@visx/xychart');
3
4
  var react = require('react');
5
+ var getStyles = require('../../utils/get-styles.js');
4
6
 
5
7
  /**
6
8
  * Formats the value for a data point based on its type
@@ -22,16 +24,18 @@ function formatPointValue(point, showValues) {
22
24
  }
23
25
  /**
24
26
  * Creates a base legend item with common properties
25
- * @param label - The label for the legend item
26
- * @param value - The value for the legend item
27
- * @param color - The color for the legend item
27
+ * @param label - The label for the legend item
28
+ * @param value - The value for the legend item
29
+ * @param color - The color for the legend item
30
+ * @param shapeStyle - The shape style for the legend item
28
31
  * @return Base legend item object
29
32
  */
30
- function createBaseLegendItem(label, value, color) {
33
+ function createBaseLegendItem(label, value, color, shapeStyle) {
31
34
  return {
32
35
  label,
33
36
  value,
34
37
  color,
38
+ shapeStyle,
35
39
  };
36
40
  }
37
41
  /**
@@ -42,11 +46,14 @@ function createBaseLegendItem(label, value, color) {
42
46
  * @param withGlyph - Whether to include glyph rendering
43
47
  * @param glyphSize - Size of the glyph
44
48
  * @param renderGlyph - Component to render the glyph
49
+ * @param legendShape - The shape to use for the legend
45
50
  * @return Array of processed legend items
46
51
  */
47
- function processSeriesData(seriesData, theme, showValues, withGlyph, glyphSize, renderGlyph) {
52
+ function processSeriesData(seriesData, theme, showValues, withGlyph, glyphSize, renderGlyph, legendShape) {
48
53
  const mapper = (series, index) => {
49
- const baseItem = createBaseLegendItem(series.label, showValues ? series.data?.length?.toString() || '0' : '', theme.colors[index % theme.colors.length]);
54
+ const { stroke } = getStyles.getSeriesStyles(series, index, theme);
55
+ const { shapeStyles } = getStyles.getItemShapeStyles(series, index, theme, legendShape);
56
+ const baseItem = createBaseLegendItem(series.label, showValues ? series.data?.length?.toString() || '0' : '', stroke, shapeStyles);
50
57
  if (withGlyph && renderGlyph) {
51
58
  return {
52
59
  ...baseItem,
@@ -84,12 +91,13 @@ function processPointData(pointData, theme, showValues, withGlyph, glyphSize, re
84
91
  }
85
92
  /**
86
93
  * Hook to transform chart data into legend items
87
- * @param data - The chart data to transform
88
- * @param theme - The chart theme for colors
89
- * @param options - Configuration options for legend generation
94
+ * @param data - The chart data to transform
95
+ * @param theme - The chart theme for colors
96
+ * @param options - Configuration options for legend generation
97
+ * @param legendShape - The shape type for legend items (string literal or React component)
90
98
  * @return Array of legend items ready for display
91
99
  */
92
- function useChartLegendData(data, theme, options = {}) {
100
+ function useChartLegendData(data, theme, options = {}, legendShape) {
93
101
  const { showValues = false, withGlyph = false, glyphSize = 8, renderGlyph } = options;
94
102
  return react.useMemo(() => {
95
103
  if (!data || !Array.isArray(data) || data.length === 0) {
@@ -97,11 +105,11 @@ function useChartLegendData(data, theme, options = {}) {
97
105
  }
98
106
  // Handle SeriesData (multiple series with data points)
99
107
  if ('data' in data[0]) {
100
- return processSeriesData(data, theme, showValues, withGlyph, glyphSize, renderGlyph);
108
+ return processSeriesData(data, theme, showValues, withGlyph, glyphSize, renderGlyph, legendShape);
101
109
  }
102
110
  // Handle DataPointDate or DataPointPercentage (single data points)
103
111
  return processPointData(data, theme, showValues, withGlyph, glyphSize, renderGlyph);
104
- }, [data, theme, showValues, withGlyph, glyphSize, renderGlyph]);
112
+ }, [data, theme, showValues, withGlyph, glyphSize, renderGlyph, legendShape]);
105
113
  }
106
114
 
107
115
  exports.useChartLegendData = useChartLegendData;
@@ -5,11 +5,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var xychart = require('@visx/xychart');
7
7
  var react = require('react');
8
- var lineChartContext = require('./line-chart-context.js');
8
+ var singleChartContext = require('../shared/single-chart-context.js');
9
9
  var lineChart_module = require('./line-chart.module.scss.js');
10
10
 
11
11
  const LineChartAnnotationsOverlay = ({ children }) => {
12
- const { chartRef, chartWidth, chartHeight } = lineChartContext.useLineChartContext();
12
+ const { chartRef, chartWidth, chartHeight } = singleChartContext.useSingleChartContext();
13
13
  const [scales, setScales] = react.useState(null);
14
14
  const [scalesStable, setScalesStable] = react.useState(false);
15
15
  // Create a signature for scale data to enable easy comparison
@@ -10,13 +10,16 @@ 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
- var chartContext = require('../../providers/chart-context/chart-context.js');
13
+ var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
14
14
  var utils = require('../../providers/chart-context/utils.js');
15
15
  var themeProvider = require('../../providers/theme/theme-provider.js');
16
+ var createComposition = require('../../utils/create-composition.js');
17
+ var getStyles = require('../../utils/get-styles.js');
16
18
  var legend = require('../legend/legend.js');
17
19
  require('../legend/base-legend.js');
18
20
  var useChartLegendData = require('../legend/use-chart-legend-data.js');
19
21
  var defaultGlyph = require('../shared/default-glyph.js');
22
+ var singleChartContext = require('../shared/single-chart-context.js');
20
23
  var useChartDataTransform = require('../shared/use-chart-data-transform.js');
21
24
  var useChartMargin = require('../shared/use-chart-margin.js');
22
25
  var useElementHeight = require('../shared/use-element-height.js');
@@ -24,7 +27,6 @@ var withResponsive = require('../shared/with-responsive.js');
24
27
  var accessibleTooltip = require('../tooltip/accessible-tooltip.js');
25
28
  var lineChartAnnotation = require('./line-chart-annotation.js');
26
29
  var lineChartAnnotationsOverlay = require('./line-chart-annotations-overlay.js');
27
- var lineChartContext = require('./line-chart-context.js');
28
30
  var lineChart_module = require('./line-chart.module.scss.js');
29
31
 
30
32
  const X_TICK_WIDTH = 100;
@@ -134,7 +136,7 @@ const LineChartScalesRef = ({ chartRef, width, height, margin }) => {
134
136
  }), [context, width, height, margin]);
135
137
  return null; // This component only provides the ref interface
136
138
  };
137
- const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legendOrientation = 'horizontal', legendAlignmentHorizontal = 'center', legendAlignmentVertical = '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) => {
139
+ 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) => {
138
140
  const providerTheme = themeProvider.useChartTheme();
139
141
  const theme = themeProvider.useXYChartTheme(data);
140
142
  const chartId = utils.useChartId(providedChartId);
@@ -204,7 +206,7 @@ const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, wi
204
206
  renderGlyph,
205
207
  }), [withLegendGlyph, glyphStyle?.radius, renderGlyph]);
206
208
  // Create legend items using the reusable hook
207
- const legendItems = useChartLegendData.useChartLegendData(dataSorted, providerTheme, legendOptions);
209
+ const legendItems = useChartLegendData.useChartLegendData(dataSorted, providerTheme, legendOptions, legendShape);
208
210
  // Memoize metadata to prevent unnecessary re-registration
209
211
  const chartMetadata = react.useMemo(() => ({
210
212
  withGradientFill,
@@ -223,7 +225,7 @@ const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, wi
223
225
  if (error) {
224
226
  return jsxRuntime.jsx("div", { className: clsx('line-chart', lineChart_module.default['line-chart']), children: error });
225
227
  }
226
- return (jsxRuntime.jsx(lineChartContext.LineChartContext.Provider, { value: {
228
+ return (jsxRuntime.jsx(singleChartContext.SingleChartContext.Provider, { value: {
227
229
  chartId,
228
230
  chartRef: internalChartRef,
229
231
  chartWidth: width,
@@ -232,42 +234,46 @@ const LineChartInternal = react.forwardRef(({ data, chartId: providedChartId, wi
232
234
  width,
233
235
  height,
234
236
  display: 'flex',
235
- flexDirection: showLegend && legendAlignmentVertical === 'top' ? 'column-reverse' : 'column',
237
+ flexDirection: showLegend && legendPosition === 'top' ? 'column-reverse' : 'column',
236
238
  position: 'relative',
237
239
  }, children: [jsxRuntime.jsx("div", { role: "grid", "aria-label": i18n.__('Line chart', 'jetpack-charts'), tabIndex: 0, onKeyDown: onChartKeyDown, onFocus: onChartFocus, onBlur: onChartBlur, ref: chartRef, children: jsxRuntime.jsxs(xychart.XYChart, { theme: theme, width: width, height: height - (showLegend ? legendHeight : 0), margin: {
238
240
  ...defaultMargin,
239
241
  ...margin,
240
- ...(showLegend && legendAlignmentVertical === 'top'
242
+ ...(showLegend && legendPosition === 'top'
241
243
  ? { top: (defaultMargin.top || 0) + legendHeight }
242
244
  : {}),
243
245
  },
244
246
  // xScale and yScale could be set in Axis as well, but they are `scale` props there.
245
247
  xScale: chartOptions.xScale, yScale: chartOptions.yScale, onPointerDown: onPointerDown, onPointerUp: onPointerUp, onPointerMove: onPointerMove, onPointerOut: onPointerOut, pointerEventsDataKey: "nearest", children: [jsxRuntime.jsx(xychart.Grid, { columns: false, numTicks: 4 }), jsxRuntime.jsx(xychart.Axis, { ...chartOptions.axis.x }), jsxRuntime.jsx(xychart.Axis, { ...chartOptions.axis.y }), dataSorted.map((seriesData, index) => {
246
- const stroke = seriesData.options?.stroke ?? theme.colors[index % theme.colors.length];
247
- const lineProps = seriesData.options?.seriesLineStyle ??
248
- providerTheme?.seriesLineStyles?.[index % providerTheme.seriesLineStyles.length] ??
249
- {};
248
+ const { stroke, lineStyles } = getStyles.getSeriesStyles(seriesData, index, providerTheme);
249
+ const lineProps = {
250
+ stroke,
251
+ ...lineStyles,
252
+ };
250
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: theme.backgroundColor, ...seriesData.options?.gradient, "data-testid": "line-gradient" })), jsxRuntime.jsx(xychart.AreaSeries, { dataKey: seriesData?.label, data: seriesData.data, ...accessors, fill: withGradientFill
251
254
  ? `url(#area-gradient-${chartId}-${index + 1})`
252
255
  : 'transparent', renderLine: true, curve: getCurveType(curveType, smoothing), lineProps: lineProps }, seriesData?.label)] }, seriesData?.label || index));
253
- }), 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, alignmentHorizontal: legendAlignmentHorizontal, alignmentVertical: legendAlignmentVertical, className: lineChart_module.default['line-chart-legend'], shape: legendShape, chartId: chartId, ref: legendRef })), children] }) }));
256
+ }), 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] }) }));
254
257
  });
255
- const LineChart = react.forwardRef((props, ref) => {
256
- const existingContext = react.useContext(chartContext.ChartContext);
257
- // If we're already in a ChartProvider context, don't create a new one
258
+ const LineChartWithProvider = react.forwardRef((props, ref) => {
259
+ const existingContext = react.useContext(globalChartsProvider.GlobalChartsContext);
260
+ // If we're already in a GlobalChartsProvider context, render the core component directly
258
261
  if (existingContext) {
259
262
  return jsxRuntime.jsx(LineChartInternal, { ...props, ref: ref });
260
263
  }
261
- // Otherwise, create our own ChartProvider
262
- return (jsxRuntime.jsx(chartContext.ChartProvider, { children: jsxRuntime.jsx(LineChartInternal, { ...props, ref: ref }) }));
264
+ // Otherwise, wrap with our own GlobalChartsProvider
265
+ return (jsxRuntime.jsx(globalChartsProvider.GlobalChartsProvider, { children: jsxRuntime.jsx(LineChartInternal, { ...props, ref: ref }) }));
263
266
  });
264
- LineChart.displayName = 'LineChart';
265
- LineChart.AnnotationsOverlay = lineChartAnnotationsOverlay.default;
266
- LineChart.Annotation = lineChartAnnotation.default;
267
- const ResponsiveLineChart = Object.assign(withResponsive.withResponsive(LineChart), {
267
+ LineChartWithProvider.displayName = 'LineChart';
268
+ createComposition.attachSubComponents(LineChartWithProvider, {
269
+ Legend: legend.Legend,
270
+ AnnotationsOverlay: lineChartAnnotationsOverlay.default,
271
+ Annotation: lineChartAnnotation.default,
272
+ });
273
+ const LineChartResponsive = createComposition.attachSubComponents(withResponsive.withResponsive(LineChartWithProvider), {
274
+ Legend: legend.Legend,
268
275
  AnnotationsOverlay: lineChartAnnotationsOverlay.default,
269
276
  Annotation: lineChartAnnotation.default,
270
277
  });
271
278
 
272
- exports.LineChartUnresponsive = LineChart;
273
- exports.default = ResponsiveLineChart;
279
+ exports.default = LineChartResponsive;
@@ -8,7 +8,7 @@ var shape = require('@visx/shape');
8
8
  var clsx = require('clsx');
9
9
  var react = require('react');
10
10
  var useChartMouseHandler = require('../../hooks/use-chart-mouse-handler.js');
11
- var chartContext = require('../../providers/chart-context/chart-context.js');
11
+ var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
12
12
  var utils = require('../../providers/chart-context/utils.js');
13
13
  var themeProvider = require('../../providers/theme/theme-provider.js');
14
14
  var themes = require('../../providers/theme/themes.js');
@@ -48,7 +48,7 @@ const validateData = (data) => {
48
48
  * @param {PieChartProps} props - Component props
49
49
  * @return {JSX.Element} The rendered chart component
50
50
  */
51
- const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false, className, showLegend = false, legendOrientation = 'horizontal', legendAlignmentHorizontal = 'center', legendAlignmentVertical = 'bottom', legendShape = 'circle', size, thickness = 1, padding = 20, gapScale = 0, cornerScale = 0, children = null, }) => {
51
+ 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
52
  const providerTheme = themeProvider.useChartTheme();
53
53
  const chartId = utils.useChartId(providedChartId);
54
54
  const [legendRef, legendHeight] = useElementHeight.useElementHeight();
@@ -73,7 +73,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
73
73
  }
74
74
  const width = size;
75
75
  const height = size;
76
- const adjustedHeight = showLegend && legendAlignmentVertical === 'top' ? height - legendHeight : height;
76
+ const adjustedHeight = showLegend && legendPosition === 'top' ? height - legendHeight : height;
77
77
  // Calculate radius based on width/height
78
78
  const radius = Math.min(width, adjustedHeight) / 2;
79
79
  // Center the chart in the available space
@@ -97,7 +97,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
97
97
  };
98
98
  return (jsxRuntime.jsxs("div", { className: clsx('pie-chart', pieChart_module.default['pie-chart'], className), style: {
99
99
  display: 'flex',
100
- flexDirection: showLegend && legendAlignmentVertical === 'top' ? 'column-reverse' : 'column',
100
+ flexDirection: showLegend && legendPosition === 'top' ? 'column-reverse' : 'column',
101
101
  }, 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 => {
102
102
  return pie.arcs.map((arc, index) => {
103
103
  const [centroidX, centroidY] = pie.path.centroid(arc);
@@ -113,18 +113,18 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
113
113
  }
114
114
  return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("path", { ...pathProps }), hasSpaceForLabel && (jsxRuntime.jsx("text", { x: centroidX, y: centroidY, dy: ".33em", fill: providerTheme.labelBackgroundColor || themes.defaultTheme.labelBackgroundColor, fontSize: 12, textAnchor: "middle", pointerEvents: "none", children: arc.data.label }))] }, `arc-${index}`));
115
115
  });
116
- } }), children] }) }), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, alignmentHorizontal: legendAlignmentHorizontal, alignmentVertical: legendAlignmentVertical, 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: {
116
+ } }), children] }) }), 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: {
117
117
  transform: 'translate(-50%, -100%)',
118
118
  } }))] }));
119
119
  };
120
120
  const PieChart = (props) => {
121
- const existingContext = react.useContext(chartContext.ChartContext);
122
- // If we're already in a ChartProvider context, don't create a new one
121
+ const existingContext = react.useContext(globalChartsProvider.GlobalChartsContext);
122
+ // If we're already in a GlobalChartsProvider context, don't create a new one
123
123
  if (existingContext) {
124
124
  return jsxRuntime.jsx(PieChartInternal, { ...props });
125
125
  }
126
- // Otherwise, create our own ChartProvider
127
- return (jsxRuntime.jsx(chartContext.ChartProvider, { children: jsxRuntime.jsx(PieChartInternal, { ...props }) }));
126
+ // Otherwise, create our own GlobalChartsProvider
127
+ return (jsxRuntime.jsx(globalChartsProvider.GlobalChartsProvider, { children: jsxRuntime.jsx(PieChartInternal, { ...props }) }));
128
128
  };
129
129
  PieChart.displayName = 'PieChart';
130
130
  var pieChart = withResponsive.withResponsive(PieChart);
@@ -10,7 +10,7 @@ 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
- var chartContext = require('../../providers/chart-context/chart-context.js');
13
+ var globalChartsProvider = require('../../providers/chart-context/global-charts-provider.js');
14
14
  var utils = require('../../providers/chart-context/utils.js');
15
15
  var themeProvider = require('../../providers/theme/theme-provider.js');
16
16
  var legend = require('../legend/legend.js');
@@ -43,7 +43,7 @@ const validateData = (data) => {
43
43
  }
44
44
  return { isValid: true, message: '' };
45
45
  };
46
- const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 400, thickness = 0.4, clockwise = true, withTooltips = false, showLegend = false, legendOrientation = 'horizontal', legendAlignmentHorizontal = 'center', legendAlignmentVertical = 'bottom', legendShape = 'circle', label, note, className, }) => {
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
47
  const providerTheme = themeProvider.useChartTheme();
48
48
  const chartId = utils.useChartId(providedChartId);
49
49
  const [legendRef, legendHeight] = useElementHeight.useElementHeight();
@@ -91,7 +91,7 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 40
91
91
  // TODO: we might want to accept height as a prop in the future, because the height of container might not always be enough.
92
92
  const height = width / 2;
93
93
  // The chart only takes the height minus the legend height.
94
- const chartHeight = height - (showLegend && legendAlignmentVertical === 'top' ? legendHeight : 0);
94
+ const chartHeight = height - (showLegend && legendPosition === 'top' ? legendHeight : 0);
95
95
  const radius = Math.min(width / 2, chartHeight);
96
96
  const innerRadius = radius * (1 - thickness);
97
97
  // Map data with index for color assignment
@@ -104,16 +104,16 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width = 40
104
104
  const endAngle = clockwise ? Math.PI / 2 : -Math.PI / 2;
105
105
  return (jsxRuntime.jsxs("div", { className: clsx('pie-semi-circle-chart', pieSemiCircleChart_module.default['pie-semi-circle-chart'], className), "data-testid": "pie-chart-container", style: {
106
106
  display: 'flex',
107
- flexDirection: showLegend && legendAlignmentVertical === 'top' ? 'column-reverse' : 'column',
107
+ flexDirection: showLegend && legendPosition === 'top' ? 'column-reverse' : 'column',
108
108
  }, 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 => {
109
109
  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)));
110
110
  } }), 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 })] })] }) }), withTooltips && tooltipOpen && tooltipData && (jsxRuntime.jsx(baseTooltip.BaseTooltip, { data: {
111
111
  label: tooltipData.label,
112
112
  value: tooltipData.value,
113
113
  valueDisplay: tooltipData.valueDisplay,
114
- }, top: tooltipTop || 0, left: tooltipLeft || 0 })), showLegend && (jsxRuntime.jsx(legend.Legend, { items: legendItems, orientation: legendOrientation, alignmentHorizontal: legendAlignmentHorizontal, alignmentVertical: legendAlignmentVertical, shape: legendShape, ref: legendRef, chartId: chartId }))] }));
114
+ }, 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 }))] }));
115
115
  };
116
- const PieSemiCircleChart = props => (jsxRuntime.jsx(chartContext.ChartProvider, { children: jsxRuntime.jsx(PieSemiCircleChartInternal, { ...props }) }));
116
+ const PieSemiCircleChart = props => (jsxRuntime.jsx(globalChartsProvider.GlobalChartsProvider, { children: jsxRuntime.jsx(PieSemiCircleChartInternal, { ...props }) }));
117
117
  PieSemiCircleChart.displayName = 'PieSemiCircleChart';
118
118
  var pieSemiCircleChart = withResponsive.withResponsive(PieSemiCircleChart);
119
119
 
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const ChartInstanceContext = react.createContext(null);
6
+ const useChartInstanceContext = () => {
7
+ const context = react.useContext(ChartInstanceContext);
8
+ if (!context) {
9
+ throw new Error('useChartInstanceContext must be used within a Chart component');
10
+ }
11
+ return context;
12
+ };
13
+ // Backward compatibility exports
14
+ const SingleChartContext = ChartInstanceContext;
15
+ const useSingleChartContext = useChartInstanceContext;
16
+
17
+ exports.ChartInstanceContext = ChartInstanceContext;
18
+ exports.SingleChartContext = SingleChartContext;
19
+ exports.useChartInstanceContext = useChartInstanceContext;
20
+ exports.useSingleChartContext = useSingleChartContext;
@@ -3,8 +3,8 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var react = require('react');
5
5
 
6
- const ChartContext = react.createContext(null);
7
- const ChartProvider = ({ children }) => {
6
+ const GlobalChartsContext = react.createContext(null);
7
+ const GlobalChartsProvider = ({ children }) => {
8
8
  const [charts, setCharts] = react.useState(() => new Map());
9
9
  const registerChart = react.useCallback((id, data) => {
10
10
  setCharts(prev => new Map(prev).set(id, data));
@@ -25,16 +25,16 @@ const ChartProvider = ({ children }) => {
25
25
  unregisterChart,
26
26
  getChartData,
27
27
  }), [charts, registerChart, unregisterChart, getChartData]);
28
- return jsxRuntime.jsx(ChartContext.Provider, { value: value, children: children });
28
+ return jsxRuntime.jsx(GlobalChartsContext.Provider, { value: value, children: children });
29
29
  };
30
- const useChartContext = () => {
31
- const context = react.useContext(ChartContext);
30
+ const useGlobalChartsContext = () => {
31
+ const context = react.useContext(GlobalChartsContext);
32
32
  if (!context) {
33
- throw new Error('useChartContext must be used within a ChartProvider');
33
+ throw new Error('useGlobalChartsContext must be used within a GlobalChartsProvider');
34
34
  }
35
35
  return context;
36
36
  };
37
37
 
38
- exports.ChartContext = ChartContext;
39
- exports.ChartProvider = ChartProvider;
40
- exports.useChartContext = useChartContext;
38
+ exports.GlobalChartsContext = GlobalChartsContext;
39
+ exports.GlobalChartsProvider = GlobalChartsProvider;
40
+ exports.useGlobalChartsContext = useGlobalChartsContext;
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chartContext = require('./chart-context.js');
3
+ var globalChartsProvider = require('./global-charts-provider.js');
4
4
  var utils = require('./utils.js');
5
5
 
6
6
 
7
7
 
8
- exports.ChartContext = chartContext.ChartContext;
9
- exports.ChartProvider = chartContext.ChartProvider;
10
- exports.useChartContext = chartContext.useChartContext;
8
+ exports.GlobalChartsContext = globalChartsProvider.GlobalChartsContext;
9
+ exports.GlobalChartsProvider = globalChartsProvider.GlobalChartsProvider;
10
+ exports.useGlobalChartsContext = globalChartsProvider.useGlobalChartsContext;
11
11
  exports.useChartId = utils.useChartId;
12
12
  exports.useChartRegistration = utils.useChartRegistration;