import { __assign, __spreadArray } from "tslib";
import * as React from 'react';
import { select as d3Select } from 'd3-selection';
import { Legends } from '../Legends/index';
import { max as d3Max, min as d3Min } from 'd3-array';
import { areArraysEqual, createNumericYAxis, createStringYAxis, domainRangeOfDateForScatterChart, domainRangeOfNumericForScatterChart, domainRangeOfXStringAxis, findNumericMinMaxOfY, isScatterPolarSeries, } from '../../utilities/index';
import { CartesianChart, } from '../../index';
import { calloutData, ChartTypes, XAxisTypes, tooltipOfAxislabels, getTypeOfAxis, getNextColor, getColorFromToken, } from '../../utilities/index';
import { classNamesFunction, DirectionalHint, find, getId, getRTL } from '@fluentui/react';
import { toImage as convertToImage } from '../../utilities/image-export-utils';
import { formatDateToLocaleString } from '@fluentui/chart-utilities';
import { renderScatterPolarCategoryLabels } from '../../utilities/scatterpolar-utils';
var getClassNames = classNamesFunction();
// Create a ScatterChart variant which uses these default styles and this styled subcomponent.
/**
 * ScatterChart component
 * {@docCategory ScatterChart}
 */
export var ScatterChartBase = React.forwardRef(function (props, forwardedRef) {
    var _a, _b;
    var _circleId = React.useMemo(function () { return getId('circle'); }, []);
    var _seriesId = React.useMemo(function () { return getId('seriesID'); }, []);
    var _verticalLine = React.useMemo(function () { return getId('verticalLine'); }, []);
    var _tooltipId = React.useMemo(function () { return getId('ScatterChartTooltipId_'); }, []);
    var _firstRenderOptimization = true;
    var _emptyChartId = React.useMemo(function () { return getId('_ScatterChart_empty'); }, []);
    var _points = React.useRef(_injectIndexPropertyInScatterChartData(props.data.scatterChartData));
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    var _calloutPoints = React.useMemo(function () { return calloutData(_points.current) || []; }, [_points]);
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    var _xAxisScale = React.useRef('');
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    var _yAxisScale = React.useRef('');
    var _uniqueCallOutID = React.useRef(null);
    var _refArray = React.useMemo(function () { return []; }, []);
    var margins = React.useRef(null);
    // eslint-disable-next-line @typescript-eslint/no-deprecated
    var renderSeries = React.useRef([]);
    var _xAxisLabels = [];
    var _xAxisCalloutAccessibilityData = {};
    var _xBandwidth = React.useRef(0);
    var cartesianChartRef = React.useRef(null);
    var legendsRef = React.useRef(null);
    var _c = React.useState(''), hoverXValue = _c[0], setHoverXValue = _c[1];
    var _d = React.useState(''), activeLegend = _d[0], setActiveLegend = _d[1];
    var _e = React.useState([]), YValueHover = _e[0], setYValueHover = _e[1];
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    var _f = React.useState([]), selectedLegendPoints = _f[0], setSelectedLegendPoints = _f[1];
    var _g = React.useState(false), isSelectedLegend = _g[0], setIsSelectedLegend = _g[1];
    var _h = React.useState(''), activePoint = _h[0], setActivePoint = _h[1];
    var _j = React.useState(), stackCalloutProps = _j[0], setStackCalloutProps = _j[1];
    var _k = React.useState(false), isCalloutVisible = _k[0], setCalloutVisible = _k[1];
    var _l = React.useState(((_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends) || []), selectedLegends = _l[0], setSelectedLegends = _l[1];
    var _m = React.useState(''), refSelected = _m[0], setRefSelected = _m[1];
    var prevSelectedLegendsRef = React.useRef(undefined);
    var _isScatterPolarRef = React.useRef(false);
    var classNames = getClassNames(props.styles, {
        theme: props.theme,
    });
    React.useEffect(function () {
        var _a, _b, _c;
        if (prevSelectedLegendsRef.current &&
            !areArraysEqual(prevSelectedLegendsRef.current, (_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends)) {
            setSelectedLegends(((_b = props.legendProps) === null || _b === void 0 ? void 0 : _b.selectedLegends) || []);
        }
        prevSelectedLegendsRef.current = (_c = props.legendProps) === null || _c === void 0 ? void 0 : _c.selectedLegends;
    }, [(_b = props.legendProps) === null || _b === void 0 ? void 0 : _b.selectedLegends]);
    React.useImperativeHandle(props.componentRef, function () {
        var _a, _b;
        return ({
            chartContainer: (_b = (_a = cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer) !== null && _b !== void 0 ? _b : null,
            toImage: function (opts) {
                var _a, _b;
                return convertToImage((_a = cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer, (_b = legendsRef.current) === null || _b === void 0 ? void 0 : _b.toSVG, getRTL(), opts);
            },
        });
    }, []);
    var _xAxisType = props.data.scatterChartData &&
        props.data.scatterChartData.length > 0 &&
        props.data.scatterChartData[0].data &&
        props.data.scatterChartData[0].data.length > 0
        ? getTypeOfAxis(props.data.scatterChartData[0].data[0].x, true)
        : XAxisTypes.StringAxis;
    var pointsRef = React.useRef([]);
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    var calloutPointsRef = React.useRef([]);
    React.useEffect(function () {
        /** note that height and width are not used to resize or set as dimesions of the chart,
         * fitParentContainer is responisble for setting the height and width or resizing of the svg/chart
         */
        if (_points.current !== _injectIndexPropertyInScatterChartData(props.data.scatterChartData) ||
            props.data !== _points.current) {
            pointsRef.current = _injectIndexPropertyInScatterChartData(props.data.scatterChartData);
            calloutPointsRef.current = calloutData(pointsRef.current);
        }
    }, [props.height, props.width, props.data, _points]);
    function _injectIndexPropertyInScatterChartData(scatterChartData) {
        return scatterChartData
            ? scatterChartData.map(function (item, index) {
                var color;
                if (typeof item.color === 'undefined') {
                    color = getNextColor(index, 0);
                }
                else {
                    color = getColorFromToken(item.color);
                }
                return __assign(__assign({}, item), { index: -1, color: color });
            })
            : [];
    }
    var _getMargins = React.useCallback(function (_margins) {
        margins.current = _margins;
    }, []);
    function _onHoverCardHide() {
        setSelectedLegendPoints([]);
        setIsSelectedLegend(false);
    }
    // eslint-disable-next-line @typescript-eslint/no-deprecated
    function _createLegends(data) {
        var legendProps = props.legendProps;
        var isLegendMultiSelectEnabled = !!(legendProps && !!legendProps.canSelectMultipleLegends);
        var mapLegendToPoints = {};
        data.forEach(function (point) {
            if (point.legend) {
                if (!mapLegendToPoints[point.legend]) {
                    mapLegendToPoints[point.legend] = [];
                }
                mapLegendToPoints[point.legend].push(point);
            }
        });
        var legendDataItems = Object.entries(mapLegendToPoints).map(function (_a) {
            var legendTitle = _a[0], points = _a[1];
            var representativePoint = points[0];
            // mapping data to the format Legends component needs
            var legend = __assign({ title: legendTitle, color: representativePoint.color, onMouseOutAction: function () {
                    setActiveLegend('');
                }, hoverAction: function () {
                    _handleChartMouseLeave();
                    setActiveLegend(legendTitle);
                } }, (representativePoint.legendShape && {
                shape: representativePoint.legendShape,
            }));
            return legend;
        });
        return (React.createElement(Legends, __assign({ legends: __spreadArray([], legendDataItems, true), enabledWrapLines: props.enabledLegendsWrapLines, overflowProps: props.legendsOverflowProps, focusZonePropsInHoverCard: props.focusZonePropsForLegendsInHoverCard, overflowText: props.legendsOverflowText }, (isLegendMultiSelectEnabled && { onLegendHoverCardLeave: _onHoverCardHide }), { onChange: _onLegendSelectionChange }, props.legendProps)));
    }
    function _onLegendSelectionChange(legendsSelected, event, currentLegend) {
        var _a, _b;
        if ((_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.canSelectMultipleLegends) {
            setSelectedLegends(legendsSelected);
        }
        else {
            setSelectedLegends(legendsSelected.slice(-1));
        }
        if ((_b = props.legendProps) === null || _b === void 0 ? void 0 : _b.onChange) {
            props.legendProps.onChange(legendsSelected, event, currentLegend);
        }
    }
    var _getPointFill = React.useCallback(function (lineColor, pointId) {
        var theme = props.theme;
        if (activePoint === pointId) {
            return theme.semanticColors.bodyBackground;
        }
        else {
            return lineColor;
        }
    }, [activePoint, props]);
    var getDomainNRangeValuesScatterChart = React.useCallback(function (
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    points, domainMargins, width, _chartType, isRTL, xAxisType, _barWidth, tickValues) {
        if (xAxisType === XAxisTypes.NumericAxis) {
            return domainRangeOfNumericForScatterChart(points, domainMargins, width, isRTL);
        }
        else if (xAxisType === XAxisTypes.DateAxis) {
            return domainRangeOfDateForScatterChart(points, domainMargins, width, isRTL, tickValues);
        }
        // String Axis type
        return domainRangeOfXStringAxis(domainMargins, width, isRTL);
    }, []);
    var _handleFocus = React.useCallback(function (seriesId, x, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData) {
        _uniqueCallOutID.current = circleId;
        var formattedData = x instanceof Date ? formatDateToLocaleString(x, props.culture, props.useUTC) : x;
        var xVal = x instanceof Date ? x.getTime() : x;
        var found = find(_calloutPoints, function (element) { return element.x === xVal; });
        // if no points need to be called out then don't show vertical line and callout card
        if (found) {
            d3Select("#".concat(_verticalLine))
                .attr('transform', function () { var _a; return "translate(".concat(((_a = _xAxisScale.current) === null || _a === void 0 ? void 0 : _a.call(_xAxisScale, x)) + _xBandwidth.current, ", 0)"); })
                .attr('visibility', 'visibility');
            _refArray.forEach(function (obj) {
                if (obj.index === seriesId) {
                    setCalloutVisible(true);
                    xAxisCalloutData ? setHoverXValue(xAxisCalloutData) : setHoverXValue('' + formattedData);
                    setRefSelected("#".concat(circleId));
                    setYValueHover(found.values);
                    setActivePoint(circleId);
                }
            });
        }
        else {
            setActivePoint(circleId);
        }
    }, [_verticalLine, _xAxisScale, _xBandwidth, _calloutPoints, _refArray, props.culture, props.useUTC]);
    var _handleHover = React.useCallback(function (x, y, lineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData, mouseEvent) {
        var _a;
        mouseEvent === null || mouseEvent === void 0 ? void 0 : mouseEvent.persist();
        var formattedData = x instanceof Date ? formatDateToLocaleString(x, props.culture, props.useUTC) : x;
        var xVal = x instanceof Date ? x.getTime() : x;
        var found = find(_calloutPoints, function (element) { return element.x === xVal; });
        // if no points need to be called out then don't show vertical line and callout card
        if (found) {
            d3Select("#".concat(_verticalLine))
                .attr('transform', function () { var _a, _b; return "translate(".concat(((_a = _xAxisScale.current) === null || _a === void 0 ? void 0 : _a.call(_xAxisScale, x)) + _xBandwidth.current, ", ").concat((_b = _yAxisScale.current) === null || _b === void 0 ? void 0 : _b.call(_yAxisScale, y), ")"); })
                .attr('visibility', 'visibility')
                .attr('y2', "".concat(lineHeight - ((_a = _yAxisScale.current) === null || _a === void 0 ? void 0 : _a.call(_yAxisScale, y))));
            if (_uniqueCallOutID.current !== circleId) {
                _uniqueCallOutID.current = circleId;
                setCalloutVisible(true);
                xAxisCalloutData ? setHoverXValue(xAxisCalloutData) : setHoverXValue('' + formattedData);
                setRefSelected("#".concat(circleId));
                setYValueHover(found.values);
                setStackCalloutProps(found);
                setActivePoint(circleId);
            }
        }
        else {
            setActivePoint(circleId);
        }
    }, [_verticalLine, _xAxisScale, _xBandwidth, _calloutPoints, props.culture, props.useUTC]);
    var _handleMouseOut = React.useCallback(function () {
        d3Select("#".concat(_verticalLine)).attr('visibility', 'hidden');
    }, [_verticalLine]);
    var _handleChartMouseLeave = React.useCallback(function () {
        _uniqueCallOutID.current = null;
        setActivePoint('');
        if (isCalloutVisible) {
            setCalloutVisible(false);
        }
    }, [_uniqueCallOutID, isCalloutVisible, setActivePoint, setCalloutVisible]);
    var _getHighlightedLegend = React.useCallback(function () {
        return selectedLegends.length > 0 ? selectedLegends : activeLegend ? [activeLegend] : [];
    }, [selectedLegends, activeLegend]);
    /**
     * This function checks if none of the legends is selected or hovered.*/
    var _noLegendHighlighted = React.useCallback(function () {
        return _getHighlightedLegend().length === 0;
    }, [_getHighlightedLegend]);
    /**
     * 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*/
    var _legendHighlighted = React.useCallback(function (legend) {
        return _getHighlightedLegend().includes(legend);
    }, [_getHighlightedLegend]);
    var _getAriaLabel = React.useCallback(function (seriesIndex, pointIndex) {
        var _a, _b;
        var series = (_a = _points.current) === null || _a === void 0 ? void 0 : _a[seriesIndex];
        var point = series.data[pointIndex];
        var formattedDate = point.x instanceof Date ? formatDateToLocaleString(point.x, props.culture, props.useUTC) : point.x;
        var xValue = point.xAxisCalloutData || formattedDate;
        var legend = series.legend;
        var yValue = point.yAxisCalloutData || point.y;
        return ((_b = point.callOutAccessibilityData) === null || _b === void 0 ? void 0 : _b.ariaLabel) || "".concat(xValue, ". ").concat(legend, ", ").concat(yValue, ".");
    }, [_points, props.culture, props.useUTC]);
    function _getRangeForScatterMarkerSize(yScale, yPadding, xMin, xMax, xPadding) {
        var _a, _b, _c, _d;
        var extraXPixels = getRTL()
            ? ((_a = _xAxisScale.current) === null || _a === void 0 ? void 0 : _a.call(_xAxisScale, xMax - xPadding)) - ((_b = _xAxisScale.current) === null || _b === void 0 ? void 0 : _b.call(_xAxisScale, xMax))
            : ((_c = _xAxisScale.current) === null || _c === void 0 ? void 0 : _c.call(_xAxisScale, xMin + xPadding)) - ((_d = _xAxisScale.current) === null || _d === void 0 ? void 0 : _d.call(_xAxisScale, xMin));
        var yMin = yScale.domain()[0];
        var extraYPixels = yScale(yMin) - yScale(yMin + yPadding);
        return Math.min(extraXPixels, extraYPixels);
    }
    var _createPlot = React.useCallback(
    // eslint-disable-next-line @typescript-eslint/no-deprecated
    function (xElement, containerHeight) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        var series = [];
        if (isSelectedLegend) {
            _points.current = selectedLegendPoints;
        }
        else {
            _points.current = _injectIndexPropertyInScatterChartData(props.data.scatterChartData);
        }
        var yMax = d3Max(_points.current, function (point) {
            return d3Max(point.data, function (item) { return item.y; });
        });
        var yMin = d3Min(_points.current, function (point) {
            return d3Min(point.data, function (item) { return item.y; });
        });
        var yPadding = (yMax - yMin) * 0.1;
        var xPadding = 0;
        var xMin = 0;
        var xMax = 0;
        if (_xAxisType === XAxisTypes.StringAxis) {
            _xBandwidth.current = ((_a = _xAxisScale.current) === null || _a === void 0 ? void 0 : _a.bandwidth()) / 2;
        }
        else if (_xAxisType === XAxisTypes.DateAxis) {
            xMin = d3Min(_points.current, function (point) {
                return d3Min(point.data, function (item) { return item.x; });
            }).getTime();
            xMax = d3Max(_points.current, function (point) {
                return d3Max(point.data, function (item) {
                    return item.x;
                });
            }).getTime();
            xPadding = (xMax - xMin) * 0.1;
        }
        else {
            xMin = d3Min(_points.current, function (point) {
                return d3Min(point.data, function (item) { return item.x; });
            });
            xMax = d3Max(_points.current, function (point) {
                return d3Max(point.data, function (item) {
                    return item.x;
                });
            });
            xPadding = (xMax - xMin) * 0.1;
        }
        var maxMarkerSize = d3Max(_points.current, function (point) {
            return d3Max(point.data, function (item) {
                return item.markerSize;
            });
        });
        var _loop_1 = function (i) {
            // eslint-disable-next-line @typescript-eslint/no-deprecated
            var pointsForSeries = [];
            var legendVal = (_d = (_c = _points.current) === null || _c === void 0 ? void 0 : _c[i]) === null || _d === void 0 ? void 0 : _d.legend;
            var seriesColor = (_f = (_e = _points.current) === null || _e === void 0 ? void 0 : _e[i]) === null || _f === void 0 ? void 0 : _f.color;
            var verticaLineHeight = containerHeight - ((_h = (_g = margins.current) === null || _g === void 0 ? void 0 : _g.bottom) !== null && _h !== void 0 ? _h : 0) + 6;
            var _loop_2 = function (j) {
                var seriesId = "".concat(_seriesId, "_").concat(i, "_").concat(j);
                var circleId = "".concat(_circleId, "_").concat(i, "_").concat(j);
                var _12 = (_o = (_m = _points.current) === null || _m === void 0 ? void 0 : _m[i]) === null || _o === void 0 ? void 0 : _o.data[j], x = _12.x, y = _12.y, xAxisCalloutData = _12.xAxisCalloutData, xAxisCalloutAccessibilityData = _12.xAxisCalloutAccessibilityData;
                var pointMarkerSize = ((_q = (_p = _points.current) === null || _p === void 0 ? void 0 : _p[i]) === null || _q === void 0 ? void 0 : _q.data[j]).markerSize;
                var extraMaxPixels = _xAxisType !== XAxisTypes.StringAxis
                    ? _getRangeForScatterMarkerSize(_yAxisScale.current, yPadding, xMin, xMax, xPadding)
                    : 0;
                var minPixel = 4;
                var maxPixel = 16;
                var circleRadius = pointMarkerSize && maxMarkerSize !== 0
                    ? _xAxisType !== XAxisTypes.StringAxis
                        ? (pointMarkerSize * extraMaxPixels) / maxMarkerSize
                        : minPixel + ((pointMarkerSize - minPixel) / (maxMarkerSize - minPixel)) * (maxPixel - minPixel)
                    : activePoint === circleId
                        ? 6
                        : 4;
                var isLegendSelected = _legendHighlighted(legendVal) || _noLegendHighlighted() || isSelectedLegend;
                var currentPointHidden = ((_s = (_r = _points.current) === null || _r === void 0 ? void 0 : _r[i]) === null || _s === void 0 ? void 0 : _s.hideNonActiveDots) && activePoint !== circleId;
                var text = (_u = (_t = _points.current) === null || _t === void 0 ? void 0 : _t[i].data[j]) === null || _u === void 0 ? void 0 : _u.text;
                pointsForSeries.push(React.createElement(React.Fragment, null,
                    React.createElement("circle", __assign({ id: circleId, key: circleId, r: Math.max(circleRadius, 4), cx: ((_v = _xAxisScale.current) === null || _v === void 0 ? void 0 : _v.call(_xAxisScale, x)) + _xBandwidth.current, cy: (_w = _yAxisScale.current) === null || _w === void 0 ? void 0 : _w.call(_yAxisScale, y), "data-is-focusable": isLegendSelected, onMouseOver: function (event) {
                            return _handleHover(x, y, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData, event);
                        }, onMouseMove: function (event) {
                            return _handleHover(x, y, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData, event);
                        }, onMouseOut: _handleMouseOut, onFocus: function () { return _handleFocus(seriesId, x, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData); }, onBlur: _handleMouseOut }, _getClickHandler((_z = (_y = (_x = _points.current) === null || _x === void 0 ? void 0 : _x[i]) === null || _y === void 0 ? void 0 : _y.data[j]) === null || _z === void 0 ? void 0 : _z.onDataPointClick), { opacity: isLegendSelected && !currentPointHidden ? 1 : 0.1, fill: _getPointFill(seriesColor, circleId), stroke: seriesColor, role: "img", "aria-label": _getAriaLabel(i, j), tabIndex: ((_1 = (_0 = _points.current) === null || _0 === void 0 ? void 0 : _0[i]) === null || _1 === void 0 ? void 0 : _1.legend) !== '' ? 0 : undefined })),
                    !_isScatterPolarRef.current && text && (React.createElement("text", { key: "".concat(circleId, "-label"), x: ((_2 = _xAxisScale.current) === null || _2 === void 0 ? void 0 : _2.call(_xAxisScale, x)) + _xBandwidth.current, y: ((_3 = _yAxisScale.current) === null || _3 === void 0 ? void 0 : _3.call(_yAxisScale, y)) + Math.max(circleRadius + 12, 16), className: classNames.markerLabel }, text))));
            };
            for (var j = 0; j < ((_l = (_k = (_j = _points.current) === null || _j === void 0 ? void 0 : _j[i]) === null || _k === void 0 ? void 0 : _k.data) === null || _l === void 0 ? void 0 : _l.length); j++) {
                _loop_2(j);
            }
            if (_isScatterPolarRef.current) {
                // Render category labels for all series at once to avoid overlap
                var allSeriesData = _points.current.map(function (s) { return ({
                    data: s.data
                        .filter(function (pt) { return typeof pt.x === 'number' && typeof pt.y === 'number'; })
                        .map(function (pt) { return ({ x: pt.x, y: pt.y, text: pt.text }); }),
                }); });
                pointsForSeries.push.apply(pointsForSeries, renderScatterPolarCategoryLabels({
                    allSeriesData: allSeriesData,
                    xAxisScale: _xAxisScale.current,
                    yAxisScale: _yAxisScale.current,
                    className: classNames.markerLabel || '',
                    maybeLineOptions: ((_5 = (_4 = _points.current) === null || _4 === void 0 ? void 0 : _4[i]) === null || _5 === void 0 ? void 0 : _5.lineOptions)
                        ? {
                            // eslint-disable-next-line @typescript-eslint/no-explicit-any
                            originXOffset: (_7 = ((_6 = _points.current) === null || _6 === void 0 ? void 0 : _6[i]).lineOptions) === null || _7 === void 0 ? void 0 : _7.originXOffset,
                        }
                        : undefined,
                }));
            }
            series.push(React.createElement("g", { key: "series_".concat(i), role: "region", "aria-label": "".concat(legendVal, ", series ").concat(i + 1, " of ").concat((_8 = _points.current) === null || _8 === void 0 ? void 0 : _8.length, " with ").concat((_11 = (_10 = (_9 = _points.current) === null || _9 === void 0 ? void 0 : _9[i]) === null || _10 === void 0 ? void 0 : _10.data) === null || _11 === void 0 ? void 0 : _11.length, " data points.") }, pointsForSeries));
        };
        for (var i = ((_b = _points.current) === null || _b === void 0 ? void 0 : _b.length) - 1; i >= 0; i--) {
            _loop_1(i);
        }
        // Removing un wanted tooltip div from DOM, when prop not provided.
        if (!props.showXAxisLablesTooltip) {
            try {
                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) {
            var xAxisElement = d3Select(xElement).call(_xAxisScale.current);
            try {
                document.getElementById(_tooltipId) && document.getElementById(_tooltipId).remove();
                // eslint-disable-next-line no-empty
            }
            catch (e) { }
            var tooltipProps = {
                tooltipCls: classNames.tooltip,
                id: _tooltipId,
                xAxis: xAxisElement,
            };
            xAxisElement && tooltipOfAxislabels(tooltipProps);
        }
        return series;
    }, [
        _xAxisScale,
        _yAxisScale,
        props.data.scatterChartData,
        props.showXAxisLablesTooltip,
        props.wrapXAxisLables,
        _circleId,
        _getAriaLabel,
        _getPointFill,
        _handleFocus,
        _handleHover,
        _handleMouseOut,
        _legendHighlighted,
        _noLegendHighlighted,
        _seriesId,
        _tooltipId,
        _xAxisType,
        activePoint,
        isSelectedLegend,
        selectedLegendPoints,
        classNames,
    ]);
    var _initializeScatterChartData = React.useCallback(function (xScale, yScale, containerHeight, containerWidth, xElement) {
        _xAxisScale.current = xScale;
        _yAxisScale.current = yScale;
        _isScatterPolarRef.current = isScatterPolarSeries(_points.current);
        renderSeries.current = _createPlot(xElement, containerHeight);
    }, [renderSeries, _xAxisScale, _yAxisScale, _createPlot]);
    /**
     * Screen readers announce an element as clickable if the onClick attribute is set.
     * This function sets the attribute only when a click event handler is provided.*/
    function _getClickHandler(func) {
        if (func) {
            return {
                onClick: func,
            };
        }
        return {};
    }
    function _isChartEmpty() {
        return !(props.data &&
            props.data.scatterChartData &&
            props.data.scatterChartData.length > 0 &&
            props.data.scatterChartData.filter(function (item) { return item.data.length; }).length > 0);
    }
    function _closeCallout() {
        setCalloutVisible(false);
    }
    function _getNumericMinMaxOfY(points, yAxisType) {
        // eslint-disable-next-line @typescript-eslint/no-shadow
        var _a = findNumericMinMaxOfY(points, yAxisType), startValue = _a.startValue, endValue = _a.endValue;
        var yPadding = 0;
        yPadding = (endValue - startValue) * 0.1;
        return {
            startValue: startValue - yPadding,
            endValue: endValue + yPadding,
        };
    }
    var _getMinMaxofXAxis = React.useCallback(function (
    // eslint-disable-next-line  @typescript-eslint/no-explicit-any
    points, 
    // eslint-disable-next-line  @typescript-eslint/no-explicit-any
    yAxisType) { return _getNumericMinMaxOfY(points, yAxisType); }, []);
    var legendProps = props.legendProps, tickValues = props.tickValues, tickFormat = props.tickFormat;
    _points.current = _injectIndexPropertyInScatterChartData(props.data.scatterChartData);
    var points = _points.current;
    if (legendProps && !!legendProps.canSelectMultipleLegends) {
        points = selectedLegendPoints.length >= 1 ? selectedLegendPoints : _points.current;
        _calloutPoints = calloutData(points);
    }
    var legendBars = null;
    // reduce computation cost by only creating legendBars
    // if when hideLegend is false.
    // NOTE: they are rendered only when hideLegend is false in CartesianChart.
    if (!props.hideLegend) {
        legendBars = _createLegends(_points.current); // ToDo: Memoize legends to improve performance.
    }
    var calloutProps = __assign({ isCalloutVisible: isCalloutVisible, directionalHint: DirectionalHint.topAutoEdge, YValueHover: YValueHover, hoverXValue: hoverXValue, id: "toolTip".concat(_uniqueCallOutID.current), target: refSelected, isBeakVisible: false, gapSpace: 15, onDismiss: _closeCallout, preventDismissOnEvent: function () { return true; }, hidden: !(!props.hideTooltip && isCalloutVisible), descriptionMessage: props.getCalloutDescriptionMessage && stackCalloutProps
            ? props.getCalloutDescriptionMessage(stackCalloutProps)
            : undefined, 'data-is-focusable': true, xAxisCalloutAccessibilityData: _xAxisCalloutAccessibilityData }, props.calloutProps);
    var tickParams = {
        tickValues: tickValues,
        tickFormat: tickFormat,
    };
    var xAxisLabels = _points.current
        .map(function (point) { return point.data.map(function (dp) { return dp.x; }); })
        .flat();
    _xAxisLabels = Array.from(new Set(xAxisLabels));
    return !_isChartEmpty() ? (React.createElement(CartesianChart, __assign({}, props, { ref: cartesianChartRef, chartTitle: props.data.chartTitle, isCalloutForStack: true, points: points, chartType: ChartTypes.ScatterChart, calloutProps: calloutProps, tickParams: tickParams, legendBars: legendBars, getmargins: _getMargins, getMinMaxOfYAxis: _getMinMaxofXAxis, getDomainNRangeValues: getDomainNRangeValuesScatterChart, createYAxis: createNumericYAxis, createStringYAxis: createStringYAxis, getGraphData: _initializeScatterChartData, xAxisType: _xAxisType, onChartMouseLeave: _handleChartMouseLeave, enableFirstRenderOptimization: _firstRenderOptimization, datasetForXAxisDomain: _xAxisLabels, componentRef: cartesianChartRef }, (_isScatterPolarRef.current ? { yMaxValue: 1, yMinValue: -1 } : {}), { 
        /* eslint-disable react/jsx-no-bind */
        // eslint-disable-next-line react/no-children-prop
        children: function (childProps) {
            _xAxisScale.current = childProps.xScale;
            _yAxisScale.current = childProps.yScalePrimary;
            return (React.createElement(React.Fragment, null,
                React.createElement("g", null,
                    React.createElement("line", { x1: 0, y1: 0, x2: 0, y2: childProps.containerHeight, stroke: '#323130', id: _verticalLine, visibility: 'hidden', strokeDasharray: '5,5' }),
                    React.createElement("g", null, renderSeries.current))));
        } }))) : (React.createElement("div", { id: _emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
});
ScatterChartBase.displayName = 'ScatterChart';
//# sourceMappingURL=ScatterChart.base.js.map