define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities", "@fluentui/react/lib/Callout", "@fluentui/react-focus", "../../utilities/locale-util", "../../utilities/index", "../Legends/index", "../../utilities/SVGTooltipText"], function (require, exports, tslib_1, React, Utilities_1, Callout_1, react_focus_1, locale_util_1, index_1, index_2, SVGTooltipText_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.CartesianChartBase = void 0;
    var getClassNames = (0, Utilities_1.classNamesFunction)();
    var ChartHoverCard = React.lazy(function () {
        return new Promise(function (resolve_1, reject_1) { require(['../../utilities/ChartHoverCard/ChartHoverCard'], resolve_1, reject_1); }).then(function (module) { return ({ default: module.ChartHoverCard }); });
    });
    var chartTypesToCheck = [index_1.ChartTypes.HorizontalBarChartWithAxis, index_1.ChartTypes.HeatMapChart];
    /**
     * Cartesian chart used for
     * 1.draw X and Y axis of the chart
     * 2.Callout
     * 3.Fit parent Continer
     */
    var CartesianChartBase = /** @class */ (function (_super) {
        tslib_1.__extends(CartesianChartBase, _super);
        function CartesianChartBase(props) {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
            var _this = _super.call(this, props) || this;
            _this.minLegendContainerHeight = 32;
            _this._isRtl = (0, Utilities_1.getRTL)();
            _this._isFirstRender = true;
            _this.isIntegralDataset = true;
            _this.calculateMaxYAxisLabelLength = function (chartType, 
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            points, className) {
                if (chartType === index_1.ChartTypes.HeatMapChart) {
                    return (0, index_1.calculateLongestLabelWidth)(points[0].data.map(function (point) { return point.y; }), ".".concat(className, " text"));
                }
                else {
                    return (0, index_1.calculateLongestLabelWidth)(points.map(function (point) { return point.y; }), ".".concat(className, " text"));
                }
            };
            // TO DO: Write a common functional component for Multi value callout and divide sub count method
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            _this._multiValueCallout = function (calloutProps) {
                var yValueHoverSubCountsExists = _this._yValueHoverSubCountsExists(calloutProps.YValueHover);
                return (React.createElement("div", { className: _this._classNames.calloutContentRoot },
                    React.createElement("div", { className: _this._classNames.calloutDateTimeContainer, style: yValueHoverSubCountsExists ? { marginBottom: '11px' } : {} },
                        React.createElement("div", tslib_1.__assign({ className: _this._classNames.calloutContentX }, (0, index_1.getAccessibleDataObject)(calloutProps.xAxisCalloutAccessibilityData, 'text', false)), (0, locale_util_1.convertToLocaleString)(calloutProps.hoverXValue, _this.props.culture))),
                    React.createElement("div", { className: _this._classNames.calloutInfoContainer, style: yValueHoverSubCountsExists ? { display: 'flex' } : {} },
                        calloutProps.YValueHover &&
                            calloutProps.YValueHover.map(function (yValue, index, yValues) {
                                var isLast = index + 1 === yValues.length;
                                var _a = yValue.shouldDrawBorderBottom, shouldDrawBorderBottom = _a === void 0 ? false : _a;
                                return (React.createElement("div", tslib_1.__assign({}, (0, index_1.getAccessibleDataObject)(yValue.callOutAccessibilityData, 'text', false), { key: "callout-content-".concat(index), style: yValueHoverSubCountsExists
                                        ? tslib_1.__assign({ display: 'inline-block' }, (shouldDrawBorderBottom && {
                                            borderBottom: "1px solid ".concat(_this.props.theme.semanticColors.menuDivider),
                                            paddingBottom: '10px',
                                        })) : tslib_1.__assign({}, (shouldDrawBorderBottom && {
                                        borderBottom: "1px solid ".concat(_this.props.theme.semanticColors.menuDivider),
                                        paddingBottom: '10px',
                                    })) }), _this._getCalloutContent(yValue, index, yValueHoverSubCountsExists, isLast)));
                            }),
                        !!calloutProps.descriptionMessage && (React.createElement("div", { className: _this._classNames.descriptionMessage }, calloutProps.descriptionMessage)))));
            };
            // Call back to the chart.
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            _this._getData = function (xScale, yScale) {
                _this.props.getGraphData &&
                    _this.props.getGraphData(xScale, yScale, _this.state.containerHeight - _this.state._removalValueForTextTuncate, _this.state.containerWidth, _this.xAxisElement, _this.yAxisElement);
            };
            _this._onChartLeave = function () {
                _this.props.onChartMouseLeave && _this.props.onChartMouseLeave();
            };
            _this._calculateChartMinWidth = function () {
                var labelWidth = 10; // Total padding on the left and right sides of the label
                // Case: rotated labels
                if (!_this.props.wrapXAxisLables &&
                    _this.props.rotateXAxisLables &&
                    _this.props.xAxisType === index_1.XAxisTypes.StringAxis) {
                    var longestLabelWidth = (0, index_1.calculateLongestLabelWidth)(_this._tickValues, ".".concat(_this._classNames.xAxis, " text"));
                    labelWidth += Math.ceil(longestLabelWidth * Math.cos(Math.PI / 4));
                }
                // Case: truncated labels
                else if (_this.props.showXAxisLablesTooltip) {
                    var tickValues = _this._tickValues.map(function (val) {
                        var numChars = _this.props.noOfCharsToTruncate || 4;
                        return val.toString().length > numChars ? "".concat(val.toString().slice(0, numChars), "...") : val;
                    });
                    var longestLabelWidth = (0, index_1.calculateLongestLabelWidth)(tickValues, ".".concat(_this._classNames.xAxis, " text"));
                    labelWidth += Math.ceil(longestLabelWidth);
                }
                // Case: wrapped labels
                else if (_this.props.wrapXAxisLables) {
                    var words_1 = [];
                    _this._tickValues.forEach(function (val) {
                        words_1.push.apply(words_1, val.toString().split(/\s+/));
                    });
                    var longestLabelWidth = (0, index_1.calculateLongestLabelWidth)(words_1, ".".concat(_this._classNames.xAxis, " text"));
                    labelWidth += Math.max(Math.ceil(longestLabelWidth), 10);
                }
                // Default case
                else {
                    var longestLabelWidth = (0, index_1.calculateLongestLabelWidth)(_this._tickValues, ".".concat(_this._classNames.xAxis, " text"));
                    labelWidth += Math.ceil(longestLabelWidth);
                }
                var minChartWidth = _this.margins.left + _this.margins.right + labelWidth * (_this._tickValues.length - 1);
                if ([index_1.ChartTypes.GroupedVerticalBarChart, index_1.ChartTypes.VerticalBarChart, index_1.ChartTypes.VerticalStackedBarChart].includes(_this.props.chartType)) {
                    var minDomainMargin = 8;
                    minChartWidth += minDomainMargin * 2;
                }
                return minChartWidth;
            };
            _this._getChartDescription = function () {
                return ((_this.props.chartTitle || 'Chart. ') +
                    _this._getAxisTitle('X', _this.props.xAxisTitle, _this.props.xAxisType) +
                    _this._getAxisTitle('Y', _this.props.yAxisTitle, _this.props.yAxisType || index_1.YAxisType.NumericAxis) +
                    (_this.props.secondaryYScaleOptions
                        ? _this._getAxisTitle('secondary Y', _this.props.secondaryYAxistitle, index_1.YAxisType.NumericAxis)
                        : ''));
            };
            _this._getAxisTitle = function (axisLabel, axisTitle, axisType) {
                return ("The ".concat(axisLabel, " axis displays ") +
                    (axisTitle ||
                        (axisType === index_1.XAxisTypes.StringAxis || axisType === index_1.YAxisType.StringAxis
                            ? 'categories'
                            : axisType === index_1.XAxisTypes.DateAxis || axisType === index_1.YAxisType.DateAxis
                                ? 'time'
                                : 'values')) +
                    '. ');
            };
            _this.state = {
                containerHeight: 0,
                containerWidth: 0,
                _width: _this.props.width || 600,
                _height: _this.props.height || 350,
                _removalValueForTextTuncate: 0,
                isRemoveValCalculated: true,
                startFromX: 0,
            };
            _this.idForGraph = (0, Utilities_1.getId)('chart_');
            _this.titleMargin = 8;
            _this.idForDefaultTabbableElement = (0, Utilities_1.getId)('defaultTabbableElement_');
            /**
             * In RTL mode, Only graph will be rendered left/right. We need to provide left and right margins manually.
             * So that, in RTL, left margins becomes right margins and viceversa.
             * As graph needs to be drawn perfecty, these values consider as default values.
             * Same margins using for all other cartesian charts. Can be accessible through 'getMargins' call back method.
             */
            _this.margins = {
                top: (_b = (_a = _this.props.margins) === null || _a === void 0 ? void 0 : _a.top) !== null && _b !== void 0 ? _b : 20,
                bottom: (_d = (_c = _this.props.margins) === null || _c === void 0 ? void 0 : _c.bottom) !== null && _d !== void 0 ? _d : 35,
                right: _this._isRtl
                    ? (_f = (_e = _this.props.margins) === null || _e === void 0 ? void 0 : _e.left) !== null && _f !== void 0 ? _f : 40
                    : ((_h = (_g = _this.props.margins) === null || _g === void 0 ? void 0 : _g.right) !== null && _h !== void 0 ? _h : (_j = _this.props) === null || _j === void 0 ? void 0 : _j.secondaryYScaleOptions)
                        ? 40
                        : 20,
                left: _this._isRtl
                    ? ((_l = (_k = _this.props.margins) === null || _k === void 0 ? void 0 : _k.right) !== null && _l !== void 0 ? _l : (_m = _this.props) === null || _m === void 0 ? void 0 : _m.secondaryYScaleOptions)
                        ? 40
                        : 20
                    : (_p = (_o = _this.props.margins) === null || _o === void 0 ? void 0 : _o.left) !== null && _p !== void 0 ? _p : 40,
            };
            if (_this.props.xAxisTitle !== undefined && _this.props.xAxisTitle !== '') {
                _this.margins.bottom = (_r = (_q = _this.props.margins) === null || _q === void 0 ? void 0 : _q.bottom) !== null && _r !== void 0 ? _r : 55;
            }
            if (_this.props.yAxisTitle !== undefined && _this.props.yAxisTitle !== '') {
                _this.margins.left = _this._isRtl
                    ? ((_t = (_s = _this.props.margins) === null || _s === void 0 ? void 0 : _s.right) !== null && _t !== void 0 ? _t : (_u = _this.props) === null || _u === void 0 ? void 0 : _u.secondaryYAxistitle)
                        ? 60
                        : 40
                    : (_w = (_v = _this.props.margins) === null || _v === void 0 ? void 0 : _v.left) !== null && _w !== void 0 ? _w : 60;
                _this.margins.right = _this._isRtl
                    ? (_y = (_x = _this.props.margins) === null || _x === void 0 ? void 0 : _x.left) !== null && _y !== void 0 ? _y : 60
                    : ((_0 = (_z = _this.props.margins) === null || _z === void 0 ? void 0 : _z.right) !== null && _0 !== void 0 ? _0 : (_1 = _this.props) === null || _1 === void 0 ? void 0 : _1.secondaryYAxistitle)
                        ? 60
                        : 40;
            }
            return _this;
        }
        CartesianChartBase.prototype.componentDidMount = function () {
            this._fitParentContainer();
            if (chartTypesToCheck.includes(this.props.chartType) && this.props.showYAxisLables && this.yAxisElement) {
                var maxYAxisLabelLength = this.calculateMaxYAxisLabelLength(this.props.chartType, this.props.points, this._classNames.yAxis);
                if (this.state.startFromX !== maxYAxisLabelLength) {
                    this.setState({
                        startFromX: maxYAxisLabelLength,
                    });
                }
            }
            else if (this.state.startFromX !== 0) {
                this.setState({
                    startFromX: 0,
                });
            }
            this.isIntegralDataset = !this.props.points.some(function (point) {
                return point.y % 1 !== 0;
            });
        };
        CartesianChartBase.prototype.componentWillUnmount = function () {
            cancelAnimationFrame(this._reqID);
        };
        CartesianChartBase.prototype.componentDidUpdate = function (prevProps) {
            if (prevProps.height !== this.props.height || prevProps.width !== this.props.width) {
                this._fitParentContainer();
            }
            if (!this.props.wrapXAxisLables &&
                this.props.rotateXAxisLables &&
                this.props.xAxisType === index_1.XAxisTypes.StringAxis) {
                var rotateLabelProps = {
                    node: this.xAxisElement,
                    xAxis: this._xScale,
                };
                var rotatedHeight = (0, index_1.rotateXAxisLabels)(rotateLabelProps);
                if (this.state.isRemoveValCalculated &&
                    this.state._removalValueForTextTuncate !== rotatedHeight + this.margins.bottom &&
                    rotatedHeight > 0) {
                    this.setState({
                        _removalValueForTextTuncate: rotatedHeight + this.margins.bottom,
                        isRemoveValCalculated: false,
                    });
                }
            }
            if (chartTypesToCheck.includes(this.props.chartType) && this.props.showYAxisLables && this.yAxisElement) {
                var maxYAxisLabelLength = this.calculateMaxYAxisLabelLength(this.props.chartType, this.props.points, this._classNames.yAxis);
                if (this.state.startFromX !== maxYAxisLabelLength) {
                    this.setState({
                        startFromX: maxYAxisLabelLength,
                    });
                }
            }
            else if (this.state.startFromX !== 0) {
                this.setState({
                    startFromX: 0,
                });
            }
            if (prevProps.points !== this.props.points) {
                this.isIntegralDataset = !this.props.points.some(function (point) {
                    return point.y % 1 !== 0;
                });
            }
        };
        CartesianChartBase.prototype.render = function () {
            var _a, _b, _c, _d;
            var _this = this;
            var _e, _f, _g, _h, _j, _k;
            var _l = this.props, calloutProps = _l.calloutProps, points = _l.points, chartType = _l.chartType, chartHoverProps = _l.chartHoverProps, svgFocusZoneProps = _l.svgFocusZoneProps, svgProps = _l.svgProps, culture = _l.culture, dateLocalizeOptions = _l.dateLocalizeOptions, timeFormatLocale = _l.timeFormatLocale, customDateTimeFormatter = _l.customDateTimeFormatter;
            if (this.props.parentRef) {
                this._fitParentContainer();
            }
            var margin = tslib_1.__assign({}, this.margins);
            if (chartTypesToCheck.includes(this.props.chartType)) {
                if (!this._isRtl) {
                    margin.left += this.state.startFromX;
                }
                else {
                    margin.right += this.state.startFromX;
                }
            }
            // Callback for margins to the chart
            this.props.getmargins && this.props.getmargins(margin);
            var callout = null;
            var children = null;
            if ((this.props.enableFirstRenderOptimization && this.chartContainer) ||
                !this.props.enableFirstRenderOptimization) {
                this._isFirstRender = false;
                var XAxisParams = {
                    domainNRangeValues: this.props.getDomainNRangeValues(points, this.props.getDomainMargins ? this.props.getDomainMargins(this.state.containerWidth) : this.margins, this.state.containerWidth, chartType, this._isRtl, this.props.xAxisType, this.props.barwidth, this.props.tickValues, 
                    // This is only used for Horizontal Bar Chart with Axis for y as string axis
                    this.state.startFromX),
                    containerHeight: this.state.containerHeight - this.state._removalValueForTextTuncate,
                    margins: this.margins,
                    xAxisElement: this.xAxisElement,
                    showRoundOffXTickValues: true,
                    xAxisCount: this.props.xAxisTickCount,
                    xAxistickSize: this.props.xAxistickSize,
                    tickPadding: this.props.tickPadding || this.props.showXAxisLablesTooltip ? 5 : 10,
                    xAxisPadding: this.props.xAxisPadding,
                    xAxisInnerPadding: this.props.xAxisInnerPadding,
                    xAxisOuterPadding: this.props.xAxisOuterPadding,
                    containerWidth: this.state.containerWidth,
                    hideTickOverlap: this.props.hideTickOverlap &&
                        !this.props.rotateXAxisLables &&
                        !this.props.showXAxisLablesTooltip &&
                        !this.props.wrapXAxisLables,
                };
                var YAxisParams = {
                    margins: this.margins,
                    containerWidth: this.state.containerWidth,
                    containerHeight: this.state.containerHeight - this.state._removalValueForTextTuncate,
                    yAxisElement: this.yAxisElement,
                    yAxisTickFormat: this.props.yAxisTickFormat,
                    yAxisTickCount: this.props.yAxisTickCount,
                    yMinValue: this.props.yMinValue || 0,
                    yMaxValue: this.props.yMaxValue || 0,
                    tickPadding: 10,
                    maxOfYVal: this.props.maxOfYVal,
                    yMinMaxValues: this.props.getMinMaxOfYAxis(points, this.props.yAxisType),
                    // please note these padding default values must be consistent in here
                    // and the parent chart(HBWA/Vertical etc..) for more details refer example
                    // http://using-d3js.com/04_07_ordinal_scales.html
                    yAxisPadding: this.props.yAxisPadding || 0,
                };
                /**
                 * These scales used for 2 purposes.
                 * 1. To create x and y axis
                 * 2. To draw the graph.
                 * For area/line chart using same scales. For other charts, creating their own scales to draw the graph.
                 */
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                var xScale = void 0;
                var tickValues = void 0;
                switch (this.props.xAxisType) {
                    case index_1.XAxisTypes.NumericAxis:
                        (_a = (0, index_1.createNumericXAxis)(XAxisParams, this.props.tickParams, this.props.chartType, culture), xScale = _a.xScale, tickValues = _a.tickValues);
                        break;
                    case index_1.XAxisTypes.DateAxis:
                        (_b = (0, index_1.createDateXAxis)(XAxisParams, this.props.tickParams, culture, dateLocalizeOptions, timeFormatLocale, customDateTimeFormatter, this.props.useUTC), xScale = _b.xScale, tickValues = _b.tickValues);
                        break;
                    case index_1.XAxisTypes.StringAxis:
                        (_c = (0, index_1.createStringXAxis)(XAxisParams, this.props.tickParams, this.props.datasetForXAxisDomain, culture), xScale = _c.xScale, tickValues = _c.tickValues);
                        break;
                    default:
                        (_d = (0, index_1.createNumericXAxis)(XAxisParams, this.props.tickParams, this.props.chartType, culture), xScale = _d.xScale, tickValues = _d.tickValues);
                }
                this._xScale = xScale;
                this._tickValues = tickValues;
                /*
                 * To enable wrapping of x axis tick values or to display complete x axis tick values,
                 * we need to calculate how much space it needed to render the text.
                 * No need to re-calculate every time the chart renders and same time need to get an update. So using setState.
                 * Required space will be calculated first time chart rendering and if any width/height of chart updated.
                 * */
                if (this.props.wrapXAxisLables || this.props.showXAxisLablesTooltip) {
                    var wrapLabelProps = {
                        node: this.xAxisElement,
                        xAxis: xScale,
                        showXAxisLablesTooltip: this.props.showXAxisLablesTooltip || false,
                        noOfCharsToTruncate: this.props.noOfCharsToTruncate || 4,
                    };
                    var temp = xScale && (0, index_1.createWrapOfXLabels)(wrapLabelProps);
                    // this value need to be updated for draw graph updated. So instead of using private value, using set state.
                    if (this.state.isRemoveValCalculated && this.state._removalValueForTextTuncate !== temp) {
                        this.setState({ _removalValueForTextTuncate: temp, isRemoveValCalculated: false });
                    }
                }
                /**
                 * These scales used for 2 purposes.
                 * 1. To create x and y axis
                 * 2. To draw the graph.
                 * For area/line chart using same scales. For other charts, creating their own scales to draw the graph.
                 */
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                var yScale = void 0;
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                var yScaleSecondary = void 0;
                var axisData = { yAxisDomainValues: [] };
                if (this.props.yAxisType && this.props.yAxisType === index_1.YAxisType.StringAxis) {
                    yScale = this.props.createStringYAxis(YAxisParams, this.props.stringDatasetForYAxisDomain, this._isRtl, this.props.barwidth);
                }
                else {
                    if ((_e = this.props) === null || _e === void 0 ? void 0 : _e.secondaryYScaleOptions) {
                        var YAxisParamsSecondary = {
                            margins: this.margins,
                            containerWidth: this.state.containerWidth,
                            containerHeight: this.state.containerHeight - this.state._removalValueForTextTuncate,
                            yAxisElement: this.yAxisElementSecondary,
                            yAxisTickFormat: this.props.yAxisTickFormat,
                            yAxisTickCount: this.props.yAxisTickCount,
                            yMinValue: ((_f = this.props.secondaryYScaleOptions) === null || _f === void 0 ? void 0 : _f.yMinValue) || 0,
                            yMaxValue: (_h = (_g = this.props.secondaryYScaleOptions) === null || _g === void 0 ? void 0 : _g.yMaxValue) !== null && _h !== void 0 ? _h : 100,
                            tickPadding: 10,
                            maxOfYVal: (_k = (_j = this.props.secondaryYScaleOptions) === null || _j === void 0 ? void 0 : _j.yMaxValue) !== null && _k !== void 0 ? _k : 100,
                            yMinMaxValues: this.props.getMinMaxOfYAxis(points, this.props.yAxisType),
                            yAxisPadding: this.props.yAxisPadding,
                        };
                        yScaleSecondary = yScaleSecondary = this.props.createYAxis(YAxisParamsSecondary, this._isRtl, axisData, this.isIntegralDataset, true, this.props.supportNegativeData, this.props.roundedTicks);
                    }
                    yScale = this.props.createYAxis(YAxisParams, this._isRtl, axisData, this.isIntegralDataset, false, this.props.supportNegativeData, this.props.roundedTicks);
                }
                /*
               * To create y axis tick values by if specified
              truncating the rest of the text and showing elipsis
              or showing the whole string,
               * */
                chartTypesToCheck.includes(this.props.chartType) &&
                    yScale &&
                    (0, index_1.createYAxisLabels)(this.yAxisElement, yScale, this.props.noOfCharsToTruncate || 4, this.props.showYAxisLablesTooltip || false, this._isRtl);
                this.props.getAxisData && this.props.getAxisData(axisData);
                // Callback function for chart, returns axis
                this._getData(xScale, yScale);
                children = this.props.children(tslib_1.__assign(tslib_1.__assign({}, this.state), { xScale: xScale, yScale: yScale, yScaleSecondary: yScaleSecondary }));
                if (!this.props.hideTooltip && calloutProps.isCalloutVisible) {
                    callout = this._generateCallout(calloutProps, chartHoverProps);
                }
            }
            this._classNames = getClassNames(this.props.styles, {
                theme: this.props.theme,
                width: this.state._width,
                height: this.state._height,
                className: this.props.className,
                isRtl: this._isRtl,
                enableReflow: this.props.enableReflow,
            });
            var svgDimensions = {
                width: this.state.containerWidth,
                height: this.state.containerHeight,
            };
            var focusDirection;
            if (this.props.focusZoneDirection === react_focus_1.FocusZoneDirection.vertical) {
                focusDirection = this.props.focusZoneDirection;
            }
            else if (this.props.focusZoneDirection) {
                focusDirection = this.props.focusZoneDirection;
            }
            else {
                focusDirection = react_focus_1.FocusZoneDirection.horizontal;
            }
            var xAxisTitleMaximumAllowedWidth = svgDimensions.width - this.margins.left - this.margins.right - this.state.startFromX;
            var yAxisTitleMaximumAllowedHeight = svgDimensions.height -
                this.margins.bottom -
                this.margins.top -
                this.state._removalValueForTextTuncate -
                this.titleMargin;
            /**
             * We have use the {@link defaultTabbableElement } to fix
             * the Focus not landing on chart while tabbing, instead  goes to legend.
             * This issue is observed in Area, line chart after performance optimization done in the PR {@link https://github.com/microsoft/fluentui/pull/27721 }
             * This issue is observed in Bar charts after the changes done by FocusZone team in the PR: {@link https://github.com/microsoft/fluentui/pull/24175 }
             * The issue in Bar Charts(VB and VSB) is due to a {@link FocusZone } update where previously an event listener was
             * attached on keydown to the window, so that whenever the tab key is pressed all outer FocusZone's
             * tab-indexes are updated (an outer FocusZone is a FocusZone that is not within another one).
             * But now after the above PR : they are attaching the
             * listeners to the FocusZone elements instead of the window. So in the first render cycle in Bar charts
             * bars are not created as in the first render cycle the size of the chart container is not known( or is 0)
             * which creates bars of height 0 so instead we do not create any bars  and instead return empty fragments.
             *
             * We have tried 2 Approaches to fix the issue:
             * 1. Using the {@link elementRef} property of FocusZone where we dispatch event for tab keydown
             *    after the second render cycle which triggers an update of the tab index in FocusZone.
             *    But this is a hacky solution and not a proper fix and also elementRef is deprecated.
             * 2. Using the default tabbable element to fix the issue.
             */
            return (React.createElement("div", { id: this.idForGraph, className: this._classNames.root, ref: function (rootElem) { return (_this.chartContainer = rootElem); }, onMouseLeave: this._onChartLeave },
                !this._isFirstRender && React.createElement("div", { id: this.idForDefaultTabbableElement }),
                React.createElement(react_focus_1.FocusZone, tslib_1.__assign({ direction: focusDirection, className: this._classNames.chartWrapper, defaultTabbableElement: "#".concat(this.idForDefaultTabbableElement) }, svgFocusZoneProps),
                    this._isFirstRender && React.createElement("div", { id: this.idForDefaultTabbableElement }),
                    React.createElement("svg", tslib_1.__assign({ width: svgDimensions.width, height: svgDimensions.height, role: "region", "aria-label": this._getChartDescription(), style: { display: 'block' } }, (0, index_1.getSecureProps)(svgProps)),
                        React.createElement("g", { ref: function (e) {
                                _this.xAxisElement = e;
                            }, id: "xAxisGElement".concat(this.idForGraph), 
                            // To add wrap of x axis lables feature, need to remove word height from svg height.
                            transform: "translate(0, ".concat(svgDimensions.height - this.margins.bottom - this.state._removalValueForTextTuncate, ")"), className: this._classNames.xAxis }),
                        this.props.xAxisTitle !== undefined && this.props.xAxisTitle !== '' && (React.createElement(SVGTooltipText_1.SVGTooltipText, { content: this.props.xAxisTitle, textProps: {
                                x: this.margins.left + this.state.startFromX + xAxisTitleMaximumAllowedWidth / 2,
                                y: svgDimensions.height - this.titleMargin,
                                className: this._classNames.axisTitle,
                                textAnchor: 'middle',
                                'aria-hidden': true,
                            }, maxWidth: xAxisTitleMaximumAllowedWidth, wrapContent: index_1.wrapContent, theme: this.props.theme, showBackground: true })),
                        React.createElement("g", { ref: function (e) {
                                _this.yAxisElement = e;
                            }, id: "yAxisGElement".concat(this.idForGraph), transform: "translate(".concat(this._isRtl
                                ? svgDimensions.width - this.margins.right - this.state.startFromX
                                : this.margins.left + this.state.startFromX, ", 0)"), className: this._classNames.yAxis }),
                        this.props.secondaryYScaleOptions && (React.createElement("g", null,
                            React.createElement("g", { ref: function (e) {
                                    _this.yAxisElementSecondary = e;
                                }, id: "yAxisGElementSecondary".concat(this.idForGraph), transform: "translate(".concat(this._isRtl ? this.margins.left : svgDimensions.width - this.margins.right, ", 0)"), className: this._classNames.yAxis }),
                            this.props.secondaryYAxistitle !== undefined && this.props.secondaryYAxistitle !== '' && (React.createElement(SVGTooltipText_1.SVGTooltipText, { content: this.props.secondaryYAxistitle, textProps: {
                                    x: (yAxisTitleMaximumAllowedHeight - this.margins.bottom) / 2 +
                                        this.state._removalValueForTextTuncate,
                                    y: this._isRtl
                                        ? this.state.startFromX - this.titleMargin
                                        : svgDimensions.width - this.margins.right,
                                    textAnchor: 'middle',
                                    transform: "translate(".concat(this._isRtl
                                        ? this.margins.right / 2 - this.titleMargin
                                        : this.margins.right / 2 + this.titleMargin, ",\n                   ").concat(svgDimensions.height - this.margins.bottom - this.margins.top - this.titleMargin, ")rotate(-90)"),
                                    className: this._classNames.axisTitle,
                                    'aria-hidden': true,
                                }, maxWidth: yAxisTitleMaximumAllowedHeight, wrapContent: index_1.wrapContent, theme: this.props.theme, showBackground: true })))),
                        children,
                        this.props.yAxisTitle !== undefined && this.props.yAxisTitle !== '' && (React.createElement(SVGTooltipText_1.SVGTooltipText, { content: this.props.yAxisTitle, textProps: {
                                x: (yAxisTitleMaximumAllowedHeight - this.margins.bottom) / 2 +
                                    this.state._removalValueForTextTuncate,
                                y: this._isRtl
                                    ? svgDimensions.width - this.margins.right / 2 + this.titleMargin
                                    : this.margins.left / 2 + this.state.startFromX - this.titleMargin,
                                textAnchor: 'middle',
                                transform: "translate(0,\n                   ".concat(svgDimensions.height - this.margins.bottom - this.margins.top - this.titleMargin, ")rotate(-90)"),
                                className: this._classNames.axisTitle,
                                'aria-hidden': true,
                            }, maxWidth: yAxisTitleMaximumAllowedHeight, wrapContent: index_1.wrapContent, theme: this.props.theme, showBackground: true })))),
                !this.props.hideLegend && (React.createElement("div", { ref: function (e) { return (_this.legendContainer = e); }, className: this._classNames.legendContainer }, this.props.legendBars)),
                callout && React.createElement(React.Suspense, { fallback: React.createElement("div", null, "Loading...") }, callout)));
        };
        /**
         * Dedicated function to return the Callout JSX Element , which can further be used to only call this when
         * only the calloutprops and charthover props changes.
         * @param calloutProps
         * @param chartHoverProps
         * @returns
         */
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        CartesianChartBase.prototype._generateCallout = function (calloutProps, chartHoverProps) {
            return (React.createElement(Callout_1.Callout, tslib_1.__assign({ hidden: !(!this.props.hideTooltip && calloutProps.isCalloutVisible), 
                /** Keep the callout updated with details of focused/hovered chart element */
                shouldUpdateWhenHidden: true }, calloutProps),
                this.props.customizedCallout && this.props.customizedCallout,
                !this.props.customizedCallout && this.props.isCalloutForStack && this._multiValueCallout(calloutProps),
                !this.props.customizedCallout && !this.props.isCalloutForStack && (React.createElement(ChartHoverCard, tslib_1.__assign({ XValue: calloutProps.XValue, Legend: calloutProps.legend, YValue: calloutProps.YValue, color: calloutProps.color, culture: this.props.culture }, chartHoverProps)))));
        };
        CartesianChartBase.prototype._yValueHoverSubCountsExists = function (yValueHover) {
            if (yValueHover) {
                return yValueHover.some(function (yValue) { return yValue.yAxisCalloutData && typeof yValue.yAxisCalloutData !== 'string'; });
            }
            return false;
        };
        CartesianChartBase.prototype._getCalloutContent = function (xValue, index, yValueHoverSubCountsExists, isLast) {
            var _a;
            var marginStyle = isLast ? {} : { marginRight: '16px' };
            var toDrawShape = xValue.index !== undefined && xValue.index !== -1;
            var _classNames = getClassNames(this.props.styles, {
                theme: this.props.theme,
                width: this.state._width,
                height: this.state._height,
                className: this.props.className,
                isRtl: this._isRtl,
                lineColor: xValue.color,
                toDrawShape: toDrawShape,
            });
            var culture = this.props.culture;
            var yValue = (0, locale_util_1.convertToLocaleString)(xValue.y, culture);
            if (!xValue.yAxisCalloutData || typeof xValue.yAxisCalloutData === 'string') {
                return (React.createElement("div", { style: yValueHoverSubCountsExists ? marginStyle : {} },
                    yValueHoverSubCountsExists && (React.createElement("div", { className: "ms-fontWeight-semibold", style: { fontSize: '12pt' } },
                        xValue.legend,
                        " (",
                        yValue,
                        ")")),
                    React.createElement("div", { id: "".concat(index, "_").concat(xValue.y), className: _classNames.calloutBlockContainer },
                        toDrawShape && (React.createElement(index_2.Shape, { svgProps: {
                                className: _classNames.shapeStyles,
                            }, pathProps: { fill: xValue.color }, shape: index_1.Points[xValue.index % Object.keys(index_1.pointTypes).length] })),
                        React.createElement("div", null,
                            React.createElement("div", { className: _classNames.calloutlegendText },
                                " ",
                                xValue.legend),
                            React.createElement("div", { className: _classNames.calloutContentY }, (0, locale_util_1.convertToLocaleString)(xValue.yAxisCalloutData ? xValue.yAxisCalloutData : (_a = xValue.y) !== null && _a !== void 0 ? _a : xValue.data, culture))))));
            }
            else {
                var subcounts_1 = xValue.yAxisCalloutData;
                return (React.createElement("div", { style: marginStyle },
                    React.createElement("div", { className: "ms-fontWeight-semibold", style: { fontSize: '12pt' } },
                        xValue.legend,
                        " (",
                        yValue,
                        ")"),
                    Object.keys(subcounts_1).map(function (subcountName) {
                        return (React.createElement("div", { key: subcountName, className: _classNames.calloutBlockContainer },
                            React.createElement("div", { className: _classNames.calloutlegendText },
                                " ",
                                (0, locale_util_1.convertToLocaleString)(subcountName, culture)),
                            React.createElement("div", { className: _classNames.calloutContentY }, (0, locale_util_1.convertToLocaleString)(subcounts_1[subcountName], culture))));
                    })));
            }
        };
        /**
         * When screen resizes, along with screen, chart also auto adjusted.
         * This method used to adjust height and width of the charts.
         */
        CartesianChartBase.prototype._fitParentContainer = function () {
            var _this = this;
            var _a = this.state, containerWidth = _a.containerWidth, containerHeight = _a.containerHeight;
            this._reqID = requestAnimationFrame(function () {
                var legendContainerHeight;
                if (_this.props.hideLegend) {
                    // If there is no legend, need not to allocate some space from total chart space.
                    legendContainerHeight = 0;
                }
                else {
                    var legendContainerComputedStyles = _this.legendContainer && getComputedStyle(_this.legendContainer);
                    legendContainerHeight =
                        ((_this.legendContainer && _this.legendContainer.getBoundingClientRect().height) ||
                            _this.minLegendContainerHeight) +
                            parseFloat((legendContainerComputedStyles && legendContainerComputedStyles.marginTop) || '0') +
                            parseFloat((legendContainerComputedStyles && legendContainerComputedStyles.marginBottom) || '0');
                }
                if (_this.props.parentRef || _this.chartContainer) {
                    var container = _this.props.parentRef ? _this.props.parentRef : _this.chartContainer;
                    var currentContainerWidth = _this.props.enableReflow && !_this._isFirstRender
                        ? Math.max(container.getBoundingClientRect().width, _this._calculateChartMinWidth())
                        : container.getBoundingClientRect().width;
                    var currentContainerHeight = container.getBoundingClientRect().height > legendContainerHeight
                        ? container.getBoundingClientRect().height
                        : 350;
                    var shouldResize = containerWidth !== currentContainerWidth ||
                        containerHeight !== currentContainerHeight - legendContainerHeight;
                    if (shouldResize) {
                        _this.setState({
                            containerWidth: currentContainerWidth,
                            containerHeight: currentContainerHeight - legendContainerHeight,
                        });
                    }
                }
            });
        };
        return CartesianChartBase;
    }(React.Component));
    exports.CartesianChartBase = CartesianChartBase;
});
//# sourceMappingURL=CartesianChart.base.js.map