@fluentui/react-charting 5.23.20 → 5.23.21

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 (47) hide show
  1. package/CHANGELOG.json +16 -1
  2. package/CHANGELOG.md +11 -2
  3. package/dist/react-charting.d.ts +6 -1
  4. package/dist/react-charting.js +1 -1
  5. package/dist/react-charting.min.js +1 -1
  6. package/etc/react-charting.api.md +2 -1
  7. package/lib/components/CommonComponents/CartesianChart.base.js +2 -2
  8. package/lib/components/CommonComponents/CartesianChart.base.js.map +1 -1
  9. package/lib/components/CommonComponents/CartesianChart.types.d.ts +6 -1
  10. package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
  11. package/lib/components/VerticalBarChart/VerticalBarChart.base.d.ts +2 -0
  12. package/lib/components/VerticalBarChart/VerticalBarChart.base.js +70 -41
  13. package/lib/components/VerticalBarChart/VerticalBarChart.base.js.map +1 -1
  14. package/lib/utilities/test-data.d.ts +16 -0
  15. package/lib/utilities/test-data.js +52 -0
  16. package/lib/utilities/test-data.js.map +1 -1
  17. package/lib/utilities/utilities.d.ts +1 -1
  18. package/lib/utilities/utilities.js +29 -4
  19. package/lib/utilities/utilities.js.map +1 -1
  20. package/lib-amd/components/CommonComponents/CartesianChart.base.js +2 -2
  21. package/lib-amd/components/CommonComponents/CartesianChart.base.js.map +1 -1
  22. package/lib-amd/components/CommonComponents/CartesianChart.types.d.ts +6 -1
  23. package/lib-amd/components/CommonComponents/CartesianChart.types.js.map +1 -1
  24. package/lib-amd/components/VerticalBarChart/VerticalBarChart.base.d.ts +2 -0
  25. package/lib-amd/components/VerticalBarChart/VerticalBarChart.base.js +70 -41
  26. package/lib-amd/components/VerticalBarChart/VerticalBarChart.base.js.map +1 -1
  27. package/lib-amd/utilities/test-data.d.ts +16 -0
  28. package/lib-amd/utilities/test-data.js +53 -1
  29. package/lib-amd/utilities/test-data.js.map +1 -1
  30. package/lib-amd/utilities/utilities.d.ts +1 -1
  31. package/lib-amd/utilities/utilities.js +29 -4
  32. package/lib-amd/utilities/utilities.js.map +1 -1
  33. package/lib-commonjs/components/CommonComponents/CartesianChart.base.js +2 -2
  34. package/lib-commonjs/components/CommonComponents/CartesianChart.base.js.map +1 -1
  35. package/lib-commonjs/components/CommonComponents/CartesianChart.types.d.ts +6 -1
  36. package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
  37. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.base.d.ts +2 -0
  38. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.base.js +70 -41
  39. package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.base.js.map +1 -1
  40. package/lib-commonjs/utilities/test-data.d.ts +16 -0
  41. package/lib-commonjs/utilities/test-data.js +53 -1
  42. package/lib-commonjs/utilities/test-data.js.map +1 -1
  43. package/lib-commonjs/utilities/utilities.d.ts +1 -1
  44. package/lib-commonjs/utilities/utilities.js +29 -4
  45. package/lib-commonjs/utilities/utilities.js.map +1 -1
  46. package/package.json +1 -1
  47. package/src/components/CommonComponents/CartesianChart.types.ts +7 -0
@@ -262,7 +262,7 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
262
262
  var xBarScale;
263
263
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
264
264
  var yBarScale = d3ScaleLinear()
265
- .domain([0, _this._yMax])
265
+ .domain([_this.props.supportNegativeData ? _this._yMin : 0, _this._yMax])
266
266
  .range([0, containerHeight - _this.margins.bottom - _this.margins.top]);
267
267
  if (_this._xAxisType === XAxisTypes.NumericAxis) {
268
268
  var xMax = d3Max(_this._points, function (point) { return point.x; });
@@ -354,6 +354,7 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
354
354
  if (yAxisData && yAxisData.yAxisDomainValues.length) {
355
355
  var domainValue = yAxisData.yAxisDomainValues;
356
356
  _this._yMax = Math.max(domainValue[domainValue.length - 1], _this.props.yMaxValue || 0);
357
+ _this._yMin = Math.min(domainValue[0], _this.props.yMinValue || 0);
357
358
  }
358
359
  };
359
360
  /**
@@ -459,6 +460,7 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
459
460
  this._adjustProps();
460
461
  this._xAxisLabels = this._points.map(function (point) { return point.x; });
461
462
  this._yMax = Math.max(d3Max(this._points, function (point) { return point.y; }), this.props.yMaxValue || 0);
463
+ this._yMin = Math.min(d3Min(this._points, function (point) { return point.y; }), this.props.yMinValue || 0);
462
464
  var legendBars = this._getLegendData(this._points, this.props.theme.palette);
463
465
  this._classNames = getClassNames(this.props.styles, {
464
466
  theme: this.props.theme,
@@ -472,7 +474,7 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
472
474
  tickValues: this.props.tickValues,
473
475
  tickFormat: this.props.tickFormat,
474
476
  };
475
- return !this._isChartEmpty() ? (React.createElement(CartesianChart, __assign({}, this.props, { chartTitle: this._getChartTitle(), points: this._points, chartType: ChartTypes.VerticalBarChart, xAxisType: this._xAxisType, createYAxis: createNumericYAxis, calloutProps: calloutProps, tickParams: tickParams }, (this._isHavingLine && this._noLegendHighlighted() && { isCalloutForStack: true }), { legendBars: legendBars, datasetForXAxisDomain: this._xAxisLabels, barwidth: this._barWidth, focusZoneDirection: FocusZoneDirection.horizontal, customizedCallout: this._getCustomizedCallout(), createStringYAxis: createStringYAxis, getmargins: this._getMargins, getMinMaxOfYAxis: findVerticalNumericMinMaxOfY, getGraphData: this._getGraphData, getDomainNRangeValues: this._getDomainNRangeValues, getAxisData: this._getAxisData, onChartMouseLeave: this._handleChartMouseLeave, getDomainMargins: this._getDomainMargins }, (this._xAxisType === XAxisTypes.StringAxis && {
477
+ return !this._isChartEmpty() ? (React.createElement(CartesianChart, __assign({}, this.props, { chartTitle: this._getChartTitle(), points: this._points, supportNegativeData: this.props.supportNegativeData, chartType: ChartTypes.VerticalBarChart, xAxisType: this._xAxisType, createYAxis: createNumericYAxis, calloutProps: calloutProps, tickParams: tickParams }, (this._isHavingLine && this._noLegendHighlighted() && { isCalloutForStack: true }), { legendBars: legendBars, datasetForXAxisDomain: this._xAxisLabels, barwidth: this._barWidth, focusZoneDirection: FocusZoneDirection.horizontal, customizedCallout: this._getCustomizedCallout(), createStringYAxis: createStringYAxis, getmargins: this._getMargins, getMinMaxOfYAxis: findVerticalNumericMinMaxOfY, getGraphData: this._getGraphData, getDomainNRangeValues: this._getDomainNRangeValues, getAxisData: this._getAxisData, onChartMouseLeave: this._handleChartMouseLeave, getDomainMargins: this._getDomainMargins }, (this._xAxisType === XAxisTypes.StringAxis && {
476
478
  xAxisInnerPadding: this._xAxisInnerPadding,
477
479
  xAxisOuterPadding: this._xAxisOuterPadding,
478
480
  }), {
@@ -534,11 +536,19 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
534
536
  });
535
537
  }
536
538
  };
539
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
540
+ VerticalBarChartBase.prototype._calculateMinBarHeight = function (yMin, yMax, yReferencePoint, yBarScale) {
541
+ var maxHeightFromBaseline = yMax < 0
542
+ ? Math.abs(yMin - yReferencePoint)
543
+ : Math.max(Math.abs(yMax - yReferencePoint), Math.abs(yMin - yReferencePoint));
544
+ return Math.ceil(yBarScale(maxHeightFromBaseline) / 100.0);
545
+ };
537
546
  VerticalBarChartBase.prototype._createNumericBars = function (containerHeight, containerWidth, xElement) {
538
547
  var _this = this;
539
548
  var _a = this.props.useSingleColor, useSingleColor = _a === void 0 ? false : _a;
540
549
  var _b = this._getScales(containerHeight, containerWidth), xBarScale = _b.xBarScale, yBarScale = _b.yBarScale;
541
550
  var colorScale = this._createColors();
551
+ var yReferencePoint = this._yMax < 0 ? this._yMax : 0;
542
552
  var bars = this._points.map(function (point, index) {
543
553
  var _a, _b, _c, _d, _e, _f;
544
554
  var shouldHighlight = _this._legendHighlighted(point.legend) || _this._noLegendHighlighted() ? true : false;
@@ -547,19 +557,25 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
547
557
  legendColor: _this.state.color,
548
558
  shouldHighlight: shouldHighlight,
549
559
  });
550
- var barHeight = Math.max(yBarScale(point.y), 0);
551
- var adjustedBarHeight = 0;
552
- if (barHeight <= 0) {
560
+ var barHeight = yBarScale(point.y) - yBarScale(yReferencePoint);
561
+ var isHeightNegative = barHeight < 0;
562
+ barHeight = Math.abs(barHeight);
563
+ // Calculate threshold for minimum visible bar height
564
+ var minBarHeight = _this._calculateMinBarHeight(_this._yMin, _this._yMax, yReferencePoint, yBarScale);
565
+ var adjustedBarHeight = barHeight;
566
+ if (barHeight === 0 || (isHeightNegative && !_this.props.supportNegativeData)) {
553
567
  return React.createElement(React.Fragment, { key: point.x }, " ");
554
568
  }
555
- else if (barHeight <= Math.ceil(yBarScale(_this._yMax) / 100.0)) {
556
- adjustedBarHeight = Math.ceil(yBarScale(_this._yMax) / 100.0);
557
- }
558
- else {
559
- adjustedBarHeight = barHeight;
569
+ // Adjust bar height if it's smaller than the threshold
570
+ else if (barHeight <= minBarHeight) {
571
+ adjustedBarHeight = minBarHeight;
560
572
  }
561
573
  var xPoint = xBarScale(point.x) - _this._barWidth / 2;
562
- var yPoint = containerHeight - _this.margins.bottom - adjustedBarHeight;
574
+ var yPoint = containerHeight -
575
+ _this.margins.bottom -
576
+ (isHeightNegative ? -1 * adjustedBarHeight : adjustedBarHeight) -
577
+ yBarScale(yReferencePoint);
578
+ var baselineHeight = containerHeight - _this.margins.bottom - yBarScale(yReferencePoint);
563
579
  var startColor = point.color && !useSingleColor ? point.color : colorScale(point.y);
564
580
  var endColor = startColor;
565
581
  if (_this.props.enableGradient) {
@@ -577,10 +593,10 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
577
593
  React.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "100%", x2: "0%", y2: "0%" },
578
594
  React.createElement("stop", { offset: "0", stopColor: startColor }),
579
595
  React.createElement("stop", { offset: "100%", stopColor: endColor })))),
580
- React.createElement("rect", { id: getId('_VBC_bar_'), x: xPoint, className: _this._classNames.opacityChangeOnHover, y: yPoint, width: _this._barWidth, "data-is-focusable": !_this.props.hideTooltip && shouldHighlight, height: adjustedBarHeight, ref: function (e) {
596
+ React.createElement("rect", { id: getId('_VBC_bar_'), x: xPoint, className: _this._classNames.opacityChangeOnHover, y: !isHeightNegative ? yPoint : baselineHeight, width: _this._barWidth, "data-is-focusable": !_this.props.hideTooltip && shouldHighlight, height: adjustedBarHeight, ref: function (e) {
581
597
  _this._refCallback(e, point.legend);
582
598
  }, onClick: point.onClick, onMouseOver: _this._onBarHover.bind(_this, point, startColor), "aria-label": _this._getAriaLabel(point), role: "img", onMouseLeave: _this._onBarLeave, onFocus: _this._onBarFocus.bind(_this, point, index, startColor), onBlur: _this._onBarLeave, fill: _this.props.enableGradient ? "url(#".concat(gradientId, ")") : startColor, rx: _this.props.roundCorners ? 3 : 0 }),
583
- _this._renderBarLabel(xPoint, yPoint, point.y, point.legend)));
599
+ _this._renderBarLabel(xPoint, yPoint, point.y, point.legend, isHeightNegative)));
584
600
  });
585
601
  // Removing un wanted tooltip div from DOM, when prop not provided.
586
602
  if (!this.props.showXAxisLablesTooltip) {
@@ -612,21 +628,28 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
612
628
  var _a = this.props.useSingleColor, useSingleColor = _a === void 0 ? false : _a;
613
629
  var _b = this._getScales(containerHeight, containerWidth), xBarScale = _b.xBarScale, yBarScale = _b.yBarScale;
614
630
  var colorScale = this._createColors();
631
+ var yReferencePoint = this._yMax < 0 ? this._yMax : 0;
615
632
  var bars = this._points.map(function (point, index) {
616
633
  var _a, _b, _c, _d, _e, _f;
617
- var barHeight = Math.max(yBarScale(point.y), 0);
618
- var adjustedBarHeight = 0;
619
- if (barHeight <= 0) {
620
- return React.createElement(React.Fragment, { key: point.x instanceof Date ? point.x.getTime() : point.x }, " ");
634
+ var barHeight = yBarScale(point.y) - yBarScale(yReferencePoint);
635
+ var isHeightNegative = barHeight < 0;
636
+ barHeight = Math.abs(barHeight);
637
+ // Calculate threshold for minimum visible bar height
638
+ var minBarHeight = _this._calculateMinBarHeight(_this._yMin, _this._yMax, yReferencePoint, yBarScale);
639
+ var adjustedBarHeight = barHeight;
640
+ if (barHeight === 0 || (isHeightNegative && !_this.props.supportNegativeData)) {
641
+ return React.createElement(React.Fragment, { key: point.x }, " ");
621
642
  }
622
- else if (barHeight <= Math.ceil(yBarScale(_this._yMax) / 100.0)) {
623
- adjustedBarHeight = Math.ceil(yBarScale(_this._yMax) / 100.0);
624
- }
625
- else {
626
- adjustedBarHeight = barHeight;
643
+ // Adjust bar height if it's smaller than the threshold
644
+ else if (barHeight <= minBarHeight) {
645
+ adjustedBarHeight = minBarHeight;
627
646
  }
628
647
  var xPoint = xBarScale(point.x);
629
- var yPoint = containerHeight - _this.margins.bottom - adjustedBarHeight;
648
+ var yPoint = containerHeight -
649
+ _this.margins.bottom -
650
+ (isHeightNegative ? -1 * adjustedBarHeight : adjustedBarHeight) -
651
+ yBarScale(yReferencePoint);
652
+ var baselineHeight = containerHeight - _this.margins.bottom - yBarScale(yReferencePoint);
630
653
  // Setting the bar width here is safe because there are no dependencies earlier in the code
631
654
  // that rely on the width of bars in vertical bar charts with string x-axis.
632
655
  _this._barWidth = getBarWidth(_this.props.barWidth, _this.props.maxBarWidth, xBarScale.bandwidth());
@@ -647,10 +670,10 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
647
670
  React.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "100%", x2: "0%", y2: "0%" },
648
671
  React.createElement("stop", { offset: "0", stopColor: startColor }),
649
672
  React.createElement("stop", { offset: "100%", stopColor: endColor })))),
650
- React.createElement("rect", { id: getId('_VBC_bar_'), x: xPoint, y: yPoint, width: _this._barWidth, height: adjustedBarHeight, "aria-label": _this._getAriaLabel(point), role: "img", ref: function (e) {
673
+ React.createElement("rect", { id: getId('_VBC_bar_'), x: xPoint, y: !isHeightNegative ? yPoint : baselineHeight, width: _this._barWidth, height: adjustedBarHeight, "aria-label": _this._getAriaLabel(point), role: "img", ref: function (e) {
651
674
  _this._refCallback(e, point.legend);
652
675
  }, onClick: point.onClick, onMouseOver: _this._onBarHover.bind(_this, point, startColor), onMouseLeave: _this._onBarLeave, onBlur: _this._onBarLeave, "data-is-focusable": !_this.props.hideTooltip, onFocus: _this._onBarFocus.bind(_this, point, index, startColor), fill: _this.props.enableGradient ? "url(#".concat(gradientId, ")") : startColor, rx: _this.props.roundCorners ? 3 : 0 }),
653
- _this._renderBarLabel(xPoint, yPoint, point.y, point.legend)));
676
+ _this._renderBarLabel(xPoint, yPoint, point.y, point.legend, isHeightNegative)));
654
677
  });
655
678
  // Removing un wanted tooltip div from DOM, when prop not provided.
656
679
  if (!this.props.showXAxisLablesTooltip) {
@@ -683,6 +706,7 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
683
706
  var _a = this.props.useSingleColor, useSingleColor = _a === void 0 ? false : _a;
684
707
  var _b = this._getScales(containerHeight, containerWidth), xBarScale = _b.xBarScale, yBarScale = _b.yBarScale;
685
708
  var colorScale = this._createColors();
709
+ var yReferencePoint = this._yMax < 0 ? this._yMax : 0;
686
710
  var bars = this._points.map(function (point, index) {
687
711
  var _a, _b, _c, _d, _e, _f;
688
712
  var shouldHighlight = _this._legendHighlighted(point.legend) || _this._noLegendHighlighted() ? true : false;
@@ -691,19 +715,25 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
691
715
  legendColor: _this.state.color,
692
716
  shouldHighlight: shouldHighlight,
693
717
  });
694
- var barHeight = Math.max(yBarScale(point.y), 0);
695
- var adjustedBarHeight = 0;
696
- if (barHeight <= 0) {
697
- return React.createElement(React.Fragment, { key: point.x instanceof Date ? point.x.getTime() : point.x }, " ");
698
- }
699
- else if (barHeight <= Math.ceil(yBarScale(_this._yMax) / 100.0)) {
700
- adjustedBarHeight = Math.ceil(yBarScale(_this._yMax) / 100.0);
718
+ var barHeight = yBarScale(point.y) - yBarScale(yReferencePoint);
719
+ var isHeightNegative = barHeight < 0;
720
+ barHeight = Math.abs(barHeight);
721
+ // Calculate threshold for minimum visible bar height
722
+ var minBarHeight = _this._calculateMinBarHeight(_this._yMin, _this._yMax, yReferencePoint, yBarScale);
723
+ var adjustedBarHeight = barHeight;
724
+ if (barHeight === 0 || (isHeightNegative && !_this.props.supportNegativeData)) {
725
+ return React.createElement(React.Fragment, { key: point.x }, " ");
701
726
  }
702
- else {
703
- adjustedBarHeight = barHeight;
727
+ // Adjust bar height if it's smaller than the threshold
728
+ else if (barHeight <= minBarHeight) {
729
+ adjustedBarHeight = minBarHeight;
704
730
  }
705
731
  var xPoint = xBarScale(point.x) - _this._barWidth / 2;
706
- var yPoint = containerHeight - _this.margins.bottom - adjustedBarHeight;
732
+ var yPoint = containerHeight -
733
+ _this.margins.bottom -
734
+ (isHeightNegative ? -1 * adjustedBarHeight : adjustedBarHeight) -
735
+ yBarScale(yReferencePoint);
736
+ var baselineHeight = containerHeight - _this.margins.bottom - yBarScale(yReferencePoint);
707
737
  var startColor = point.color && !useSingleColor ? point.color : colorScale(point.y);
708
738
  var endColor = startColor;
709
739
  if (_this.props.enableGradient) {
@@ -721,10 +751,10 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
721
751
  React.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "100%", x2: "0%", y2: "0%" },
722
752
  React.createElement("stop", { offset: "0", stopColor: startColor }),
723
753
  React.createElement("stop", { offset: "100%", stopColor: endColor })))),
724
- React.createElement("rect", { id: getId('_VBC_bar_'), x: xPoint, className: _this._classNames.opacityChangeOnHover, y: yPoint, width: _this._barWidth, "data-is-focusable": !_this.props.hideTooltip && shouldHighlight, height: adjustedBarHeight, ref: function (e) {
754
+ React.createElement("rect", { id: getId('_VBC_bar_'), x: xPoint, className: _this._classNames.opacityChangeOnHover, y: !isHeightNegative ? yPoint : baselineHeight, width: _this._barWidth, "data-is-focusable": !_this.props.hideTooltip && shouldHighlight, height: adjustedBarHeight, ref: function (e) {
725
755
  _this._refCallback(e, point.legend);
726
756
  }, onClick: point.onClick, onMouseOver: _this._onBarHover.bind(_this, point, startColor), "aria-label": _this._getAriaLabel(point), role: "img", onMouseLeave: _this._onBarLeave, onFocus: _this._onBarFocus.bind(_this, point, index, startColor), onBlur: _this._onBarLeave, fill: _this.props.enableGradient ? "url(#".concat(gradientId, ")") : startColor, rx: _this.props.roundCorners ? 3 : 0 }),
727
- _this._renderBarLabel(xPoint, yPoint, point.y, point.legend)));
757
+ _this._renderBarLabel(xPoint, yPoint, point.y, point.legend, isHeightNegative)));
728
758
  });
729
759
  // Removing un wanted tooltip div from DOM, when prop not provided.
730
760
  if (!this.props.showXAxisLablesTooltip) {
@@ -773,17 +803,16 @@ var VerticalBarChartBase = /** @class */ (function (_super) {
773
803
  activeLegend: '',
774
804
  });
775
805
  };
776
- VerticalBarChartBase.prototype._renderBarLabel = function (xPoint, yPoint, barValue, legend) {
806
+ VerticalBarChartBase.prototype._renderBarLabel = function (xPoint, yPoint, barValue, legend, isNegativeBar) {
777
807
  if (this.props.hideLabels ||
778
808
  this._barWidth < 16 ||
779
809
  !(this._legendHighlighted(legend) || this._noLegendHighlighted())) {
780
810
  return null;
781
811
  }
782
- return (React.createElement("text", { x: xPoint + this._barWidth / 2, y: yPoint - 6, textAnchor: "middle", className: this._classNames.barLabel, "aria-hidden": true }, formatValueWithSIPrefix(barValue)));
812
+ return (React.createElement("text", { x: xPoint + this._barWidth / 2, y: isNegativeBar ? yPoint + 12 : yPoint - 6, textAnchor: "middle", className: this._classNames.barLabel, "aria-hidden": true }, formatValueWithSIPrefix(barValue)));
783
813
  };
784
814
  VerticalBarChartBase.prototype._isChartEmpty = function () {
785
- return (this._points.length === 0 ||
786
- (d3Max(this._points, function (point) { return point.y; }) <= 0 && !this._isHavingLine));
815
+ return this._points.length === 0 || (this._points.every(function (point) { return point.y === 0; }) && !this._isHavingLine);
787
816
  };
788
817
  VerticalBarChartBase.defaultProps = {
789
818
  maxBarWidth: 24,