define(["require", "exports", "tslib", "react", "@fluentui/react/lib/Utilities", "@fluentui/react/lib/Callout", "@fluentui/react-focus", "../../index", "./Pie/index", "../../utilities/index", "../../utilities/locale-util", "../../utilities/image-export-utils"], function (require, exports, tslib_1, React, Utilities_1, Callout_1, react_focus_1, index_1, index_2, index_3, locale_util_1, image_export_utils_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.DonutChartBase = void 0;
    var getClassNames = (0, Utilities_1.classNamesFunction)();
    var LEGEND_CONTAINER_HEIGHT = 40;
    var DonutChartBase = /** @class */ (function (_super) {
        tslib_1.__extends(DonutChartBase, _super);
        function DonutChartBase(props) {
            var _a;
            var _this = _super.call(this, props) || this;
            _this.toImage = function (opts) {
                var _a;
                return (0, image_export_utils_1.toImage)(_this._rootElem, (_a = _this._legendsRef.current) === null || _a === void 0 ? void 0 : _a.toSVG, (0, Utilities_1.getRTL)(), opts);
            };
            _this._closeCallout = function () {
                _this.setState({
                    showHover: false,
                });
            };
            _this._focusCallback = function (data, id, element) {
                _this._currentHoverElement = element;
                _this.setState({
                    /** Show the callout if highlighted arc is focused and Hide it if unhighlighted arc is focused */
                    showHover: _this._noLegendsHighlighted() || _this._isLegendHighlighted(data.legend),
                    value: data.data.toString(),
                    legend: data.legend,
                    color: data.color,
                    xCalloutValue: data.xAxisCalloutData,
                    yCalloutValue: data.yAxisCalloutData,
                    focusedArcId: id,
                    dataPointCalloutProps: data,
                    callOutAccessibilityData: data.callOutAccessibilityData,
                });
            };
            _this._hoverCallback = function (data, e) {
                var _a, _b, _c, _d;
                if (_this._calloutAnchorPoint !== data) {
                    _this._calloutAnchorPoint = data;
                    _this._currentHoverElement = e;
                    var color = data.color;
                    if (_this.props.enableGradient) {
                        var pointIndex = Math.max(((_b = (_a = _this.props.data) === null || _a === void 0 ? void 0 : _a.chartData) === null || _b === void 0 ? void 0 : _b.findIndex(function (item) { return item.legend === data.legend; })) || 0, 0);
                        color = ((_c = data.gradient) === null || _c === void 0 ? void 0 : _c[0]) || (0, index_3.getNextGradient)(pointIndex, 0, (_d = _this.props.theme) === null || _d === void 0 ? void 0 : _d.isInverted)[0];
                    }
                    _this.setState({
                        /** Show the callout if highlighted arc is hovered and Hide it if unhighlighted arc is hovered */
                        showHover: _this._noLegendsHighlighted() || _this._isLegendHighlighted(data.legend),
                        value: data.data.toString(),
                        legend: data.legend,
                        color: color,
                        xCalloutValue: data.xAxisCalloutData,
                        yCalloutValue: data.yAxisCalloutData,
                        dataPointCalloutProps: data,
                        callOutAccessibilityData: data.callOutAccessibilityData,
                    });
                }
            };
            _this._onBlur = function () {
                _this.setState({ focusedArcId: '' });
            };
            _this._handleChartMouseLeave = function () {
                _this._calloutAnchorPoint = null;
                _this.setState({ showHover: false });
            };
            _this._isLegendHighlighted = function (legend) {
                return _this._getHighlightedLegend().includes(legend);
            };
            _this._noLegendsHighlighted = function () {
                return _this._getHighlightedLegend().length === 0;
            };
            _this._addDefaultColors = function (donutChartDataPoint) {
                return donutChartDataPoint
                    ? donutChartDataPoint.map(function (item, index) {
                        var _a, _b;
                        var color;
                        // isInverted property is applicable to v8 themes only
                        if (typeof item.color === 'undefined') {
                            color = (0, index_3.getNextColor)(index, 0, (_a = _this.props.theme) === null || _a === void 0 ? void 0 : _a.isInverted);
                        }
                        else {
                            color = (0, index_3.getColorFromToken)(item.color, (_b = _this.props.theme) === null || _b === void 0 ? void 0 : _b.isInverted);
                        }
                        return tslib_1.__assign(tslib_1.__assign({}, item), { color: color });
                    })
                    : [];
            };
            (0, Utilities_1.initializeComponentRef)(_this);
            _this.state = {
                showHover: false,
                value: '',
                legend: '',
                _width: _this.props.width || 200,
                _height: _this.props.height || 200,
                activeLegend: undefined,
                color: '',
                xCalloutValue: '',
                yCalloutValue: '',
                focusedArcId: '',
                selectedLegends: ((_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends) || [],
            };
            _this._hoverCallback = _this._hoverCallback.bind(_this);
            _this._focusCallback = _this._focusCallback.bind(_this);
            _this._hoverLeave = _this._hoverLeave.bind(_this);
            _this._calloutId = (0, Utilities_1.getId)('callout');
            _this._uniqText = (0, Utilities_1.getId)('_Pie_');
            _this._emptyChartId = (0, Utilities_1.getId)('_DonutChart_empty');
            _this._legendsRef = React.createRef();
            return _this;
        }
        DonutChartBase.getDerivedStateFromProps = function (nextProps, prevState) {
            var widthState;
            if (nextProps.width && nextProps.width !== prevState._width) {
                widthState = { _width: nextProps.width };
            }
            var heightState;
            if (nextProps.height && nextProps.height !== prevState._height) {
                heightState = { _height: nextProps.height - LEGEND_CONTAINER_HEIGHT };
            }
            return tslib_1.__assign(tslib_1.__assign({}, widthState), heightState);
        };
        DonutChartBase.prototype.componentDidMount = function () {
            if (this._rootElem) {
                this.setState({
                    _width: this._rootElem.offsetWidth,
                    _height: this._rootElem.offsetHeight - LEGEND_CONTAINER_HEIGHT,
                });
            }
        };
        DonutChartBase.prototype.componentDidUpdate = function (prevProps) {
            var _a, _b, _c;
            if (!(0, index_3.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) || [],
                });
            }
        };
        DonutChartBase.prototype.render = function () {
            var _this = this;
            var _a = this.props, data = _a.data, _b = _a.hideLegend, hideLegend = _b === void 0 ? false : _b;
            var points = this._addDefaultColors(data === null || data === void 0 ? void 0 : data.chartData);
            this._classNames = getClassNames(this.props.styles, {
                theme: this.props.theme,
                width: this.state._width,
                height: this.state._height,
                color: this.state.color,
                className: this.props.className,
            });
            var legendBars = this._createLegends(points);
            var donutMarginHorizontal = this.props.hideLabels ? 0 : 80;
            var donutMarginVertical = this.props.hideLabels ? 0 : 40;
            var outerRadius = Math.min(this.state._width - donutMarginHorizontal, this.state._height - donutMarginVertical) / 2;
            var chartData = this._elevateToMinimums(points.filter(function (d) { return d.data >= 0; }));
            var valueInsideDonut = this.props.innerRadius !== 0 ? this._valueInsideDonut(this.props.valueInsideDonut, chartData) : '';
            return !this._isChartEmpty() ? (React.createElement("div", { className: this._classNames.root, ref: function (rootElem) { return (_this._rootElem = rootElem); }, onMouseLeave: this._handleChartMouseLeave },
                React.createElement(react_focus_1.FocusZone, { direction: react_focus_1.FocusZoneDirection.horizontal, handleTabKey: react_focus_1.FocusZoneTabbableElements.all },
                    React.createElement("div", null,
                        React.createElement("svg", { className: this._classNames.chart, "aria-label": data === null || data === void 0 ? void 0 : data.chartTitle, ref: function (node) { return _this._setViewBox(node); } },
                            React.createElement(index_2.Pie, { width: this.state._width, height: this.state._height, outerRadius: outerRadius, innerRadius: this.props.innerRadius, data: chartData, enableGradient: this.props.enableGradient, roundCorners: this.props.roundCorners, onFocusCallback: this._focusCallback, hoverOnCallback: this._hoverCallback, hoverLeaveCallback: this._hoverLeave, uniqText: this._uniqText, onBlurCallback: this._onBlur, activeArc: this._getHighlightedLegend(), focusedArcId: this.state.focusedArcId || '', href: this.props.href, calloutId: this._calloutId, valueInsideDonut: this._toLocaleString(valueInsideDonut), theme: this.props.theme, showLabelsInPercent: this.props.showLabelsInPercent, hideLabels: this.props.hideLabels })))),
                React.createElement(Callout_1.Callout, tslib_1.__assign({ target: this._currentHoverElement, alignTargetEdge: true, isBeakVisible: false, directionalHint: Callout_1.DirectionalHint.topAutoEdge, gapSpace: 15, hidden: !(!this.props.hideTooltip && this.state.showHover), id: this._calloutId, onDismiss: this._closeCallout, 
                    // eslint-disable-next-line @typescript-eslint/no-deprecated
                    preventDismissOnLostFocus: true, 
                    /** Keep the callout updated with details of focused/hovered arc */
                    shouldUpdateWhenHidden: true }, this.props.calloutProps, (0, index_3.getAccessibleDataObject)(this.state.callOutAccessibilityData, 'text', false)), this.props.onRenderCalloutPerDataPoint ? (this.props.onRenderCalloutPerDataPoint(this.state.dataPointCalloutProps)) : (React.createElement(index_1.ChartHoverCard, { Legend: this.state.xCalloutValue ? this.state.xCalloutValue : this.state.legend, YValue: this.state.yCalloutValue ? this.state.yCalloutValue : this.state.value, color: this.state.color, culture: this.props.culture }))),
                !hideLegend && React.createElement("div", { className: this._classNames.legendContainer }, legendBars))) : (React.createElement("div", { id: this._emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
        };
        Object.defineProperty(DonutChartBase.prototype, "chartContainer", {
            get: function () {
                return this._rootElem;
            },
            enumerable: false,
            configurable: true
        });
        DonutChartBase.prototype._elevateToMinimums = function (data) {
            var sumOfData = 0;
            var minPercent = 0.01;
            var elevatedData = [];
            data.forEach(function (item) {
                sumOfData += item.data;
            });
            data.forEach(function (item) {
                elevatedData.push(minPercent * sumOfData > item.data && item.data > 0
                    ? tslib_1.__assign(tslib_1.__assign({}, item), { data: minPercent * sumOfData, yAxisCalloutData: item.yAxisCalloutData === undefined ? item.data.toLocaleString() : item.yAxisCalloutData }) : item);
            });
            return elevatedData;
        };
        DonutChartBase.prototype._setViewBox = function (node) {
            var _a, _b;
            if (node === null) {
                return;
            }
            var widthVal = node.parentElement ? node.parentElement.clientWidth : this.state._width;
            var heightVal = node.parentElement && ((_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.offsetHeight) > this.state._height
                ? (_b = node.parentElement) === null || _b === void 0 ? void 0 : _b.offsetHeight
                : this.state._height;
            var viewbox = "0 0 ".concat(widthVal, " ").concat(heightVal);
            node.setAttribute('viewBox', viewbox);
        };
        DonutChartBase.prototype._createLegends = function (chartData) {
            var _this = this;
            var legendDataItems = chartData.map(function (point, index) {
                var _a, _b;
                var color = _this.props.enableGradient
                    ? ((_a = point.gradient) === null || _a === void 0 ? void 0 : _a[0]) || (0, index_3.getNextGradient)(index, 0, (_b = _this.props.theme) === null || _b === void 0 ? void 0 : _b.isInverted)[0]
                    : point.color;
                // mapping data to the format Legends component needs
                var legend = {
                    title: point.legend,
                    color: color,
                    hoverAction: function () {
                        _this._handleChartMouseLeave();
                        _this.setState({ activeLegend: point.legend });
                    },
                    onMouseOutAction: function () {
                        _this.setState({ activeLegend: undefined });
                    },
                };
                return legend;
            });
            var legends = (React.createElement(index_1.Legends, tslib_1.__assign({ legends: legendDataItems, centerLegends: true, overflowProps: this.props.legendsOverflowProps, focusZonePropsInHoverCard: this.props.focusZonePropsForLegendsInHoverCard, overflowText: this.props.legendsOverflowText }, this.props.legendProps, { 
                // eslint-disable-next-line react/jsx-no-bind
                onChange: this._onLegendSelectionChange.bind(this), ref: this._legendsRef })));
            return legends;
        };
        DonutChartBase.prototype._onLegendSelectionChange = function (selectedLegends, event, currentLegend) {
            var _a, _b;
            if (this.props.legendProps && ((_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);
            }
        };
        DonutChartBase.prototype._hoverLeave = function () {
            /**/
        };
        DonutChartBase.prototype._valueInsideDonut = function (valueInsideDonut, data) {
            var _this = this;
            var highlightedLegends = this._getHighlightedLegend();
            if (valueInsideDonut !== undefined && (highlightedLegends.length === 1 || this.state.showHover)) {
                var pointValue = data.find(function (point) { return _this._isLegendHighlighted(point.legend); });
                return pointValue
                    ? pointValue.yAxisCalloutData
                        ? pointValue.yAxisCalloutData
                        : pointValue.data
                    : valueInsideDonut;
            }
            else if (highlightedLegends.length > 0) {
                var totalValue_1 = 0;
                data.forEach(function (point) {
                    if (highlightedLegends.includes(point.legend)) {
                        totalValue_1 += point.data;
                    }
                });
                return totalValue_1;
            }
            else {
                return valueInsideDonut;
            }
        };
        DonutChartBase.prototype._toLocaleString = function (data) {
            var localeString = (0, locale_util_1.convertToLocaleString)(data, this.props.culture);
            if (!localeString) {
                return data;
            }
            return localeString === null || localeString === void 0 ? void 0 : localeString.toString();
        };
        /**
         * This function returns
         * the selected legend if there is one
         * or the hovered legend if none of the legends is selected.
         */
        DonutChartBase.prototype._getHighlightedLegend = function () {
            return this.state.selectedLegends.length > 0
                ? this.state.selectedLegends
                : this.state.activeLegend
                    ? [this.state.activeLegend]
                    : [];
        };
        DonutChartBase.prototype._isChartEmpty = function () {
            return !(this.props.data &&
                this.props.data.chartData &&
                this.props.data.chartData.filter(function (d) { return d.data > 0; }).length > 0);
        };
        DonutChartBase.defaultProps = {
            innerRadius: 0,
            hideLabels: true,
        };
        return DonutChartBase;
    }(React.Component));
    exports.DonutChartBase = DonutChartBase;
});
//# sourceMappingURL=DonutChart.base.js.map