"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AreaChartBase = void 0;
var tslib_1 = require("tslib");
var React = require("react");
var d3_array_1 = require("d3-array");
var d3_selection_1 = require("d3-selection");
var d3_selection_2 = require("d3-selection");
var d3_shape_1 = require("d3-shape");
var Utilities_1 = require("@fluentui/react/lib/Utilities");
var index_1 = require("../../index");
var Utilities_2 = require("@fluentui/react/lib/Utilities");
var index_2 = require("../../utilities/index");
var index_3 = require("../Legends/index");
var Callout_1 = require("@fluentui/react/lib/Callout");
var image_export_utils_1 = require("../../utilities/image-export-utils");
var getClassNames = (0, Utilities_1.classNamesFunction)();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var bisect = (0, d3_array_1.bisector)(function (d) { return d.x; }).left;
var COMPONENT_NAME = 'AREA CHART';
var InterceptVisibility;
(function (InterceptVisibility) {
    InterceptVisibility["show"] = "visibility";
    InterceptVisibility["hide"] = "hidden";
})(InterceptVisibility || (InterceptVisibility = {}));
var AreaChartBase = /** @class */ (function (_super) {
    tslib_1.__extends(AreaChartBase, _super);
    function AreaChartBase(props) {
        var _a;
        var _this = _super.call(this, props) || this;
        _this.toImage = function (opts) {
            var _a, _b;
            return (0, image_export_utils_1.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, (0, Utilities_1.getRTL)(), opts);
        };
        _this._getDomainNRangeValues = function (points, margins, width, chartType, isRTL, xAxisType, barWidth, tickValues) {
            var domainNRangeValue;
            if (xAxisType === index_2.XAxisTypes.NumericAxis) {
                domainNRangeValue = (0, index_2.domainRangeOfNumericForAreaChart)(points, margins, width, isRTL);
            }
            else if (xAxisType === index_2.XAxisTypes.DateAxis) {
                domainNRangeValue = (0, index_2.domainRangeOfDateForAreaLineVerticalBarChart)(points, margins, width, isRTL, tickValues, chartType, barWidth);
            }
            else {
                domainNRangeValue = { dStartValue: 0, dEndValue: 0, rStartValue: 0, rEndValue: 0 };
            }
            return domainNRangeValue;
        };
        _this._getMargins = function (margins) {
            _this.margins = margins;
        };
        _this._onRectMouseMove = function (mouseEvent) {
            mouseEvent.persist();
            var data = _this.props.data;
            var lineChartData = data.lineChartData;
            // This will get the value of the X when mouse is on the chart
            var selectedLegends = _this.state.selectedLegends;
            var xOffset = _this._xAxisRectScale.invert((0, d3_selection_1.pointer)(mouseEvent)[0], document.getElementById(_this._rectId));
            var i = bisect(lineChartData[0].data, xOffset);
            var d0 = lineChartData[0].data[i - 1];
            var d1 = lineChartData[0].data[i];
            var pointToHighlight = null;
            var index = null;
            var axisType = lineChartData[0].data.length > 0 ? (0, index_2.getTypeOfAxis)(lineChartData[0].data[0].x, true) : null;
            if (d0 === undefined && d1 !== undefined) {
                pointToHighlight = d1.x;
                index = i;
            }
            else if (d0 !== undefined && d1 === undefined) {
                pointToHighlight = d0.x;
                index = i - 1;
            }
            else {
                var x0 = void 0;
                var point0 = void 0;
                var point1 = void 0;
                switch (axisType) {
                    case index_2.XAxisTypes.DateAxis:
                        x0 = new Date(xOffset).getTime();
                        point0 = d0.x.getTime();
                        point1 = d1.x.getTime();
                        pointToHighlight = Math.abs(x0 - point0) > Math.abs(x0 - point1) ? d1.x : d0.x;
                        index = Math.abs(x0 - point0) > Math.abs(x0 - point1) ? i : i - 1;
                        break;
                    case index_2.XAxisTypes.NumericAxis:
                        x0 = xOffset;
                        point0 = d0.x;
                        point1 = d1.x;
                        pointToHighlight = Math.abs(x0 - point0) > Math.abs(x0 - point1) ? d1.x : d0.x;
                        index = Math.abs(x0 - point0) > Math.abs(x0 - point1) ? i : i - 1;
                        break;
                    default:
                        break;
                }
            }
            var _a = lineChartData[0].data[index], xAxisCalloutData = _a.xAxisCalloutData, xAxisCalloutAccessibilityData = _a.xAxisCalloutAccessibilityData;
            var formattedDate = pointToHighlight instanceof Date ? (0, index_2.formatDate)(pointToHighlight, _this.props.useUTC) : pointToHighlight;
            var modifiedXVal = pointToHighlight instanceof Date ? pointToHighlight.getTime() : pointToHighlight;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            var found = (0, Utilities_1.find)(_this._calloutPoints, function (element) {
                return element.x === modifiedXVal;
            });
            var nearestCircleToHighlight = axisType === index_2.XAxisTypes.DateAxis ? pointToHighlight.getTime() : pointToHighlight;
            var pointToHighlightUpdated = _this.state.nearestCircleToHighlight !== nearestCircleToHighlight;
            // if no points need to be called out then don't show vertical line and callout card
            if (found && pointToHighlightUpdated && !_this.state.isShowCalloutPending) {
                var filteredValues = selectedLegends.length > 0
                    ? found.values.filter(function (value) { return selectedLegends.includes(value.legend); })
                    : found.values;
                _this.setState({
                    nearestCircleToHighlight: nearestCircleToHighlight,
                    isCalloutVisible: false,
                    isShowCalloutPending: true,
                    lineXValue: _this._xAxisRectScale(pointToHighlight),
                    displayOfLine: InterceptVisibility.show,
                    isCircleClicked: false,
                    stackCalloutProps: tslib_1.__assign(tslib_1.__assign({}, found), { values: filteredValues }),
                    YValueHover: filteredValues,
                    dataPointCalloutProps: tslib_1.__assign(tslib_1.__assign({}, found), { values: filteredValues }),
                    hoverXValue: xAxisCalloutData ? xAxisCalloutData : formattedDate,
                    xAxisCalloutAccessibilityData: xAxisCalloutAccessibilityData,
                    activePoint: '',
                });
            }
            else {
                /*
                When above if condition is false but found=true, it means either
          
                1). pointToHighlightUpdated is false.
                For this case we dont need to do anything.
          
                2). isShowCalloutPending is true.
                For this case there will be no callout updation for the event.
                This condition has been added to prevent repeated callout flashing.
                Currently there is a fraction of second delay between hover event and subsequent callout refresh.
                In the meantime if another event is received, the callout continues to flash for the set of
                intermediate hover events.
          
                This does not cause any issue as the user interaction takes atleast a fraction of second and the final
                callout state is ultimately achieved.
                If a user performs very swift mouse maneuver, the intermediate events will be lost but the callout experience
                remains smooth.
                */
            }
            if (!found) {
                _this.setState({
                    isCalloutVisible: false,
                    nearestCircleToHighlight: nearestCircleToHighlight,
                    displayOfLine: InterceptVisibility.hide,
                    isCircleClicked: false,
                });
            }
        };
        /**
         * just cleaning up the state which we have set in the mouse move event
         */
        _this._onRectMouseOut = function () {
            /**/
        };
        _this._handleChartMouseLeave = function () {
            _this.setState({
                refSelected: null,
                isCalloutVisible: false,
                nearestCircleToHighlight: null,
                lineXValue: 0,
                displayOfLine: InterceptVisibility.hide,
                isCircleClicked: false,
                stackCalloutProps: undefined,
                dataPointCalloutProps: undefined,
                hoverXValue: undefined,
                YValueHover: [],
            });
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this._getDataPoints = function (keys, dataSet) {
            var _a;
            var renderPoints = [];
            var maxOfYVal = 0;
            if (_this.props.mode === 'tozeroy') {
                keys.forEach(function (key, index) {
                    var currentLayer = [];
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    dataSet.forEach(function (d) {
                        currentLayer.push({
                            values: [0, d[key]], // Start from zero for "tozeroy" mode
                            xVal: d.xVal,
                        });
                        if (d[key] > maxOfYVal) {
                            maxOfYVal = d[key];
                        }
                    });
                    renderPoints.push(currentLayer);
                });
            }
            else {
                var dataValues = (0, d3_shape_1.stack)().keys(keys)(dataSet);
                maxOfYVal = (0, d3_array_1.max)(dataValues[dataValues.length - 1], function (dp) { return dp[1]; });
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                dataValues.forEach(function (layer) {
                    var currentLayer = [];
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    layer.forEach(function (d) {
                        currentLayer.push({
                            values: d,
                            xVal: d.data.xVal,
                        });
                    });
                    renderPoints.push(currentLayer);
                });
            }
            _this._isMultiStackChart = !!(((_a = _this.props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends)
                ? (renderPoints === null || renderPoints === void 0 ? void 0 : renderPoints.length) >= 1
                : (renderPoints === null || renderPoints === void 0 ? void 0 : renderPoints.length) > 1);
            return {
                renderData: renderPoints,
                maxOfYVal: maxOfYVal,
            };
        };
        _this._createDataSet = function (points) {
            if (_this.props.enablePerfOptimization && _this._enableComputationOptimization) {
                var allChartPoints_1 = [];
                var dataSet_1 = [];
                var colors_1 = [];
                var opacity_1 = [];
                var calloutPoints = (0, index_2.calloutData)(points);
                points &&
                    points.length &&
                    points.forEach(function (singleChartPoint) {
                        colors_1.push(singleChartPoint.color);
                        opacity_1.push(singleChartPoint.opacity || 1);
                        allChartPoints_1.push.apply(allChartPoints_1, singleChartPoint.data);
                    });
                var mapOfXvalToListOfDataPoints_1 = {};
                allChartPoints_1.forEach(function (dataPoint) {
                    var xValue = dataPoint.x instanceof Date ? dataPoint.x.toLocaleString() : dataPoint.x;
                    // map of x value to the list of data points which share the same x value .
                    if (mapOfXvalToListOfDataPoints_1[xValue]) {
                        mapOfXvalToListOfDataPoints_1[xValue].push(dataPoint);
                    }
                    else {
                        mapOfXvalToListOfDataPoints_1[xValue] = [dataPoint];
                    }
                });
                Object.keys(mapOfXvalToListOfDataPoints_1).forEach(function (key) {
                    var value = mapOfXvalToListOfDataPoints_1[key];
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    var singleDataset = {};
                    value.forEach(function (singleDataPoint, index) {
                        singleDataset.xVal = singleDataPoint.x;
                        singleDataset["chart".concat(index)] = singleDataPoint.y;
                    });
                    dataSet_1.push(singleDataset);
                });
                // get keys from dataset, used to render data
                var keysLength = dataSet_1 && Object.keys(dataSet_1[0]).length;
                var keys = [];
                for (var i = 0; i < keysLength - 1; i++) {
                    var keyVal = "chart".concat(i);
                    keys.push(keyVal);
                }
                // Data used to draw graph
                var data = _this._getDataPoints(keys, dataSet_1);
                return {
                    colors: colors_1,
                    opacity: opacity_1,
                    keys: keys,
                    data: data,
                    calloutPoints: calloutPoints,
                };
            }
            else {
                var allChartPoints_2 = [];
                var dataSet = [];
                var colors_2 = [];
                var opacity_2 = [];
                var calloutPoints = (0, index_2.calloutData)(points);
                points &&
                    points.length &&
                    points.forEach(function (singleChartPoint) {
                        colors_2.push(singleChartPoint.color);
                        opacity_2.push(singleChartPoint.opacity || 1);
                        allChartPoints_2.push.apply(allChartPoints_2, singleChartPoint.data);
                    });
                var tempArr = allChartPoints_2;
                var _loop_1 = function () {
                    var valToCheck = tempArr[0].x instanceof Date ? tempArr[0].x.toLocaleString() : tempArr[0].x;
                    var filteredChartPoints = tempArr.filter(function (point) { return (point.x instanceof Date ? point.x.toLocaleString() : point.x) === valToCheck; });
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    var singleDataset = {};
                    filteredChartPoints.forEach(function (singleDataPoint, index) {
                        singleDataset.xVal = singleDataPoint.x;
                        singleDataset["chart".concat(index)] = singleDataPoint.y;
                    });
                    dataSet.push(singleDataset);
                    // removing compared objects from array
                    var val = tempArr[0].x instanceof Date ? tempArr[0].x.toLocaleString() : tempArr[0].x;
                    tempArr = tempArr.filter(function (point) { return (point.x instanceof Date ? point.x.toLocaleString() : point.x) !== val; });
                };
                while (tempArr.length) {
                    _loop_1();
                }
                // get keys from dataset, used to create stacked data
                var keysLength = dataSet && Object.keys(dataSet[0]).length;
                var keys = [];
                for (var i = 0; i < keysLength - 1; i++) {
                    var keyVal = "chart".concat(i);
                    keys.push(keyVal);
                }
                // Data used to draw graph
                var data = _this._getDataPoints(keys, dataSet);
                return {
                    colors: colors_2,
                    opacity: opacity_2,
                    keys: keys,
                    data: data,
                    calloutPoints: calloutPoints,
                };
            }
        };
        _this._getCustomizedCallout = function () {
            return _this.props.onRenderCalloutPerStack
                ? _this.props.onRenderCalloutPerStack(_this.state.stackCalloutProps)
                : _this.props.onRenderCalloutPerDataPoint
                    ? _this.props.onRenderCalloutPerDataPoint(_this.state.dataPointCalloutProps)
                    : null;
        };
        _this._getGraphData = function (
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        xAxis, 
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        yAxis, containerHeight, containerWidth, xElement) {
            _this._chart = _this._drawGraph(containerHeight, xAxis, yAxis, xElement);
        };
        _this._getLegendData = function (points) {
            var data = points;
            var actions = [];
            data.forEach(function (singleChartData) {
                var color = singleChartData.color;
                var checkSimilarLegends = actions.filter(function (leg) { return leg.title === singleChartData.legend && leg.color === color; });
                if (checkSimilarLegends.length > 0) {
                    return;
                }
                var legend = {
                    title: singleChartData.legend,
                    color: color,
                    hoverAction: function () {
                        _this._handleChartMouseLeave();
                        _this._onLegendHover(singleChartData.legend);
                    },
                    onMouseOutAction: function () {
                        _this._onLegendLeave();
                    },
                };
                actions.push(legend);
            });
            return (React.createElement(index_3.Legends, tslib_1.__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._onDataPointClick = function (func) {
            if (func) {
                func();
            }
            _this.setState({ isCircleClicked: true });
        };
        _this._getOpacity = function (legend) {
            if (!_this._isMultiStackChart) {
                return 0.7;
            }
            else {
                var opacity = _this._legendHighlighted(legend) || _this._noLegendHighlighted() ? 0.7 : 0.1;
                return opacity;
            }
        };
        _this._getLineOpacity = function (legend) {
            if (!_this._isMultiStackChart) {
                return 1;
            }
            else {
                var opacity = 0.3;
                if (_this.state.isCalloutVisible) {
                    opacity = 1;
                }
                if (!_this._noLegendHighlighted()) {
                    opacity = _this._legendHighlighted(legend) ? 0 : 0.1;
                }
                return opacity;
            }
        };
        _this._updateCircleFillColor = function (xDataPoint, lineColor, circleId) {
            var fillColor = lineColor;
            if (_this.state.nearestCircleToHighlight === xDataPoint || _this.state.activePoint === circleId) {
                _this._highlightedCircleId = circleId;
                if (!_this.state.isCircleClicked) {
                    fillColor = _this.props.theme.semanticColors.bodyBackground;
                }
            }
            return fillColor;
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this._drawGraph = function (containerHeight, xScale, yScale, xElement) {
            var points = _this._addDefaultColors(_this.props.data.lineChartData);
            var _a = _this.props.data, pointOptions = _a.pointOptions, pointLineOptions = _a.pointLineOptions;
            var area = (0, d3_shape_1.area)()
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                .x(function (d) { return xScale(d.xVal); })
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                .y0(function (d) { return yScale(d.values[0]); })
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                .y1(function (d) { return yScale(d.values[1]); })
                .curve(d3_shape_1.curveMonotoneX);
            var line = (0, d3_shape_1.line)()
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                .x(function (d) { return xScale(d.xVal); })
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                .y(function (d) { return yScale(d.values[1]); })
                .curve(d3_shape_1.curveMonotoneX);
            var graph = [];
            var lineColor;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            _this._data.forEach(function (singleStackedData, index) {
                var _a, _b, _c, _d, _e;
                var layerOpacity = _this.props.mode === 'tozeroy' ? 0.8 : _this._opacity[index];
                graph.push(React.createElement(React.Fragment, { key: "".concat(index, "-graph-").concat(_this._uniqueIdForGraph) },
                    _this.props.enableGradient && (React.createElement("defs", null,
                        React.createElement("linearGradient", { id: "gradient_".concat(index), x1: "0%", x2: "0%", y1: "0%", y2: "100%" },
                            React.createElement("stop", { offset: "0", stopColor: _this._colors[index] }),
                            React.createElement("stop", { offset: "100%", stopColor: "transparent" })))),
                    React.createElement("path", { id: "".concat(index, "-line-").concat(_this._uniqueIdForGraph), d: line(singleStackedData), fill: 'transparent', strokeWidth: (_b = (_a = points[index].lineOptions) === null || _a === void 0 ? void 0 : _a.strokeWidth) !== null && _b !== void 0 ? _b : 3, stroke: _this._colors[index], opacity: _this._getLineOpacity(points[index].legend), onMouseMove: _this._onRectMouseMove, onMouseOut: _this._onRectMouseOut, onMouseOver: _this._onRectMouseMove, strokeDasharray: (_c = points[index].lineOptions) === null || _c === void 0 ? void 0 : _c.strokeDasharray, strokeDashoffset: (_d = points[index].lineOptions) === null || _d === void 0 ? void 0 : _d.strokeDashoffset, strokeLinecap: (_e = points[index].lineOptions) === null || _e === void 0 ? void 0 : _e.strokeLinecap }),
                    singleStackedData.length === 1 ? (React.createElement("circle", { id: "".concat(index, "-graph-").concat(_this._uniqueIdForGraph), cx: xScale(singleStackedData[0].xVal), cy: yScale(singleStackedData[0].values[1]), r: 6, stroke: _this._colors[index], strokeWidth: 3, fill: _this._colors[index], opacity: layerOpacity, fillOpacity: _this._getOpacity(points[index].legend), onMouseMove: _this._onRectMouseMove, onMouseOut: _this._onRectMouseOut, onMouseOver: _this._onRectMouseMove })) : (React.createElement("path", tslib_1.__assign({ id: "".concat(index, "-graph-").concat(_this._uniqueIdForGraph), d: area(singleStackedData), fill: _this.props.enableGradient ? "url(#gradient_".concat(index, ")") : _this._colors[index], opacity: layerOpacity, fillOpacity: _this._getOpacity(points[index].legend), onMouseMove: _this._onRectMouseMove, onMouseOut: _this._onRectMouseOut, onMouseOver: _this._onRectMouseMove }, (_this.props.optimizeLargeData && {
                        'data-is-focusable': _this._legendHighlighted(points[index].legend) || _this._noLegendHighlighted(),
                        role: 'img',
                        'aria-label': "".concat(points[index].legend, ", series ").concat(index + 1, " of ").concat(points.length, " with ").concat(points[index].data.length, " data points."),
                    }))))));
            });
            var circleRadius = pointOptions && pointOptions.r ? Number(pointOptions.r) : 8;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            _this._data.forEach(function (singleStackedData, index) {
                if (points.length === index) {
                    return;
                }
                if (!_this.props.optimizeLargeData || singleStackedData.length === 1) {
                    // Render circles for all data points
                    graph.push(React.createElement("g", { key: "".concat(index, "-dots-").concat(_this._uniqueIdForGraph), d: area(singleStackedData), clipPath: "url(#clip)", role: "region", "aria-label": "".concat(points[index].legend, ", series ").concat(index + 1, " of ").concat(points.length, " with ").concat(points[index].data.length, " data points.") }, singleStackedData.map(function (singlePoint, pointIndex) {
                        var circleId = "".concat(_this._circleId, "_").concat(index * _this._data[0].length + pointIndex);
                        var xDataPoint = singlePoint.xVal instanceof Date ? singlePoint.xVal.getTime() : singlePoint.xVal;
                        lineColor = points[index].color;
                        var legend = points[index].legend;
                        return (React.createElement("circle", tslib_1.__assign({ key: circleId, id: circleId, "data-is-focusable": _this._legendHighlighted(points[index].legend) || _this._noLegendHighlighted(), cx: xScale(singlePoint.xVal), cy: yScale(singlePoint.values[1]), stroke: lineColor, strokeWidth: 3, fill: _this._updateCircleFillColor(xDataPoint, lineColor, circleId), onMouseOut: _this._onRectMouseOut, onMouseOver: _this._onRectMouseMove, onClick: _this._onDataPointClick.bind(_this, points[index].data[pointIndex].onDataPointClick), onFocus: function () { return _this._handleFocus(index, pointIndex, circleId); }, onBlur: _this._handleBlur }, (0, index_2.getSecureProps)(pointOptions), { r: _this._getCircleRadius(xDataPoint, circleRadius, circleId, legend), role: "img", "aria-label": _this._getAriaLabel(index, pointIndex) })));
                    })));
                }
                else {
                    // Render circles for data points close to the mouse pointer only
                    singleStackedData.forEach(function (singlePoint, pointIndex) {
                        var xDataPoint = singlePoint.xVal instanceof Date ? singlePoint.xVal.getTime() : singlePoint.xVal;
                        if (_this.state.nearestCircleToHighlight === xDataPoint) {
                            var circleId = "".concat(_this._circleId, "_").concat(index * _this._data[0].length + pointIndex);
                            lineColor = points[index].color;
                            var legend = points[index].legend;
                            graph.push(React.createElement("circle", tslib_1.__assign({ key: circleId, id: circleId, cx: xScale(singlePoint.xVal), cy: yScale(singlePoint.values[1]), stroke: lineColor, strokeWidth: 3, fill: _this._updateCircleFillColor(xDataPoint, lineColor, circleId), onMouseOut: _this._onRectMouseOut, onMouseOver: _this._onRectMouseMove, onClick: _this._onDataPointClick.bind(_this, points[index].data[pointIndex].onDataPointClick) }, (0, index_2.getSecureProps)(pointOptions), { r: _this._getCircleRadius(xDataPoint, circleRadius, circleId, legend) })));
                        }
                    });
                }
            });
            graph.push(React.createElement("line", tslib_1.__assign({ id: _this._verticalLineId, key: _this._verticalLineId, x1: _this.state.lineXValue, y1: 0, x2: _this.state.lineXValue, y2: containerHeight, strokeWidth: 1, strokeDasharray: 5.5, stroke: lineColor, opacity: 0.5, visibility: _this.state.displayOfLine }, (0, index_2.getSecureProps)(pointLineOptions))));
            var classNames = getClassNames(_this.props.styles, {
                theme: _this.props.theme,
            });
            // Removing un wanted tooltip div from DOM, when prop not provided.
            if (!_this.props.showXAxisLablesTooltip) {
                try {
                    document.getElementById(_this._tooltipId) && document.getElementById(_this._tooltipId).remove();
                    // eslint-disable-next-line no-empty
                }
                catch (e) { }
            }
            // Used to display tooltip at x axis labels.
            if (!_this.props.wrapXAxisLables && _this.props.showXAxisLablesTooltip) {
                var xAxisElement = (0, d3_selection_2.select)(xElement).call(xScale);
                try {
                    document.getElementById(_this._tooltipId) && document.getElementById(_this._tooltipId).remove();
                    // eslint-disable-next-line no-empty
                }
                catch (e) { }
                var tooltipProps = {
                    tooltipCls: classNames.tooltip,
                    id: _this._tooltipId,
                    xAxis: xAxisElement,
                };
                xAxisElement && (0, index_2.tooltipOfXAxislabels)(tooltipProps);
            }
            return graph;
        };
        _this._getCircleRadius = function (xDataPoint, circleRadius, circleId, legend) {
            var _a = _this.state, isCircleClicked = _a.isCircleClicked, nearestCircleToHighlight = _a.nearestCircleToHighlight, activePoint = _a.activePoint;
            // Show the circle if no legends are selected or if the point's legend is in the selected legends
            if (!_this._legendHighlighted(legend)) {
                return 0;
            }
            if (isCircleClicked && nearestCircleToHighlight === xDataPoint) {
                return 1;
            }
            else if (nearestCircleToHighlight === xDataPoint || activePoint === circleId) {
                return circleRadius;
            }
            else {
                return 0;
            }
        };
        _this._closeCallout = function () {
            _this.setState({
                isCalloutVisible: false,
            });
        };
        /**
         * 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 (legend) {
            return _this._getHighlightedLegend().includes(legend);
        };
        /**
         * This function checks if none of the legends is selected or hovered.
         */
        _this._noLegendHighlighted = function () {
            return _this._getHighlightedLegend().length === 0;
        };
        _this._addDefaultColors = function (lineChartData) {
            return lineChartData
                ? lineChartData.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_2.getNextColor)(index, 0, (_a = _this.props.theme) === null || _a === void 0 ? void 0 : _a.isInverted);
                    }
                    else {
                        color = (0, index_2.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 });
                })
                : [];
        };
        _this._handleFocus = function (lineIndex, pointIndex, circleId) {
            var _a = _this.props.data.lineChartData[lineIndex].data[pointIndex], x = _a.x, y = _a.y, xAxisCalloutData = _a.xAxisCalloutData;
            var formattedDate = x instanceof Date ? (0, index_2.formatDate)(x, _this.props.useUTC) : x;
            var modifiedXVal = x instanceof Date ? x.getTime() : x;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            var found = _this._calloutPoints.find(function (e) { return e.x === modifiedXVal; });
            // Show details in the callout for the focused point only
            found.values = found.values.filter(function (e) { return e.y === y; });
            var filteredValues = _this._getFilteredLegendValues(found.values);
            _this.setState({
                refSelected: "#".concat(circleId),
                isCalloutVisible: true,
                hoverXValue: xAxisCalloutData ? xAxisCalloutData : formattedDate,
                YValueHover: filteredValues,
                stackCalloutProps: tslib_1.__assign(tslib_1.__assign({}, found), { values: filteredValues }),
                dataPointCalloutProps: tslib_1.__assign(tslib_1.__assign({}, found), { values: filteredValues }),
                activePoint: circleId,
            });
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this._getFilteredLegendValues = function (values) {
            !_this._noLegendHighlighted()
                ? values.filter(function (value) { return _this._legendHighlighted(value.legend); })
                : values;
        };
        _this._handleBlur = function () {
            _this.setState({
                refSelected: null,
                isCalloutVisible: false,
                hoverXValue: undefined,
                YValueHover: [],
                stackCalloutProps: undefined,
                dataPointCalloutProps: undefined,
                activePoint: '',
            });
        };
        _this._getChartTitle = function () {
            var _a = _this.props.data, chartTitle = _a.chartTitle, lineChartData = _a.lineChartData;
            return (chartTitle ? "".concat(chartTitle, ". ") : '') + "Area chart with ".concat((lineChartData === null || lineChartData === void 0 ? void 0 : lineChartData.length) || 0, " data series. ");
        };
        (0, Utilities_1.initializeComponentRef)(_this);
        _this._createSet = (0, Utilities_1.memoizeFunction)(_this._createDataSet);
        _this.state = {
            selectedLegends: ((_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends) || [],
            activeLegend: undefined,
            hoverXValue: '',
            isCalloutVisible: false,
            refSelected: null,
            YValueHover: [],
            lineXValue: 0,
            displayOfLine: InterceptVisibility.hide,
            isCircleClicked: false,
            nearestCircleToHighlight: null,
            isShowCalloutPending: false,
            activePoint: '',
        };
        (0, Utilities_2.warnDeprecations)(COMPONENT_NAME, props, {
            showYAxisGridLines: 'Dont use this property. Lines are drawn by default',
        });
        _this._uniqueIdForGraph = (0, Utilities_1.getId)('areaChart_');
        _this._verticalLineId = (0, Utilities_1.getId)('verticalLine_');
        _this._circleId = (0, Utilities_1.getId)('circle');
        _this._rectId = (0, Utilities_1.getId)('rectangle');
        _this._tooltipId = (0, Utilities_1.getId)('AreaChartTooltipID');
        _this._enableComputationOptimization = true;
        _this._firstRenderOptimization = true;
        _this._emptyChartId = (0, Utilities_1.getId)('_AreaChart_empty');
        _this._cartesianChartRef = React.createRef();
        _this._legendsRef = React.createRef();
        return _this;
    }
    AreaChartBase.prototype.componentDidUpdate = function (prevProps) {
        var _a, _b, _c;
        if (!(0, index_2.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) || [],
            });
        }
        if (this.state.isShowCalloutPending) {
            this.setState({
                refSelected: "#".concat(this._highlightedCircleId),
                isCalloutVisible: true,
                isShowCalloutPending: false,
            });
        }
    };
    AreaChartBase.prototype.render = function () {
        var _this = this;
        if (!this._isChartEmpty()) {
            var lineChartData = this.props.data.lineChartData;
            var points = this._addDefaultColors(lineChartData);
            var _a = this._createSet(points), colors = _a.colors, opacity = _a.opacity, data = _a.data, calloutPoints = _a.calloutPoints;
            this._calloutPoints = calloutPoints;
            var isXAxisDateType = (0, index_2.getXAxisType)(points);
            this._colors = colors;
            this._opacity = opacity;
            this._data = data.renderData;
            var legends = this._getLegendData(points);
            var tickParams = {
                tickValues: this.props.tickValues,
                tickFormat: this.props.tickFormat,
            };
            var calloutProps = tslib_1.__assign({ target: this.state.refSelected, isCalloutVisible: this.state.isCalloutVisible, directionalHint: Callout_1.DirectionalHint.topAutoEdge, YValueHover: this.state.YValueHover, hoverXValue: this.state.hoverXValue, id: "toolTip".concat(this._uniqueCallOutID), gapSpace: 15, isBeakVisible: false, onDismiss: this._closeCallout, 'data-is-focusable': true, xAxisCalloutAccessibilityData: this.state.xAxisCalloutAccessibilityData }, this.props.calloutProps);
            return (React.createElement(index_1.CartesianChart, tslib_1.__assign({}, this.props, { chartTitle: this._getChartTitle(), points: points, chartType: index_2.ChartTypes.AreaChart, calloutProps: calloutProps, legendBars: legends, createYAxis: index_2.createNumericYAxis, isCalloutForStack: true, xAxisType: isXAxisDateType ? index_2.XAxisTypes.DateAxis : index_2.XAxisTypes.NumericAxis, tickParams: tickParams, maxOfYVal: data.maxOfYVal, getGraphData: this._getGraphData, getDomainNRangeValues: this._getDomainNRangeValues, createStringYAxis: index_2.createStringYAxis, getmargins: this._getMargins, getMinMaxOfYAxis: index_2.findNumericMinMaxOfY, customizedCallout: this._getCustomizedCallout(), onChartMouseLeave: this._handleChartMouseLeave, enableFirstRenderOptimization: this.props.enablePerfOptimization && this._firstRenderOptimization, ref: this._cartesianChartRef, 
                /* eslint-disable react/jsx-no-bind */
                // eslint-disable-next-line react/no-children-prop
                children: function (props) {
                    _this._xAxisRectScale = props.xScale;
                    var ticks = _this._xAxisRectScale.ticks();
                    var width1 = _this._xAxisRectScale(ticks[ticks.length - 1]);
                    var rectHeight = props.containerHeight - _this.margins.top;
                    return (React.createElement(React.Fragment, null,
                        React.createElement("g", null,
                            React.createElement("rect", { id: _this._rectId, width: width1, height: rectHeight, fill: 'transparent', onMouseMove: _this._onRectMouseMove, onMouseOut: _this._onRectMouseOut, onMouseOver: _this._onRectMouseMove })),
                        React.createElement("g", null, _this._chart)));
                } })));
        }
        return (React.createElement("div", { id: this._emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
    };
    Object.defineProperty(AreaChartBase.prototype, "chartContainer", {
        get: function () {
            var _a;
            return ((_a = this._cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer) || null;
        },
        enumerable: false,
        configurable: true
    });
    AreaChartBase.prototype._onLegendHover = function (legend) {
        this.setState({
            activeLegend: legend,
        });
    };
    AreaChartBase.prototype._onLegendLeave = function () {
        this.setState({
            activeLegend: undefined,
        });
    };
    AreaChartBase.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);
        }
    };
    AreaChartBase.prototype._getHighlightedLegend = function () {
        return this.state.selectedLegends.length > 0
            ? this.state.selectedLegends
            : this.state.activeLegend
                ? [this.state.activeLegend]
                : [];
    };
    AreaChartBase.prototype._getAriaLabel = function (lineIndex, pointIndex) {
        var _a;
        var line = this.props.data.lineChartData[lineIndex];
        var point = line.data[pointIndex];
        var formattedDate = point.x instanceof Date ? (0, index_2.formatDate)(point.x, this.props.useUTC) : point.x;
        var xValue = point.xAxisCalloutData || formattedDate;
        var legend = line.legend;
        var yValue = point.yAxisCalloutData || point.y;
        return ((_a = point.callOutAccessibilityData) === null || _a === void 0 ? void 0 : _a.ariaLabel) || "".concat(xValue, ". ").concat(legend, ", ").concat(yValue, ".");
    };
    AreaChartBase.prototype._isChartEmpty = function () {
        return !((this.props.data &&
            this.props.data.lineChartData &&
            this.props.data.lineChartData.length > 0 &&
            this.props.data.lineChartData.filter(function (item) { return item.data.length === 0; }).length === 0)
        // if all the data sets have no data
        // filtering all items which have no data and checking if the length of the filtered array is 0
        // which means chart is not empty
        );
    };
    AreaChartBase.defaultProps = {
        useUTC: true,
    };
    return AreaChartBase;
}(React.Component));
exports.AreaChartBase = AreaChartBase;
//# sourceMappingURL=AreaChart.base.js.map