import { __assign, __extends, __spreadArray } from "tslib";
import * as React from 'react';
import { select as d3Select, pointer } from 'd3-selection';
import { bisector } from 'd3-array';
import { Legends } from '../Legends/index';
import { line as d3Line, curveLinear as d3curveLinear } from 'd3-shape';
import { max as d3Max, min as d3Min } from 'd3-array';
import { classNamesFunction, getId, find, memoizeFunction, getRTL, initializeComponentRef, } from '@fluentui/react/lib/Utilities';
import { CartesianChart, } from '../../index';
import { DirectionalHint } from '@fluentui/react/lib/Callout';
import { EventsAnnotation } from './eventAnnotation/EventAnnotation';
import { calloutData, ChartTypes, getXAxisType, XAxisTypes, tooltipOfXAxislabels, Points, pointTypes, getTypeOfAxis, getNextColor, getColorFromToken, findNumericMinMaxOfY, createNumericYAxis, domainRangeOfDateForAreaLineVerticalBarChart, domainRangeOfNumericForAreaChart, createStringYAxis, formatDate, areArraysEqual, } from '../../utilities/index';
import { toImage } from '../../utilities/image-export-utils';
var getClassNames = classNamesFunction();
var PointSize;
(function (PointSize) {
    PointSize[PointSize["hoverSize"] = 11] = "hoverSize";
    PointSize[PointSize["invisibleSize"] = 1] = "invisibleSize";
})(PointSize || (PointSize = {}));
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var bisect = bisector(function (d) { return d.x; }).left;
var DEFAULT_LINE_STROKE_SIZE = 4;
// The given shape of a icon must be 2.5 times bigger than line width (known as stroke width)
var PATH_MULTIPLY_SIZE = 2.5;
/**
 *
 * @param x units from origin
 * @param y units from origin
 * @param w is the legnth of the each side of a shape
 * @param index index to get the shape path
 */
var _getPointPath = function (x, y, w, index) {
    var allPointPaths = [
        // circle path
        "M".concat(x - w / 2, " ").concat(y, "\n     A").concat(w / 2, " ").concat(w / 2, " 0 1 0 ").concat(x + w / 2, " ").concat(y, "\n     M").concat(x - w / 2, " ").concat(y, "\n     A ").concat(w / 2, " ").concat(w / 2, " 0 1 1 ").concat(x + w / 2, " ").concat(y, "\n     "),
        //square
        "M".concat(x - w / 2, " ").concat(y - w / 2, "\n     L").concat(x + w / 2, " ").concat(y - w / 2, "\n     L").concat(x + w / 2, " ").concat(y + w / 2, "\n     L").concat(x - w / 2, " ").concat(y + w / 2, "\n     Z"),
        //triangle
        "M".concat(x - w / 2, " ").concat(y - 0.2886 * w, "\n     H ").concat(x + w / 2, "\n     L").concat(x, " ").concat(y + 0.5774 * w, " Z"),
        //diamond
        "M".concat(x, " ").concat(y - w / 2, "\n     L").concat(x + w / 2, " ").concat(y, "\n     L").concat(x, " ").concat(y + w / 2, "\n     L").concat(x - w / 2, " ").concat(y, "\n     Z"),
        //pyramid
        "M".concat(x, " ").concat(y - 0.5774 * w, "\n     L").concat(x + w / 2, " ").concat(y + 0.2886 * w, "\n     L").concat(x - w / 2, " ").concat(y + 0.2886 * w, " Z"),
        //hexagon
        "M".concat(x - 0.5 * w, " ").concat(y - 0.866 * w, "\n     L").concat(x + 0.5 * w, " ").concat(y - 0.866 * w, "\n     L").concat(x + w, " ").concat(y, "\n     L").concat(x + 0.5 * w, " ").concat(y + 0.866 * w, "\n     L").concat(x - 0.5 * w, " ").concat(y + 0.866 * w, "\n     L").concat(x - w, " ").concat(y, "\n     Z"),
        //pentagon
        "M".concat(x, " ").concat(y - 0.851 * w, "\n     L").concat(x + 0.6884 * w, " ").concat(y - 0.2633 * w, "\n     L").concat(x + 0.5001 * w, " ").concat(y + 0.6884 * w, "\n     L").concat(x - 0.5001 * w, " ").concat(y + 0.6884 * w, "\n     L").concat(x - 0.6884 * w, " ").concat(y - 0.2633 * w, "\n     Z"),
        //octagon
        "M".concat(x - 0.5001 * w, " ").concat(y - 1.207 * w, "\n     L").concat(x + 0.5001 * w, " ").concat(y - 1.207 * w, "\n     L").concat(x + 1.207 * w, " ").concat(y - 0.5001 * w, "\n     L").concat(x + 1.207 * w, " ").concat(y + 0.5001 * w, "\n     L").concat(x + 0.5001 * w, " ").concat(y + 1.207 * w, "\n     L").concat(x - 0.5001 * w, " ").concat(y + 1.207 * w, "\n     L").concat(x - 1.207 * w, " ").concat(y + 0.5001 * w, "\n     L").concat(x - 1.207 * w, " ").concat(y - 0.5001 * w, "\n     Z"),
    ];
    return allPointPaths[index];
};
var LineChartBase = /** @class */ (function (_super) {
    __extends(LineChartBase, _super);
    function LineChartBase(props) {
        var _a, _b, _c, _d, _e;
        var _this_1 = _super.call(this, props) || this;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this_1._xAxisScale = '';
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        _this_1._yAxisScale = '';
        _this_1.eventLabelHeight = 36;
        _this_1._isRTL = getRTL();
        _this_1._xMin = Number.NEGATIVE_INFINITY;
        _this_1._yMin = Number.NEGATIVE_INFINITY;
        _this_1._xMax = Number.POSITIVE_INFINITY;
        _this_1._xPadding = 0;
        _this_1._yPadding = 0;
        _this_1.toImage = function (opts) {
            var _a, _b;
            return toImage((_a = _this_1._cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer, (_b = _this_1._legendsRef.current) === null || _b === void 0 ? void 0 : _b.toSVG, _this_1._isRTL, opts);
        };
        _this_1._getDomainNRangeValues = function (points, margins, width, chartType, isRTL, xAxisType, barWidth, tickValues, shiftX) {
            var domainNRangeValue;
            if (_this_1.props.lineMode === 'scatter' && xAxisType === XAxisTypes.NumericAxis) {
                domainNRangeValue = _this_1._getDomainNRangeValuesWithPadding(points, margins, width, isRTL);
            }
            else if (xAxisType === XAxisTypes.NumericAxis) {
                domainNRangeValue = domainRangeOfNumericForAreaChart(points, margins, width, isRTL);
            }
            else if (xAxisType === XAxisTypes.DateAxis) {
                domainNRangeValue = domainRangeOfDateForAreaLineVerticalBarChart(points, margins, width, isRTL, tickValues, chartType, barWidth);
            }
            else {
                domainNRangeValue = { dStartValue: 0, dEndValue: 0, rStartValue: 0, rEndValue: 0 };
            }
            return domainNRangeValue;
        };
        _this_1._injectIndexPropertyInLineChartData = function (lineChartData, isFilterSelectedLegends) {
            if (isFilterSelectedLegends === void 0) { isFilterSelectedLegends = false; }
            var _a = _this_1.props.allowMultipleShapesForPoints, allowMultipleShapesForPoints = _a === void 0 ? false : _a;
            // Apply filter only if isPropChange is true
            var filteredData = isFilterSelectedLegends
                ? lineChartData === null || lineChartData === void 0 ? void 0 : lineChartData.filter(function (item) {
                    var _a, _b, _c;
                    return ((_b = (_a = _this_1.props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegends) === null || _b === void 0 ? void 0 : _b.includes(item.legend)) ||
                        ((_c = _this_1.props.legendProps) === null || _c === void 0 ? void 0 : _c.selectedLegend) === item.legend;
                })
                : lineChartData;
            return filteredData
                ? filteredData.map(function (item, index) {
                    var _a, _b;
                    var color;
                    // isInverted property is applicable to v8 themes only
                    if (typeof item.color === 'undefined') {
                        color = getNextColor(index, 0, (_a = _this_1.props.theme) === null || _a === void 0 ? void 0 : _a.isInverted);
                    }
                    else {
                        color = getColorFromToken(item.color, (_b = _this_1.props.theme) === null || _b === void 0 ? void 0 : _b.isInverted);
                    }
                    return __assign(__assign({}, item), { index: allowMultipleShapesForPoints ? index : -1, color: color });
                })
                : [];
        };
        _this_1._getCustomizedCallout = function () {
            return _this_1.props.onRenderCalloutPerStack
                ? _this_1.props.onRenderCalloutPerStack(_this_1.state.stackCalloutProps)
                : _this_1.props.onRenderCalloutPerDataPoint
                    ? _this_1.props.onRenderCalloutPerDataPoint(_this_1.state.dataPointCalloutProps)
                    : null;
        };
        _this_1._getNumericMinMaxOfY = function (points) {
            // eslint-disable-next-line @typescript-eslint/no-shadow
            var _a = findNumericMinMaxOfY(points), startValue = _a.startValue, endValue = _a.endValue;
            _this_1._yMin = startValue;
            if (_this_1.props.lineMode === 'scatter') {
                _this_1._yPadding = (endValue - startValue) * 0.1;
            }
            return {
                startValue: startValue - _this_1._yPadding,
                endValue: endValue + _this_1._yPadding,
            };
        };
        _this_1._getMargins = function (margins) {
            _this_1.margins = margins;
        };
        _this_1._initializeLineChartData = function (xScale, yScale, containerHeight, containerWidth, xElement) {
            _this_1._xAxisScale = xScale;
            _this_1._yAxisScale = yScale;
            _this_1._renderedColorFillBars = _this_1.props.colorFillBars ? _this_1._createColorFillBars(containerHeight) : [];
            _this_1.lines = _this_1._createLines(xElement, containerHeight);
        };
        _this_1._handleSingleLegendSelectionAction = function (lineChartItem) {
            if (_this_1.state.selectedLegend === lineChartItem.legend) {
                _this_1.setState({ selectedLegend: '' });
                _this_1._handleLegendClick(lineChartItem, null);
            }
            else {
                _this_1.setState({ selectedLegend: lineChartItem.legend });
                _this_1._handleLegendClick(lineChartItem, lineChartItem.legend);
            }
        };
        _this_1._onHoverCardHide = function () {
            _this_1.setState({
                selectedLegendPoints: [],
                selectedColorBarLegend: [],
                isSelectedLegend: false,
            });
        };
        _this_1._closeCallout = function () {
            _this_1.setState({
                isCalloutVisible: false,
            });
        };
        _this_1._getBoxWidthOfShape = function (pointId, pointIndex, isLastPoint) {
            var _a = _this_1.props, _b = _a.allowMultipleShapesForPoints, allowMultipleShapesForPoints = _b === void 0 ? false : _b, _c = _a.strokeWidth, strokeWidth = _c === void 0 ? DEFAULT_LINE_STROKE_SIZE : _c;
            var activePoint = _this_1.state.activePoint;
            if (allowMultipleShapesForPoints) {
                if (activePoint === pointId) {
                    return PointSize.hoverSize;
                }
                else if (pointIndex === 1 || isLastPoint) {
                    return strokeWidth * PATH_MULTIPLY_SIZE;
                }
                else {
                    return PointSize.invisibleSize;
                }
            }
            else {
                if (activePoint === pointId) {
                    return PointSize.hoverSize;
                }
                else {
                    return PointSize.invisibleSize;
                }
            }
        };
        _this_1._getPath = function (xPos, yPos, pointId, pointIndex, isLastPoint, pointOftheLine) {
            var _a = _this_1.props.allowMultipleShapesForPoints, allowMultipleShapesForPoints = _a === void 0 ? false : _a;
            var w = _this_1._getBoxWidthOfShape(pointId, pointIndex, isLastPoint);
            var index = allowMultipleShapesForPoints ? pointOftheLine % Object.keys(pointTypes).length : 0;
            var widthRatio = pointTypes[index].widthRatio;
            w = widthRatio > 1 ? w / widthRatio : w;
            return _getPointPath(xPos, yPos, w, index);
        };
        _this_1._getPointFill = function (lineColor, pointId, pointIndex, isLastPoint) {
            var activePoint = _this_1.state.activePoint;
            var _a = _this_1.props, theme = _a.theme, _b = _a.allowMultipleShapesForPoints, allowMultipleShapesForPoints = _b === void 0 ? false : _b;
            if (allowMultipleShapesForPoints) {
                if (pointIndex === 1 || isLastPoint) {
                    if (activePoint === pointId) {
                        return theme.semanticColors.bodyBackground;
                    }
                    else {
                        return lineColor;
                    }
                }
                else {
                    if (activePoint === pointId) {
                        return theme.semanticColors.bodyBackground;
                    }
                    else {
                        return lineColor;
                    }
                }
            }
            else {
                if (activePoint === pointId) {
                    return theme.semanticColors.bodyBackground;
                }
                else {
                    return lineColor;
                }
            }
        };
        _this_1._createColorFillBars = function (containerHeight) {
            var _a;
            var colorFillBars = [];
            if (_this_1.state.isSelectedLegend) {
                _this_1._colorFillBars = _this_1.state.selectedColorBarLegend;
            }
            else {
                _this_1._colorFillBars = _this_1.props.colorFillBars;
            }
            var yMinMaxValues = findNumericMinMaxOfY(_this_1._points);
            var FILL_Y_PADDING = 3;
            for (var i = 0; i < _this_1._colorFillBars.length; i++) {
                var colorFillBar = _this_1._colorFillBars[i];
                var legend = typeof colorFillBar.legend === 'string' ? colorFillBar.legend.replace(/\W/g, '') : '';
                var colorFillBarId = getId(legend);
                // isInverted property is applicable to v8 themes only
                var color = getColorFromToken(colorFillBar.color, (_a = _this_1.props.theme) === null || _a === void 0 ? void 0 : _a.isInverted);
                if (colorFillBar.applyPattern) {
                    // Using a pattern element because CSS was unable to render diagonal stripes for rect elements
                    colorFillBars.push(_this_1._getStripePattern(color, i));
                }
                for (var j = 0; j < colorFillBar.data.length; j++) {
                    var startX = colorFillBar.data[j].startX;
                    var endX = colorFillBar.data[j].endX;
                    var opacity = _this_1._legendHighlighted(colorFillBar.legend) || _this_1._noLegendHighlighted() || _this_1.state.isSelectedLegend
                        ? _this_1._getColorFillBarOpacity(colorFillBar)
                        : 0.1;
                    colorFillBars.push(React.createElement("rect", { fill: colorFillBar.applyPattern ? "url(#".concat(_this_1._colorFillBarPatternId, "_").concat(i, ")") : color, fillOpacity: opacity, x: _this_1._isRTL ? _this_1._xAxisScale(endX) : _this_1._xAxisScale(startX), y: _this_1._yAxisScale(yMinMaxValues.endValue) - FILL_Y_PADDING, width: Math.abs(_this_1._xAxisScale(endX) - _this_1._xAxisScale(startX)), height: _this_1._yAxisScale(_this_1.props.yMinValue || 0) - _this_1._yAxisScale(yMinMaxValues.endValue) + FILL_Y_PADDING, key: "".concat(colorFillBarId).concat(j) }));
                }
            }
            return colorFillBars;
        };
        _this_1._getStripePattern = function (color, id) {
            // This describes a tile pattern that resembles diagonal stripes
            // For more information: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
            var stripePath = 'M-4,4 l8,-8 M0,16 l16,-16 M12,20 l8,-8';
            return (React.createElement("pattern", { id: "".concat(_this_1._colorFillBarPatternId, "_").concat(id), width: 16, height: 16, key: "".concat(_this_1._colorFillBarPatternId, "_").concat(id), patternUnits: 'userSpaceOnUse' },
                React.createElement("path", { d: stripePath, stroke: color, strokeWidth: 1.25 })));
        };
        _this_1._checkInGap = function (pointIndex, gaps, currentGapIndex) {
            var gapIndex = currentGapIndex;
            var isInGap = false;
            while (gapIndex < gaps.length && pointIndex > gaps[gapIndex].endIndex) {
                gapIndex++;
            }
            if (gapIndex < gaps.length && pointIndex > gaps[gapIndex].startIndex && pointIndex <= gaps[gapIndex].endIndex) {
                isInGap = true;
            }
            return { isInGap: isInGap, gapIndex: gapIndex };
        };
        _this_1._onMouseOverLargeDataset = function (linenumber, lineHeight, mouseEvent) {
            mouseEvent.persist();
            var data = _this_1.props.data;
            var lineChartData = data.lineChartData;
            // This will get the value of the X when mouse is on the chart
            var xOffset = _this_1._xAxisScale.invert(pointer(mouseEvent)[0], document.getElementById(_this_1._rectId));
            var i = bisect(lineChartData[linenumber].data, xOffset);
            var d0 = lineChartData[linenumber].data[i - 1];
            var d1 = lineChartData[linenumber].data[i];
            var axisType = null;
            var xPointToHighlight = null;
            var index = null;
            if (d0 === undefined && d1 !== undefined) {
                xPointToHighlight = d1.x;
                index = i;
            }
            else if (d0 !== undefined && d1 === undefined) {
                xPointToHighlight = d0.x;
                index = i - 1;
            }
            else {
                axisType = getTypeOfAxis(lineChartData[linenumber].data[0].x, true);
                var x0 = void 0;
                var point0 = void 0;
                var point1 = void 0;
                switch (axisType) {
                    case XAxisTypes.DateAxis:
                        x0 = new Date(xOffset).getTime();
                        point0 = d0.x.getTime();
                        point1 = d1.x.getTime();
                        xPointToHighlight = 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;
                        xPointToHighlight = 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[linenumber].data[index], xAxisCalloutData = _a.xAxisCalloutData, xAxisCalloutAccessibilityData = _a.xAxisCalloutAccessibilityData;
            var formattedDate = xPointToHighlight instanceof Date ? formatDate(xPointToHighlight, _this_1.props.useUTC) : xPointToHighlight;
            var modifiedXVal = xPointToHighlight instanceof Date ? xPointToHighlight.getTime() : xPointToHighlight;
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            var found = find(_this_1._calloutPoints, function (element) {
                return element.x === modifiedXVal;
            });
            var pointToHighlight = lineChartData[linenumber].data[index];
            var pointToHighlightUpdated = _this_1.state.nearestCircleToHighlight === null ||
                (_this_1.state.nearestCircleToHighlight !== null &&
                    pointToHighlight !== null &&
                    (_this_1.state.nearestCircleToHighlight.x !== pointToHighlight.x ||
                        _this_1.state.nearestCircleToHighlight.y !== pointToHighlight.y));
            // if no points need to be called out then don't show vertical line and callout card
            if (found && pointToHighlightUpdated) {
                _this_1._uniqueCallOutID = "#".concat(_this_1._staticHighlightCircle, "_").concat(linenumber);
                d3Select("#".concat(_this_1._staticHighlightCircle, "_").concat(linenumber))
                    .attr('cx', "".concat(_this_1._xAxisScale(pointToHighlight.x)))
                    .attr('cy', "".concat(_this_1._yAxisScale(pointToHighlight.y)))
                    .attr('visibility', 'visibility');
                d3Select("#".concat(_this_1._verticalLine))
                    .attr('transform', function () { return "translate(".concat(_this_1._xAxisScale(pointToHighlight.x), ", ").concat(_this_1._yAxisScale(pointToHighlight.y), ")"); })
                    .attr('visibility', 'visibility')
                    .attr('y2', "".concat(lineHeight - _this_1._yAxisScale(pointToHighlight.y)));
                _this_1.setState({
                    nearestCircleToHighlight: pointToHighlight,
                    isCalloutVisible: true,
                    refSelected: "#".concat(_this_1._staticHighlightCircle, "_").concat(linenumber),
                    stackCalloutProps: found,
                    YValueHover: found.values,
                    dataPointCalloutProps: found,
                    hoverXValue: xAxisCalloutData ? xAxisCalloutData : formattedDate,
                    xAxisCalloutAccessibilityData: xAxisCalloutAccessibilityData,
                    activePoint: '',
                    activeLine: linenumber,
                });
            }
            if (!found) {
                _this_1.setState({
                    isCalloutVisible: false,
                    nearestCircleToHighlight: pointToHighlight,
                    activePoint: '',
                    activeLine: linenumber,
                });
            }
        };
        _this_1._handleFocus = function (lineId, x, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData) {
            _this_1._uniqueCallOutID = circleId;
            var formattedData = x instanceof Date ? formatDate(x, _this_1.props.useUTC) : x;
            var xVal = x instanceof Date ? x.getTime() : x;
            var found = find(_this_1._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) {
                var _this_2 = _this_1;
                d3Select("#".concat(_this_1._verticalLine))
                    .attr('transform', function () { return "translate(".concat(_this_2._xAxisScale(x), ", 0)"); })
                    .attr('visibility', 'visibility');
                _this_1._refArray.forEach(function (obj) {
                    if (obj.index === lineId) {
                        _this_1.setState({
                            isCalloutVisible: true,
                            refSelected: obj.refElement,
                            hoverXValue: xAxisCalloutData ? xAxisCalloutData : '' + formattedData,
                            YValueHover: found.values,
                            stackCalloutProps: found,
                            dataPointCalloutProps: found,
                            activePoint: circleId,
                            xAxisCalloutAccessibilityData: xAxisCalloutAccessibilityData,
                        });
                    }
                });
            }
            else {
                _this_1.setState({
                    activePoint: circleId,
                });
            }
        };
        _this_1._handleHover = function (x, y, lineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData, mouseEvent) {
            mouseEvent.persist();
            var formattedData = x instanceof Date ? formatDate(x, _this_1.props.useUTC) : x;
            var xVal = x instanceof Date ? x.getTime() : x;
            var _this = _this_1;
            var found = find(_this_1._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(_this_1._verticalLine))
                    .attr('transform', function () { return "translate(".concat(_this._xAxisScale(x), ", ").concat(_this._yAxisScale(y), ")"); })
                    .attr('visibility', 'visibility')
                    .attr('y2', "".concat(lineHeight - _this._yAxisScale(y)));
                if (_this_1._uniqueCallOutID !== circleId) {
                    _this_1._uniqueCallOutID = circleId;
                    _this_1.setState({
                        isCalloutVisible: true,
                        refSelected: "#".concat(circleId),
                        hoverXValue: xAxisCalloutData ? xAxisCalloutData : '' + formattedData,
                        YValueHover: found.values,
                        stackCalloutProps: found,
                        dataPointCalloutProps: found,
                        activePoint: circleId,
                        xAxisCalloutAccessibilityData: xAxisCalloutAccessibilityData,
                        nearestCircleToHighlight: null,
                        activeLine: null,
                    });
                }
            }
            else {
                _this_1.setState({
                    activePoint: circleId,
                    nearestCircleToHighlight: null,
                    activeLine: null,
                });
            }
        };
        /**
         * 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.
         */
        _this_1._getClickHandler = function (func) {
            if (func) {
                return {
                    onClick: func,
                };
            }
            return {};
        };
        _this_1._handleMouseOut = function () {
            d3Select("#".concat(_this_1._verticalLine)).attr('visibility', 'hidden');
        };
        _this_1._handleChartMouseLeave = function () {
            _this_1._uniqueCallOutID = null;
            _this_1.setState({
                isCalloutVisible: false,
                activePoint: '',
                activeLine: null,
            });
        };
        _this_1._handleLegendClick = function (lineChartItem, selectedLegend) {
            if (lineChartItem.onLegendClick) {
                lineChartItem.onLegendClick(selectedLegend);
            }
        };
        _this_1._handleMultipleLineLegendSelectionAction = function (selectedLine) {
            var selectedLineIndex = _this_1.state.selectedLegendPoints.reduce(function (acc, line, index) {
                if (acc > -1 || line.legend !== selectedLine.legend) {
                    return acc;
                }
                else {
                    return index;
                }
            }, -1);
            var selectedLines;
            if (selectedLineIndex === -1) {
                selectedLines = __spreadArray(__spreadArray([], _this_1.state.selectedLegendPoints, true), [selectedLine], false);
            }
            else {
                selectedLines = _this_1.state.selectedLegendPoints
                    .slice(0, selectedLineIndex)
                    .concat(_this_1.state.selectedLegendPoints.slice(selectedLineIndex + 1));
            }
            var areAllLineLegendsSelected = _this_1.props.data && selectedLines.length === _this_1.props.data.lineChartData.length;
            if (areAllLineLegendsSelected &&
                ((_this_1.props.colorFillBars && _this_1.props.colorFillBars.length === _this_1.state.selectedColorBarLegend.length) ||
                    !_this_1.props.colorFillBars)) {
                // Clear all legends if all legends including color fill bar legends are selected
                // Or clear all legends if all legends are selected and there are no color fill bars
                _this_1._clearMultipleLegendSelections();
            }
            else if (!selectedLines.length && !_this_1.state.selectedColorBarLegend.length) {
                // Clear all legends if no legends including color fill bar legends are selected
                _this_1._clearMultipleLegendSelections();
            }
            else {
                // Otherwise, set state when one or more legends are selected, including color fill bar legends
                _this_1.setState({
                    selectedLegendPoints: selectedLines,
                    isSelectedLegend: true,
                });
            }
            var selectedLegendTitlesToPass = selectedLines.map(function (line) { return line.legend; });
            _this_1._handleLegendClick(selectedLine, selectedLegendTitlesToPass);
        };
        _this_1._handleMultipleColorFillBarLegendSelectionAction = function (selectedColorFillBar) {
            var selectedColorFillBarIndex = _this_1.state.selectedColorBarLegend.reduce(function (acc, colorFillBar, index) {
                if (acc > -1 || colorFillBar.legend !== selectedColorFillBar.legend) {
                    return acc;
                }
                else {
                    return index;
                }
            }, -1);
            var selectedColorFillBars;
            if (selectedColorFillBarIndex === -1) {
                selectedColorFillBars = __spreadArray(__spreadArray([], _this_1.state.selectedColorBarLegend, true), [selectedColorFillBar], false);
            }
            else {
                selectedColorFillBars = _this_1.state.selectedColorBarLegend
                    .slice(0, selectedColorFillBarIndex)
                    .concat(_this_1.state.selectedColorBarLegend.slice(selectedColorFillBarIndex + 1));
            }
            var areAllColorFillBarLegendsSelected = selectedColorFillBars.length === (_this_1.props.colorFillBars && _this_1.props.colorFillBars.length);
            if (areAllColorFillBarLegendsSelected &&
                ((_this_1.props.data && _this_1.props.data.lineChartData.length === _this_1.state.selectedLegendPoints.length) ||
                    !_this_1.props.data)) {
                // Clear all legends if all legends, including line legends, are selected
                // Or clear all legends if all legends are selected and there is no line data
                _this_1._clearMultipleLegendSelections();
            }
            else if (!selectedColorFillBars.length && !_this_1.state.selectedLegendPoints.length) {
                // Clear all legends if no legends are selected, including line legends
                _this_1._clearMultipleLegendSelections();
            }
            else {
                // set state when one or more legends are selected, including line legends
                _this_1.setState({
                    selectedColorBarLegend: selectedColorFillBars,
                    isSelectedLegend: true,
                });
            }
            var selectedLegendTitlesToPass = selectedColorFillBars.map(function (colorFillBar) { return colorFillBar.legend; });
            _this_1._handleLegendClick(selectedColorFillBar, selectedLegendTitlesToPass);
        };
        _this_1._clearMultipleLegendSelections = function () {
            _this_1.setState({
                selectedColorBarLegend: [],
                selectedLegendPoints: [],
                isSelectedLegend: 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_1._legendHighlighted = function (legend) {
            return (_this_1.state.selectedLegend === legend || (_this_1.state.selectedLegend === '' && _this_1.state.activeLegend === legend));
        };
        /**
         * This function checks if none of the legends is selected or hovered.
         */
        _this_1._noLegendHighlighted = function () {
            return _this_1.state.selectedLegend === '' && _this_1.state.activeLegend === '';
        };
        _this_1._getColorFillBarOpacity = function (colorFillBar) {
            return colorFillBar.applyPattern ? 1 : 0.4;
        };
        _this_1._getAriaLabel = function (lineIndex, pointIndex) {
            var _a;
            var line = _this_1._points[lineIndex];
            var point = line.data[pointIndex];
            var formattedDate = point.x instanceof Date ? formatDate(point.x, _this_1.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, ".");
        };
        _this_1._getDomainNRangeValuesWithPadding = function (points, margins, width, isRTL) {
            _this_1._xMin = d3Min(points, function (point) {
                return d3Min(point.data, function (item) { return item.x; });
            });
            _this_1._xMax = d3Max(points, function (point) {
                return d3Max(point.data, function (item) {
                    return item.x;
                });
            });
            if (_this_1.props.lineMode === 'scatter') {
                _this_1._xPadding = (_this_1._xMax - _this_1._xMin) * 0.1;
            }
            var rStartValue = margins.left;
            var rEndValue = width - margins.right;
            return isRTL
                ? {
                    dStartValue: _this_1._xMax + _this_1._xPadding,
                    dEndValue: _this_1._xMin - _this_1._xPadding,
                    rStartValue: rStartValue,
                    rEndValue: rEndValue,
                }
                : {
                    dStartValue: _this_1._xMin - _this_1._xPadding,
                    dEndValue: _this_1._xMax + _this_1._xPadding,
                    rStartValue: rStartValue,
                    rEndValue: rEndValue,
                };
        };
        _this_1._getChartTitle = function () {
            var _a = _this_1.props.data, chartTitle = _a.chartTitle, lineChartData = _a.lineChartData;
            return (chartTitle ? "".concat(chartTitle, ". ") : '') + "Line chart with ".concat((lineChartData === null || lineChartData === void 0 ? void 0 : lineChartData.length) || 0, " lines. ");
        };
        initializeComponentRef(_this_1);
        _this_1.state = {
            hoverXValue: '',
            activeLegend: '',
            YValueHover: [],
            refSelected: '',
            selectedLegend: (_b = (_a = props.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegend) !== null && _b !== void 0 ? _b : '',
            isCalloutVisible: false,
            selectedLegendPoints: _this_1._injectIndexPropertyInLineChartData(_this_1.props.data.lineChartData, true),
            selectedColorBarLegend: [],
            isSelectedLegend: ((_e = (_d = (_c = _this_1.props.legendProps) === null || _c === void 0 ? void 0 : _c.selectedLegends) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0) > 0,
            activePoint: '',
            nearestCircleToHighlight: null,
            activeLine: null,
        };
        _this_1._refArray = [];
        _this_1._points = _this_1._injectIndexPropertyInLineChartData(_this_1.props.data.lineChartData);
        _this_1._colorFillBars = [];
        _this_1._calloutPoints = calloutData(_this_1._points) || [];
        _this_1._circleId = getId('circle');
        _this_1._lineId = getId('lineID');
        _this_1._borderId = getId('borderID');
        _this_1._verticalLine = getId('verticalLine');
        _this_1._colorFillBarPatternId = getId('colorFillBarPattern');
        _this_1._tooltipId = getId('LineChartTooltipId_');
        _this_1._rectId = getId('containerRectLD');
        _this_1._staticHighlightCircle = getId('staticHighlightCircle');
        _this_1._createLegendsMemoized = memoizeFunction(function (data) { return _this_1._createLegends(data); });
        _this_1._firstRenderOptimization = true;
        _this_1._emptyChartId = getId('_LineChart_empty');
        _this_1._cartesianChartRef = React.createRef();
        _this_1._legendsRef = React.createRef();
        props.eventAnnotationProps &&
            props.eventAnnotationProps.labelHeight &&
            (_this_1.eventLabelHeight = props.eventAnnotationProps.labelHeight);
        return _this_1;
    }
    LineChartBase.prototype.componentDidUpdate = function (prevProps) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        if (((_a = prevProps.legendProps) === null || _a === void 0 ? void 0 : _a.selectedLegend) !== ((_b = this.props.legendProps) === null || _b === void 0 ? void 0 : _b.selectedLegend) ||
            !areArraysEqual((_c = prevProps.legendProps) === null || _c === void 0 ? void 0 : _c.selectedLegends, (_d = this.props.legendProps) === null || _d === void 0 ? void 0 : _d.selectedLegends)) {
            this.setState({
                selectedLegend: (_f = (_e = this.props.legendProps) === null || _e === void 0 ? void 0 : _e.selectedLegend) !== null && _f !== void 0 ? _f : '',
                selectedLegendPoints: this._injectIndexPropertyInLineChartData(this.props.data.lineChartData, true),
                isSelectedLegend: ((_j = (_h = (_g = this.props.legendProps) === null || _g === void 0 ? void 0 : _g.selectedLegends) === null || _h === void 0 ? void 0 : _h.length) !== null && _j !== void 0 ? _j : 0) > 0,
            });
        }
        /** note that height and width are not used to resize or set as dimesions of the chart,
         * fitParentContainer is responsible for setting the height and width or resizing of the svg/chart
         */
        if (prevProps.height !== this.props.height ||
            prevProps.width !== this.props.width ||
            prevProps.data !== this.props.data) {
            this._points = this._injectIndexPropertyInLineChartData(this.props.data.lineChartData);
            this._calloutPoints = calloutData(this._points) || [];
        }
    };
    LineChartBase.prototype.render = function () {
        var _this_1 = this;
        var _a = this.props, tickValues = _a.tickValues, tickFormat = _a.tickFormat, eventAnnotationProps = _a.eventAnnotationProps, legendProps = _a.legendProps, data = _a.data;
        this._points = this._injectIndexPropertyInLineChartData(data.lineChartData);
        var isXAxisDateType = getXAxisType(this._points);
        var points = this._points;
        if (legendProps && !!legendProps.canSelectMultipleLegends) {
            points = this.state.selectedLegendPoints.length >= 1 ? this.state.selectedLegendPoints : this._points;
            this._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 (!this.props.hideLegend) {
            legendBars = this._createLegendsMemoized(this._points);
        }
        var calloutProps = __assign({ isCalloutVisible: this.state.isCalloutVisible, directionalHint: DirectionalHint.topAutoEdge, YValueHover: this.state.YValueHover, hoverXValue: this.state.hoverXValue, id: "toolTip".concat(this._uniqueCallOutID), target: this.state.refSelected, isBeakVisible: false, gapSpace: 15, onDismiss: this._closeCallout, preventDismissOnEvent: function () { return true; }, hidden: !(!this.props.hideTooltip && this.state.isCalloutVisible), descriptionMessage: this.props.getCalloutDescriptionMessage && this.state.stackCalloutProps
                ? this.props.getCalloutDescriptionMessage(this.state.stackCalloutProps)
                : undefined, 'data-is-focusable': true, xAxisCalloutAccessibilityData: this.state.xAxisCalloutAccessibilityData }, this.props.calloutProps);
        var tickParams = {
            tickValues: tickValues,
            tickFormat: tickFormat,
        };
        return !this._isChartEmpty() ? (React.createElement(CartesianChart, __assign({}, this.props, { chartTitle: this._getChartTitle(), points: points, chartType: ChartTypes.LineChart, isCalloutForStack: true, calloutProps: calloutProps, tickParams: tickParams, legendBars: legendBars, createYAxis: createNumericYAxis, getmargins: this._getMargins, getMinMaxOfYAxis: this._getNumericMinMaxOfY, getGraphData: this._initializeLineChartData, xAxisType: isXAxisDateType ? XAxisTypes.DateAxis : XAxisTypes.NumericAxis, customizedCallout: this._getCustomizedCallout(), getDomainNRangeValues: this._getDomainNRangeValues, createStringYAxis: createStringYAxis, 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_1._xAxisScale = props.xScale;
                _this_1._yAxisScale = props.yScale;
                return (React.createElement(React.Fragment, null,
                    React.createElement("g", null,
                        React.createElement("line", { x1: 0, y1: 0, x2: 0, y2: props.containerHeight, stroke: '#323130', id: _this_1._verticalLine, visibility: 'hidden', strokeDasharray: '5,5' }),
                        _this_1.props.optimizeLargeData ? (React.createElement("rect", { id: _this_1._rectId, width: props.containerWidth, height: props.containerHeight, fill: 'transparent' })) : (React.createElement(React.Fragment, null)),
                        React.createElement("g", null,
                            _this_1._renderedColorFillBars,
                            _this_1.lines),
                        eventAnnotationProps && (React.createElement(EventsAnnotation, __assign({ theme: _this_1.props.theme }, eventAnnotationProps, { scale: props.xScale, chartYTop: _this_1.margins.top + _this_1.eventLabelHeight, chartYBottom: props.containerHeight - 35 }))))));
            } }))) : (React.createElement("div", { id: this._emptyChartId, role: 'alert', style: { opacity: '0' }, "aria-label": 'Graph has no data to display' }));
    };
    Object.defineProperty(LineChartBase.prototype, "chartContainer", {
        get: function () {
            var _a;
            return ((_a = this._cartesianChartRef.current) === null || _a === void 0 ? void 0 : _a.chartContainer) || null;
        },
        enumerable: false,
        configurable: true
    });
    LineChartBase.prototype._createLegends = function (data) {
        var _this_1 = this;
        var _a = this.props, legendProps = _a.legendProps, _b = _a.allowMultipleShapesForPoints, allowMultipleShapesForPoints = _b === void 0 ? false : _b;
        var isLegendMultiSelectEnabled = !!(legendProps && !!legendProps.canSelectMultipleLegends);
        var legendDataItems = data.map(function (point) {
            var color = point.color;
            // mapping data to the format Legends component needs
            var legend = __assign(__assign({ title: point.legend, color: color, action: function () {
                    if (isLegendMultiSelectEnabled) {
                        _this_1._handleMultipleLineLegendSelectionAction(point);
                    }
                    else {
                        _this_1._handleSingleLegendSelectionAction(point);
                    }
                }, onMouseOutAction: function () {
                    _this_1.setState({ activeLegend: '' });
                }, hoverAction: function () {
                    _this_1._handleChartMouseLeave();
                    _this_1.setState({ activeLegend: point.legend });
                } }, (point.legendShape && {
                shape: point.legendShape,
            })), (allowMultipleShapesForPoints && {
                shape: Points[point.index % Object.keys(pointTypes).length],
            }));
            return legend;
        });
        var colorFillBarsLegendDataItems = this.props.colorFillBars
            ? this.props.colorFillBars.map(function (colorFillBar, index) {
                var _a;
                var title = colorFillBar.legend;
                // isInverted property is applicable to v8 themes only
                var color = getColorFromToken(colorFillBar.color, (_a = _this_1.props.theme) === null || _a === void 0 ? void 0 : _a.isInverted);
                var legend = {
                    title: title,
                    color: color,
                    action: function () {
                        if (isLegendMultiSelectEnabled) {
                            _this_1._handleMultipleColorFillBarLegendSelectionAction(colorFillBar);
                        }
                        else {
                            _this_1._handleSingleLegendSelectionAction(colorFillBar);
                        }
                    },
                    onMouseOutAction: function () {
                        _this_1.setState({ activeLegend: '' });
                    },
                    hoverAction: function () {
                        _this_1._handleChartMouseLeave();
                        _this_1.setState({ activeLegend: title });
                    },
                    opacity: _this_1._getColorFillBarOpacity(colorFillBar),
                    stripePattern: colorFillBar.applyPattern,
                };
                return legend;
            })
            : [];
        return (React.createElement(Legends, __assign({ legends: __spreadArray(__spreadArray([], legendDataItems, true), colorFillBarsLegendDataItems, true), enabledWrapLines: this.props.enabledLegendsWrapLines, overflowProps: this.props.legendsOverflowProps, focusZonePropsInHoverCard: this.props.focusZonePropsForLegendsInHoverCard, overflowText: this.props.legendsOverflowText }, (isLegendMultiSelectEnabled && { onLegendHoverCardLeave: this._onHoverCardHide }), this.props.legendProps, { ref: this._legendsRef })));
    };
    LineChartBase.prototype._getRangeForScatterMarkerSize = function () {
        var extraXPixels = this._isRTL
            ? this._xAxisScale(this._xMax - this._xPadding) - this._xAxisScale(this._xMax)
            : this._xAxisScale(this._xMin + this._xPadding) - this._xAxisScale(this._xMin);
        var extraYPixels = this._yAxisScale(this._yMin) - this._yAxisScale(this._yMin + this._yPadding);
        return Math.min(extraXPixels, extraYPixels);
    };
    LineChartBase.prototype._createLines = function (xElement, containerHeight) {
        var _this_1 = this;
        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;
        var lines = [];
        if (this.state.isSelectedLegend) {
            this._points = this.state.selectedLegendPoints;
        }
        else {
            this._points = this._injectIndexPropertyInLineChartData(this.props.data.lineChartData);
        }
        var extraMaxPixels = this.props.lineMode === 'scatter' ? this._getRangeForScatterMarkerSize() : 0;
        var maxMarkerSize = d3Max(this._points, function (point) {
            return d3Max(point.data, function (item) {
                return item.markerSize;
            });
        });
        var _loop_1 = function (i) {
            var linesForLine = [];
            var bordersForLine = [];
            var pointsForLine = [];
            var legendVal = this_1._points[i].legend;
            var lineColor = this_1._points[i].color;
            var activePoint = this_1.state.activePoint;
            var theme = this_1.props.theme;
            var verticaLineHeight = containerHeight - this_1.margins.bottom + 6;
            if (this_1._points[i].data.length === 1) {
                var _2 = this_1._points[i].data[0], x1_1 = _2.x, y1 = _2.y, xAxisCalloutData_1 = _2.xAxisCalloutData, xAxisCalloutAccessibilityData_1 = _2.xAxisCalloutAccessibilityData;
                var circleId_1 = "".concat(this_1._circleId, "_").concat(i);
                var isLegendSelected = this_1._legendHighlighted(legendVal) || this_1._noLegendHighlighted() || this_1.state.isSelectedLegend;
                var currentMarkerSize = this_1._points[i].data[0].markerSize;
                pointsForLine.push(React.createElement("circle", __assign({ id: circleId_1, key: circleId_1, r: currentMarkerSize
                        ? (currentMarkerSize * extraMaxPixels) / maxMarkerSize
                        : activePoint === circleId_1
                            ? 5.5
                            : 3.5, cx: this_1._xAxisScale(x1_1), cy: this_1._yAxisScale(y1), fill: activePoint === circleId_1 ? theme.semanticColors.bodyBackground : lineColor, opacity: isLegendSelected ? 1 : 0.1, onMouseOver: this_1._handleHover.bind(this_1, x1_1, y1, verticaLineHeight, xAxisCalloutData_1, circleId_1, xAxisCalloutAccessibilityData_1), onMouseMove: this_1._handleHover.bind(this_1, x1_1, y1, verticaLineHeight, xAxisCalloutData_1, circleId_1, xAxisCalloutAccessibilityData_1), onMouseOut: this_1._handleMouseOut, strokeWidth: activePoint === circleId_1 ? DEFAULT_LINE_STROKE_SIZE : 0, stroke: activePoint === circleId_1 ? lineColor : '', role: "img", "aria-label": this_1._getAriaLabel(i, 0), "data-is-focusable": isLegendSelected, ref: function (e) {
                        _this_1._refCallback(e, circleId_1);
                    }, onFocus: function () { return _this_1._handleFocus(circleId_1, x1_1, xAxisCalloutData_1, circleId_1, xAxisCalloutAccessibilityData_1); }, onBlur: this_1._handleMouseOut }, this_1._getClickHandler(this_1._points[i].data[0].onDataPointClick))));
            }
            var gapIndex = 0;
            var gaps = (_b = (_a = this_1._points[i].gaps) === null || _a === void 0 ? void 0 : _a.sort(function (a, b) { return a.startIndex - b.startIndex; })) !== null && _b !== void 0 ? _b : [];
            // Use path rendering technique for larger datasets to optimize performance.
            if (this_1.props.optimizeLargeData && this_1._points[i].data.length > 1) {
                var line = d3Line()
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    .x(function (d) { return _this_1._xAxisScale(d[0]); })
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    .y(function (d) { return _this_1._yAxisScale(d[1]); })
                    .curve(d3curveLinear);
                var lineId = "".concat(this_1._lineId, "_").concat(i);
                var borderId = "".concat(this_1._borderId, "_").concat(i);
                var strokeWidth = ((_c = this_1._points[i].lineOptions) === null || _c === void 0 ? void 0 : _c.strokeWidth) || this_1.props.strokeWidth || DEFAULT_LINE_STROKE_SIZE;
                var isLegendSelected = this_1._legendHighlighted(legendVal) || this_1._noLegendHighlighted() || this_1.state.isSelectedLegend;
                var lineData = [];
                for (var k = 0; k < this_1._points[i].data.length; k++) {
                    lineData.push([
                        this_1._points[i].data[k].x instanceof Date
                            ? this_1._points[i].data[k].x.getTime()
                            : this_1._points[i].data[k].x,
                        this_1._points[i].data[k].y,
                    ]);
                }
                if (isLegendSelected) {
                    var lineBorderWidth = ((_d = this_1._points[i].lineOptions) === null || _d === void 0 ? void 0 : _d.lineBorderWidth)
                        ? Number.parseFloat(this_1._points[i].lineOptions.lineBorderWidth.toString())
                        : 0;
                    if (lineBorderWidth > 0) {
                        bordersForLine.push(React.createElement("path", { id: borderId, key: borderId, d: line(lineData), fill: "transparent", strokeLinecap: (_f = (_e = this_1._points[i].lineOptions) === null || _e === void 0 ? void 0 : _e.strokeLinecap) !== null && _f !== void 0 ? _f : 'round', strokeWidth: Number.parseFloat(strokeWidth.toString()) + lineBorderWidth, stroke: ((_g = this_1._points[i].lineOptions) === null || _g === void 0 ? void 0 : _g.lineBorderColor) || theme.semanticColors.bodyBackground, opacity: 1 }));
                    }
                    linesForLine.push(React.createElement("path", __assign({ id: lineId, key: lineId, d: line(lineData), fill: "transparent", "data-is-focusable": true, stroke: lineColor, strokeWidth: strokeWidth, strokeLinecap: (_j = (_h = this_1._points[i].lineOptions) === null || _h === void 0 ? void 0 : _h.strokeLinecap) !== null && _j !== void 0 ? _j : 'round', strokeDasharray: (_k = this_1._points[i].lineOptions) === null || _k === void 0 ? void 0 : _k.strokeDasharray, onMouseMove: this_1._onMouseOverLargeDataset.bind(this_1, i, verticaLineHeight), onMouseOver: this_1._onMouseOverLargeDataset.bind(this_1, i, verticaLineHeight), onMouseOut: this_1._handleMouseOut }, this_1._getClickHandler(this_1._points[i].onLineClick), { opacity: 1 })));
                }
                else {
                    linesForLine.push(React.createElement("path", { id: lineId, key: lineId, d: line(lineData), fill: "transparent", "data-is-focusable": false, stroke: lineColor, strokeWidth: strokeWidth, strokeLinecap: (_m = (_l = this_1._points[i].lineOptions) === null || _l === void 0 ? void 0 : _l.strokeLinecap) !== null && _m !== void 0 ? _m : 'round', strokeDasharray: (_o = this_1._points[i].lineOptions) === null || _o === void 0 ? void 0 : _o.strokeDasharray, opacity: 0.1 }));
                }
                var isPointHighlighted = this_1.state.activeLine !== null && this_1.state.activeLine === i;
                pointsForLine.push(React.createElement("circle", { id: "".concat(this_1._staticHighlightCircle, "_").concat(i), key: "".concat(this_1._staticHighlightCircle, "_").concat(i), r: 5.5, cx: 0, cy: 0, fill: theme.semanticColors.bodyBackground, strokeWidth: DEFAULT_LINE_STROKE_SIZE, stroke: lineColor, visibility: isPointHighlighted ? 'visibility' : 'hidden', onMouseMove: this_1._onMouseOverLargeDataset.bind(this_1, i, verticaLineHeight), onMouseOver: this_1._onMouseOverLargeDataset.bind(this_1, i, verticaLineHeight), onMouseOut: this_1._handleMouseOut }));
            }
            else if (!this_1.props.optimizeLargeData) {
                var _loop_2 = function (j) {
                    var gapResult = this_1._checkInGap(j, gaps, gapIndex);
                    var isInGap = gapResult.isInGap;
                    gapIndex = gapResult.gapIndex;
                    var lineId = "".concat(this_1._lineId, "_").concat(i, "_").concat(j);
                    var borderId = "".concat(this_1._borderId, "_").concat(i, "_").concat(j);
                    var circleId = "".concat(this_1._circleId, "_").concat(i, "_").concat(j);
                    var _3 = this_1._points[i].data[j - 1], x1 = _3.x, y1 = _3.y, xAxisCalloutData = _3.xAxisCalloutData, xAxisCalloutAccessibilityData = _3.xAxisCalloutAccessibilityData;
                    var _4 = this_1._points[i].data[j], x2 = _4.x, y2 = _4.y;
                    var path = this_1._getPath(this_1._xAxisScale(x1), this_1._yAxisScale(y1), circleId, j, false, this_1._points[i].index);
                    var strokeWidth = ((_p = this_1._points[i].lineOptions) === null || _p === void 0 ? void 0 : _p.strokeWidth) || this_1.props.strokeWidth || DEFAULT_LINE_STROKE_SIZE;
                    var isLegendSelected = this_1._legendHighlighted(legendVal) || this_1._noLegendHighlighted() || this_1.state.isSelectedLegend;
                    var currentPointHidden = this_1._points[i].hideNonActiveDots && activePoint !== circleId;
                    var currentMarkerSize = this_1._points[i].data[j - 1].markerSize;
                    pointsForLine.push(this_1.props.lineMode === 'scatter' ? (React.createElement("circle", __assign({ id: circleId, key: circleId, r: currentMarkerSize ? (currentMarkerSize * extraMaxPixels) / maxMarkerSize : 4, cx: this_1._xAxisScale(x1), cy: this_1._yAxisScale(y1), "data-is-focusable": isLegendSelected, onMouseOver: this_1._handleHover.bind(this_1, x1, y1, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData), onMouseMove: this_1._handleHover.bind(this_1, x1, y1, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData), onMouseOut: this_1._handleMouseOut, onFocus: function () { return _this_1._handleFocus(lineId, x1, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData); }, onBlur: this_1._handleMouseOut }, this_1._getClickHandler(this_1._points[i].data[j - 1].onDataPointClick), { opacity: isLegendSelected && !currentPointHidden ? 1 : 0.01, fill: this_1._getPointFill(lineColor, circleId, j, false), stroke: lineColor, strokeWidth: strokeWidth, role: "img", "aria-label": this_1._getAriaLabel(i, j - 1) }))) : (React.createElement("path", __assign({ id: circleId, key: circleId, d: path, "data-is-focusable": isLegendSelected, onMouseOver: this_1._handleHover.bind(this_1, x1, y1, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData), onMouseMove: this_1._handleHover.bind(this_1, x1, y1, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData), onMouseOut: this_1._handleMouseOut, onFocus: function () { return _this_1._handleFocus(lineId, x1, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData); }, onBlur: this_1._handleMouseOut }, this_1._getClickHandler(this_1._points[i].data[j - 1].onDataPointClick), { opacity: isLegendSelected && !currentPointHidden ? 1 : 0.01, fill: this_1._getPointFill(lineColor, circleId, j, false), stroke: lineColor, strokeWidth: strokeWidth, role: "img", "aria-label": this_1._getAriaLabel(i, j - 1) }))));
                    if (j + 1 === this_1._points[i].data.length) {
                        // If this is last point of the line segment.
                        var lastCircleId_1 = "".concat(circleId).concat(j, "L");
                        var hiddenHoverCircleId = "".concat(circleId).concat(j, "D");
                        var lastPointHidden = this_1._points[i].hideNonActiveDots && activePoint !== lastCircleId_1;
                        path = this_1._getPath(this_1._xAxisScale(x2), this_1._yAxisScale(y2), lastCircleId_1, j, true, this_1._points[i].index);
                        var _5 = this_1._points[i].data[j], lastCirlceXCallout_1 = _5.xAxisCalloutData, lastCirlceXCalloutAccessibilityData_1 = _5.xAxisCalloutAccessibilityData;
                        currentMarkerSize = this_1._points[i].data[j].markerSize;
                        pointsForLine.push(React.createElement(React.Fragment, { key: "".concat(lastCircleId_1, "_container") },
                            this_1.props.lineMode === 'scatter' ? (React.createElement("circle", __assign({ id: lastCircleId_1, key: lastCircleId_1, r: currentMarkerSize ? (currentMarkerSize * extraMaxPixels) / maxMarkerSize : 4, cx: this_1._xAxisScale(x2), cy: this_1._yAxisScale(y2), "data-is-focusable": isLegendSelected, onMouseOver: this_1._handleHover.bind(this_1, x2, y2, verticaLineHeight, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1), onMouseMove: this_1._handleHover.bind(this_1, x2, y2, verticaLineHeight, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1), onMouseOut: this_1._handleMouseOut, onFocus: function () {
                                    return _this_1._handleFocus(lineId, x2, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1);
                                }, onBlur: this_1._handleMouseOut }, this_1._getClickHandler(this_1._points[i].data[j].onDataPointClick), { opacity: isLegendSelected && !lastPointHidden ? 1 : 0.01, fill: this_1._getPointFill(lineColor, lastCircleId_1, j, true), stroke: lineColor, strokeWidth: strokeWidth, role: "img", "aria-label": this_1._getAriaLabel(i, j) }))) : (React.createElement("path", __assign({ id: lastCircleId_1, key: lastCircleId_1, d: path, "data-is-focusable": isLegendSelected, onMouseOver: this_1._handleHover.bind(this_1, x2, y2, verticaLineHeight, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1), onMouseMove: this_1._handleHover.bind(this_1, x2, y2, verticaLineHeight, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1), onMouseOut: this_1._handleMouseOut, onFocus: function () {
                                    return _this_1._handleFocus(lineId, x2, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1);
                                }, onBlur: this_1._handleMouseOut }, this_1._getClickHandler(this_1._points[i].data[j].onDataPointClick), { opacity: isLegendSelected && !lastPointHidden ? 1 : 0.01, fill: this_1._getPointFill(lineColor, lastCircleId_1, j, true), stroke: lineColor, strokeWidth: strokeWidth, role: "img", "aria-label": this_1._getAriaLabel(i, j) }))),
                            React.createElement("circle", { id: hiddenHoverCircleId, key: hiddenHoverCircleId, r: 8, cx: this_1._xAxisScale(x2), cy: this_1._yAxisScale(y2), opacity: 0, width: 0, onMouseOver: this_1._handleHover.bind(this_1, x2, y2, verticaLineHeight, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1), onMouseMove: this_1._handleHover.bind(this_1, x2, y2, verticaLineHeight, lastCirlceXCallout_1, lastCircleId_1, lastCirlceXCalloutAccessibilityData_1), onMouseOut: this_1._handleMouseOut, strokeWidth: 0, focusable: false, onBlur: this_1._handleMouseOut })));
                    }
                    if (this_1.props.lineMode !== 'scatter') {
                        if (isLegendSelected) {
                            // don't draw line if it is in a gap
                            if (!isInGap) {
                                var lineBorderWidth = ((_q = this_1._points[i].lineOptions) === null || _q === void 0 ? void 0 : _q.lineBorderWidth)
                                    ? Number.parseFloat(this_1._points[i].lineOptions.lineBorderWidth.toString())
                                    : 0;
                                if (lineBorderWidth > 0) {
                                    bordersForLine.push(React.createElement("line", { id: borderId, key: borderId, x1: this_1._xAxisScale(x1), y1: this_1._yAxisScale(y1), x2: this_1._xAxisScale(x2), y2: this_1._yAxisScale(y2), strokeLinecap: (_s = (_r = this_1._points[i].lineOptions) === null || _r === void 0 ? void 0 : _r.strokeLinecap) !== null && _s !== void 0 ? _s : 'round', strokeWidth: Number.parseFloat(strokeWidth.toString()) + lineBorderWidth, stroke: ((_t = this_1._points[i].lineOptions) === null || _t === void 0 ? void 0 : _t.lineBorderColor) || theme.semanticColors.bodyBackground, opacity: 1 }));
                                }
                                linesForLine.push(React.createElement("line", __assign({ id: lineId, key: lineId, x1: this_1._xAxisScale(x1), y1: this_1._yAxisScale(y1), x2: this_1._xAxisScale(x2), y2: this_1._yAxisScale(y2), strokeWidth: strokeWidth, ref: function (e) {
                                        _this_1._refCallback(e, lineId);
                                    }, onMouseOver: this_1._handleHover.bind(this_1, x1, y1, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData), onMouseMove: this_1._handleHover.bind(this_1, x1, y1, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData), onMouseOut: this_1._handleMouseOut, stroke: lineColor, strokeLinecap: (_v = (_u = this_1._points[i].lineOptions) === null || _u === void 0 ? void 0 : _u.strokeLinecap) !== null && _v !== void 0 ? _v : 'round', strokeDasharray: (_w = this_1._points[i].lineOptions) === null || _w === void 0 ? void 0 : _w.strokeDasharray, strokeDashoffset: (_x = this_1._points[i].lineOptions) === null || _x === void 0 ? void 0 : _x.strokeDashoffset, opacity: 1 }, this_1._getClickHandler(this_1._points[i].onLineClick))));
                            }
                        }
                        else {
                            if (!isInGap) {
                                linesForLine.push(React.createElement("line", { id: lineId, key: lineId, x1: this_1._xAxisScale(x1), y1: this_1._yAxisScale(y1), x2: this_1._xAxisScale(x2), y2: this_1._yAxisScale(y2), strokeWidth: strokeWidth, stroke: lineColor, strokeLinecap: (_z = (_y = this_1._points[i].lineOptions) === null || _y === void 0 ? void 0 : _y.strokeLinecap) !== null && _z !== void 0 ? _z : 'round', strokeDasharray: (_0 = this_1._points[i].lineOptions) === null || _0 === void 0 ? void 0 : _0.strokeDasharray, strokeDashoffset: (_1 = this_1._points[i].lineOptions) === null || _1 === void 0 ? void 0 : _1.strokeDashoffset, opacity: 0.1 }));
                            }
                        }
                    }
                };
                for (var j = 1; j < this_1._points[i].data.length; j++) {
                    _loop_2(j);
                }
            }
            lines.push(React.createElement("g", { key: "line_".concat(i), role: "region", "aria-label": "".concat(legendVal, ", line ").concat(i + 1, " of ").concat(this_1._points.length, " with ").concat(this_1._points[i].data.length, " data points.") },
                bordersForLine,
                linesForLine,
                pointsForLine));
        };
        var this_1 = this;
        for (var i = this._points.length - 1; i >= 0; i--) {
            _loop_1(i);
        }
        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 = d3Select(xElement).call(this._xAxisScale);
            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 && tooltipOfXAxislabels(tooltipProps);
        }
        return lines;
    };
    LineChartBase.prototype._refCallback = function (element, legendTitle) {
        this._refArray.push({ index: legendTitle, refElement: element });
    };
    LineChartBase.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; }).length > 0);
    };
    LineChartBase.defaultProps = {
        enableReflow: true,
        useUTC: true,
    };
    return LineChartBase;
}(React.Component));
export { LineChartBase };
//# sourceMappingURL=LineChart.base.js.map