'use client';
import * as React from 'react';
import { useAreaChartStyles } from './useAreaChartStyles.styles';
import { max as d3Max, bisector } from 'd3-array';
import { pointer } from 'd3-selection';
import { select as d3Select } from 'd3-selection';
import { tokens } from '@fluentui/react-theme';
import { area as d3Area, stack as d3Stack, curveMonotoneX as d3CurveBasis, line as d3Line } from 'd3-shape';
import { CartesianChart } from '../../index';
import { calloutData, getXAxisType, ChartTypes, XAxisTypes, getTypeOfAxis, tooltipOfAxislabels, getNextColor, getColorFromToken, getSecureProps, areArraysEqual, getCurveFactory, findNumericMinMaxOfY, createNumericYAxis, domainRangeOfNumericForAreaLineScatterCharts, domainRangeOfDateForAreaLineScatterVerticalBarCharts, createStringYAxis, useRtl, findCalloutPoints } from '../../utilities/index';
import { useId } from '@fluentui/react-utilities';
import { Legends } from '../Legends/index';
import { toImage } from '../../utilities/image-export-utils';
import { formatDateToLocaleString } from '@fluentui/chart-utilities';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const bisect = bisector((d)=>d.x).left;
var InterceptVisibility = /*#__PURE__*/ function(InterceptVisibility) {
    InterceptVisibility["show"] = "visibility";
    InterceptVisibility["hide"] = "hidden";
    return InterceptVisibility;
}(InterceptVisibility || {});
//by default d3-shape 3.2.0 limits the< path> data point precision to 3 digits(d3/d3-path#10)
export const AreaChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
    var _props_legendProps;
    const _uniqueIdForGraph = useId('areaChart_');
    const _verticalLineId = useId('verticalLine_');
    const _circleId = useId('circle');
    const _rectId = useId('rectangle');
    const _tooltipId = useId('AreaChartTooltipID');
    //enableComputationOptimization is used for optimized code to group data points by x value
    //from O(n^2) to O(n) using a map.
    const _enableComputationOptimization = true;
    const _firstRenderOptimization = true;
    const _emptyChartId = useId('_AreaChart_empty');
    let _containsSecondaryYAxis = false;
    let _hasMissingXValues = _containsMissingXValues();
    let _hasDuplicateXValues = _xCoordinateContainsMultipleY();
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let _calloutPoints;
    let _createSet;
    let _colors;
    let _opacity;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let _data;
    let _chart;
    let _margins;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let _xAxisRectScale;
    // determines if the given area chart has multiple stacked bar charts
    let _isMultiStackChart;
    const cartesianChartRef = React.useRef(null);
    const _legendsRef = React.useRef(null);
    const _isRTL = useRtl();
    const [selectedLegends, setSelectedLegends] = React.useState(((_props_legendProps = props.legendProps) === null || _props_legendProps === void 0 ? void 0 : _props_legendProps.selectedLegends) || []);
    const [activeLegend, setActiveLegend] = React.useState(undefined);
    const [hoverXValue, setHoverXValue] = React.useState('');
    // eslint-disable-next-line @typescript-eslint/no-shadow
    const [YValueHover, setYValueHover] = React.useState([]);
    const [lineXValue, setLineXValue] = React.useState(0);
    const [displayOfLine, setDisplayOfLine] = React.useState("hidden");
    const [isCircleClicked, setIsCircleClicked] = React.useState(false);
    const [nearestCircleToHighlight, setNearestCircleToHighlight] = React.useState(null);
    const [activePoint, setActivePoint] = React.useState('');
    const [dataPointCalloutProps, setDataPointCalloutProps] = React.useState();
    const [stackCalloutProps, setStackCalloutProps] = React.useState();
    const [xAxisCalloutAccessibilityData, setXAxisCalloutAccessibilityData] = React.useState();
    const [clickPosition, setClickPosition] = React.useState({
        x: 0,
        y: 0
    });
    const [isPopoverOpen, setPopoverOpen] = React.useState(false);
    const prevPropsRef = React.useRef(null);
    React.useEffect(()=>{
        if (prevPropsRef.current) {
            var _prevProps_legendProps, _props_legendProps;
            const prevProps = prevPropsRef.current;
            if (!areArraysEqual((_prevProps_legendProps = prevProps.legendProps) === null || _prevProps_legendProps === void 0 ? void 0 : _prevProps_legendProps.selectedLegends, (_props_legendProps = props.legendProps) === null || _props_legendProps === void 0 ? void 0 : _props_legendProps.selectedLegends)) {
                var _props_legendProps1;
                setSelectedLegends(((_props_legendProps1 = props.legendProps) === null || _props_legendProps1 === void 0 ? void 0 : _props_legendProps1.selectedLegends) || []);
            }
        }
        prevPropsRef.current = props;
    }, [
        props
    ]);
    React.useImperativeHandle(props.componentRef, ()=>{
        var _cartesianChartRef_current;
        var _cartesianChartRef_current_chartContainer;
        return {
            chartContainer: (_cartesianChartRef_current_chartContainer = (_cartesianChartRef_current = cartesianChartRef.current) === null || _cartesianChartRef_current === void 0 ? void 0 : _cartesianChartRef_current.chartContainer) !== null && _cartesianChartRef_current_chartContainer !== void 0 ? _cartesianChartRef_current_chartContainer : null,
            toImage: (opts)=>{
                var _cartesianChartRef_current, _legendsRef_current;
                return toImage((_cartesianChartRef_current = cartesianChartRef.current) === null || _cartesianChartRef_current === void 0 ? void 0 : _cartesianChartRef_current.chartContainer, (_legendsRef_current = _legendsRef.current) === null || _legendsRef_current === void 0 ? void 0 : _legendsRef_current.toSVG, _isRTL, opts);
            }
        };
    }, []);
    const classes = useAreaChartStyles(props);
    function _getMinMaxOfYAxis(points, yAxisType, useSecondaryYScale) {
        return findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale);
    }
    function _getDomainNRangeValues(points, margins, width, chartType, isRTL, xAxisType, barWidth, tickValues) {
        let domainNRangeValue;
        if (xAxisType === XAxisTypes.NumericAxis) {
            domainNRangeValue = domainRangeOfNumericForAreaLineScatterCharts(points, margins, width, isRTL);
        } else if (xAxisType === XAxisTypes.DateAxis) {
            domainNRangeValue = domainRangeOfDateForAreaLineScatterVerticalBarCharts(points, margins, width, isRTL, tickValues, chartType, barWidth);
        } else {
            domainNRangeValue = {
                dStartValue: 0,
                dEndValue: 0,
                rStartValue: 0,
                rEndValue: 0
            };
        }
        return domainNRangeValue;
    }
    function _getMargins(margins) {
        _margins = margins;
    }
    function _onRectMouseMove(mouseEvent) {
        mouseEvent.persist();
        const { data } = props;
        const { lineChartData } = data;
        _updatePosition(mouseEvent.clientX, mouseEvent.clientY);
        // This will get the value of the X when mouse is on the chart
        // eslint-disable-next-line @nx/workspace-no-restricted-globals
        const xOffset = _xAxisRectScale.invert(pointer(mouseEvent)[0], document.getElementById(_rectId));
        const i = bisect(lineChartData[0].data, xOffset);
        const d0 = lineChartData[0].data[i - 1];
        const d1 = lineChartData[0].data[i];
        let pointToHighlight = null;
        let index = null;
        const axisType = lineChartData[0].data.length > 0 ? 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 {
            let x0;
            let point0;
            let point1;
            switch(axisType){
                case 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 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;
            }
        }
        // eslint-disable-next-line @typescript-eslint/no-shadow
        const { xAxisCalloutData, xAxisCalloutAccessibilityData } = lineChartData[0].data[index];
        const formattedDate = pointToHighlight instanceof Date ? formatDateToLocaleString(pointToHighlight, props.culture, props.useUTC) : pointToHighlight;
        const found = findCalloutPoints(_calloutPoints, pointToHighlight);
        // eslint-disable-next-line @typescript-eslint/no-shadow
        const _nearestCircleToHighlight = axisType === XAxisTypes.DateAxis ? pointToHighlight.getTime() : pointToHighlight;
        // if no points need to be called out then don't show vertical line and callout card
        if (found) {
            const filteredValues = _getFilteredLegendValues(found.values);
            setNearestCircleToHighlight(_nearestCircleToHighlight);
            setLineXValue(_xAxisRectScale(pointToHighlight));
            setDisplayOfLine("visibility");
            setIsCircleClicked(false);
            setStackCalloutProps({
                ...found,
                values: filteredValues
            });
            setYValueHover(filteredValues);
            setDataPointCalloutProps({
                ...found,
                values: filteredValues
            });
            setHoverXValue(xAxisCalloutData ? xAxisCalloutData : formattedDate);
            setXAxisCalloutAccessibilityData(xAxisCalloutAccessibilityData);
            setActivePoint('');
        } else {
            setPopoverOpen(false);
            setNearestCircleToHighlight(nearestCircleToHighlight);
            setDisplayOfLine("hidden");
            setIsCircleClicked(false);
        }
    }
    /**
     * just cleaning up the state which we have set in the mouse move event
     */ function _onRectMouseOut() {
    /**/ }
    function _updatePosition(newX, newY) {
        const threshold = 1; // Set a threshold for movement
        const { x, y } = clickPosition;
        // Calculate the distance moved
        const distance = Math.sqrt(Math.pow(newX - x, 2) + Math.pow(newY - y, 2));
        // Update the position only if the distance moved is greater than the threshold
        if (distance > threshold) {
            setClickPosition({
                x: newX,
                y: newY
            });
            setPopoverOpen(true);
        }
    }
    function _handleChartMouseLeave() {
        setPopoverOpen(false);
        setNearestCircleToHighlight(null);
        setLineXValue(0);
        setDisplayOfLine("hidden");
        setIsCircleClicked(false);
        setStackCalloutProps(undefined);
        setDataPointCalloutProps(undefined);
        setHoverXValue(undefined);
        setYValueHover([]);
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    function _getDataPoints(keys, dataSet) {
        var _props_legendProps;
        const renderPoints = [];
        let maxOfYVal = 0;
        if (_shouldFillToZeroY()) {
            keys.forEach((key, index)=>{
                const currentLayer = [];
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                dataSet.forEach((d)=>{
                    currentLayer.push({
                        values: [
                            0,
                            d[key]
                        ],
                        xVal: d.xVal
                    });
                    if (d[key] > maxOfYVal) {
                        maxOfYVal = d[key];
                    }
                });
                renderPoints.push(currentLayer);
            });
        } else {
            const dataValues = d3Stack().keys(keys)(dataSet);
            maxOfYVal = d3Max(dataValues[dataValues.length - 1], (dp)=>dp[1]);
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            dataValues.forEach((layer)=>{
                const currentLayer = [];
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                layer.forEach((d)=>{
                    currentLayer.push({
                        values: d,
                        xVal: d.data.xVal
                    });
                });
                renderPoints.push(currentLayer);
            });
        }
        _isMultiStackChart = !!(((_props_legendProps = props.legendProps) === null || _props_legendProps === void 0 ? void 0 : _props_legendProps.selectedLegends) ? (renderPoints === null || renderPoints === void 0 ? void 0 : renderPoints.length) >= 1 : (renderPoints === null || renderPoints === void 0 ? void 0 : renderPoints.length) > 1);
        return {
            renderData: renderPoints,
            // The maxOfYVal prop is only required for the primary y-axis. When the data includes
            // a secondary y-axis, the mode defaults to tozeroy, so maxOfYVal should be calculated using
            // only the data points associated with the primary y-axis.
            maxOfYVal: _containsSecondaryYAxis ? findNumericMinMaxOfY(props.data.lineChartData).endValue : maxOfYVal
        };
    }
    function _createDataSet(points) {
        if (props.enablePerfOptimization && _enableComputationOptimization && !_hasDuplicateXValues) {
            const allChartPoints = [];
            const dataSet = [];
            const colors = [];
            const opacity = [];
            const calloutPoints = calloutData(points);
            points && points.length && points.forEach((singleChartPoint)=>{
                colors.push(singleChartPoint.color);
                opacity.push(singleChartPoint.opacity || 1);
                allChartPoints.push(...singleChartPoint.data);
            });
            const mapOfXvalToListOfDataPoints = {};
            allChartPoints.forEach((dataPoint)=>{
                const 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[xValue]) {
                    mapOfXvalToListOfDataPoints[xValue].push(dataPoint);
                } else {
                    mapOfXvalToListOfDataPoints[xValue] = [
                        dataPoint
                    ];
                }
            });
            Object.keys(mapOfXvalToListOfDataPoints).forEach((key)=>{
                const value = mapOfXvalToListOfDataPoints[key];
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                const singleDataset = {};
                value.forEach((singleDataPoint, index)=>{
                    singleDataset.xVal = singleDataPoint.x;
                    singleDataset[`chart${index}`] = singleDataPoint.y;
                });
                dataSet.push(singleDataset);
            });
            // get keys from dataset, used to render data
            const keysLength = dataSet && Object.keys(dataSet[0]).length;
            const keys = [];
            for(let i = 0; i < keysLength - 1; i++){
                const keyVal = `chart${i}`;
                keys.push(keyVal);
            }
            // Data used to draw graph
            const data = _getDataPoints(keys, dataSet);
            return {
                colors,
                opacity,
                keys,
                data,
                calloutPoints
            };
        } else {
            const allChartPoints = [];
            const dataSet = [];
            const colors = [];
            const opacity = [];
            const calloutPoints = calloutData(points);
            let data = {};
            const keys = [];
            let index = 0;
            points && points.length && points.forEach((singleChartPoint)=>{
                // if legend is not populated, then assign a legend
                if (_hasDuplicateXValues && !singleChartPoint.legend) {
                    singleChartPoint.legend = `chart${index}`;
                    ++index;
                }
                singleChartPoint.data.forEach((point)=>{
                    point.legend = singleChartPoint.legend;
                });
                colors.push(singleChartPoint.color);
                opacity.push(singleChartPoint.opacity || 1);
                allChartPoints.push(...singleChartPoint.data);
            });
            if (!_hasDuplicateXValues) {
                let tempArr = allChartPoints;
                while(tempArr.length){
                    const valToCheck = tempArr[0].x instanceof Date ? tempArr[0].x.toLocaleString() : tempArr[0].x;
                    const filteredChartPoints = tempArr.filter((point)=>(point.x instanceof Date ? point.x.toLocaleString() : point.x) === valToCheck);
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    const singleDataset = {};
                    filteredChartPoints.forEach((singleDataPoint, id)=>{
                        singleDataset.xVal = singleDataPoint.x;
                        singleDataset[`chart${id}`] = singleDataPoint.y;
                    });
                    dataSet.push(singleDataset);
                    // removing compared objects from array
                    const val = tempArr[0].x instanceof Date ? tempArr[0].x.toLocaleString() : tempArr[0].x;
                    tempArr = tempArr.filter((point)=>(point.x instanceof Date ? point.x.toLocaleString() : point.x) !== val);
                }
                // get keys from dataset, used to create stacked data
                const keysLength = dataSet && Object.keys(dataSet[0]).length;
                for(let i = 0; i < keysLength - 1; i++){
                    const keyVal = `chart${i}`;
                    keys.push(keyVal);
                }
                // Data used to draw graph
                data = _getDataPoints(keys, dataSet);
            } else {
                const datasetForDuplicateValues = _createDatasetForXCoordinateWithMultipleYValues(allChartPoints);
                data = _getDataPoints(datasetForDuplicateValues.keys, datasetForDuplicateValues.filteredDataSet);
            }
            return {
                colors,
                opacity,
                keys,
                data,
                calloutPoints
            };
        }
    }
    function _createDatasetForXCoordinateWithMultipleYValues(allChartPoints) {
        const dataSet = [];
        // Group data points by x-axis value
        const groupedData = {};
        allChartPoints.forEach((dataPoint)=>{
            const xValue = dataPoint.x instanceof Date ? dataPoint.x.toLocaleString() : dataPoint.x;
            if (!groupedData[xValue]) {
                groupedData[xValue] = [];
            }
            groupedData[xValue].push(dataPoint);
        });
        // Aggregate data points for each x-axis value
        Object.keys(groupedData).forEach((xValue)=>{
            const dataPoints = groupedData[xValue];
            dataPoints.forEach((dataPoint, id)=>{
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                const singleDataset = {
                    xVal: dataPoints[0].x
                };
                const key = dataPoint.legend ? dataPoint.legend : `chart${id}`;
                singleDataset[key] = dataPoint.y;
                dataSet.push(singleDataset);
            });
        });
        // get all unique keys from each array within the dataSet
        const allLegends = [];
        dataSet.forEach((item)=>{
            Object.keys(item).forEach((key)=>{
                if (key !== 'xVal' && !allLegends.includes(key)) {
                    allLegends.push(key);
                }
            });
        });
        dataSet.forEach((item)=>{
            allLegends.forEach((legend)=>{
                if (!item[legend]) {
                    item[legend] = 0; // Fill with 0 if the legend is missing
                }
            });
        });
        // exclude all items within dataset having all legend values 0
        const filteredDataSet = dataSet.filter((item)=>{
            return allLegends.some((legend)=>item[legend] !== 0);
        });
        const keys = Array.from(new Set(filteredDataSet.flatMap((item)=>Object.keys(item).filter((key)=>key !== 'xVal'))));
        return {
            keys,
            filteredDataSet
        };
    }
    function _getCustomizedCallout() {
        return props.onRenderCalloutPerStack ? props.onRenderCalloutPerStack(stackCalloutProps) : props.onRenderCalloutPerDataPoint ? props.onRenderCalloutPerDataPoint(dataPointCalloutProps) : null;
    }
    function _getGraphData(// eslint-disable-next-line @typescript-eslint/no-explicit-any
    xAxis, // eslint-disable-next-line @typescript-eslint/no-explicit-any
    yAxis, containerHeight, containerWidth, xElement, yAxisElement, yScaleSecondary) {
        _chart = _drawGraph(containerHeight, xAxis, yAxis, yScaleSecondary, xElement);
    }
    function _onLegendHover(legend) {
        setActiveLegend(legend);
    }
    function _onLegendLeave() {
        setActiveLegend(undefined);
    }
    function _getLegendData(points) {
        const data = points;
        const actions = [];
        data.forEach((singleChartData)=>{
            const color = singleChartData.color;
            const checkSimilarLegends = actions.filter((leg)=>leg.title === singleChartData.legend && leg.color === color);
            if (checkSimilarLegends.length > 0) {
                return;
            }
            const legend = {
                title: singleChartData.legend,
                color,
                hoverAction: ()=>{
                    _handleChartMouseLeave();
                    _onLegendHover(singleChartData.legend);
                },
                onMouseOutAction: ()=>{
                    _onLegendLeave();
                }
            };
            actions.push(legend);
        });
        return /*#__PURE__*/ React.createElement(Legends, {
            legends: actions,
            enabledWrapLines: props.enabledLegendsWrapLines,
            ...props.legendProps,
            onChange: _onLegendSelectionChange,
            legendRef: _legendsRef
        });
    }
    function _onLegendSelectionChange(// eslint-disable-next-line @typescript-eslint/no-shadow
    selectedLegends, event, currentLegend) {
        var _props_legendProps, _props_legendProps1;
        if ((_props_legendProps = props.legendProps) === null || _props_legendProps === void 0 ? void 0 : _props_legendProps.canSelectMultipleLegends) {
            setSelectedLegends(selectedLegends);
        } else {
            setSelectedLegends(selectedLegends.slice(-1));
        }
        if ((_props_legendProps1 = props.legendProps) === null || _props_legendProps1 === void 0 ? void 0 : _props_legendProps1.onChange) {
            props.legendProps.onChange(selectedLegends, event, currentLegend);
        }
    }
    function _onDataPointClick(func) {
        if (func) {
            func();
        }
        setIsCircleClicked(true);
    }
    function _getOpacity(legend) {
        if (!_isMultiStackChart) {
            return 0.7;
        } else {
            const opacity = _legendHighlighted(legend) || _noLegendHighlighted() ? 0.7 : 0.1;
            return opacity;
        }
    }
    function _getLineOpacity(legend) {
        if (!_isMultiStackChart) {
            return 1;
        } else {
            let opacity = 0.3;
            if (isPopoverOpen) {
                opacity = 1;
            }
            if (!_noLegendHighlighted()) {
                opacity = _legendHighlighted(legend) ? 0 : 0.1;
            }
            return opacity;
        }
    }
    function _updateCircleFillColor(xDataPoint, lineColor, circleId) {
        let fillColor = lineColor;
        if (nearestCircleToHighlight === xDataPoint || activePoint === circleId) {
            if (!isCircleClicked) {
                fillColor = tokens.colorNeutralBackground1;
            }
        }
        return fillColor;
    }
    function _drawGraph(containerHeight, // eslint-disable-next-line @typescript-eslint/no-explicit-any
    xScale, yScalePrimary, yScaleSecondary, xElement) {
        const points = _addDefaultColors(props.data.lineChartData);
        const { pointOptions, pointLineOptions } = props.data;
        const graph = [];
        let lineColor;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _data.forEach((singleStackedData, index)=>{
            var _points_index, _points_index_lineOptions, _points_index1, _points_index_lineOptions1, _points_index2, _points_index_lineOptions2, _points_index3, _points_index_lineOptions3, _points_index4, _points_index_lineOptions4, _points_index5;
            const yScale = ((_points_index = points[index]) === null || _points_index === void 0 ? void 0 : _points_index.useSecondaryYScale) && yScaleSecondary ? yScaleSecondary : yScalePrimary;
            const curveFactory = getCurveFactory((_points_index1 = points[index]) === null || _points_index1 === void 0 ? void 0 : (_points_index_lineOptions = _points_index1.lineOptions) === null || _points_index_lineOptions === void 0 ? void 0 : _points_index_lineOptions.curve, d3CurveBasis);
            const area = d3Area()// eslint-disable-next-line @typescript-eslint/no-explicit-any
            .x((d)=>xScale(d.xVal))// eslint-disable-next-line @typescript-eslint/no-explicit-any
            .y0((d)=>yScale(d.values[0]))// eslint-disable-next-line @typescript-eslint/no-explicit-any
            .y1((d)=>yScale(d.values[1])).curve(curveFactory);
            const line = d3Line()// eslint-disable-next-line @typescript-eslint/no-explicit-any
            .x((d)=>xScale(d.xVal))// eslint-disable-next-line @typescript-eslint/no-explicit-any
            .y((d)=>yScale(d.values[1])).curve(curveFactory);
            const layerOpacity = _shouldFillToZeroY() ? 0.8 : _opacity[index];
            var _points_index_lineOptions_strokeWidth;
            graph.push(/*#__PURE__*/ React.createElement(React.Fragment, {
                key: `${index}-graph-${_uniqueIdForGraph}`
            }, props.enableGradient && /*#__PURE__*/ React.createElement("defs", null, /*#__PURE__*/ React.createElement("linearGradient", {
                id: `gradient_${index}`,
                x1: "0%",
                x2: "0%",
                y1: "0%",
                y2: "100%"
            }, /*#__PURE__*/ React.createElement("stop", {
                offset: "0",
                stopColor: _colors[index]
            }), /*#__PURE__*/ React.createElement("stop", {
                offset: "100%",
                stopColor: "transparent"
            }))), /*#__PURE__*/ React.createElement("path", {
                id: `${index}-line-${_uniqueIdForGraph}`,
                d: line(singleStackedData),
                fill: 'transparent',
                strokeWidth: (_points_index_lineOptions_strokeWidth = (_points_index2 = points[index]) === null || _points_index2 === void 0 ? void 0 : (_points_index_lineOptions1 = _points_index2.lineOptions) === null || _points_index_lineOptions1 === void 0 ? void 0 : _points_index_lineOptions1.strokeWidth) !== null && _points_index_lineOptions_strokeWidth !== void 0 ? _points_index_lineOptions_strokeWidth : 3,
                stroke: _colors[index],
                opacity: _getLineOpacity(points[index].legend),
                onMouseMove: (event)=>_onRectMouseMove(event),
                onMouseOut: _onRectMouseOut,
                onMouseOver: (event)=>_onRectMouseMove(event),
                strokeDasharray: (_points_index3 = points[index]) === null || _points_index3 === void 0 ? void 0 : (_points_index_lineOptions2 = _points_index3.lineOptions) === null || _points_index_lineOptions2 === void 0 ? void 0 : _points_index_lineOptions2.strokeDasharray,
                strokeDashoffset: (_points_index4 = points[index]) === null || _points_index4 === void 0 ? void 0 : (_points_index_lineOptions3 = _points_index4.lineOptions) === null || _points_index_lineOptions3 === void 0 ? void 0 : _points_index_lineOptions3.strokeDashoffset,
                strokeLinecap: (_points_index5 = points[index]) === null || _points_index5 === void 0 ? void 0 : (_points_index_lineOptions4 = _points_index5.lineOptions) === null || _points_index_lineOptions4 === void 0 ? void 0 : _points_index_lineOptions4.strokeLinecap
            }), singleStackedData.length === 1 ? /*#__PURE__*/ React.createElement("circle", {
                id: `${index}-graph-${_uniqueIdForGraph}`,
                cx: xScale(singleStackedData[0].xVal),
                cy: yScale(singleStackedData[0].values[1]),
                r: 6,
                stroke: _colors[index],
                strokeWidth: 3,
                fill: _colors[index],
                opacity: layerOpacity,
                fillOpacity: _getOpacity(points[index].legend),
                onMouseMove: (event)=>_onRectMouseMove(event),
                onFocus: (event)=>_handleFocus(event, index, 0, `${_circleId}_${index}`),
                onMouseOut: _onRectMouseOut,
                onMouseOver: (event)=>_onRectMouseMove(event)
            }) : /*#__PURE__*/ React.createElement("path", {
                id: `${index}-graph-${_uniqueIdForGraph}`,
                d: area(singleStackedData),
                fill: props.enableGradient ? `url(#gradient_${index})` : _colors[index],
                opacity: layerOpacity,
                fillOpacity: _getOpacity(points[index].legend),
                onMouseMove: (event)=>_onRectMouseMove(event),
                onMouseOut: _onRectMouseOut,
                onMouseOver: (event)=>_onRectMouseMove(event),
                ...props.optimizeLargeData && {
                    tabIndex: _legendHighlighted(points[index].legend) || _noLegendHighlighted() ? 0 : undefined,
                    role: 'img',
                    'aria-label': `${points[index].legend}, series ${index + 1} of ${points.length} with ${points[index].data.length} data points.`
                }
            })));
        });
        const circleRadius = pointOptions && pointOptions.r ? Number(pointOptions.r) : 8;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _data.forEach((singleStackedData, index)=>{
            var _points_index;
            if (points.length === index) {
                return;
            }
            const yScale = ((_points_index = points[index]) === null || _points_index === void 0 ? void 0 : _points_index.useSecondaryYScale) && yScaleSecondary ? yScaleSecondary : yScalePrimary;
            if (!props.optimizeLargeData || singleStackedData.length === 1) {
                // Render circles for all data points
                graph.push(/*#__PURE__*/ React.createElement("g", {
                    key: `${index}-dots-${_uniqueIdForGraph}`,
                    clipPath: "url(#clip)",
                    role: "region",
                    "aria-label": `${points[index].legend}, series ${index + 1} of ${points.length} with ${points[index].data.length} data points.`
                }, singleStackedData.map((singlePoint, pointIndex)=>{
                    const circleId = `${_circleId}_${index * _data[0].length + pointIndex}`;
                    const xDataPoint = singlePoint.xVal instanceof Date ? singlePoint.xVal.getTime() : singlePoint.xVal;
                    lineColor = points[index].color;
                    const legend = points[index].legend;
                    return /*#__PURE__*/ React.createElement("circle", {
                        key: circleId,
                        id: circleId,
                        tabIndex: _legendHighlighted(points[index].legend) || _noLegendHighlighted() ? 0 : undefined,
                        cx: xScale(singlePoint.xVal),
                        cy: yScale(singlePoint.values[1]),
                        stroke: lineColor,
                        strokeWidth: 3,
                        fill: _updateCircleFillColor(xDataPoint, lineColor, circleId),
                        onMouseOut: _onRectMouseOut,
                        onMouseOver: (event)=>_onRectMouseMove(event),
                        ..._getOnClickHandler(points, index, pointIndex),
                        onFocus: (event)=>_handleFocus(event, index, pointIndex, circleId),
                        onBlur: _handleBlur,
                        ...getSecureProps(pointOptions),
                        r: _getCircleRadius(xDataPoint, circleRadius, circleId, legend),
                        role: "img",
                        "aria-label": !_hasDuplicateXValues && !_hasMissingXValues && _getAriaLabel(index, pointIndex) || undefined
                    });
                })));
            } else {
                // Render circles for data points close to the mouse pointer only
                singleStackedData.forEach((singlePoint, pointIndex)=>{
                    const xDataPoint = singlePoint.xVal instanceof Date ? singlePoint.xVal.getTime() : singlePoint.xVal;
                    if (nearestCircleToHighlight === xDataPoint) {
                        const circleId = `${_circleId}_${index * _data[0].length + pointIndex}`;
                        lineColor = points[index].color;
                        const legend = points[index].legend;
                        graph.push(/*#__PURE__*/ React.createElement("circle", {
                            key: circleId,
                            id: circleId,
                            cx: xScale(singlePoint.xVal),
                            cy: yScale(singlePoint.values[1]),
                            stroke: lineColor,
                            strokeWidth: 3,
                            fill: _updateCircleFillColor(xDataPoint, lineColor, circleId),
                            onMouseOut: _onRectMouseOut,
                            onMouseOver: (event)=>_onRectMouseMove(event),
                            onFocus: (event)=>_handleFocus(event, index, pointIndex, circleId),
                            ..._getOnClickHandler(points, index, pointIndex),
                            ...getSecureProps(pointOptions),
                            r: _getCircleRadius(xDataPoint, circleRadius, circleId, legend)
                        }));
                    }
                });
            }
        });
        graph.push(/*#__PURE__*/ React.createElement("line", {
            id: _verticalLineId,
            key: _verticalLineId,
            x1: lineXValue,
            y1: 0,
            x2: lineXValue,
            y2: containerHeight,
            strokeWidth: 1,
            strokeDasharray: 5.5,
            stroke: lineColor,
            opacity: 0.5,
            visibility: displayOfLine,
            ...getSecureProps(pointLineOptions)
        }));
        // Removing un wanted tooltip div from DOM, when prop not provided.
        if (!props.showXAxisLablesTooltip) {
            try {
                // eslint-disable-next-line @nx/workspace-no-restricted-globals
                document.getElementById(_tooltipId) && document.getElementById(_tooltipId).remove();
            // eslint-disable-next-line no-empty
            } catch (e) {}
        }
        // Used to display tooltip at x axis labels.
        if (!props.wrapXAxisLables && props.showXAxisLablesTooltip) {
            const xAxisElement = d3Select(xElement).call(xScale);
            try {
                // eslint-disable-next-line @nx/workspace-no-restricted-globals
                document.getElementById(_tooltipId) && document.getElementById(_tooltipId).remove();
            // eslint-disable-next-line no-empty
            } catch (e) {}
            const tooltipProps = {
                tooltipCls: classes.tooltip,
                id: _tooltipId,
                axis: xAxisElement
            };
            xAxisElement && tooltipOfAxislabels(tooltipProps);
        }
        return graph;
    }
    function _getOnClickHandler(points, index, pointIndex) {
        if (!_hasDuplicateXValues && !_hasMissingXValues) {
            return {
                onClick: ()=>_onDataPointClick(points[index].data[pointIndex].onDataPointClick)
            };
        }
        return {};
    }
    function _getCircleRadius(xDataPoint, circleRadius, circleId, legend) {
        // Show the circle if no legends are selected or if the point's legend is in the selected legends
        if (!_noLegendHighlighted() && !_legendHighlighted(legend)) {
            return 0;
        }
        if (isCircleClicked && nearestCircleToHighlight === xDataPoint) {
            return 1;
        } else if (nearestCircleToHighlight === xDataPoint || activePoint === circleId) {
            return circleRadius;
        } else {
            return 0;
        }
    }
    /**
     * This function checks if the given legend is highlighted or not.
     * A legend can be highlighted in 2 ways:
     * 1. selection: if the user clicks on it
     * 2. hovering: if there is no selected legend and the user hovers over it
     */ function _legendHighlighted(legend) {
        return _getHighlightedLegend().includes(legend);
    }
    /**
     * This function checks if none of the legends is selected or hovered.
     */ function _noLegendHighlighted() {
        return _getHighlightedLegend().length === 0;
    }
    function _getHighlightedLegend() {
        return selectedLegends.length > 0 ? selectedLegends : activeLegend ? [
            activeLegend
        ] : [];
    }
    function _addDefaultColors(lineChartData) {
        if (_hasMissingXValues) {
            // get union of all x values
            const allXValues = new Set();
            lineChartData && lineChartData.forEach((line)=>{
                line.data.forEach((point)=>{
                    const xValue = point.x instanceof Date ? point.x.toLocaleString() : point.x;
                    allXValues.add(xValue);
                });
            });
            lineChartData && lineChartData.forEach((line)=>{
                allXValues.forEach((xValue)=>{
                    const point = line.data.find((item)=>{
                        return item.x instanceof Date ? item.x.toLocaleString() === xValue : item.x === xValue;
                    });
                    if (!point) {
                        line.data.push({
                            x: typeof xValue === 'string' ? new Date(xValue) : xValue,
                            y: 0,
                            legend: line.legend
                        });
                    }
                });
                // sort the data points by x value
                line.data.sort((a, b)=>{
                    const xA = a.x instanceof Date ? a.x.getTime() : a.x;
                    const xB = b.x instanceof Date ? b.x.getTime() : b.x;
                    return xA < xB ? -1 : xA > xB ? 1 : 0;
                });
            });
        }
        return lineChartData ? lineChartData.map((item, index)=>{
            let color;
            // isInverted property is applicable to v8 themes only
            if (typeof item.color === 'undefined') {
                color = getNextColor(index, 0);
            } else {
                color = getColorFromToken(item.color);
            }
            return {
                ...item,
                color
            };
        }) : [];
    }
    function _handleFocus(event, lineIndex, pointIndex, circleId) {
        let cx = 0;
        let cy = 0;
        const targetRect = event.target.getBoundingClientRect();
        cx = targetRect.left + targetRect.width / 2;
        cy = targetRect.top + targetRect.height / 2;
        _updatePosition(cx, cy);
        const { x, y, xAxisCalloutData } = props.data.lineChartData[lineIndex].data[pointIndex];
        const formattedDate = x instanceof Date ? formatDateToLocaleString(x, props.culture, props.useUTC) : x;
        const found = findCalloutPoints(_calloutPoints, x);
        if (found) {
            // Show details in the callout for the focused point only
            found.values = found.values.filter((e)=>e.y === y);
            const filteredValues = _getFilteredLegendValues(found.values);
            setPopoverOpen(true);
            setHoverXValue(xAxisCalloutData ? xAxisCalloutData : formattedDate);
            setYValueHover(filteredValues);
            setStackCalloutProps({
                ...found,
                values: filteredValues
            });
            setDataPointCalloutProps({
                ...found,
                values: filteredValues
            });
            setActivePoint(circleId);
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    function _getFilteredLegendValues(values) {
        return !_noLegendHighlighted() ? values.filter((value)=>_legendHighlighted(value.legend)) : values;
    }
    function _handleBlur() {
        setPopoverOpen(false);
        setHoverXValue(undefined);
        setYValueHover([]);
        setStackCalloutProps(undefined);
        setDataPointCalloutProps(undefined);
        setActivePoint('');
    }
    function _getAriaLabel(lineIndex, pointIndex) {
        var _point_callOutAccessibilityData;
        const line = props.data.lineChartData[lineIndex];
        const point = line.data[pointIndex];
        const formattedDate = point.x instanceof Date ? formatDateToLocaleString(point.x, props.culture, props.useUTC) : point.x;
        const xValue = point.xAxisCalloutData || formattedDate;
        const legend = line.legend;
        const yValue = point.yAxisCalloutData || point.y;
        return ((_point_callOutAccessibilityData = point.callOutAccessibilityData) === null || _point_callOutAccessibilityData === void 0 ? void 0 : _point_callOutAccessibilityData.ariaLabel) || `${xValue}. ${legend}, ${yValue}.`;
    }
    function _isChartEmpty() {
        return !(props.data && props.data.lineChartData && props.data.lineChartData.length > 0 && // eslint-disable-next-line @typescript-eslint/no-explicit-any
        props.data.lineChartData.filter((item)=>item.data.length === 0).length === 0);
    }
    function _getChartTitle() {
        const { chartTitle, lineChartData } = props.data;
        return (chartTitle ? `${chartTitle}. ` : '') + `Area chart with ${(lineChartData === null || lineChartData === void 0 ? void 0 : lineChartData.length) || 0} data series. `;
    }
    function _xCoordinateContainsMultipleY() {
        const { lineChartData } = props.data;
        if (!lineChartData) {
            return false;
        }
        for (const item of lineChartData){
            const xValueMap = {};
            for (const point of item.data){
                const xValue = point.x instanceof Date ? point.x.toLocaleString() : point.x;
                if (!xValueMap[xValue]) {
                    xValueMap[xValue] = [];
                }
                xValueMap[xValue].push(point.y);
                if (xValueMap[xValue].length > 1) {
                    return true;
                }
            }
        }
        return false;
    }
    function _containsMissingXValues() {
        const { lineChartData } = props.data;
        if (!lineChartData) {
            return false;
        }
        const allXValues = new Set();
        lineChartData.forEach((line)=>{
            line.data.forEach((point)=>{
                const xValue = point.x instanceof Date ? point.x.toLocaleString() : point.x;
                allXValues.add(xValue);
            });
        });
        // for all x values, check if the x value is present in all series
        let hasMissingValues = false;
        lineChartData.forEach((line)=>{
            allXValues.forEach((xValue)=>{
                const point = line.data.find((item)=>{
                    return item.x instanceof Date ? item.x.toLocaleString() === xValue : item.x === xValue;
                });
                if (!point) {
                    hasMissingValues = true;
                }
            });
        });
        return hasMissingValues;
    }
    function _shouldFillToZeroY() {
        return props.mode === 'tozeroy' || _containsSecondaryYAxis;
    }
    if (!_isChartEmpty()) {
        const { lineChartData } = props.data;
        const points = _addDefaultColors(lineChartData);
        _containsSecondaryYAxis = !!props.secondaryYScaleOptions && points.some((point)=>point.useSecondaryYScale);
        _createSet = _createDataSet;
        const { colors, opacity, data, calloutPoints } = _createSet(points);
        _calloutPoints = calloutPoints;
        const isXAxisDateType = getXAxisType(points);
        _colors = colors;
        _opacity = opacity;
        _data = data.renderData;
        const legends = _getLegendData(points);
        const tickParams = {
            tickValues: props.tickValues,
            tickFormat: props.tickFormat
        };
        const calloutProps = {
            YValueHover: YValueHover,
            hoverXValue: hoverXValue,
            xAxisCalloutAccessibilityData,
            ...props.calloutProps,
            clickPosition,
            isPopoverOpen: isPopoverOpen && !_hasDuplicateXValues && !_hasMissingXValues,
            isCartesian: true,
            customCallout: {
                customizedCallout: _getCustomizedCallout() !== null ? _getCustomizedCallout() : undefined,
                customCalloutProps: props.calloutPropsPerDataPoint ? props.calloutPropsPerDataPoint(dataPointCalloutProps) : undefined
            },
            isCalloutForStack: true
        };
        return /*#__PURE__*/ React.createElement(CartesianChart, {
            ...props,
            chartTitle: _getChartTitle(),
            points: points,
            chartType: ChartTypes.AreaChart,
            calloutProps: calloutProps,
            legendBars: legends,
            createYAxis: createNumericYAxis,
            xAxisType: isXAxisDateType ? XAxisTypes.DateAxis : XAxisTypes.NumericAxis,
            tickParams: tickParams,
            maxOfYVal: data.maxOfYVal,
            getGraphData: _getGraphData,
            getDomainNRangeValues: _getDomainNRangeValues,
            createStringYAxis: createStringYAxis,
            getmargins: _getMargins,
            onChartMouseLeave: _handleChartMouseLeave,
            getMinMaxOfYAxis: _getMinMaxOfYAxis,
            enableFirstRenderOptimization: props.enablePerfOptimization && _firstRenderOptimization,
            componentRef: cartesianChartRef,
            /* eslint-disable react/jsx-no-bind */ // eslint-disable-next-line react/no-children-prop, @typescript-eslint/no-shadow
            children: (props)=>{
                _xAxisRectScale = props.xScale;
                const ticks = _xAxisRectScale.ticks();
                const width1 = _xAxisRectScale(ticks[ticks.length - 1]);
                const rectHeight = props.containerHeight - _margins.top;
                return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("g", null, /*#__PURE__*/ React.createElement("rect", {
                    id: _rectId,
                    width: width1,
                    height: rectHeight,
                    fill: 'transparent',
                    onMouseMove: (event)=>_onRectMouseMove(event),
                    onMouseOut: _onRectMouseOut,
                    onMouseOver: (event)=>_onRectMouseMove(event)
                })), /*#__PURE__*/ React.createElement("g", null, _chart));
            }
        });
    }
    return /*#__PURE__*/ React.createElement("div", {
        id: _emptyChartId,
        role: 'alert',
        style: {
            opacity: '0'
        },
        "aria-label": 'Graph has no data to display'
    });
});
AreaChart.displayName = 'AreaChart';
