@fluentui/react-charts 0.0.0-nightly-20250813-0406.1 → 0.0.0-nightly-20250815-0407.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +15 -15
  2. package/dist/index.d.ts +16 -9
  3. package/lib/components/CommonComponents/CartesianChart.js +12 -16
  4. package/lib/components/CommonComponents/CartesianChart.js.map +1 -1
  5. package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
  6. package/lib/components/DeclarativeChart/DeclarativeChart.js +3 -2
  7. package/lib/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  8. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +41 -9
  9. package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  10. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +130 -35
  11. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  12. package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.types.js.map +1 -1
  13. package/lib/types/DataPoint.js.map +1 -1
  14. package/lib/utilities/utilities.js +10 -4
  15. package/lib/utilities/utilities.js.map +1 -1
  16. package/lib-commonjs/components/CommonComponents/CartesianChart.js +12 -15
  17. package/lib-commonjs/components/CommonComponents/CartesianChart.js.map +1 -1
  18. package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
  19. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js +2 -1
  20. package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
  21. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +46 -9
  22. package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
  23. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +129 -34
  24. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
  25. package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.types.js.map +1 -1
  26. package/lib-commonjs/types/DataPoint.js.map +1 -1
  27. package/lib-commonjs/utilities/utilities.js +10 -4
  28. package/lib-commonjs/utilities/utilities.js.map +1 -1
  29. package/package.json +12 -12
@@ -19,6 +19,7 @@ const _reacttheme = require("@fluentui/react-theme");
19
19
  const _index = require("../../index");
20
20
  const _index1 = require("../../utilities/index");
21
21
  const _imageexportutils = require("../../utilities/image-export-utils");
22
+ const _chartutilities = require("@fluentui/chart-utilities");
22
23
  const barGapMultiplier = 0.2;
23
24
  const barGapMin = 1;
24
25
  const MIN_DOMAIN_MARGIN = 8;
@@ -46,6 +47,8 @@ const VerticalStackedBarChart = (props)=>{
46
47
  const cartesianChartRef = _react.useRef(null);
47
48
  const Y_ORIGIN = 0;
48
49
  const _legendsRef = _react.useRef(null);
50
+ let _yAxisType;
51
+ let _yAxisLabels = [];
49
52
  const [selectedLegends, setSelectedLegends] = _react.useState(((_props_legendProps = props.legendProps) === null || _props_legendProps === void 0 ? void 0 : _props_legendProps.selectedLegends) || []);
50
53
  const [activeLegend, setActiveLegend] = _react.useState(undefined);
51
54
  const [dataForHoverCard, setDataForHoverCard] = _react.useState(0);
@@ -246,15 +249,22 @@ const VerticalStackedBarChart = (props)=>{
246
249
  _lineObject = _getFormattedLineData(props.data);
247
250
  _xAxisInnerPadding = (0, _index1.getScalePadding)(props.xAxisInnerPadding, props.xAxisPadding, _xAxisType === _index1.XAxisTypes.StringAxis ? 2 / 3 : 1 / 2);
248
251
  _xAxisOuterPadding = (0, _index1.getScalePadding)(props.xAxisOuterPadding, props.xAxisPadding, 0);
252
+ _initYAxisParams();
249
253
  }
250
254
  function _createDataSetLayer() {
251
255
  const tempArr = [];
252
256
  const dataset = _points.map((singlePointData)=>{
257
+ tempArr.push(singlePointData.xAxisPoint);
258
+ if (_yAxisType === _index1.YAxisType.StringAxis) {
259
+ return {
260
+ x: singlePointData.xAxisPoint,
261
+ y: 0
262
+ };
263
+ }
253
264
  let total = 0;
254
265
  singlePointData.chartData.forEach((point)=>{
255
266
  total = total + point.data;
256
267
  });
257
- tempArr.push(singlePointData.xAxisPoint);
258
268
  return {
259
269
  x: singlePointData.xAxisPoint,
260
270
  y: total
@@ -285,7 +295,7 @@ const VerticalStackedBarChart = (props)=>{
285
295
  }
286
296
  function _getGraphData(xScale, yScale, containerHeight, containerWidth, xElement) {
287
297
  const { xBarScale, yBarScale } = _getScales(containerHeight, containerWidth);
288
- return _bars = _createBar(xBarScale, yBarScale, containerHeight, xElement);
298
+ return _bars = _createBar(xBarScale, _yAxisType === _index1.YAxisType.StringAxis ? yScale : yBarScale, containerHeight, xElement);
289
299
  }
290
300
  function _getAxisData(yAxisData) {
291
301
  if (yAxisData && yAxisData.yAxisDomainValues.length) {
@@ -412,6 +422,7 @@ const VerticalStackedBarChart = (props)=>{
412
422
  const y1 = useSecondaryYScale ? yScaleSecondary(lineObject[item][i - 1].y) : yScalePrimary(lineObject[item][i - 1].y);
413
423
  const x2 = xScale(lineObject[item][i].xItem.xAxisPoint);
414
424
  const y2 = useSecondaryYScale ? yScaleSecondary(lineObject[item][i].y) : yScalePrimary(lineObject[item][i].y);
425
+ const yScaleBandwidthTranslate = !useSecondaryYScale && _yAxisType === _index1.YAxisType.StringAxis ? yScalePrimary.bandwidth() / 2 : 0;
415
426
  if (lineBorderWidth > 0) {
416
427
  borderForLines.push(/*#__PURE__*/ _react.createElement("line", {
417
428
  key: `${index}-${i}-BorderLine`,
@@ -424,7 +435,7 @@ const VerticalStackedBarChart = (props)=>{
424
435
  fill: "transparent",
425
436
  strokeLinecap: "round",
426
437
  stroke: _reacttheme.tokens.colorNeutralBackground1,
427
- transform: `translate(${xScaleBandwidthTranslate}, 0)`
438
+ transform: `translate(${xScaleBandwidthTranslate}, ${yScaleBandwidthTranslate})`
428
439
  }));
429
440
  }
430
441
  var _lineObject_item__lineOptions_strokeWidth, _lineObject_item__lineOptions_strokeLinecap;
@@ -439,7 +450,7 @@ const VerticalStackedBarChart = (props)=>{
439
450
  strokeLinecap: (_lineObject_item__lineOptions_strokeLinecap = (_lineObject_item__lineOptions1 = lineObject[item][0].lineOptions) === null || _lineObject_item__lineOptions1 === void 0 ? void 0 : _lineObject_item__lineOptions1.strokeLinecap) !== null && _lineObject_item__lineOptions_strokeLinecap !== void 0 ? _lineObject_item__lineOptions_strokeLinecap : 'round',
440
451
  strokeDasharray: (_lineObject_item__lineOptions2 = lineObject[item][0].lineOptions) === null || _lineObject_item__lineOptions2 === void 0 ? void 0 : _lineObject_item__lineOptions2.strokeDasharray,
441
452
  stroke: lineObject[item][i].color,
442
- transform: `translate(${xScaleBandwidthTranslate}, 0)`,
453
+ transform: `translate(${xScaleBandwidthTranslate}, ${yScaleBandwidthTranslate})`,
443
454
  onMouseOver: (event)=>_lineHover(lineObject[item][i - 1], event),
444
455
  onMouseLeave: _handleMouseOut
445
456
  }));
@@ -451,6 +462,7 @@ const VerticalStackedBarChart = (props)=>{
451
462
  refElement: null
452
463
  };
453
464
  const noBarsAndLinesActive = circlePoint.xItem.chartData.filter((dataPoint)=>_noLegendHighlighted() || _isLegendHighlighted(dataPoint.legend)).length === 0;
465
+ const yScaleBandwidthTranslate = !circlePoint.useSecondaryYScale && _yAxisType === _index1.YAxisType.StringAxis ? yScalePrimary.bandwidth() / 2 : 0;
454
466
  dots.push(/*#__PURE__*/ _react.createElement("circle", {
455
467
  key: `${index}-${subIndex}-dot`,
456
468
  cx: xScale(circlePoint.xItem.xAxisPoint),
@@ -464,7 +476,7 @@ const VerticalStackedBarChart = (props)=>{
464
476
  // Elements with visibility: hidden cannot receive focus, so use opacity: 0 instead to hide them.
465
477
  // For more information, see https://fuzzbomb.github.io/accessibility-demos/visually-hidden-focus-test.html
466
478
  opacity: _getCircleOpacityAndRadius(circlePoint.xItem.xAxisPoint, circlePoint.legend).opacity,
467
- transform: `translate(${xScaleBandwidthTranslate}, 0)`,
479
+ transform: `translate(${xScaleBandwidthTranslate}, ${yScaleBandwidthTranslate})`,
468
480
  ref: (e)=>circleRef.refElement = e,
469
481
  ...noBarsAndLinesActive ? {
470
482
  tabIndex: !props.hideTooltip ? 0 : undefined,
@@ -536,14 +548,15 @@ const VerticalStackedBarChart = (props)=>{
536
548
  if ((_calloutAnchorPoint === null || _calloutAnchorPoint === void 0 ? void 0 : _calloutAnchorPoint.chartDataPoint) !== point || (_calloutAnchorPoint === null || _calloutAnchorPoint === void 0 ? void 0 : _calloutAnchorPoint.xAxisDataPoint) !== xAxisPoint) {
537
549
  _calloutAnchorPoint = {
538
550
  chartDataPoint: point,
539
- xAxisDataPoint: `${xAxisPoint}`
551
+ xAxisDataPoint: xAxisPoint instanceof Date ? (0, _chartutilities.formatDateToLocaleString)(xAxisPoint, props.culture, props.useUTC) : xAxisPoint.toString()
540
552
  };
553
+ const xCalloutValue = point.xAxisCalloutData || (xAxisPoint instanceof Date ? (0, _chartutilities.formatDateToLocaleString)(xAxisPoint, props.culture, props.useUTC) : xAxisPoint.toString());
541
554
  _updatePosition(clientX, clientY);
542
555
  setPopoverOpen(_noLegendHighlighted() || _isLegendHighlighted(point.legend));
543
556
  setCalloutLegend(point.legend);
544
557
  setDataForHoverCard(point.data);
545
558
  setColor(color);
546
- setXCalloutValue(point.xAxisCalloutData ? point.xAxisCalloutData : `${xAxisPoint}`);
559
+ setXCalloutValue(xCalloutValue);
547
560
  setYCalloutValue(point.yAxisCalloutData);
548
561
  setDataPointCalloutProps(point);
549
562
  setCallOutAccessibilityData(point.callOutAccessibilityData);
@@ -577,22 +590,29 @@ const VerticalStackedBarChart = (props)=>{
577
590
  }
578
591
  function _getBarGapAndScale(bars, yBarScale, defaultTotalHeight) {
579
592
  const { barGapMax = 0 } = props;
580
- // When displaying gaps between the bars, the height of each bar is
581
- // adjusted so that the total of all bars is not changed by the gaps
582
- const totalData = bars.reduce((iter, value)=>iter + Math.abs(value.data), 0);
583
- const totalHeight = defaultTotalHeight !== null && defaultTotalHeight !== void 0 ? defaultTotalHeight : Math.abs(yBarScale(totalData) - yBarScale(Y_ORIGIN));
593
+ let totalData = 0;
594
+ let totalHeight;
584
595
  let sumOfPercent = 0;
585
- bars.forEach((point)=>{
586
- let value = Math.abs(point.data) / totalData * 100;
587
- if (value < 1 && value !== 0) {
588
- value = 1;
589
- }
590
- sumOfPercent += value;
591
- });
592
- const scalingRatio = sumOfPercent !== 0 ? sumOfPercent / 100 : 1;
596
+ let scalingRatio;
597
+ if (_yAxisType === _index1.YAxisType.StringAxis) {
598
+ totalHeight = defaultTotalHeight !== null && defaultTotalHeight !== void 0 ? defaultTotalHeight : bars.reduce((total, bar)=>total + yBarScale(bar.data), 0);
599
+ } else {
600
+ // When displaying gaps between the bars, the height of each bar is
601
+ // adjusted so that the total of all bars is not changed by the gaps
602
+ totalData = bars.reduce((iter, value)=>iter + Math.abs(value.data), 0);
603
+ totalHeight = defaultTotalHeight !== null && defaultTotalHeight !== void 0 ? defaultTotalHeight : Math.abs(yBarScale(totalData) - yBarScale(Y_ORIGIN));
604
+ bars.forEach((point)=>{
605
+ let value = Math.abs(point.data) / totalData * 100;
606
+ if (value < 1 && value !== 0) {
607
+ value = 1;
608
+ }
609
+ sumOfPercent += value;
610
+ });
611
+ scalingRatio = sumOfPercent !== 0 ? sumOfPercent / 100 : 1;
612
+ }
593
613
  const gaps = barGapMax && bars.length - 1;
594
614
  const gapHeight = gaps && Math.max(barGapMin, Math.min(barGapMax, totalHeight * barGapMultiplier / gaps));
595
- const heightValueScale = (totalHeight - gapHeight * gaps) / (totalData * scalingRatio);
615
+ const heightValueScale = _yAxisType === _index1.YAxisType.StringAxis ? 0 : (totalHeight - gapHeight * gaps) / (totalData * scalingRatio);
596
616
  return {
597
617
  gapHeight,
598
618
  heightValueScale,
@@ -742,7 +762,7 @@ const VerticalStackedBarChart = (props)=>{
742
762
  const xPoint = xBarScale(_xAxisType === _index1.XAxisTypes.NumericAxis ? singleChartData.xAxisPoint : _xAxisType === _index1.XAxisTypes.DateAxis ? singleChartData.xAxisPoint : singleChartData.xAxisPoint);
743
763
  const xScaleBandwidthTranslate = _xAxisType !== _index1.XAxisTypes.StringAxis ? -_barWidth / 2 : (xBarScale.bandwidth() - _barWidth) / 2;
744
764
  let barTotalValue = 0;
745
- const barsToDisplay = singleChartData.chartData.filter((point)=>point.data !== 0);
765
+ const barsToDisplay = singleChartData.chartData.filter((point)=>point.data !== 0 && point.data !== '' && !(_yAxisType === _index1.YAxisType.StringAxis && typeof yBarScale(point.data) === 'undefined'));
746
766
  if (!barsToDisplay.length) {
747
767
  return undefined;
748
768
  }
@@ -750,7 +770,7 @@ const VerticalStackedBarChart = (props)=>{
750
770
  if (heightValueScale < 0) {
751
771
  return undefined;
752
772
  }
753
- const yBaseline = containerHeight - _margins.bottom - yBarScale(Y_ORIGIN);
773
+ const yBaseline = containerHeight - _margins.bottom - (_yAxisType === _index1.YAxisType.StringAxis ? 0 : yBarScale(Y_ORIGIN));
754
774
  let yPositiveStart = yBaseline;
755
775
  let yNegativeStart = yBaseline;
756
776
  let yPoint = 0;
@@ -770,22 +790,29 @@ const VerticalStackedBarChart = (props)=>{
770
790
  role: 'img',
771
791
  tabIndex: !props.hideTooltip && shouldHighlight ? 0 : undefined
772
792
  };
773
- let barHeight = Math.abs(heightValueScale * point.data);
774
- // FIXME: The current scaling logic may produce different min and gap heights for each bar stack.
775
- const minHeight = Math.max(heightValueScale * absStackTotal / 100.0, barMinimumHeight);
776
- if (barHeight < minHeight) {
777
- barHeight = minHeight;
778
- }
793
+ let barHeight;
779
794
  const gapOffset = index ? gapHeight : 0;
780
- if (point.data >= Y_ORIGIN) {
795
+ if (_yAxisType === _index1.YAxisType.StringAxis) {
796
+ barHeight = Math.max(containerHeight - _margins.bottom - (yBarScale(point.data) + yBarScale.bandwidth() / 2) - gapOffset, barMinimumHeight, 1);
781
797
  yPositiveStart -= barHeight + gapOffset;
782
798
  yPoint = yPositiveStart;
783
799
  } else {
784
- yPoint = yNegativeStart + gapOffset;
785
- yNegativeStart = yPoint + barHeight;
800
+ barHeight = Math.abs(heightValueScale * point.data);
801
+ // FIXME: The current scaling logic may produce different min and gap heights for each bar stack.
802
+ const minHeight = Math.max(heightValueScale * absStackTotal / 100.0, barMinimumHeight);
803
+ if (barHeight < minHeight) {
804
+ barHeight = minHeight;
805
+ }
806
+ if (point.data >= Y_ORIGIN) {
807
+ yPositiveStart -= barHeight + gapOffset;
808
+ yPoint = yPositiveStart;
809
+ } else {
810
+ yPoint = yNegativeStart + gapOffset;
811
+ yNegativeStart = yPoint + barHeight;
812
+ }
813
+ barTotalValue += point.data;
814
+ heightOfLastBar = index === barsToDisplay.length - 1 ? barHeight : 0;
786
815
  }
787
- barTotalValue += point.data;
788
- heightOfLastBar = index === barsToDisplay.length - 1 ? barHeight : 0;
789
816
  if (barCornerRadius && barHeight > barCornerRadius && index === barsToDisplay.length - 1) {
790
817
  return /*#__PURE__*/ _react.createElement(_react.Fragment, {
791
818
  key: index + indexNumber + `${shouldFocusWholeStack}`
@@ -848,7 +875,7 @@ const VerticalStackedBarChart = (props)=>{
848
875
  };
849
876
  let showLabel = false;
850
877
  let barLabel = 0;
851
- if (!props.hideLabels) {
878
+ if (!props.hideLabels && _yAxisType !== _index1.YAxisType.StringAxis) {
852
879
  if (_noLegendHighlighted()) {
853
880
  showLabel = true;
854
881
  barLabel = barTotalValue;
@@ -918,6 +945,68 @@ const VerticalStackedBarChart = (props)=>{
918
945
  endValue: (0, _d3array.max)(values)
919
946
  };
920
947
  }
948
+ function _initYAxisParams() {
949
+ if (_points[0].chartData.length > 0) {
950
+ _yAxisType = (0, _index1.getTypeOfAxis)(_points[0].chartData[0].data, false);
951
+ } else {
952
+ Object.keys(_lineObject).forEach((lineLegend)=>{
953
+ if (!_lineObject[lineLegend][0].useSecondaryYScale) {
954
+ _yAxisType = (0, _index1.getTypeOfAxis)(_lineObject[lineLegend][0].y, false);
955
+ }
956
+ });
957
+ }
958
+ if (_yAxisType === _index1.YAxisType.StringAxis) {
959
+ const legendToYValues = {};
960
+ _points.forEach((xPoint)=>{
961
+ xPoint.chartData.forEach((bar)=>{
962
+ if (!legendToYValues[bar.legend]) {
963
+ legendToYValues[bar.legend] = [
964
+ `${bar.data}`
965
+ ];
966
+ } else {
967
+ legendToYValues[bar.legend].push(`${bar.data}`);
968
+ }
969
+ });
970
+ });
971
+ const yAxisLabels = new Set();
972
+ Object.values(legendToYValues).forEach((yValues)=>{
973
+ yValues.forEach((yVal)=>{
974
+ yAxisLabels.add(yVal);
975
+ });
976
+ });
977
+ Object.values(_lineObject).forEach((linePoints)=>{
978
+ linePoints.forEach((linePoint)=>{
979
+ if (!linePoint.useSecondaryYScale) {
980
+ yAxisLabels.add(`${linePoint.y}`);
981
+ }
982
+ });
983
+ });
984
+ _yAxisLabels = Array.from(yAxisLabels);
985
+ }
986
+ }
987
+ function _getYDomainMargins(containerHeight) {
988
+ /**
989
+ * Specifies the extra top margin to apply above the highest y-axis tick label.
990
+ * Useful when stacked bars extend beyond the combined height of all y-axis labels (or categories).
991
+ */ let yAxisTickMarginTop = 0;
992
+ /** Total height available to render the bars */ const totalHeight = containerHeight - _margins.bottom - _margins.top;
993
+ if (_yAxisType === _index1.YAxisType.StringAxis) {
994
+ /** Maximum height of the stacked bars, expressed in multiples of the height of a y-axis label (or category) */ let maxBarHeightInLabels = 0;
995
+ _points.forEach((xPoint)=>{
996
+ /** Height of the stacked bar, expressed in multiples of the height of a y-axis label (or category) */ let barHeightInLabels = 0;
997
+ xPoint.chartData.forEach((bar)=>{
998
+ barHeightInLabels += _yAxisLabels.indexOf(`${bar.data}`) + 1;
999
+ });
1000
+ maxBarHeightInLabels = Math.max(maxBarHeightInLabels, barHeightInLabels);
1001
+ });
1002
+ /** Height of a y-axis label (or category) */ const yAxisLabelHeight = maxBarHeightInLabels === 0 ? 0 : totalHeight / maxBarHeightInLabels;
1003
+ yAxisTickMarginTop += yAxisLabelHeight * (maxBarHeightInLabels - _yAxisLabels.length);
1004
+ }
1005
+ return {
1006
+ ..._margins,
1007
+ top: _margins.top + yAxisTickMarginTop
1008
+ };
1009
+ }
921
1010
  if (!_isChartEmpty()) {
922
1011
  _adjustProps();
923
1012
  const _isHavingLines = props.data.some((item)=>item.lineData && item.lineData.length > 0);
@@ -973,6 +1062,12 @@ const VerticalStackedBarChart = (props)=>{
973
1062
  },
974
1063
  componentRef: cartesianChartRef,
975
1064
  showRoundOffXTickValues: !(0, _index1.isScalePaddingDefined)(props.xAxisInnerPadding, props.xAxisPadding),
1065
+ yAxisType: _yAxisType,
1066
+ stringDatasetForYAxisDomain: [
1067
+ '',
1068
+ ..._yAxisLabels
1069
+ ],
1070
+ getYDomainMargins: _getYDomainMargins,
976
1071
  /* eslint-disable react/jsx-no-bind */ children: (props)=>{
977
1072
  return /*#__PURE__*/ _react.createElement(_react.Fragment, null, /*#__PURE__*/ _react.createElement("g", null, _bars), /*#__PURE__*/ _react.createElement("g", null, _isHavingLines && _createLines(props.xScale, props.yScalePrimary, props.containerHeight, props.containerWidth, props.yScaleSecondary)));
978
1073
  }