@fluentui/react-charts 9.2.1 → 9.2.2

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 (101) hide show
  1. package/CHANGELOG.md +24 -2
  2. package/dist/index.d.ts +79 -5
  3. package/lib/ChartTable.js +1 -0
  4. package/lib/ChartTable.js.map +1 -0
  5. package/lib/components/AreaChart/AreaChart.js.map +1 -1
  6. package/lib/components/ChartTable/ChartTable.js +57 -0
  7. package/lib/components/ChartTable/ChartTable.js.map +1 -0
  8. package/lib/components/ChartTable/ChartTable.types.js +1 -0
  9. package/lib/components/ChartTable/ChartTable.types.js.map +1 -0
  10. package/lib/components/ChartTable/index.js +3 -0
  11. package/lib/components/ChartTable/index.js.map +1 -0
  12. package/lib/components/ChartTable/useChartTableStyles.styles.js +93 -0
  13. package/lib/components/ChartTable/useChartTableStyles.styles.js.map +1 -0
  14. package/lib/components/ChartTable/useChartTableStyles.styles.raw.js +55 -0
  15. package/lib/components/ChartTable/useChartTableStyles.styles.raw.js.map +1 -0
  16. package/lib/components/CommonComponents/CartesianChart.js +110 -81
  17. package/lib/components/CommonComponents/CartesianChart.js.map +1 -1
  18. package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
  19. package/lib/components/CommonComponents/ChartPopover.types.js.map +1 -1
  20. package/lib/components/DeclarativeChart/DeclarativeChart.js +20 -10
  21. package/lib/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  22. package/lib/components/DeclarativeChart/PlotlyColorAdapter.js +95 -0
  23. package/lib/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -0
  24. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +164 -77
  25. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  26. package/lib/components/DonutChart/DonutChart.js.map +1 -1
  27. package/lib/components/DonutChart/DonutChart.types.js.map +1 -1
  28. package/lib/components/DonutChart/Pie/Pie.js.map +1 -1
  29. package/lib/components/FunnelChart/FunnelChart.js.map +1 -1
  30. package/lib/components/GanttChart/GanttChart.js.map +1 -1
  31. package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +161 -141
  32. package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
  33. package/lib/components/HeatMapChart/HeatMapChart.js.map +1 -1
  34. package/lib/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  35. package/lib/components/HorizontalBarChart/HorizontalBarChart.types.js.map +1 -1
  36. package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
  37. package/lib/components/Legends/Legends.js.map +1 -1
  38. package/lib/components/Legends/OverflowMenu.js.map +1 -1
  39. package/lib/components/LineChart/LineChart.js.map +1 -1
  40. package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
  41. package/lib/components/VerticalBarChart/VerticalBarChart.js +12 -11
  42. package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  43. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +57 -51
  44. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  45. package/lib/index.js +1 -0
  46. package/lib/index.js.map +1 -1
  47. package/lib/utilities/FocusableTooltipText.js.map +1 -1
  48. package/lib/utilities/utilities.js +26 -37
  49. package/lib/utilities/utilities.js.map +1 -1
  50. package/lib/utilities/vbc-utils.js +24 -0
  51. package/lib/utilities/vbc-utils.js.map +1 -1
  52. package/lib-commonjs/ChartTable.js +6 -0
  53. package/lib-commonjs/ChartTable.js.map +1 -0
  54. package/lib-commonjs/components/AreaChart/AreaChart.js.map +1 -1
  55. package/lib-commonjs/components/ChartTable/ChartTable.js +68 -0
  56. package/lib-commonjs/components/ChartTable/ChartTable.js.map +1 -0
  57. package/lib-commonjs/components/ChartTable/ChartTable.types.js +6 -0
  58. package/lib-commonjs/components/ChartTable/ChartTable.types.js.map +1 -0
  59. package/lib-commonjs/components/ChartTable/index.js +8 -0
  60. package/lib-commonjs/components/ChartTable/index.js.map +1 -0
  61. package/lib-commonjs/components/ChartTable/useChartTableStyles.styles.js +196 -0
  62. package/lib-commonjs/components/ChartTable/useChartTableStyles.styles.js.map +1 -0
  63. package/lib-commonjs/components/ChartTable/useChartTableStyles.styles.raw.js +69 -0
  64. package/lib-commonjs/components/ChartTable/useChartTableStyles.styles.raw.js.map +1 -0
  65. package/lib-commonjs/components/CommonComponents/CartesianChart.js +109 -80
  66. package/lib-commonjs/components/CommonComponents/CartesianChart.js.map +1 -1
  67. package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
  68. package/lib-commonjs/components/CommonComponents/ChartPopover.types.js.map +1 -1
  69. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js +19 -9
  70. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  71. package/lib-commonjs/components/DeclarativeChart/PlotlyColorAdapter.js +120 -0
  72. package/lib-commonjs/components/DeclarativeChart/PlotlyColorAdapter.js.map +1 -0
  73. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +164 -77
  74. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  75. package/lib-commonjs/components/DonutChart/DonutChart.js.map +1 -1
  76. package/lib-commonjs/components/DonutChart/DonutChart.types.js.map +1 -1
  77. package/lib-commonjs/components/DonutChart/Pie/Pie.js.map +1 -1
  78. package/lib-commonjs/components/FunnelChart/FunnelChart.js.map +1 -1
  79. package/lib-commonjs/components/GanttChart/GanttChart.js.map +1 -1
  80. package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +159 -139
  81. package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
  82. package/lib-commonjs/components/HeatMapChart/HeatMapChart.js.map +1 -1
  83. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.js.map +1 -1
  84. package/lib-commonjs/components/HorizontalBarChart/HorizontalBarChart.types.js.map +1 -1
  85. package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
  86. package/lib-commonjs/components/Legends/Legends.js.map +1 -1
  87. package/lib-commonjs/components/Legends/OverflowMenu.js.map +1 -1
  88. package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
  89. package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
  90. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +11 -10
  91. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
  92. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +56 -50
  93. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  94. package/lib-commonjs/index.js +1 -0
  95. package/lib-commonjs/index.js.map +1 -1
  96. package/lib-commonjs/utilities/FocusableTooltipText.js.map +1 -1
  97. package/lib-commonjs/utilities/utilities.js +29 -37
  98. package/lib-commonjs/utilities/utilities.js.map +1 -1
  99. package/lib-commonjs/utilities/vbc-utils.js +27 -0
  100. package/lib-commonjs/utilities/vbc-utils.js.map +1 -1
  101. package/package.json +9 -9
@@ -4,14 +4,11 @@ import { select as d3Select } from 'd3-selection';
4
4
  import { max as d3Max, min as d3Min } from 'd3-array';
5
5
  import { scaleBand as d3ScaleBand } from 'd3-scale';
6
6
  import { useId } from '@fluentui/react-utilities';
7
- import { ChartTypes, getAccessibleDataObject, tooltipOfAxislabels, XAxisTypes, getTypeOfAxis, formatScientificLimitWidth, getScalePadding, getBarWidth, isScalePaddingDefined, createNumericYAxis, domainRangeOfXStringAxis, createStringYAxis, getNextColor, areArraysEqual, calculateLongestLabelWidth, useRtl } from '../../utilities/index';
8
- import { CartesianChart, Legends, DataVizPalette, getColorFromToken } from '../../index';
7
+ import { ChartTypes, getAccessibleDataObject, tooltipOfAxislabels, XAxisTypes, getTypeOfAxis, formatScientificLimitWidth, getScalePadding, getBarWidth, isScalePaddingDefined, createNumericYAxis, domainRangeOfXStringAxis, createStringYAxis, getNextColor, areArraysEqual, calculateLongestLabelWidth, useRtl, calcRequiredWidth, calcTotalWidth, calcBandwidth, calcTotalBandUnits } from '../../utilities/index';
8
+ import { CartesianChart, Legends } from '../../index';
9
9
  import { toImage } from '../../utilities/image-export-utils';
10
10
  const MIN_DOMAIN_MARGIN = 8;
11
11
  const X1_INNER_PADDING = 0.1;
12
- // x1_inner_padding = space_between_bars / (space_between_bars + bar_width)
13
- // => space_between_bars = (x1_inner_padding / (1 - x1_inner_padding)) * bar_width
14
- /** Rate at which the space between the bars in a group changes wrt the bar width */ const BAR_GAP_RATE = X1_INNER_PADDING / (1 - X1_INNER_PADDING);
15
12
  const VERTICAL_BAR_GAP = 1;
16
13
  const MIN_BAR_HEIGHT = 1;
17
14
  export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
@@ -22,7 +19,6 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
22
19
  const _emptyChartId = useId('_GVBC_empty');
23
20
  const _useRtl = useRtl();
24
21
  let _domainMargin = MIN_DOMAIN_MARGIN;
25
- let _keys = [];
26
22
  let _xAxisLabels = [];
27
23
  let _datasetForBars = [];
28
24
  let _margins = {
@@ -32,13 +28,14 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
32
28
  left: 0
33
29
  };
34
30
  let _groupedVerticalBarGraph = [];
35
- let _refArray = [];
36
31
  let _yMax = 0;
37
32
  let _calloutAnchorPoint = null;
38
33
  let _barWidth = 0;
39
34
  let _groupWidth = 0;
40
35
  let _xAxisInnerPadding = 0;
41
36
  let _xAxisOuterPadding = 0;
37
+ let _legends = [];
38
+ let _legendColorMap = {};
42
39
  const cartesianChartRef = React.useRef(null);
43
40
  const Y_ORIGIN = 0;
44
41
  const _legendsRef = React.useRef(null);
@@ -82,44 +79,53 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
82
79
  _barWidth = getBarWidth(props.barWidth, props.maxBarWidth);
83
80
  // x0_inner_padding = space_between_groups / (space_between_groups + group_width)
84
81
  // space_between_groups = 2 * bar_width
85
- // group_width = keys.length * bar_width + (keys.length - 1) * space_between_bars
86
- _xAxisInnerPadding = getScalePadding(props.xAxisInnerPadding, undefined, 2 / (2 + keys.length + (keys.length - 1) * BAR_GAP_RATE));
82
+ // group_width = _legends.length * bar_width + (_legends.length - 1) * space_between_bars
83
+ _xAxisInnerPadding = getScalePadding(props.xAxisInnerPadding, undefined, 2 / (2 + calcTotalBandUnits(_legends.length, X1_INNER_PADDING)));
87
84
  _xAxisOuterPadding = getScalePadding(props.xAxisOuterPadding);
88
85
  };
89
86
  const _createDataset = (points)=>{
90
87
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
88
  const datasetForBars = [];
92
- const dataset = [];
93
89
  points.forEach((point, index)=>{
94
- const singleDatasetPoint = {};
95
90
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
91
  const singleDatasetPointForBars = {};
97
- const singleDataSeries = [];
98
- point.series.forEach((seriesPoint, seriesIndex)=>{
99
- singleDatasetPoint[seriesPoint.key] = seriesPoint.data;
100
- singleDatasetPointForBars[seriesPoint.key] = {
101
- ...seriesPoint
102
- };
103
- singleDataSeries.push(seriesPoint);
92
+ const legendToBarPoint = {};
93
+ point.series.forEach((seriesPoint)=>{
94
+ if (!singleDatasetPointForBars[seriesPoint.legend]) {
95
+ singleDatasetPointForBars[seriesPoint.legend] = [
96
+ {
97
+ ...seriesPoint
98
+ }
99
+ ];
100
+ legendToBarPoint[seriesPoint.legend] = {
101
+ ...seriesPoint
102
+ };
103
+ } else {
104
+ singleDatasetPointForBars[seriesPoint.legend].push({
105
+ ...seriesPoint
106
+ });
107
+ legendToBarPoint[seriesPoint.legend].data += seriesPoint.data;
108
+ }
104
109
  });
105
110
  singleDatasetPointForBars.xAxisPoint = point.name;
106
111
  singleDatasetPointForBars.indexNum = index;
107
- singleDatasetPointForBars.groupSeries = singleDataSeries;
112
+ singleDatasetPointForBars.groupSeries = Object.values(legendToBarPoint);
108
113
  singleDatasetPointForBars.stackCallOutAccessibilityData = point.stackCallOutAccessibilityData;
109
114
  datasetForBars.push(singleDatasetPointForBars);
110
- dataset.push(singleDatasetPoint);
111
115
  });
112
116
  return datasetForBars;
113
117
  };
114
118
  const _createDataSetOfGVBC = (points)=>{
115
- const keys = [];
119
+ const legends = new Set();
116
120
  const xAxisLabels = points.map((singlePoint)=>singlePoint.name);
117
- points[0].series.forEach((singleKey)=>{
118
- keys.push(singleKey.key);
121
+ points.forEach((point)=>{
122
+ point.series.forEach((seriesPoint)=>{
123
+ legends.add(seriesPoint.legend);
124
+ });
119
125
  });
120
126
  const datasetForBars = _createDataset(points);
121
127
  return {
122
- keys,
128
+ legends: Array.from(legends),
123
129
  xAxisLabels,
124
130
  datasetForBars
125
131
  };
@@ -135,36 +141,22 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
135
141
  props.legendProps.onChange(selectedLegends, event, currentLegend);
136
142
  }
137
143
  };
144
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
138
145
  const _getLegendData = (points)=>{
139
- const data = points;
140
- const defaultPalette = [
141
- getColorFromToken(DataVizPalette.color1),
142
- getColorFromToken(DataVizPalette.color2),
143
- getColorFromToken(DataVizPalette.color3),
144
- getColorFromToken(DataVizPalette.color4),
145
- getColorFromToken(DataVizPalette.color5)
146
- ];
147
146
  const actions = [];
148
- data.forEach((singleChartData)=>{
149
- singleChartData.series.forEach((point)=>{
150
- let color = point.color ? point.color : defaultPalette[Math.floor(Math.random() * 4 + 1)];
151
- const checkSimilarLegends = actions.filter((leg)=>leg.title === point.legend && leg.color === color);
152
- if (checkSimilarLegends.length > 0) {
153
- return;
147
+ _legends.forEach((legendTitle)=>{
148
+ const legend = {
149
+ title: legendTitle,
150
+ color: _legendColorMap[legendTitle][0],
151
+ hoverAction: ()=>{
152
+ _handleChartMouseLeave();
153
+ _onLegendHover(legendTitle);
154
+ },
155
+ onMouseOutAction: ()=>{
156
+ _onLegendLeave();
154
157
  }
155
- const legend = {
156
- title: point.legend,
157
- color,
158
- hoverAction: ()=>{
159
- _handleChartMouseLeave();
160
- _onLegendHover(point.legend);
161
- },
162
- onMouseOutAction: ()=>{
163
- _onLegendLeave();
164
- }
165
- };
166
- actions.push(legend);
167
- });
158
+ };
159
+ actions.push(legend);
168
160
  });
169
161
  return /*#__PURE__*/ React.createElement(Legends, {
170
162
  legends: actions,
@@ -175,13 +167,40 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
175
167
  legendRef: _legendsRef
176
168
  });
177
169
  };
178
- const points = props.data;
179
- const { keys, xAxisLabels, datasetForBars } = _createDataSetOfGVBC(points);
180
- _keys = keys;
170
+ const _addDefaultColors = (data)=>{
171
+ _legendColorMap = {};
172
+ let colorIndex = 0;
173
+ var _data_map;
174
+ return (_data_map = data === null || data === void 0 ? void 0 : data.map((point)=>{
175
+ var _point_series;
176
+ var _point_series_map;
177
+ return {
178
+ ...point,
179
+ series: (_point_series_map = (_point_series = point.series) === null || _point_series === void 0 ? void 0 : _point_series.map((seriesPoint)=>{
180
+ if (!_legendColorMap[seriesPoint.legend]) {
181
+ let startColor = seriesPoint.color ? seriesPoint.color : getNextColor(colorIndex, 0);
182
+ let endColor = startColor;
183
+ _legendColorMap[seriesPoint.legend] = [
184
+ startColor,
185
+ endColor
186
+ ];
187
+ colorIndex += 1;
188
+ }
189
+ return {
190
+ ...seriesPoint,
191
+ color: _legendColorMap[seriesPoint.legend][0]
192
+ };
193
+ })) !== null && _point_series_map !== void 0 ? _point_series_map : []
194
+ };
195
+ })) !== null && _data_map !== void 0 ? _data_map : [];
196
+ };
197
+ const points = _addDefaultColors(props.data);
198
+ const { legends, xAxisLabels, datasetForBars } = _createDataSetOfGVBC(points);
199
+ _legends = legends;
181
200
  _xAxisLabels = xAxisLabels;
182
201
  _datasetForBars = datasetForBars;
183
202
  const _xAxisType = getTypeOfAxis(points[0].name, true);
184
- const legends = _getLegendData(points);
203
+ const legendBars = _getLegendData(points);
185
204
  _adjustProps();
186
205
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Add commentMore actions
187
206
  function _getMinMaxOfYAxis(datasetForBars, yAxisType, useSecondaryYScale) {
@@ -241,8 +260,8 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
241
260
  const xScale0 = _createX0Scale(containerWidth);
242
261
  // Setting the bar width here is safe because there are no dependencies earlier in the code
243
262
  // that rely on the width of bars in vertical bar charts with string x-axis.
244
- _barWidth = getBarWidth(props.barWidth, props.maxBarWidth, xScale0.bandwidth() / (_keys.length + (_keys.length - 1) * BAR_GAP_RATE));
245
- _groupWidth = (_keys.length + (_keys.length - 1) * BAR_GAP_RATE) * _barWidth;
263
+ _barWidth = getBarWidth(props.barWidth, props.maxBarWidth, calcBandwidth(xScale0.bandwidth(), _legends.length, X1_INNER_PADDING));
264
+ _groupWidth = calcRequiredWidth(_barWidth, _legends.length, X1_INNER_PADDING);
246
265
  const xScale1 = _createX1Scale();
247
266
  const allGroupsBars = [];
248
267
  _datasetForBars.forEach((singleSet)=>{
@@ -253,10 +272,6 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
253
272
  const _getMargins = (margins)=>{
254
273
  _margins = margins;
255
274
  };
256
- const _getOpacity = (legendTitle)=>{
257
- const opacity = _legendHighlighted(legendTitle) || _noLegendHighlighted() ? '' : '0.1';
258
- return opacity;
259
- };
260
275
  function updatePosition(newX, newY) {
261
276
  const threshold = 1; // Set a threshold for movement
262
277
  const { x, y } = clickPosition;
@@ -295,96 +310,102 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
295
310
  setPopoverOpen(false);
296
311
  };
297
312
  const onBarFocus = (event, pointData, // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
- groupData, refArrayIndexNumber)=>{
313
+ groupData)=>{
299
314
  let x = 0;
300
315
  let y = 0;
301
316
  const targetRect = event.target.getBoundingClientRect();
302
317
  x = targetRect.left + targetRect.width / 2;
303
318
  y = targetRect.top + targetRect.height / 2;
304
319
  updatePosition(x, y);
305
- _refArray.forEach((obj, index)=>{
306
- if (obj.index === pointData.legend && refArrayIndexNumber === index) {
307
- setPopoverOpen(_noLegendHighlighted() || _legendHighlighted(pointData.legend));
308
- setCalloutLegend(pointData.legend);
309
- setDataForHoverCard(pointData.data);
310
- setColor(pointData.color);
311
- setXCalloutValue(pointData.xAxisCalloutData);
312
- setYCalloutValue(pointData.yAxisCalloutData);
313
- setCallOutAccessibilityData(props.isCalloutForStack ? groupData.stackCallOutAccessibilityData : pointData.callOutAccessibilityData);
314
- setYValueHover(groupData.groupSeries);
315
- setHoverXValue(pointData.xAxisCalloutData);
316
- }
317
- });
318
- };
319
- const _refCallback = (element, legendTitle, refIndexNumber)=>{
320
- _refArray[refIndexNumber] = {
321
- index: legendTitle,
322
- refElement: element
323
- };
320
+ setPopoverOpen(_noLegendHighlighted() || _legendHighlighted(pointData.legend));
321
+ setCalloutLegend(pointData.legend);
322
+ setDataForHoverCard(pointData.data);
323
+ setColor(pointData.color);
324
+ setXCalloutValue(pointData.xAxisCalloutData);
325
+ setYCalloutValue(pointData.yAxisCalloutData);
326
+ setCallOutAccessibilityData(props.isCalloutForStack ? groupData.stackCallOutAccessibilityData : pointData.callOutAccessibilityData);
327
+ setYValueHover(groupData.groupSeries);
328
+ setHoverXValue(pointData.xAxisCalloutData);
324
329
  };
325
330
  const _buildGraph = (// eslint-disable-next-line @typescript-eslint/no-explicit-any
326
331
  singleSet, // eslint-disable-next-line @typescript-eslint/no-explicit-any
327
332
  xScale0, // eslint-disable-next-line @typescript-eslint/no-explicit-any
328
333
  xScale1, yScalePrimary, yScaleSecondary, containerHeight, xElement)=>{
334
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
329
335
  const singleGroup = [];
336
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
330
337
  const barLabelsForGroup = [];
331
- const tempDataSet = Object.keys(datasetForBars[0]).splice(0, keys.length);
332
- tempDataSet.forEach((datasetKey, index)=>{
333
- const refIndexNumber = singleSet.indexNum * tempDataSet.length + index;
334
- const pointData = singleSet[datasetKey];
335
- const yBarScale = pointData.useSecondaryYScale && yScaleSecondary ? yScaleSecondary : yScalePrimary;
336
- if (pointData) {
337
- // To align the centers of the generated bandwidth and the calculated one when they differ,
338
- // use the following addend.
339
- const xPoint = xScale1(datasetKey) + (xScale1.bandwidth() - _barWidth) / 2;
340
- const startColor = pointData.color ? pointData.color : getNextColor(index, 0);
338
+ // Get the actual legends present at this x-axis point
339
+ const presentLegends = Object.keys(singleSet).filter((key)=>key in _legendColorMap);
340
+ const effectiveGroupWidth = calcRequiredWidth(_barWidth, presentLegends.length, X1_INNER_PADDING);
341
+ // For stacked bars, center the single bar group in the available space
342
+ // Instead of using the global legend position, use the local position within present legends
343
+ const localScale = d3ScaleBand().domain(presentLegends).range(_useRtl ? [
344
+ effectiveGroupWidth,
345
+ 0
346
+ ] : [
347
+ 0,
348
+ effectiveGroupWidth
349
+ ]).paddingInner(X1_INNER_PADDING);
350
+ _legends.forEach((legendTitle, legendIndex)=>{
351
+ const barPoints = singleSet[legendTitle];
352
+ if (barPoints) {
353
+ const yBarScale = barPoints[0].useSecondaryYScale && yScaleSecondary ? yScaleSecondary : yScalePrimary;
354
+ var _localScale;
355
+ const xPoint = ((_localScale = localScale(legendTitle)) !== null && _localScale !== void 0 ? _localScale : 0) + (localScale.bandwidth() - _barWidth) / 2;
356
+ const isLegendActive = _legendHighlighted(legendTitle) || _noLegendHighlighted();
357
+ const barOpacity = isLegendActive ? '' : '0.1';
358
+ let barTotalValue = 0;
341
359
  const yBaseline = yBarScale(Y_ORIGIN);
342
360
  let yPositiveStart = yBaseline;
343
361
  let yNegativeStart = yBaseline;
344
362
  let yPoint = Y_ORIGIN;
345
- const barGap = VERTICAL_BAR_GAP / 2 * (index > 0 ? 2 : 0);
346
- const height = Math.max(yBarScale(Y_ORIGIN) - yBarScale(Math.abs(pointData.data)), MIN_BAR_HEIGHT);
347
- if (pointData.data >= Y_ORIGIN) {
348
- yPositiveStart -= height + barGap;
349
- yPoint = yPositiveStart;
350
- } else {
351
- yPoint = yNegativeStart + barGap;
352
- yNegativeStart = yPoint + height;
353
- }
354
- // Not rendering data with 0.
355
- pointData.data && singleGroup.push(/*#__PURE__*/ React.createElement(React.Fragment, {
356
- key: `${singleSet.indexNum}-${index}`
357
- }, /*#__PURE__*/ React.createElement("rect", {
358
- className: classes.opacityChangeOnHover,
359
- height: height,
360
- width: _barWidth,
361
- x: xPoint,
362
- y: yPoint,
363
- opacity: _getOpacity(pointData.legend),
364
- ref: (e)=>{
365
- _refCallback(e, pointData.legend, refIndexNumber);
366
- },
367
- fill: startColor,
368
- rx: 0,
369
- onMouseOver: (event)=>onBarHover(pointData, singleSet, event),
370
- onMouseMove: (event)=>onBarHover(pointData, singleSet, event),
371
- onMouseOut: _onBarLeave,
372
- onFocus: (event)=>onBarFocus(event, pointData, singleSet, refIndexNumber),
373
- onBlur: _onBarLeave,
374
- onClick: pointData.onClick,
375
- "aria-label": getAriaLabel(pointData, singleSet.xAxisPoint),
376
- tabIndex: _legendHighlighted(pointData.legend) || _noLegendHighlighted() ? 0 : undefined,
377
- role: "img"
378
- })));
379
- if (pointData.data && !props.hideLabels && _barWidth >= 16 && (_legendHighlighted(pointData.legend) || _noLegendHighlighted())) {
363
+ barPoints.forEach((pointData, pointIndex)=>{
364
+ if (!pointData.data) {
365
+ // Not rendering data with 0.
366
+ return;
367
+ }
368
+ const barGap = VERTICAL_BAR_GAP / 2 * (pointIndex > 0 ? 2 : 0);
369
+ const height = Math.max(yBarScale(Y_ORIGIN) - yBarScale(Math.abs(pointData.data)), MIN_BAR_HEIGHT);
370
+ const pointColor = pointData.color; // Use the color of the current point
371
+ if (pointData.data >= Y_ORIGIN) {
372
+ yPositiveStart -= height + barGap;
373
+ yPoint = yPositiveStart;
374
+ } else {
375
+ yPoint = yNegativeStart + barGap;
376
+ yNegativeStart = yPoint + height;
377
+ }
378
+ singleGroup.push(/*#__PURE__*/ React.createElement("rect", {
379
+ key: `${singleSet.indexNum}-${legendIndex}-${pointIndex}`,
380
+ className: classes.opacityChangeOnHover,
381
+ height: height,
382
+ width: _barWidth,
383
+ x: xPoint,
384
+ y: yPoint,
385
+ opacity: barOpacity,
386
+ fill: pointColor,
387
+ rx: 0,
388
+ onMouseOver: (event)=>onBarHover(pointData, singleSet, event),
389
+ onMouseMove: (event)=>onBarHover(pointData, singleSet, event),
390
+ onMouseOut: _onBarLeave,
391
+ onFocus: (event)=>onBarFocus(event, pointData, singleSet),
392
+ onBlur: _onBarLeave,
393
+ onClick: pointData.onClick,
394
+ "aria-label": getAriaLabel(pointData, singleSet.xAxisPoint),
395
+ tabIndex: _legendHighlighted(pointData.legend) || _noLegendHighlighted() ? 0 : undefined,
396
+ role: "img"
397
+ }));
398
+ barTotalValue += pointData.data;
399
+ });
400
+ if (barTotalValue !== null && !props.hideLabels && _barWidth >= 16 && isLegendActive) {
380
401
  barLabelsForGroup.push(/*#__PURE__*/ React.createElement("text", {
381
- key: `${singleSet.indexNum}-${index}`,
402
+ key: `${singleSet.indexNum}-${legendIndex}`,
382
403
  x: xPoint + _barWidth / 2,
383
- y: pointData.data >= Y_ORIGIN ? yPositiveStart - 6 : yNegativeStart + 12,
404
+ y: barTotalValue >= Y_ORIGIN ? yPositiveStart - 6 : yNegativeStart + 12,
384
405
  textAnchor: "middle",
385
406
  className: classes.barLabel,
386
407
  "aria-hidden": true
387
- }, typeof props.yAxisTickFormat === 'function' ? props.yAxisTickFormat(pointData.data) : formatScientificLimitWidth(pointData.data)));
408
+ }, typeof props.yAxisTickFormat === 'function' ? props.yAxisTickFormat(barTotalValue) : formatScientificLimitWidth(barTotalValue)));
388
409
  }
389
410
  }
390
411
  });
@@ -404,7 +425,7 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
404
425
  }
405
426
  return /*#__PURE__*/ React.createElement("g", {
406
427
  key: singleSet.indexNum,
407
- transform: `translate(${xScale0(singleSet.xAxisPoint) + (xScale0.bandwidth() - _groupWidth) / 2}, 0)`
428
+ transform: `translate(${xScale0(singleSet.xAxisPoint) + (xScale0.bandwidth() - effectiveGroupWidth) / 2}, 0)`
408
429
  }, singleGroup, barLabelsForGroup);
409
430
  };
410
431
  // For grouped vertical bar chart, First need to define total scale (from start to end)
@@ -421,7 +442,7 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
421
442
  };
422
443
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
423
444
  const _createX1Scale = ()=>{
424
- return d3ScaleBand().domain(keys)// When there is only one group, xScale0 adds padding around it,
445
+ return d3ScaleBand().domain(_legends)// When there is only one group, xScale0 adds padding around it,
425
446
  // causing the bandwidth to become smaller than the actual group width.
426
447
  // So to render bars in the group correctly, use groupWidth instead of the generated scale bandwidth.
427
448
  .range(_useRtl ? [
@@ -472,8 +493,7 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
472
493
  return ((_point_callOutAccessibilityData = point.callOutAccessibilityData) === null || _point_callOutAccessibilityData === void 0 ? void 0 : _point_callOutAccessibilityData.ariaLabel) || `${xValue}. ${legend}, ${yValue}.`;
473
494
  };
474
495
  const _getDomainMargins = (containerWidth)=>{
475
- /** Total width available to render the bars */ const totalWidth = containerWidth - (_margins.left + MIN_DOMAIN_MARGIN) - (_margins.right + MIN_DOMAIN_MARGIN);
476
- /** Rate at which the space between the groups changes wrt the group width */ const groupGapRate = _xAxisInnerPadding / (1 - _xAxisInnerPadding);
496
+ /** Total width available to render the bars */ const totalWidth = calcTotalWidth(containerWidth, _margins, MIN_DOMAIN_MARGIN);
477
497
  if (_xAxisType === XAxisTypes.StringAxis) {
478
498
  if (isScalePaddingDefined(props.xAxisOuterPadding)) {
479
499
  // Setting the domain margin for string x-axis to 0 because the xAxisOuterPadding prop is now available
@@ -483,19 +503,19 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
483
503
  // Update the bar width so that when CartesianChart rerenders,
484
504
  // the following calculations don't use the previous bar width.
485
505
  _barWidth = getBarWidth(props.barWidth, props.maxBarWidth);
486
- const groupWidth = (keys.length + (keys.length - 1) * BAR_GAP_RATE) * _barWidth;
487
- /** Total width required to render the groups. Directly proportional to group width */ const reqWidth = (xAxisLabels.length + (xAxisLabels.length - 1) * groupGapRate) * groupWidth;
506
+ const groupWidth = calcRequiredWidth(_barWidth, _legends.length, X1_INNER_PADDING);
507
+ /** Total width required to render the groups. Directly proportional to group width */ const reqWidth = calcRequiredWidth(groupWidth, _xAxisLabels.length, _xAxisInnerPadding);
488
508
  if (totalWidth >= reqWidth) {
489
509
  // Center align the chart by setting equal left and right margins for domain
490
510
  _domainMargin = MIN_DOMAIN_MARGIN + (totalWidth - reqWidth) / 2;
491
511
  }
492
512
  } else if (props.mode === 'plotly' && xAxisLabels.length > 1) {
493
513
  // Calculate the remaining width after rendering groups at their maximum allowable width
494
- const groupBandwidth = totalWidth / (xAxisLabels.length + (xAxisLabels.length - 1) * groupGapRate);
495
- const barBandwidth = groupBandwidth / (keys.length + (keys.length - 1) * BAR_GAP_RATE);
514
+ const groupBandwidth = calcBandwidth(totalWidth, _xAxisLabels.length, _xAxisInnerPadding);
515
+ const barBandwidth = calcBandwidth(groupBandwidth, _legends.length, X1_INNER_PADDING);
496
516
  const barWidth = getBarWidth(props.barWidth, props.maxBarWidth, barBandwidth);
497
- const groupWidth = (keys.length + (keys.length - 1) * BAR_GAP_RATE) * barWidth;
498
- let reqWidth = (xAxisLabels.length + (xAxisLabels.length - 1) * groupGapRate) * groupWidth;
517
+ const groupWidth = calcRequiredWidth(barWidth, _legends.length, X1_INNER_PADDING);
518
+ let reqWidth = calcRequiredWidth(groupWidth, _xAxisLabels.length, _xAxisInnerPadding);
499
519
  const margin1 = (totalWidth - reqWidth) / 2;
500
520
  let margin2 = Number.POSITIVE_INFINITY;
501
521
  if (!props.hideTickOverlap) {
@@ -517,7 +537,7 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
517
537
  return !(props.data && props.data.length > 0 && props.data.filter((item)=>item.series.length).length > 0);
518
538
  };
519
539
  const _getChartTitle = ()=>{
520
- return (props.chartTitle ? `${props.chartTitle}. ` : '') + `Vertical bar chart with ${_xAxisLabels.length} groups of ${_keys.length} bars each. `;
540
+ return (props.chartTitle ? `${props.chartTitle}. ` : '') + `Vertical bar chart with ${_xAxisLabels.length} groups of ${_legends.length} bars each. `;
521
541
  };
522
542
  return !_isChartEmpty() ? /*#__PURE__*/ React.createElement(CartesianChart, {
523
543
  ...props,
@@ -528,7 +548,7 @@ export const GroupedVerticalBarChart = /*#__PURE__*/ React.forwardRef((props = {
528
548
  getMinMaxOfYAxis: _getMinMaxOfYAxis,
529
549
  createStringYAxis: createStringYAxis,
530
550
  calloutProps: calloutProps,
531
- legendBars: legends,
551
+ legendBars: legendBars,
532
552
  xAxisType: _xAxisType,
533
553
  createYAxis: createNumericYAxis,
534
554
  datasetForXAxisDomain: _xAxisLabels,