define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities", "./index", "@fluentui/react/lib/Callout", "../../utilities/locale-util", "../../utilities/index", "@fluentui/react-focus", "../../utilities/FocusableTooltipText"], function (require, exports, tslib_1, React, Utilities_1, index_1, Callout_1, locale_util_1, index_2, react_focus_1, FocusableTooltipText_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.HorizontalBarChartBase = void 0;
    var getClassNames = (0, Utilities_1.classNamesFunction)();
    var HorizontalBarChartBase = /** @class */ (function (_super) {
        tslib_1.__extends(HorizontalBarChartBase, _super);
        function HorizontalBarChartBase(props) {
            var _this = _super.call(this, props) || this;
            _this._isRTL = (0, Utilities_1.getRTL)();
            _this._handleChartMouseLeave = function () {
                _this._calloutAnchorPoint = null;
                if (_this.state.isCalloutVisible) {
                    _this.setState({
                        isCalloutVisible: false,
                        hoverValue: '',
                        refSelected: null,
                        lineColor: '',
                        legend: '',
                    });
                }
            };
            _this._adjustProps = function () {
                _this._barHeight = _this.props.barHeight || 12;
                _this._classNames = getClassNames(_this.props.styles, {
                    theme: _this.props.theme,
                    width: _this.props.width,
                    className: _this.props.className,
                    barHeight: _this._barHeight,
                    color: _this.state.lineColor,
                    variant: _this.props.variant,
                    hideLabels: _this.props.hideLabels,
                });
            };
            _this._getChartDataText = function (data) {
                return _this.props.barChartCustomData ? (React.createElement("div", { role: "text" }, _this.props.barChartCustomData(data))) : (_this._getDefaultTextData(data));
            };
            _this._closeCallout = function () {
                _this.setState({
                    isCalloutVisible: false,
                });
            };
            _this._getAriaLabel = function (point) {
                var _a;
                var legend = point.xAxisCalloutData || point.legend;
                var benchMark = point.data;
                var yValue = point.yAxisCalloutData ||
                    (point.horizontalBarChartdata ? "".concat(point.horizontalBarChartdata.x, "/").concat(point.horizontalBarChartdata.y) : 0);
                return (((_a = point.callOutAccessibilityData) === null || _a === void 0 ? void 0 : _a.ariaLabel) ||
                    (legend ? "".concat(legend, ", ") : '') + "".concat(yValue, ".") + (benchMark ? 'with benchmark at ' + "".concat(benchMark, ", ") : ''));
            };
            _this.state = {
                isCalloutVisible: false,
                hoverValue: '',
                lineColor: '',
                legend: '',
                refSelected: null,
                color: '',
                xCalloutValue: '',
                yCalloutValue: '',
                barSpacingInPercent: 0,
            };
            _this._refArray = [];
            _this._uniqLineText = '_HorizontalLine_' + Math.random().toString(36).substring(7);
            _this._hoverOff = _this._hoverOff.bind(_this);
            _this._calloutId = (0, Utilities_1.getId)('callout');
            _this._emptyChartId = (0, Utilities_1.getId)('_HBC_empty');
            _this.barChartSvgRef = React.createRef();
            return _this;
        }
        HorizontalBarChartBase.prototype.componentDidMount = function () {
            var _a;
            var svgWidth = ((_a = this.barChartSvgRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) || 0;
            var MARGIN_WIDTH_IN_PX = 3;
            if (svgWidth) {
                var currentBarSpacing = (MARGIN_WIDTH_IN_PX / svgWidth) * 100;
                this.setState({ barSpacingInPercent: currentBarSpacing });
            }
        };
        HorizontalBarChartBase.prototype.render = function () {
            var _this = this;
            var _a = this.props, data = _a.data, theme = _a.theme;
            this._adjustProps();
            var palette = theme.palette;
            var datapoint = 0;
            return !this._isChartEmpty() ? (React.createElement("div", { className: this._classNames.root, onMouseLeave: this._handleChartMouseLeave },
                data.map(function (points, index) {
                    if (points.chartData && points.chartData[0] && points.chartData[0].horizontalBarChartdata.x) {
                        datapoint = points.chartData[0].horizontalBarChartdata.x;
                    }
                    else {
                        datapoint = 0;
                    }
                    points.chartData[1] = {
                        legend: '',
                        horizontalBarChartdata: {
                            x: points.chartData[0].horizontalBarChartdata.y - datapoint,
                            y: points.chartData[0].horizontalBarChartdata.y,
                        },
                        color: palette.neutralLight,
                    };
                    // Hide right side text of chart title for absolute-scale variant
                    var chartDataText = _this.props.variant === index_1.HorizontalBarChartVariant.AbsoluteScale ? null : _this._getChartDataText(points);
                    var bars = _this._createBars(points, palette, index);
                    var keyVal = _this._uniqLineText + '_' + index;
                    var classNames = getClassNames(_this.props.styles, {
                        theme: _this.props.theme,
                        width: _this.props.width,
                        showTriangle: !!points.chartData[0].data,
                        variant: _this.props.variant,
                    });
                    return (React.createElement("div", { key: index },
                        React.createElement("div", { className: classNames.items },
                            React.createElement(react_focus_1.FocusZone, { direction: react_focus_1.FocusZoneDirection.horizontal },
                                React.createElement("div", { className: _this._classNames.chartTitle },
                                    points.chartTitle && (React.createElement(FocusableTooltipText_1.FocusableTooltipText, { className: _this._classNames.chartTitleLeft, content: points.chartTitle, accessibilityData: points.chartTitleAccessibilityData })),
                                    chartDataText)),
                            points.chartData[0].data && _this._createBenchmark(points),
                            React.createElement(react_focus_1.FocusZone, { direction: react_focus_1.FocusZoneDirection.horizontal, className: _this._classNames.chartWrapper },
                                React.createElement("svg", { ref: _this.barChartSvgRef, className: _this._classNames.chart, "aria-label": points.chartTitle },
                                    React.createElement("g", { id: keyVal, key: keyVal, ref: function (e) {
                                            _this._refCallback(e, points.chartData[0].legend);
                                        }, 
                                        // NOTE: points.chartData![0] contains current data value
                                        onClick: function () {
                                            var p = points.chartData[0];
                                            if (p && p.onClick) {
                                                p.onClick();
                                            }
                                        } }, bars))))));
                }),
                React.createElement(Callout_1.Callout, tslib_1.__assign({ target: this.state.refSelected, coverTarget: true, isBeakVisible: false, gapSpace: 30, hidden: !(!this.props.hideTooltip && this.state.isCalloutVisible), directionalHint: Callout_1.DirectionalHint.topAutoEdge, id: this._calloutId, onDismiss: this._closeCallout, 
                    // eslint-disable-next-line @typescript-eslint/no-deprecated
                    preventDismissOnLostFocus: true }, this.props.calloutProps, (0, index_2.getAccessibleDataObject)(this.state.callOutAccessibilityData)),
                    React.createElement(React.Fragment, null, this.props.onRenderCalloutPerHorizontalBar ? (this.props.onRenderCalloutPerHorizontalBar(this.state.barCalloutProps)) : (React.createElement(index_2.ChartHoverCard, { Legend: this.state.xCalloutValue ? this.state.xCalloutValue : this.state.legend, YValue: this.state.yCalloutValue ? this.state.yCalloutValue : this.state.hoverValue, color: this.state.lineColor, culture: this.props.culture })))))) : (React.createElement("div", { id: this._emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
        };
        HorizontalBarChartBase.prototype._refCallback = function (element, legendTitle) {
            this._refArray.push({ index: legendTitle, refElement: element });
        };
        HorizontalBarChartBase.prototype._hoverOn = function (hoverValue, point) {
            var _a, _b, _c, _d;
            if ((!this.state.isCalloutVisible || this.state.legend !== point.legend) && this._calloutAnchorPoint !== point) {
                var currentHoveredElement = (0, Utilities_1.find)(this._refArray, function (currentElement) { return currentElement.index === point.legend; });
                this._calloutAnchorPoint = point;
                var color = point.color;
                if (this.props.enableGradient) {
                    var pointIndex = Math.max(((_b = (_a = this.props.data) === null || _a === void 0 ? void 0 : _a.map(function (v) { return v.chartData; })) === null || _b === void 0 ? void 0 : _b.findIndex(function (item) { return (item === null || item === void 0 ? void 0 : item[0].data) === point.data && (item === null || item === void 0 ? void 0 : item[0].legend) === point.legend; })) || 0, 0);
                    color = ((_c = point.gradient) === null || _c === void 0 ? void 0 : _c[0]) || (0, index_2.getNextGradient)(pointIndex, 0, (_d = this.props.theme) === null || _d === void 0 ? void 0 : _d.isInverted)[0];
                }
                this.setState({
                    isCalloutVisible: true,
                    hoverValue: hoverValue,
                    lineColor: color,
                    legend: point.legend,
                    refSelected: currentHoveredElement.refElement,
                    xCalloutValue: point.xAxisCalloutData,
                    yCalloutValue: point.yAxisCalloutData,
                    barCalloutProps: point,
                    callOutAccessibilityData: point.callOutAccessibilityData,
                });
            }
        };
        HorizontalBarChartBase.prototype._hoverOff = function () {
            /**/
        };
        HorizontalBarChartBase.prototype._getDefaultTextData = function (data) {
            var culture = this.props.culture;
            var chartDataMode = this.props.chartDataMode || 'default';
            var chartData = data.chartData[0];
            var x = chartData.horizontalBarChartdata.x;
            var y = chartData.horizontalBarChartdata.y;
            var accessibilityData = (0, index_2.getAccessibleDataObject)(data.chartDataAccessibilityData, 'text', false);
            switch (chartDataMode) {
                case 'default':
                    return (React.createElement("div", tslib_1.__assign({ className: this._classNames.chartTitleRight }, accessibilityData), (0, locale_util_1.convertToLocaleString)(x, culture)));
                case 'fraction':
                    return (React.createElement("div", tslib_1.__assign({}, accessibilityData),
                        React.createElement("span", { className: this._classNames.chartTitleRight }, (0, locale_util_1.convertToLocaleString)(x, culture)),
                        React.createElement("span", { className: this._classNames.chartDataTextDenominator }, ' / ' + (0, locale_util_1.convertToLocaleString)(y, culture))));
                case 'percentage':
                    var dataRatioPercentage = "".concat((0, locale_util_1.convertToLocaleString)(Math.round((x / y) * 100), culture), "%");
                    return (React.createElement("div", tslib_1.__assign({ className: this._classNames.chartTitleRight }, accessibilityData), dataRatioPercentage));
            }
        };
        HorizontalBarChartBase.prototype._createBenchmark = function (data) {
            var totalData = data.chartData[0].horizontalBarChartdata.y;
            var benchmarkData = data.chartData[0].data;
            var benchmarkRatio = Math.round(((benchmarkData ? benchmarkData : 0) / totalData) * 100);
            var benchmarkStyles = {
                left: 'calc(' + benchmarkRatio + '% - 4px)',
            };
            return (React.createElement("div", { className: this._classNames.benchmarkContainer },
                React.createElement("div", { className: this._classNames.triangle, style: benchmarkStyles })));
        };
        /**
         * This functions returns an array of <rect> elements, which form the bars
         * For each bar an x value, and a width needs to be specified
         * The computations are done based on percentages
         * Extra margin is also provided, in the x value to provide some spacing in between the bars
         */
        HorizontalBarChartBase.prototype._createBars = function (data, palette, dataPointIndex) {
            var _this = this;
            var _a;
            var noOfBars = ((_a = data.chartData) === null || _a === void 0 ? void 0 : _a.reduce(function (count, point) { return (count += (point.data || 0) > 0 ? 1 : 0); }, 0)) ||
                1;
            var totalMarginPercent = this.state.barSpacingInPercent * (noOfBars - 1);
            var defaultPalette = [palette.blueLight, palette.blue, palette.blueMid, palette.red, palette.black];
            // calculating starting point of each bar and it's range
            var startingPoint = [];
            var total = data.chartData.reduce(function (acc, point) {
                return acc + (point.horizontalBarChartdata.x ? point.horizontalBarChartdata.x : 0);
            }, 0);
            var prevPosition = 0;
            var value = 0;
            var sumOfPercent = 0;
            data.chartData.map(function (point, index) {
                var pointData = point.horizontalBarChartdata.x ? point.horizontalBarChartdata.x : 0;
                value = (pointData / total) * 100;
                if (value < 0) {
                    value = 0;
                }
                else if (value < 1 && value !== 0) {
                    value = 1;
                }
                sumOfPercent += value;
                return sumOfPercent;
            });
            /**
             * The %age of the space occupied by the margin needs to subtracted
             * while computing the scaling ratio, since the margins are not being
             * scaled down, only the data is being scaled down from a higher percentage to lower percentage
             * Eg: 95% of the space is taken by the bars, 5% by the margins
             * Now if the sumOfPercent is 120% -> This needs to be scaled down to 95%, not 100%
             * since that's only space available to the bars
             */
            var scalingRatio = sumOfPercent !== 0 ? (sumOfPercent - totalMarginPercent) / 100 : 1;
            var bars = data.chartData.map(function (point, index) {
                var _a, _b, _c, _d;
                var startColor = point.color ? point.color : defaultPalette[Math.floor(Math.random() * 4 + 1)];
                var endColor = startColor;
                if (_this.props.enableGradient && index !== 1) {
                    startColor = ((_a = point.gradient) === null || _a === void 0 ? void 0 : _a[0]) || (0, index_2.getNextGradient)(dataPointIndex, 0, (_b = _this.props.theme) === null || _b === void 0 ? void 0 : _b.isInverted)[0];
                    endColor = ((_c = point.gradient) === null || _c === void 0 ? void 0 : _c[1]) || (0, index_2.getNextGradient)(dataPointIndex, 0, (_d = _this.props.theme) === null || _d === void 0 ? void 0 : _d.isInverted)[1];
                }
                var pointData = point.horizontalBarChartdata.x ? point.horizontalBarChartdata.x : 0;
                if (index > 0) {
                    prevPosition += value;
                }
                value = (pointData / total) * 100;
                if (value < 0) {
                    value = 0;
                }
                else if (value < 1 && value !== 0) {
                    value = 1 / scalingRatio;
                }
                else {
                    value = value / scalingRatio;
                }
                startingPoint.push(prevPosition);
                var xValue = point.horizontalBarChartdata.x;
                var placeholderIndex = 1;
                // Render bar label instead of placeholder bar for absolute-scale variant
                if (index === placeholderIndex && _this.props.variant === index_1.HorizontalBarChartVariant.AbsoluteScale) {
                    if (_this.props.hideLabels) {
                        return React.createElement("text", { key: index });
                    }
                    var barValue = data.chartData[0].horizontalBarChartdata.x;
                    return (React.createElement("text", { key: index, x: "".concat(_this._isRTL ? 100 - startingPoint[index] : startingPoint[index], "%"), y: _this._barHeight / 2, dominantBaseline: "central", transform: "translate(".concat(_this._isRTL ? -4 : 4, ")"), className: _this._classNames.barLabel, "aria-hidden": true }, (0, index_2.formatValueWithSIPrefix)(barValue)));
                }
                var gradientId = (0, Utilities_1.getId)('HBC_Gradient') + "_".concat(dataPointIndex, "_").concat(index);
                return (React.createElement(React.Fragment, { key: index },
                    _this.props.enableGradient && (React.createElement("defs", null,
                        React.createElement("linearGradient", { id: gradientId },
                            React.createElement("stop", { offset: "0", stopColor: startColor }),
                            React.createElement("stop", { offset: "100%", stopColor: endColor })))),
                    React.createElement("rect", { key: index, x: "".concat(_this._isRTL
                            ? 100 - startingPoint[index] - value - index * _this.state.barSpacingInPercent
                            : startingPoint[index] + index * _this.state.barSpacingInPercent, "%"), y: 0, rx: _this.props.roundCorners ? 3 : 0, "data-is-focusable": point.legend !== '' ? true : false, width: value + '%', height: _this._barHeight, fill: _this.props.enableGradient ? "url(#".concat(gradientId, ")") : startColor, onMouseOver: point.legend !== '' ? _this._hoverOn.bind(_this, xValue, point) : undefined, onFocus: point.legend !== '' ? _this._hoverOn.bind(_this, xValue, point) : undefined, role: "img", "aria-label": _this._getAriaLabel(point), onBlur: _this._hoverOff, onMouseLeave: _this._hoverOff, className: _this._classNames.barWrapper })));
            });
            return bars;
        };
        HorizontalBarChartBase.prototype._isChartEmpty = function () {
            return !(this.props.data && this.props.data.length > 0);
        };
        return HorizontalBarChartBase;
    }(React.Component));
    exports.HorizontalBarChartBase = HorizontalBarChartBase;
});
//# sourceMappingURL=HorizontalBarChart.base.js.map