import { __assign, __extends } from "tslib";
import * as React from 'react';
import { max as d3Max, min as d3Min } from 'd3-array';
import { select as d3Select } from 'd3-selection';
import { scaleLinear as d3ScaleLinear, scaleBand as d3ScaleBand } from 'd3-scale';
import { classNamesFunction, getId, getRTL, initializeComponentRef, memoizeFunction, warnDeprecations, } from '@fluentui/react/lib/Utilities';
import { DirectionalHint } from '@fluentui/react/lib/Callout';
import { FocusZoneDirection } from '@fluentui/react-focus';
import { ChartTypes, getAccessibleDataObject, tooltipOfAxislabels, XAxisTypes, getTypeOfAxis, formatScientificLimitWidth, getScalePadding, getBarWidth, isScalePaddingDefined, createNumericYAxis, domainRangeOfXStringAxis, createStringYAxis, getNextGradient, getNextColor, areArraysEqual, calculateLongestLabelWidth, sortAxisCategories, } from '../../utilities/index';
import { CartesianChart, Legends, } from '../../index';
import { toImage } from '../../utilities/image-export-utils';
import { rgb } from 'd3-color';
var COMPONENT_NAME = 'GROUPED VERTICAL BAR CHART';
var getClassNames = classNamesFunction();
var MIN_DOMAIN_MARGIN = 8;
var X1_INNER_PADDING = 0.1;
// x1_inner_padding = space_between_bars / (space_between_bars + bar_width)
// => space_between_bars = (x1_inner_padding / (1 - x1_inner_padding)) * bar_width
/** Rate at which the space between the bars in a group changes wrt the bar width */
var BAR_GAP_RATE = X1_INNER_PADDING / (1 - X1_INNER_PADDING);
var VERTICAL_BAR_GAP = 1;
var MIN_BAR_HEIGHT = 1;
var GroupedVerticalBarChartBase = /** @class */ (function (_super) {
    __extends(GroupedVerticalBarChartBase, _super);
    function GroupedVerticalBarChartBase(props) {
        var _a;
        var _this = _super.call(this, props) || this;
        _this._isRtl = getRTL();
        _this._legendColorMap = {};
        _this.Y_ORIGIN = 0;
        _this.toImage = function (opts) {
            var _a, _b;
            return toImage((_a = _this._cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer, (_b = _this._legendsRef.current) === null || _b === void 0 ? void 0 : _b.toSVG, _this._isRtl, opts);
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this._getMinMaxOfYAxis = function (datasetForBars, yAxisType, useSecondaryYScale) {
            var values = [];
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            datasetForBars.forEach(function (data) {
                data.groupSeries.forEach(function (point) {
                    if (!useSecondaryYScale === !point.useSecondaryYScale) {
                        values.push(point.data);
                    }
                });
            });
            return { startValue: d3Min(values), endValue: d3Max(values) };
        };
        _this._getDomainNRangeValues = function (points, margins, width, chartType, isRTL, xAxisType, barWidth, tickValues, shiftX) {
            var domainNRangeValue;
            if (xAxisType === XAxisTypes.NumericAxis || xAxisType === XAxisTypes.DateAxis) {
                domainNRangeValue = { dStartValue: 0, dEndValue: 0, rStartValue: 0, rEndValue: 0 };
            }
            else {
                domainNRangeValue = domainRangeOfXStringAxis(margins, width, isRTL);
            }
            return domainNRangeValue;
        };
        _this._getGraphData = function (xScale, yScalePrimary, containerHeight, containerWidth, xElement, yAxisElement, yScaleSecondary) {
            var xScale0 = _this._createX0Scale(containerWidth);
            // Setting the bar width here is safe because there are no dependencies earlier in the code
            // that rely on the width of bars in vertical bar charts with string x-axis.
            _this._barWidth = getBarWidth(_this.props.barwidth, _this.props.maxBarWidth, xScale0.bandwidth() / (_this._legends.length + (_this._legends.length - 1) * BAR_GAP_RATE));
            _this._groupWidth = (_this._legends.length + (_this._legends.length - 1) * BAR_GAP_RATE) * _this._barWidth;
            var xScale1 = _this._createX1Scale();
            var allGroupsBars = [];
            _this._datasetForBars.forEach(function (singleSet) {
                allGroupsBars.push(_this._buildGraph(singleSet, xScale0, xScale1, yScalePrimary, yScaleSecondary, containerHeight, xElement));
            });
            _this._groupedVerticalBarGraph = allGroupsBars;
        };
        _this._getMargins = function (margins) { return (_this.margins = margins); };
        _this._createDataSetOfGVBC = function (points) {
            var legends = new Set();
            var xAxisLabels = _this._getOrderedXAxisLabels(points);
            points.forEach(function (point) {
                point.series.forEach(function (seriesPoint) {
                    legends.add(seriesPoint.legend);
                });
            });
            var datasetForBars = _this._createDataset(points);
            return {
                legends: Array.from(legends),
                xAxisLabels: xAxisLabels,
                datasetForBars: datasetForBars,
            };
        };
        _this._getCustomizedCallout = function () {
            return _this.props.onRenderCalloutPerDataPoint
                ? _this.props.onRenderCalloutPerDataPoint(_this.state.dataPointCalloutProps)
                : null;
        };
        _this._onBarHover = function (pointData, 
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        groupData, mouseEvent) {
            mouseEvent.persist();
            if (_this._calloutAnchorPoint !== pointData) {
                _this._calloutAnchorPoint = pointData;
                _this.setState({
                    refSelected: mouseEvent,
                    /** Show the callout if highlighted bar is hovered and Hide it if unhighlighted bar is hovered */
                    isCalloutVisible: _this._noLegendHighlighted() || _this._legendHighlighted(pointData.legend),
                    calloutLegend: pointData.legend,
                    dataForHoverCard: pointData.data,
                    color: pointData.color,
                    xCalloutValue: pointData.xAxisCalloutData,
                    yCalloutValue: pointData.yAxisCalloutData,
                    dataPointCalloutProps: pointData,
                    callOutAccessibilityData: _this.props.isCalloutForStack
                        ? groupData.stackCallOutAccessibilityData
                        : pointData.callOutAccessibilityData,
                    YValueHover: groupData.groupSeries,
                    hoverXValue: pointData.xAxisCalloutData,
                });
            }
        };
        _this._onBarLeave = function () {
            /**/
        };
        _this._handleChartMouseLeave = function () {
            _this._calloutAnchorPoint = null;
            _this.setState({ isCalloutVisible: false });
        };
        _this._onBarFocus = function (pointData, 
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        groupData, focusEvent) {
            _this.setState({
                refSelected: focusEvent.currentTarget,
                /** Show the callout if highlighted bar is focused and Hide it if unhighlighted bar is focused */
                isCalloutVisible: _this._noLegendHighlighted() || _this._legendHighlighted(pointData.legend),
                calloutLegend: pointData.legend,
                dataForHoverCard: pointData.data,
                color: pointData.color,
                xCalloutValue: pointData.xAxisCalloutData,
                yCalloutValue: pointData.yAxisCalloutData,
                dataPointCalloutProps: pointData,
                callOutAccessibilityData: _this.props.isCalloutForStack
                    ? groupData.stackCallOutAccessibilityData
                    : pointData.callOutAccessibilityData,
                YValueHover: groupData.groupSeries,
                hoverXValue: pointData.xAxisCalloutData,
            });
        };
        _this._redirectToUrl = function (href) {
            href ? (window.location.href = href) : '';
        };
        _this._buildGraph = function (
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        singleSet, 
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        xScale0, 
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        xScale1, yScalePrimary, yScaleSecondary, containerHeight, xElement) {
            var singleGroup = [];
            var barLabelsForGroup = [];
            _this._legends.forEach(function (legendTitle, legendIndex) {
                var barPoints = singleSet[legendTitle];
                if (barPoints) {
                    var yBarScale_1 = barPoints[0].useSecondaryYScale && yScaleSecondary ? yScaleSecondary : yScalePrimary;
                    // To align the centers of the generated bandwidth and the calculated one when they differ,
                    // use the following addend.
                    var xPoint_1 = xScale1(legendTitle) + (xScale1.bandwidth() - _this._barWidth) / 2;
                    var isLegendActive_1 = _this._legendHighlighted(legendTitle) || _this._noLegendHighlighted();
                    var barOpacity_1 = isLegendActive_1 ? '' : '0.1';
                    var barTotalValue_1 = 0;
                    var yBaseline = yBarScale_1(_this.Y_ORIGIN);
                    var yPositiveStart_1 = yBaseline;
                    var yNegativeStart_1 = yBaseline;
                    var yPoint_1 = _this.Y_ORIGIN;
                    barPoints.forEach(function (pointData, pointIndex) {
                        var _a, _b;
                        if (!pointData.data) {
                            // Not rendering data with 0.
                            return;
                        }
                        var gradientId = getId('GVBC_Gradient') + "_".concat(singleSet.indexNum, "_").concat(legendIndex, "_").concat(pointIndex);
                        if (_this.props.enableGradient) {
                            var startColor = ((_a = pointData.gradient) === null || _a === void 0 ? void 0 : _a[0]) || pointData.color;
                            var endColor = ((_b = pointData.gradient) === null || _b === void 0 ? void 0 : _b[1]) || pointData.color;
                            singleGroup.push(React.createElement("defs", { key: "defs_".concat(gradientId) },
                                React.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "100%", x2: "0%", y2: "0%" },
                                    React.createElement("stop", { offset: "0%", stopColor: startColor }),
                                    React.createElement("stop", { offset: "100%", stopColor: endColor }))));
                        }
                        var barGap = (VERTICAL_BAR_GAP / 2) * (pointIndex > 0 ? 2 : 0);
                        var height = Math.max(yBarScale_1(_this.Y_ORIGIN) - yBarScale_1(Math.abs(pointData.data)), MIN_BAR_HEIGHT);
                        var pointColor = pointData.color; // Use the color of the current point
                        if (pointData.data >= _this.Y_ORIGIN) {
                            yPositiveStart_1 -= height + barGap;
                            yPoint_1 = yPositiveStart_1;
                        }
                        else {
                            yPoint_1 = yNegativeStart_1 + barGap;
                            yNegativeStart_1 = yPoint_1 + height;
                        }
                        singleGroup.push(React.createElement("rect", { key: "".concat(singleSet.indexNum, "-").concat(legendIndex, "-").concat(pointIndex), className: _this._classNames.opacityChangeOnHover, height: height, width: _this._barWidth, x: xPoint_1, y: yPoint_1, "data-is-focusable": !_this.props.hideTooltip && isLegendActive_1, opacity: barOpacity_1, fill: _this.props.enableGradient ? "url(#".concat(gradientId, ")") : pointColor, rx: _this.props.roundCorners ? 3 : 0, onMouseOver: _this._onBarHover.bind(_this, pointData, singleSet), onMouseMove: _this._onBarHover.bind(_this, pointData, singleSet), onMouseOut: _this._onBarLeave, onFocus: _this._onBarFocus.bind(_this, pointData, singleSet), onBlur: _this._onBarLeave, onClick: _this.props.href ? _this._redirectToUrl.bind(_this, _this.props.href) : pointData.onClick, "aria-label": _this._getAriaLabel(pointData, singleSet.xAxisPoint), role: "img" }));
                        barTotalValue_1 += pointData.data;
                    });
                    if (barTotalValue_1 !== null && !_this.props.hideLabels && _this._barWidth >= 16 && isLegendActive_1) {
                        barLabelsForGroup.push(React.createElement("text", { key: "".concat(singleSet.indexNum, "-").concat(legendIndex), x: xPoint_1 + _this._barWidth / 2, y: barTotalValue_1 >= _this.Y_ORIGIN ? yPositiveStart_1 - 6 : yNegativeStart_1 + 12, textAnchor: "middle", className: _this._classNames.barLabel, "aria-hidden": true }, typeof _this.props.yAxisTickFormat === 'function'
                            ? _this.props.yAxisTickFormat(barTotalValue_1)
                            : formatScientificLimitWidth(barTotalValue_1)));
                    }
                }
            });
            // Used to display tooltip at x axis labels.
            if (!_this.props.wrapXAxisLables && _this.props.showXAxisLablesTooltip) {
                var xAxisElement = d3Select(xElement).call(xScale0);
                try {
                    document.getElementById(_this._tooltipId) && document.getElementById(_this._tooltipId).remove();
                    // eslint-disable-next-line no-empty
                }
                catch (e) { }
                var tooltipProps = {
                    tooltipCls: _this._classNames.tooltip,
                    id: _this._tooltipId,
                    axis: xAxisElement,
                };
                xAxisElement && tooltipOfAxislabels(tooltipProps);
            }
            return (React.createElement("g", { key: singleSet.indexNum, transform: "translate(".concat(xScale0(singleSet.xAxisPoint) + (xScale0.bandwidth() - _this._groupWidth) / 2, ", 0)") },
                singleGroup,
                barLabelsForGroup));
        };
        _this._createDataset = function (points) {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            var datasetForBars = [];
            points.forEach(function (point, index) {
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                var singleDatasetPointForBars = {};
                var legendToBarPoint = {};
                point.series.forEach(function (seriesPoint) {
                    if (!singleDatasetPointForBars[seriesPoint.legend]) {
                        singleDatasetPointForBars[seriesPoint.legend] = [__assign({}, seriesPoint)];
                        legendToBarPoint[seriesPoint.legend] = __assign({}, seriesPoint);
                    }
                    else {
                        singleDatasetPointForBars[seriesPoint.legend].push(__assign({}, seriesPoint));
                        legendToBarPoint[seriesPoint.legend].data += seriesPoint.data;
                    }
                });
                singleDatasetPointForBars.xAxisPoint = point.name;
                singleDatasetPointForBars.indexNum = index;
                singleDatasetPointForBars.groupSeries = Object.values(legendToBarPoint);
                singleDatasetPointForBars.stackCallOutAccessibilityData = point.stackCallOutAccessibilityData;
                datasetForBars.push(singleDatasetPointForBars);
            });
            return datasetForBars;
        };
        // For grouped vertical bar chart, First need to define total scale (from start to end)
        // From that need to define scale for single group of bars - done by createX1Scale
        _this._createX0Scale = function (containerWidth) {
            var x0Axis = d3ScaleBand()
                .domain(_this._xAxisLabels)
                .range(_this._isRtl
                ? [containerWidth - _this.margins.right - _this._domainMargin, _this.margins.left + _this._domainMargin]
                : [_this.margins.left + _this._domainMargin, containerWidth - _this.margins.right - _this._domainMargin])
                .paddingInner(_this._xAxisInnerPadding)
                .paddingOuter(_this._xAxisOuterPadding);
            return x0Axis;
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this._createX1Scale = function () {
            return (d3ScaleBand()
                .domain(_this._legends)
                // When there is only one group, xScale0 adds padding around it,
                // causing the bandwidth to become smaller than the actual group width.
                // So to render bars in the group correctly, use groupWidth instead of the generated scale bandwidth.
                .range(_this._isRtl ? [_this._groupWidth, 0] : [0, _this._groupWidth])
                .paddingInner(X1_INNER_PADDING));
        };
        _this._closeCallout = function () {
            _this.setState({
                isCalloutVisible: false,
            });
        };
        _this._getLegendData = function () {
            var actions = [];
            _this._legends.forEach(function (legendTitle) {
                var legend = {
                    title: legendTitle,
                    color: _this._legendColorMap[legendTitle][0],
                    hoverAction: function () {
                        _this._handleChartMouseLeave();
                        _this._onLegendHover(legendTitle);
                    },
                    onMouseOutAction: function () {
                        _this._onLegendLeave();
                    },
                };
                actions.push(legend);
            });
            return (React.createElement(Legends, __assign({ legends: actions, overflowProps: _this.props.legendsOverflowProps, enabledWrapLines: _this.props.enabledLegendsWrapLines, focusZonePropsInHoverCard: _this.props.focusZonePropsForLegendsInHoverCard }, _this.props.legendProps, { onChange: _this._onLegendSelectionChange.bind(_this), ref: _this._legendsRef })));
        };
        _this._getAxisData = function (yAxisData) {
            if (yAxisData && yAxisData.yAxisDomainValues.length) {
                var domainValue = yAxisData.yAxisDomainValues;
                _this._yMax = Math.max(domainValue[domainValue.length - 1], _this.props.yMaxValue || 0);
            }
        };
        /**
         * This function checks if the given legend is highlighted or not.
         * A legend can be highlighted in 2 ways:
         * 1. selection: if the user clicks on it
         * 2. hovering: if there is no selected legend and the user hovers over it
         */
        _this._legendHighlighted = function (legendTitle) {
            return _this._getHighlightedLegend().includes(legendTitle);
        };
        /**
         * This function checks if none of the legends is selected or hovered.
         */
        _this._noLegendHighlighted = function () {
            return _this._getHighlightedLegend().length === 0;
        };
        _this._getAriaLabel = function (point, xAxisPoint) {
            var _a;
            var xValue = point.xAxisCalloutData || xAxisPoint;
            var legend = point.legend;
            var yValue = point.yAxisCalloutData || point.data;
            return ((_a = point.callOutAccessibilityData) === null || _a === void 0 ? void 0 : _a.ariaLabel) || "".concat(xValue, ". ").concat(legend, ", ").concat(yValue, ".");
        };
        _this._getDomainMargins = function (containerWidth) {
            _this._domainMargin = MIN_DOMAIN_MARGIN;
            /** Total width available to render the bars */
            var totalWidth = containerWidth - (_this.margins.left + MIN_DOMAIN_MARGIN) - (_this.margins.right + MIN_DOMAIN_MARGIN);
            /** Rate at which the space between the groups changes wrt the group width */
            var groupGapRate = _this._xAxisInnerPadding / (1 - _this._xAxisInnerPadding);
            if (_this._xAxisType === XAxisTypes.StringAxis) {
                if (isScalePaddingDefined(_this.props.xAxisOuterPadding)) {
                    // Setting the domain margin for string x-axis to 0 because the xAxisOuterPadding prop is now available
                    // to adjust the space before the first group and after the last group.
                    _this._domainMargin = 0;
                }
                else if (_this.props.barwidth !== 'auto') {
                    // Update the bar width so that when CartesianChart rerenders,
                    // the following calculations don't use the previous bar width.
                    _this._barWidth = getBarWidth(_this.props.barwidth, _this.props.maxBarWidth);
                    var groupWidth = (_this._legends.length + (_this._legends.length - 1) * BAR_GAP_RATE) * _this._barWidth;
                    /** Total width required to render the groups. Directly proportional to group width */
                    var reqWidth = (_this._xAxisLabels.length + (_this._xAxisLabels.length - 1) * groupGapRate) * groupWidth;
                    if (totalWidth >= reqWidth) {
                        // Center align the chart by setting equal left and right margins for domain
                        _this._domainMargin = MIN_DOMAIN_MARGIN + (totalWidth - reqWidth) / 2;
                    }
                }
                else if (_this.props.mode === 'plotly' && _this._xAxisLabels.length > 1) {
                    // Calculate the remaining width after rendering groups at their maximum allowable width
                    var groupBandwidth = totalWidth / (_this._xAxisLabels.length + (_this._xAxisLabels.length - 1) * groupGapRate);
                    var barBandwidth = groupBandwidth / (_this._legends.length + (_this._legends.length - 1) * BAR_GAP_RATE);
                    var barWidth = getBarWidth(_this.props.barwidth, _this.props.maxBarWidth, barBandwidth);
                    var groupWidth = (_this._legends.length + (_this._legends.length - 1) * BAR_GAP_RATE) * barWidth;
                    var reqWidth = (_this._xAxisLabels.length + (_this._xAxisLabels.length - 1) * groupGapRate) * groupWidth;
                    var margin1 = (totalWidth - reqWidth) / 2;
                    var margin2 = Number.POSITIVE_INFINITY;
                    if (!_this.props.hideTickOverlap) {
                        // Calculate the remaining width after accounting for the space required to render x-axis labels
                        var step = calculateLongestLabelWidth(_this._xAxisLabels) + 20;
                        reqWidth = (_this._xAxisLabels.length - _this._xAxisInnerPadding) * step;
                        margin2 = (totalWidth - reqWidth) / 2;
                    }
                    _this._domainMargin = MIN_DOMAIN_MARGIN + Math.max(0, Math.min(margin1, margin2));
                }
            }
            return __assign(__assign({}, _this.margins), { left: _this.margins.left + _this._domainMargin, right: _this.margins.right + _this._domainMargin });
        };
        _this._getChartTitle = function () {
            var chartTitle = _this.props.chartTitle;
            return ((chartTitle ? "".concat(chartTitle, ". ") : '') +
                "Vertical bar chart with ".concat(_this._xAxisLabels.length, " groups of ").concat(_this._legends.length, " bars each. "));
        };
        // Lighten/Darken a color by a given percentage using d3-scale
        _this._adjustColor = function (color, percentage, lightenColor, isDarkTheme) {
            var targetColor = lightenColor ? (isDarkTheme ? '#000000' : '#ffffff') : isDarkTheme ? '#ffffff' : '#000000';
            var colorInterpolator = d3ScaleLinear().domain([0, 1]).range([color, targetColor]);
            return rgb(colorInterpolator(percentage)).formatRgb();
        };
        _this._addDefaultColors = function (data) {
            var _a;
            _this._legendColorMap = {};
            var colorIndex = 0;
            return ((_a = data === null || data === void 0 ? void 0 : data.map(function (point) {
                var _a, _b;
                return __assign(__assign({}, point), { series: (_b = (_a = point.series) === null || _a === void 0 ? void 0 : _a.map(function (seriesPoint) {
                        var _a, _b, _c, _d, _e, _f, _g;
                        var startColor = seriesPoint.color
                            ? seriesPoint.color
                            : getNextColor(colorIndex, 0, (_a = _this.props.theme) === null || _a === void 0 ? void 0 : _a.isInverted);
                        var endColor = startColor;
                        if (_this.props.enableGradient) {
                            if (seriesPoint.color) {
                                // Generate gradient colors based on seriesPoint.color
                                startColor = _this._adjustColor(seriesPoint.color || endColor, 0.2, false, (_b = _this.props.theme) === null || _b === void 0 ? void 0 : _b.isInverted);
                                endColor = _this._adjustColor(seriesPoint.color || startColor, 0.2, true, (_c = _this.props.theme) === null || _c === void 0 ? void 0 : _c.isInverted);
                            }
                            else {
                                var nextGradient = getNextGradient(colorIndex, 0, (_d = _this.props.theme) === null || _d === void 0 ? void 0 : _d.isInverted);
                                startColor = ((_e = seriesPoint.gradient) === null || _e === void 0 ? void 0 : _e[0]) || nextGradient[0];
                                endColor = ((_f = seriesPoint.gradient) === null || _f === void 0 ? void 0 : _f[1]) || nextGradient[1];
                            }
                        }
                        var pointGradient = [startColor, endColor];
                        if (!_this._legendColorMap[seriesPoint.legend]) {
                            _this._legendColorMap[seriesPoint.legend] = [startColor, endColor];
                        }
                        colorIndex += 1;
                        return __assign(__assign(__assign({}, seriesPoint), { color: (_g = seriesPoint.color) !== null && _g !== void 0 ? _g : _this._legendColorMap[seriesPoint.legend][0] }), (_this.props.enableGradient ? { gradient: pointGradient } : {}));
                    })) !== null && _b !== void 0 ? _b : [] });
            })) !== null && _a !== void 0 ? _a : []);
        };
        _this._getOrderedXAxisLabels = function (points) {
            if (_this._xAxisType !== XAxisTypes.StringAxis) {
                return [];
            }
            return sortAxisCategories(_this._mapCategoryToValues(points), _this.props.xAxisCategoryOrder);
        };
        _this._mapCategoryToValues = function (points) {
            var categoryToValues = {};
            points.forEach(function (point) {
                if (!categoryToValues[point.name]) {
                    categoryToValues[point.name] = [];
                }
                point.series.forEach(function (seriesPoint) {
                    categoryToValues[point.name].push(seriesPoint.data);
                });
            });
            return categoryToValues;
        };
        initializeComponentRef(_this);
        _this._createSet = memoizeFunction(function (data) { return _this._createDataSetOfGVBC(data); });
        _this.state = {
            color: '',
            dataForHoverCard: 0,
            isCalloutVisible: false,
            refSelected: null,
            selectedLegends: ((_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends) || [],
            xCalloutValue: '',
            yCalloutValue: '',
            YValueHover: [],
            hoverXValue: '',
            calloutLegend: '',
            activeLegend: '',
        };
        warnDeprecations(COMPONENT_NAME, props, {
            showYAxisGridLines: 'Dont use this property. Lines are drawn by default',
            showXAxisPath: 'Dont use this property. Axis line removed default.',
            showYAxisPath: 'Dont use this property. No need to display Y axis path. Handling default',
            showXAxisGridLines: 'Dont use this property. Handling with default value.',
            legendColor: 'Dont use this property. colour will pick from given data.',
        });
        _this._calloutId = getId('callout');
        _this._tooltipId = getId('GVBCTooltipId_');
        _this._emptyChartId = getId('_GVBC_empty');
        _this._domainMargin = MIN_DOMAIN_MARGIN;
        _this._cartesianChartRef = React.createRef();
        _this._legendsRef = React.createRef();
        return _this;
    }
    GroupedVerticalBarChartBase.prototype.componentDidUpdate = function (prevProps) {
        var _a, _b, _c;
        if (!areArraysEqual((_a = prevProps.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends, (_b = this.props.legendProps) === null || _b === void 0 ? void 0 : _b.selectedLegends)) {
            this.setState({
                selectedLegends: ((_c = this.props.legendProps) === null || _c === void 0 ? void 0 : _c.selectedLegends) || [],
            });
        }
    };
    GroupedVerticalBarChartBase.prototype.render = function () {
        var _this = this;
        var points = this._addDefaultColors(this.props.data);
        this._xAxisType = getTypeOfAxis(points[0].name, true);
        var _a = this._createSet(points), legends = _a.legends, xAxisLabels = _a.xAxisLabels, datasetForBars = _a.datasetForBars;
        this._legends = legends;
        this._xAxisLabels = xAxisLabels;
        this._datasetForBars = datasetForBars;
        var legendBars = this._getLegendData();
        this._adjustProps();
        // The maxOfYVal prop is only required for the primary y-axis, so yMax should be calculated
        // using only the data points associated with the primary y-axis.
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        var yMax = this._getMinMaxOfYAxis(this._datasetForBars).endValue;
        this._yMax = Math.max(yMax, this.props.yMaxValue || 0);
        this._classNames = getClassNames(this.props.styles, {
            theme: this.props.theme,
            href: this.props.href,
        });
        var calloutProps = __assign(__assign(__assign({ target: this.state.refSelected, isCalloutVisible: this.state.isCalloutVisible, directionalHint: DirectionalHint.topAutoEdge, id: "toolTip".concat(this._calloutId), gapSpace: 15, isBeakVisible: false, setInitialFocus: true, color: this.state.color, Legend: this.state.calloutLegend, XValue: this.state.xCalloutValue, YValue: this.state.yCalloutValue ? this.state.yCalloutValue : this.state.dataForHoverCard, YValueHover: this.state.YValueHover, hoverXValue: this.state.hoverXValue, onDismiss: this._closeCallout }, this.props.calloutProps), { preventDismissOnLostFocus: true }), getAccessibleDataObject(this.state.callOutAccessibilityData, 'text', false));
        var tickParams = {
            tickValues: this.props.tickValues,
            tickFormat: this.props.tickFormat,
        };
        return !this._isChartEmpty() ? (React.createElement(CartesianChart, __assign({}, this.props, { chartTitle: this._getChartTitle(), points: this._datasetForBars, chartType: ChartTypes.GroupedVerticalBarChart, calloutProps: calloutProps, legendBars: legendBars, xAxisType: this._xAxisType, createYAxis: createNumericYAxis, datasetForXAxisDomain: this._xAxisLabels, tickParams: tickParams, getDomainNRangeValues: this._getDomainNRangeValues, getMinMaxOfYAxis: this._getMinMaxOfYAxis, createStringYAxis: createStringYAxis, tickPadding: this.props.tickPadding || 5, maxOfYVal: this._yMax, svgFocusZoneProps: {
                direction: FocusZoneDirection.horizontal,
            }, customizedCallout: this._getCustomizedCallout(), getmargins: this._getMargins, getGraphData: this._getGraphData, getAxisData: this._getAxisData, onChartMouseLeave: this._handleChartMouseLeave, getDomainMargins: this._getDomainMargins }, (this._xAxisType === XAxisTypes.StringAxis && {
            xAxisInnerPadding: this._xAxisInnerPadding,
            xAxisOuterPadding: this._xAxisOuterPadding,
        }), { barwidth: this._barWidth, ref: this._cartesianChartRef, 
            /* eslint-disable react/jsx-no-bind */
            children: function () {
                return React.createElement("g", null, _this._groupedVerticalBarGraph);
            } }))) : (React.createElement("div", { id: this._emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
    };
    Object.defineProperty(GroupedVerticalBarChartBase.prototype, "chartContainer", {
        get: function () {
            var _a;
            return ((_a = this._cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer) || null;
        },
        enumerable: false,
        configurable: true
    });
    GroupedVerticalBarChartBase.prototype._onLegendHover = function (legendTitle) {
        this.setState({
            activeLegend: legendTitle,
        });
    };
    GroupedVerticalBarChartBase.prototype._onLegendLeave = function () {
        this.setState({
            activeLegend: '',
        });
    };
    GroupedVerticalBarChartBase.prototype._onLegendSelectionChange = function (selectedLegends, event, currentLegend) {
        var _a, _b;
        if ((_a = this.props.legendProps) === null || _a === void 0 ? void 0 : _a.canSelectMultipleLegends) {
            this.setState({ selectedLegends: selectedLegends });
        }
        else {
            this.setState({ selectedLegends: selectedLegends.slice(-1) });
        }
        if ((_b = this.props.legendProps) === null || _b === void 0 ? void 0 : _b.onChange) {
            this.props.legendProps.onChange(selectedLegends, event, currentLegend);
        }
    };
    GroupedVerticalBarChartBase.prototype._getHighlightedLegend = function () {
        return this.state.selectedLegends.length > 0
            ? this.state.selectedLegends
            : this.state.activeLegend
                ? [this.state.activeLegend]
                : [];
    };
    GroupedVerticalBarChartBase.prototype._isChartEmpty = function () {
        return !(this.props.data &&
            this.props.data.length > 0 &&
            this.props.data.filter(function (item) { return item.series.length; }).length > 0);
    };
    GroupedVerticalBarChartBase.prototype._adjustProps = function () {
        this._barWidth = getBarWidth(this.props.barwidth, this.props.maxBarWidth);
        // x0_inner_padding = space_between_groups / (space_between_groups + group_width)
        // space_between_groups = 2 * bar_width
        // group_width = this._legends.length * bar_width + (this._legends.length - 1) * space_between_bars
        this._xAxisInnerPadding = getScalePadding(this.props.xAxisInnerPadding, undefined, 2 / (2 + this._legends.length + (this._legends.length - 1) * BAR_GAP_RATE));
        this._xAxisOuterPadding = getScalePadding(this.props.xAxisOuterPadding);
    };
    GroupedVerticalBarChartBase.defaultProps = {
        maxBarWidth: 24,
        xAxisCategoryOrder: 'default',
    };
    return GroupedVerticalBarChartBase;
}(React.Component));
export { GroupedVerticalBarChartBase };
//# sourceMappingURL=GroupedVerticalBarChart.base.js.map