"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.areArraysEqual = exports.getSecureProps = exports.isScalePaddingDefined = exports.getScalePadding = exports.getBarWidth = exports.formatScientificLimitWidth = exports.wrapTextInsideDonut = exports.rotateXAxisLabels = exports.getAccessibleDataObject = exports.pointTypes = exports.CustomPoints = exports.Points = exports.getTypeOfAxis = exports.findHBCWANumericMinMaxOfY = exports.findVerticalNumericMinMaxOfY = exports.findVSBCNumericMinMaxOfY = exports.findNumericMinMaxOfY = exports.domainRageOfVerticalNumeric = exports.domainRangeOfDateForAreaLineVerticalBarChart = exports.domainRangeOfVSBCNumeric = exports.domainRangeOfXStringAxis = exports.domainRangeOfNumericForHorizontalBarChartWithAxis = exports.computeLongestBars = exports.groupChartDataByYValue = exports.domainRangeOfNumericForAreaChart = exports.getXAxisType = exports.tooltipOfAxislabels = exports.calculateLongestLabelWidth = exports.wrapContent = exports.createYAxisLabels = exports.createWrapOfXLabels = exports.DEFAULT_WRAP_WIDTH = exports.silceOrAppendToArray = exports.getUnique = exports.calloutData = exports.createStringYAxis = exports.createStringYAxisForHorizontalBarChartWithAxis = exports.createNumericYAxis = exports.createYAxisForHorizontalBarChartWithAxis = exports.prepareDatapoints = exports.createStringXAxis = exports.createDateXAxis = exports.getDateFormatLevel = exports.createNumericXAxis = exports.defaultYAxisTickFormatter = exports.YAxisType = exports.XAxisTypes = exports.ChartTypes = exports.MIN_DONUT_RADIUS = exports.MIN_DOMAIN_MARGIN = void 0;
exports.isTextMode = exports.isScatterPolarSeries = exports.getContrastTextColor = exports.getInvertedTextColor = exports.sortAxisCategories = exports.truncateString = exports.domainRangeOfNumericForScatterChart = exports.domainRangeOfDateForScatterChart = exports.getCurveFactory = exports.createMeasurementSpan = exports.copyStyle = exports.resolveCSSVariables = void 0;
var tslib_1 = require("tslib");
var d3_axis_1 = require("d3-axis");
var d3_array_1 = require("d3-array");
var d3_scale_1 = require("d3-scale");
var d3_selection_1 = require("d3-selection");
var d3_format_1 = require("d3-format");
var d3_time_format_1 = require("d3-time-format");
var d3_time_1 = require("d3-time");
var d3_format_2 = require("d3-format");
var react_1 = require("@fluentui/react");
var d3_shape_1 = require("d3-shape");
var chart_utilities_1 = require("@fluentui/chart-utilities");
var colors_1 = require("./colors");
exports.MIN_DOMAIN_MARGIN = 8;
exports.MIN_DONUT_RADIUS = 1;
var ChartTypes;
(function (ChartTypes) {
    ChartTypes[ChartTypes["AreaChart"] = 0] = "AreaChart";
    ChartTypes[ChartTypes["LineChart"] = 1] = "LineChart";
    ChartTypes[ChartTypes["VerticalBarChart"] = 2] = "VerticalBarChart";
    ChartTypes[ChartTypes["VerticalStackedBarChart"] = 3] = "VerticalStackedBarChart";
    ChartTypes[ChartTypes["GroupedVerticalBarChart"] = 4] = "GroupedVerticalBarChart";
    ChartTypes[ChartTypes["HeatMapChart"] = 5] = "HeatMapChart";
    ChartTypes[ChartTypes["HorizontalBarChartWithAxis"] = 6] = "HorizontalBarChartWithAxis";
    ChartTypes[ChartTypes["ScatterChart"] = 7] = "ScatterChart";
    ChartTypes[ChartTypes["GanttChart"] = 8] = "GanttChart";
})(ChartTypes || (exports.ChartTypes = ChartTypes = {}));
var XAxisTypes;
(function (XAxisTypes) {
    XAxisTypes[XAxisTypes["NumericAxis"] = 0] = "NumericAxis";
    XAxisTypes[XAxisTypes["DateAxis"] = 1] = "DateAxis";
    XAxisTypes[XAxisTypes["StringAxis"] = 2] = "StringAxis";
})(XAxisTypes || (exports.XAxisTypes = XAxisTypes = {}));
var YAxisType;
(function (YAxisType) {
    YAxisType[YAxisType["NumericAxis"] = 0] = "NumericAxis";
    YAxisType[YAxisType["DateAxis"] = 1] = "DateAxis";
    YAxisType[YAxisType["StringAxis"] = 2] = "StringAxis";
})(YAxisType || (exports.YAxisType = YAxisType = {}));
function yAxisTickFormatterInternal(value, limitWidth) {
    if (limitWidth === void 0) { limitWidth = false; }
    // Use SI format prefix with 2 decimal places without insignificant trailing zeros
    var formatter = (0, d3_format_2.formatPrefix)('.2~', value);
    if (Math.abs(value) < 1) {
        // Don't use SI notation for small numbers as it is less readable
        formatter = (0, d3_format_1.format)('.2~g');
    }
    else if (limitWidth && Math.abs(value) >= 1000) {
        // If width is limited, use SI format prefix with 1 point precision
        formatter = (0, d3_format_2.formatPrefix)('.1~', value);
    }
    var formattedValue = formatter(value);
    // Replace 'G' with 'B' if the value is greater than 10^9 as it is a more common convention
    if (Math.abs(value) >= 1e9) {
        return formattedValue.replace('G', 'B');
    }
    return formattedValue;
}
/**
 * Formatter for y axis ticks.
 * @param value - The number to format.
 * @returns The formatted string .
 */
function defaultYAxisTickFormatter(value) {
    return yAxisTickFormatterInternal(value);
}
exports.defaultYAxisTickFormatter = defaultYAxisTickFormatter;
/**
 * Create Numeric X axis
 * @export
 * @param {IXAxisParams} xAxisParams
 */
function createNumericXAxis(xAxisParams, tickParams, chartType, culture) {
    var _a;
    var domainNRangeValues = xAxisParams.domainNRangeValues, _b = xAxisParams.showRoundOffXTickValues, showRoundOffXTickValues = _b === void 0 ? true : _b, _c = xAxisParams.xAxistickSize, xAxistickSize = _c === void 0 ? 6 : _c, _d = xAxisParams.tickPadding, tickPadding = _d === void 0 ? 10 : _d, xAxisCount = xAxisParams.xAxisCount, xAxisElement = xAxisParams.xAxisElement, hideTickOverlap = xAxisParams.hideTickOverlap, calcMaxLabelWidth = xAxisParams.calcMaxLabelWidth;
    var xAxisScale = (0, d3_scale_1.scaleLinear)()
        .domain([domainNRangeValues.dStartValue, domainNRangeValues.dEndValue])
        .range([domainNRangeValues.rStartValue, domainNRangeValues.rEndValue]);
    showRoundOffXTickValues && xAxisScale.nice();
    var tickCount = xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : 6;
    var tickFormat = function (domainValue, _index) {
        if (tickParams.tickFormat) {
            return (0, d3_format_1.format)(tickParams.tickFormat)(domainValue);
        }
        var xAxisValue = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
        return (0, chart_utilities_1.formatToLocaleString)(xAxisValue, culture);
    };
    if (hideTickOverlap && typeof xAxisCount === 'undefined') {
        var longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map(tickFormat)) + 20;
        var _e = xAxisScale.range(), start = _e[0], end = _e[1];
        tickCount = Math.min(Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)), 10);
    }
    var xAxis = (0, d3_axis_1.axisBottom)(xAxisScale)
        .tickSize(xAxistickSize)
        .tickPadding(tickPadding)
        .ticks(tickCount)
        .tickFormat(tickFormat);
    if ([ChartTypes.HorizontalBarChartWithAxis, ChartTypes.GanttChart].includes(chartType)) {
        xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top));
    }
    if (tickParams.tickValues) {
        xAxis.tickValues(tickParams.tickValues);
    }
    if (xAxisElement) {
        (0, d3_selection_1.select)(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true');
    }
    var tickValues = ((_a = tickParams.tickValues) !== null && _a !== void 0 ? _a : xAxisScale.ticks(tickCount)).map(xAxis.tickFormat());
    return { xScale: xAxisScale, tickValues: tickValues };
}
exports.createNumericXAxis = createNumericXAxis;
/**
 * This function returns a multilevel formatter for a given date range.
 * It determines the appropriate date format to accommodate each tick value.
 * The goal is to represent the date label in the smallest possible format without loss of information.
 * The challenge here is to adhere to locale specific formats while ensuring the complete label is shown.
 * There is an exhaustive map of all possible date/time units and their respective formats.
 * Based on the range of formatting granularity levels, a format spanning the range is returned.
 * @param startLevel - The starting level of the date format.
 * @param endLevel - The ending level of the date format.
 * @param locale - The locale object for formatting.
 * @param useUTC
 * @returns
 */
function getMultiLevelD3DateFormatter(startLevel, endLevel, locale, useUTC) {
    var timeFormat = locale ? (useUTC ? locale.utcFormat : locale.format) : useUTC ? d3_time_format_1.utcFormat : d3_time_format_1.timeFormat;
    // Refer to https://d3js.org/d3-time-format#locale_format to see explanation about each format specifier
    var DEFAULT = '%c';
    var MS = '.%L';
    var MS_S = ':%S.%L';
    var MS_S_MIN = '%M:%S.%L';
    var MS_S_MIN_H = '%-I:%M:%S.%L %p';
    var MS_S_MIN_H_D = '%a %d, %X';
    var MS_S_MIN_H_D_W = '%b %d, %X';
    var MS_S_MIN_H_D_W_M = MS_S_MIN_H_D_W;
    var MS_S_MIN_H_D_W_M_Y = DEFAULT;
    var S = ':%S';
    var S_MIN = '%-I:%M:%S';
    var S_MIN_H = '%X';
    var S_MIN_H_D = MS_S_MIN_H_D;
    var S_MIN_H_D_W = MS_S_MIN_H_D_W;
    var S_MIN_H_D_W_M = MS_S_MIN_H_D_W_M;
    var S_MIN_H_D_W_M_Y = DEFAULT;
    var MIN = '%-I:%M %p';
    var MIN_H = MIN;
    var MIN_H_D = '%a %d, %-I:%M %p';
    var MIN_H_D_W = '%b %d, %-I:%M %p';
    var MIN_H_D_W_M = MIN_H_D_W;
    var MIN_H_D_W_M_Y = '%x, %-I:%M %p';
    var H = '%-I %p';
    var H_D = '%a %d, %-I %p';
    var H_D_W = '%b %d, %-I %p';
    var H_D_W_M = H_D_W;
    var H_D_W_M_Y = '%x, %-I %p';
    var D = '%a %d';
    var D_W = '%b %d';
    var D_W_M = D_W;
    var D_W_M_Y = '%x';
    var W = D_W;
    var W_M = W;
    var W_M_Y = D_W_M_Y;
    var M = '%B';
    var M_Y = '%b %Y';
    var Y = '%Y';
    var MULTI_LEVEL_DATE_TIME_FORMATS = [
        // ms, s, min, h, d, w, m, y
        [MS, MS_S, MS_S_MIN, MS_S_MIN_H, MS_S_MIN_H_D, MS_S_MIN_H_D_W, MS_S_MIN_H_D_W_M, MS_S_MIN_H_D_W_M_Y], // ms
        [DEFAULT, S, S_MIN, S_MIN_H, S_MIN_H_D, S_MIN_H_D_W, S_MIN_H_D_W_M, S_MIN_H_D_W_M_Y], // s
        [DEFAULT, DEFAULT, MIN, MIN_H, MIN_H_D, MIN_H_D_W, MIN_H_D_W_M, MIN_H_D_W_M_Y], // min
        [DEFAULT, DEFAULT, DEFAULT, H, H_D, H_D_W, H_D_W_M, H_D_W_M_Y], // h
        [DEFAULT, DEFAULT, DEFAULT, DEFAULT, D, D_W, D_W_M, D_W_M_Y], // d
        [DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, W, W_M, W_M_Y], // w
        [DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, M, M_Y], // m
        [DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, Y], // y
    ];
    var formatter = timeFormat(MULTI_LEVEL_DATE_TIME_FORMATS[startLevel][endLevel]);
    return formatter;
}
function getDateFormatLevel(date, useUTC) {
    var _a;
    var timeSecond = useUTC ? d3_time_1.utcSecond : d3_time_1.timeSecond;
    var timeMinute = useUTC ? d3_time_1.utcMinute : d3_time_1.timeMinute;
    var timeHour = useUTC ? d3_time_1.utcHour : d3_time_1.timeHour;
    var timeDay = useUTC ? d3_time_1.utcDay : d3_time_1.timeDay;
    var timeMonth = useUTC ? d3_time_1.utcMonth : d3_time_1.timeMonth;
    var timeWeek = useUTC ? d3_time_1.utcWeek : d3_time_1.timeWeek;
    var timeYear = useUTC ? d3_time_1.utcYear : d3_time_1.timeYear;
    var formats = [
        { formatLevel: 0, condition: function (d) { return timeSecond(d) < d; } }, // Milliseconds
        { formatLevel: 1, condition: function (d) { return timeMinute(d) < d; } }, // Seconds
        { formatLevel: 2, condition: function (d) { return timeHour(d) < d; } }, // Minutes
        { formatLevel: 3, condition: function (d) { return timeDay(d) < d; } }, // Hours
        { formatLevel: 4, condition: function (d) { return timeMonth(d) < d && timeWeek(d) < d; } }, // Days
        { formatLevel: 5, condition: function (d) { return timeMonth(d) < d; } }, // Weeks
        { formatLevel: 6, condition: function (d) { return timeYear(d) < d; } }, // Months
        { formatLevel: 7, condition: function () { return true; } }, // Years (default)
    ];
    var matchedFormat = formats.find(function (_a) {
        var condition = _a.condition;
        return condition(date);
    });
    return (_a = matchedFormat === null || matchedFormat === void 0 ? void 0 : matchedFormat.formatLevel) !== null && _a !== void 0 ? _a : 7;
}
exports.getDateFormatLevel = getDateFormatLevel;
function isPowerOf10(num) {
    var roundedfinalYMax = (0, chart_utilities_1.handleFloatingPointPrecisionError)(num);
    return Math.log10(roundedfinalYMax) % 1 === 0;
}
/**
 * Creating Date x axis of the Chart
 * @export
 * @param {IXAxisParams} xAxisParams
 * @param {ITickParams} tickParams
 */
function createDateXAxis(xAxisParams, tickParams, culture, options, timeFormatLocale, customDateTimeFormatter, useUTC, chartType) {
    var _a;
    var domainNRangeValues = xAxisParams.domainNRangeValues, xAxisElement = xAxisParams.xAxisElement, _b = xAxisParams.tickPadding, tickPadding = _b === void 0 ? 6 : _b, _c = xAxisParams.xAxistickSize, xAxistickSize = _c === void 0 ? 6 : _c, xAxisCount = xAxisParams.xAxisCount, calcMaxLabelWidth = xAxisParams.calcMaxLabelWidth;
    var xAxisScale = useUTC ? (0, d3_scale_1.scaleUtc)() : (0, d3_scale_1.scaleTime)();
    xAxisScale
        .domain([domainNRangeValues.dStartValue, domainNRangeValues.dEndValue])
        .range([domainNRangeValues.rStartValue, domainNRangeValues.rEndValue])
        .nice();
    var tickCount = xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : 6;
    var lowestFormatLevel = 100;
    var highestFormatLevel = -1;
    var locale = timeFormatLocale ? (0, d3_time_format_1.timeFormatLocale)(timeFormatLocale) : undefined;
    xAxisScale.ticks().forEach(function (domainValue) {
        var formatLevel = getDateFormatLevel(domainValue, useUTC);
        if (formatLevel > highestFormatLevel) {
            highestFormatLevel = formatLevel;
        }
        if (formatLevel < lowestFormatLevel) {
            lowestFormatLevel = formatLevel;
        }
    });
    var formatOptions = options !== null && options !== void 0 ? options : (0, chart_utilities_1.getMultiLevelDateTimeFormatOptions)(lowestFormatLevel, highestFormatLevel);
    var formatFn = getMultiLevelD3DateFormatter(lowestFormatLevel, highestFormatLevel, locale, useUTC);
    var tickFormat = function (domainValue, _index) {
        if (customDateTimeFormatter) {
            return customDateTimeFormatter(domainValue);
        }
        if (timeFormatLocale) {
            return formatFn(domainValue);
        }
        if (culture === undefined && tickParams.tickFormat) {
            if (useUTC) {
                return (0, d3_time_format_1.utcFormat)(tickParams.tickFormat)(domainValue);
            }
            else {
                return (0, d3_time_format_1.timeFormat)(tickParams.tickFormat)(domainValue);
            }
        }
        return (0, chart_utilities_1.formatDateToLocaleString)(domainValue, culture, useUTC, false, formatOptions);
    };
    var longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map(tickFormat)) + 40;
    var _d = xAxisScale.range(), start = _d[0], end = _d[1];
    var maxPossibleTickCount = Math.min(Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)), 10);
    tickCount = Math.min(maxPossibleTickCount, xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : tickCount);
    var xAxis = (0, d3_axis_1.axisBottom)(xAxisScale)
        .tickSize(xAxistickSize)
        .tickPadding(tickPadding)
        .ticks(tickCount)
        .tickFormat(tickFormat);
    if ([ChartTypes.GanttChart].includes(chartType)) {
        xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top));
    }
    tickParams.tickValues ? xAxis.tickValues(tickParams.tickValues) : '';
    if (xAxisElement) {
        (0, d3_selection_1.select)(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true');
    }
    var tickValues = ((_a = tickParams.tickValues) !== null && _a !== void 0 ? _a : xAxisScale.ticks(tickCount)).map(xAxis.tickFormat());
    return { xScale: xAxisScale, tickValues: tickValues };
}
exports.createDateXAxis = createDateXAxis;
/**
 * Create String X axis
 * Currently using for only Vetical stacked bar chart and grouped vertical bar chart
 * @export
 * @param {IXAxisParams} xAxisParams
 * @param {ITickParams} tickParams
 * @param {string[]} dataset
 * @returns
 */
function createStringXAxis(xAxisParams, tickParams, dataset, culture) {
    var _a;
    var domainNRangeValues = xAxisParams.domainNRangeValues, _b = xAxisParams.xAxistickSize, xAxistickSize = _b === void 0 ? 6 : _b, _c = xAxisParams.tickPadding, tickPadding = _c === void 0 ? 10 : _c, _d = xAxisParams.xAxisPadding, xAxisPadding = _d === void 0 ? 0.1 : _d, xAxisInnerPadding = xAxisParams.xAxisInnerPadding, xAxisOuterPadding = xAxisParams.xAxisOuterPadding, containerWidth = xAxisParams.containerWidth, hideTickOverlap = xAxisParams.hideTickOverlap, calcMaxLabelWidth = xAxisParams.calcMaxLabelWidth;
    var xAxisScale = (0, d3_scale_1.scaleBand)()
        .domain(dataset)
        .range([domainNRangeValues.rStartValue, domainNRangeValues.rEndValue])
        .paddingInner(typeof xAxisInnerPadding !== 'undefined' ? xAxisInnerPadding : xAxisPadding)
        .paddingOuter(typeof xAxisOuterPadding !== 'undefined' ? xAxisOuterPadding : xAxisPadding);
    var tickValues = (_a = tickParams.tickValues) !== null && _a !== void 0 ? _a : dataset;
    if (hideTickOverlap) {
        var nonOverlappingTickValues = [];
        // Here, we need the width of each individual label to detect overlaps,
        // but calculateLongestLabelWidth returns the maximum pixel width from an array of labels.
        // So call this function separately for each label, instead of the entire array.
        var tickSizes = tickValues.map(function (value) { return calcMaxLabelWidth([value]); });
        // for LTR
        var start = 0;
        var end = containerWidth;
        var sign = 1;
        var range = xAxisScale.range();
        if (range[1] - range[0] < 0) {
            // for RTL
            start = containerWidth;
            end = 0;
            sign = -1;
        }
        for (var i = tickValues.length - 1; i >= 0; i--) {
            var tickPosition = xAxisScale(tickValues[i]);
            if (sign * (tickPosition - (sign * tickSizes[i]) / 2 - start) >= 0 &&
                sign * (tickPosition + (sign * tickSizes[i]) / 2 - end) <= 0) {
                nonOverlappingTickValues.push(tickValues[i]);
                end = tickPosition - sign * (tickSizes[i] / 2 + 10);
            }
        }
        nonOverlappingTickValues = nonOverlappingTickValues.reverse();
        tickValues = nonOverlappingTickValues;
    }
    var xAxis = (0, d3_axis_1.axisBottom)(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).tickValues(tickValues);
    if (xAxisParams.xAxisElement) {
        (0, d3_selection_1.select)(xAxisParams.xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true');
    }
    return { xScale: xAxisScale, tickValues: tickValues };
}
exports.createStringXAxis = createStringXAxis;
/**
 * This method is used to calculate the rounded tick values for the y-axis
 * @param {number} minVal
 * @param {number} maxVal
 * @param {number} splitInto
 * @returns {number[]}
 */
function calculateRoundedTicks(minVal, maxVal, splitInto) {
    var finalYmin = minVal >= 0 && minVal === maxVal ? 0 : minVal;
    var finalYmax = minVal < 0 && minVal === maxVal ? 0 : maxVal;
    var ticksInterval = (0, d3_array_1.nice)(finalYmin, finalYmax, splitInto);
    var ticks = (0, d3_array_1.ticks)(ticksInterval[0], ticksInterval[ticksInterval.length - 1], splitInto);
    if (ticks[ticks.length - 1] > finalYmax && isPowerOf10(finalYmax)) {
        ticks.pop();
    }
    return ticks;
}
/**
 * This method used for creating data points for the y axis.
 * @export
 * @param {number} maxVal
 * @param {number} minVal
 * @param {number} splitInto
 * @param {boolean} isIntegralDataset
 * @returns {number[]}
 */
function prepareDatapoints(maxVal, minVal, splitInto, isIntegralDataset, roundedTicks) {
    if (roundedTicks) {
        return calculateRoundedTicks(minVal, maxVal, splitInto);
    }
    var val = isIntegralDataset
        ? Math.ceil((maxVal - minVal) / splitInto)
        : (maxVal - minVal) / splitInto >= 1
            ? Math.ceil((maxVal - minVal) / splitInto)
            : (maxVal - minVal) / splitInto;
    /*
      For cases where we have negative and positive values
      The dataPointsArray is filled from 0 to minVal by val difference
      Then the array is reversed and values from 0(excluding 0) to maxVal are appended
      This ensures presence of 0 to act as an anchor reference.
      For simple cases where the scale may not encounter such a need for 0,
      We simply fill from minVal to maxVal
    */
    var dataPointsArray = [minVal < 0 && maxVal >= 0 ? 0 : minVal];
    /*For the case of all positive or all negative, we need to add another value
     in array for atleast one interval, but in case of mix of positive and negative,
     there will always be one more entry that will be added by the logic we have*/
    if (dataPointsArray[0] === minVal) {
        dataPointsArray.push(minVal + val);
    }
    if (minVal < 0 && maxVal >= 0) {
        while (dataPointsArray[dataPointsArray.length - 1] > minVal) {
            dataPointsArray.push(dataPointsArray[dataPointsArray.length - 1] - val);
        }
        dataPointsArray.reverse();
    }
    while (dataPointsArray[dataPointsArray.length - 1] < maxVal) {
        dataPointsArray.push(dataPointsArray[dataPointsArray.length - 1] + val);
    }
    return dataPointsArray;
}
exports.prepareDatapoints = prepareDatapoints;
function createYAxisForHorizontalBarChartWithAxis(yAxisParams, isRtl) {
    var _a = yAxisParams.yMinMaxValues, yMinMaxValues = _a === void 0 ? { startValue: 0, endValue: 0 } : _a, _b = yAxisParams.yAxisElement, yAxisElement = _b === void 0 ? null : _b, _c = yAxisParams.yMaxValue, yMaxValue = _c === void 0 ? 0 : _c, _d = yAxisParams.yMinValue, yMinValue = _d === void 0 ? 0 : _d, containerHeight = yAxisParams.containerHeight, margins = yAxisParams.margins, _e = yAxisParams.tickPadding, tickPadding = _e === void 0 ? 12 : _e, _f = yAxisParams.maxOfYVal, maxOfYVal = _f === void 0 ? 0 : _f, yAxisTickFormat = yAxisParams.yAxisTickFormat, _g = yAxisParams.yAxisTickCount, yAxisTickCount = _g === void 0 ? 4 : _g;
    // maxOfYVal coming from horizontal bar chart with axis (Calculation done at base file)
    var tempVal = maxOfYVal || yMinMaxValues.endValue;
    var finalYmax = tempVal > yMaxValue ? tempVal : yMaxValue;
    var finalYmin = yMinMaxValues.startValue < yMinValue ? Math.min(0, yMinMaxValues.startValue) : yMinValue;
    var yAxisScale = (0, d3_scale_1.scaleLinear)()
        .domain([finalYmin, finalYmax])
        .range([containerHeight - margins.bottom, margins.top]);
    var axis = isRtl ? (0, d3_axis_1.axisRight)(yAxisScale) : (0, d3_axis_1.axisLeft)(yAxisScale);
    var yAxis = axis.tickPadding(tickPadding).ticks(yAxisTickCount);
    yAxisTickFormat ? yAxis.tickFormat(yAxisTickFormat) : yAxis.tickFormat(defaultYAxisTickFormatter);
    yAxisElement ? (0, d3_selection_1.select)(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
    return yAxisScale;
}
exports.createYAxisForHorizontalBarChartWithAxis = createYAxisForHorizontalBarChartWithAxis;
function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDataset, useSecondaryYScale, supportNegativeData, roundedTicks) {
    if (useSecondaryYScale === void 0) { useSecondaryYScale = false; }
    if (supportNegativeData === void 0) { supportNegativeData = false; }
    if (roundedTicks === void 0) { roundedTicks = false; }
    var _a = yAxisParams.yMinMaxValues, yMinMaxValues = _a === void 0 ? { startValue: 0, endValue: 0 } : _a, _b = yAxisParams.yAxisElement, yAxisElement = _b === void 0 ? null : _b, _c = yAxisParams.yMaxValue, yMaxValue = _c === void 0 ? 0 : _c, _d = yAxisParams.yMinValue, yMinValue = _d === void 0 ? 0 : _d, containerHeight = yAxisParams.containerHeight, containerWidth = yAxisParams.containerWidth, margins = yAxisParams.margins, _e = yAxisParams.tickPadding, tickPadding = _e === void 0 ? 12 : _e, _f = yAxisParams.maxOfYVal, maxOfYVal = _f === void 0 ? 0 : _f, yAxisTickFormat = yAxisParams.yAxisTickFormat, _g = yAxisParams.yAxisTickCount, yAxisTickCount = _g === void 0 ? 4 : _g, eventAnnotationProps = yAxisParams.eventAnnotationProps, eventLabelHeight = yAxisParams.eventLabelHeight;
    // maxOfYVal coming from only area chart and Grouped vertical bar chart(Calculation done at base file)
    var tempVal = maxOfYVal || yMinMaxValues.endValue || 0;
    var finalYmax = tempVal > yMaxValue ? tempVal : yMaxValue;
    var finalYmin = supportNegativeData
        ? Math.min(yMinMaxValues.startValue || 0, yMinValue || 0)
        : yMinMaxValues.startValue < yMinValue
            ? 0
            : yMinValue;
    var domainValues = prepareDatapoints(finalYmax, finalYmin, yAxisTickCount, isIntegralDataset, roundedTicks);
    var yAxisScale = (0, d3_scale_1.scaleLinear)()
        .domain([supportNegativeData ? domainValues[0] : finalYmin, domainValues[domainValues.length - 1]])
        .range([containerHeight - margins.bottom, margins.top + (eventAnnotationProps ? eventLabelHeight : 0)]);
    var axis = (!isRtl && useSecondaryYScale) || (isRtl && !useSecondaryYScale) ? (0, d3_axis_1.axisRight)(yAxisScale) : (0, d3_axis_1.axisLeft)(yAxisScale);
    var yAxis = axis
        .tickPadding(tickPadding)
        .tickValues(domainValues)
        .tickSizeInner(-(containerWidth - margins.left - margins.right));
    yAxisTickFormat ? yAxis.tickFormat(yAxisTickFormat) : yAxis.tickFormat(defaultYAxisTickFormatter);
    yAxisElement ? (0, d3_selection_1.select)(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
    axisData.yAxisDomainValues = domainValues;
    return yAxisScale;
}
exports.createNumericYAxis = createNumericYAxis;
/**
 * Creating String Y axis of the chart for Horizontal Bar Chart With Axis
 * @param yAxisParams
 * @param dataPoints
 * @param isRtl
 */
var createStringYAxisForHorizontalBarChartWithAxis = function (yAxisParams, dataPoints, isRtl, barWidth) {
    var containerHeight = yAxisParams.containerHeight, _a = yAxisParams.tickPadding, tickPadding = _a === void 0 ? 12 : _a, margins = yAxisParams.margins, yAxisTickFormat = yAxisParams.yAxisTickFormat, yAxisElement = yAxisParams.yAxisElement, yAxisPadding = yAxisParams.yAxisPadding;
    var yAxisPaddingValue = yAxisPadding !== null && yAxisPadding !== void 0 ? yAxisPadding : 0.5;
    yAxisPaddingValue = yAxisPaddingValue === 1 ? 0.99 : yAxisPaddingValue;
    var yAxisScale = (0, d3_scale_1.scaleBand)()
        .domain(dataPoints)
        .range([containerHeight - margins.bottom, margins.top])
        .padding(yAxisPaddingValue);
    var axis = isRtl ? (0, d3_axis_1.axisRight)(yAxisScale) : (0, d3_axis_1.axisLeft)(yAxisScale);
    var yAxis = axis.tickPadding(tickPadding).ticks(dataPoints);
    if (yAxisTickFormat) {
        yAxis.tickFormat(yAxisTickFormat);
    }
    yAxisElement ? (0, d3_selection_1.select)(yAxisElement).call(yAxis).selectAll('text') : '';
    return yAxisScale;
};
exports.createStringYAxisForHorizontalBarChartWithAxis = createStringYAxisForHorizontalBarChartWithAxis;
/**
 * Creating String Y axis of the chart for other chart except Horizontal Bar Chart With Axis
 * @param yAxisParams
 * @param dataPoints
 * @param isRtl
 */
var createStringYAxis = function (yAxisParams, dataPoints, isRtl, barWidth, chartType) {
    var containerHeight = yAxisParams.containerHeight, _a = yAxisParams.tickPadding, tickPadding = _a === void 0 ? 12 : _a, margins = yAxisParams.margins, yAxisTickFormat = yAxisParams.yAxisTickFormat, yAxisElement = yAxisParams.yAxisElement, _b = yAxisParams.yAxisPadding, yAxisPadding = _b === void 0 ? 0 : _b, containerWidth = yAxisParams.containerWidth;
    var yAxisScale = (0, d3_scale_1.scaleBand)()
        .domain(dataPoints)
        .range([containerHeight - margins.bottom, margins.top])
        .padding(yAxisPadding);
    if (chartType === ChartTypes.VerticalStackedBarChart) {
        yAxisScale.paddingInner(1).paddingOuter(0);
    }
    var axis = isRtl ? (0, d3_axis_1.axisRight)(yAxisScale) : (0, d3_axis_1.axisLeft)(yAxisScale);
    var yAxis = axis.tickPadding(tickPadding).tickValues(dataPoints).tickSize(0);
    if (chartType === ChartTypes.VerticalStackedBarChart) {
        axis.tickSizeInner(-(containerWidth - margins.left - margins.right));
    }
    if (yAxisTickFormat) {
        yAxis.tickFormat(yAxisTickFormat);
    }
    yAxisElement ? (0, d3_selection_1.select)(yAxisElement).call(yAxis).selectAll('text') : '';
    return yAxisScale;
};
exports.createStringYAxis = createStringYAxis;
/**
 * For area chart and line chart, while displaying stackCallout, Need to form a callout data object.
 * This methos creates an object for those 2 charts.
 * @param values
 */
// changing the type to any as it is used by multiple charts with different data types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function calloutData(values) {
    var combinedResult = [];
    values.forEach(function (line) {
        var elements = line.data
            .filter(function (point) { return !point.hideCallout; })
            .map(function (point) {
            return tslib_1.__assign(tslib_1.__assign({}, point), { legend: line.legend, color: line.color, index: line.index });
        });
        combinedResult = combinedResult.concat(elements);
    });
    var xValToDataPoints = {};
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    combinedResult.forEach(function (ele) {
        var xValue = ele.x instanceof Date ? ele.x.getTime() : ele.x;
        if (xValue in xValToDataPoints) {
            xValToDataPoints[xValue].push({
                legend: ele.legend,
                y: ele.y,
                color: ele.color,
                xAxisCalloutData: ele.xAxisCalloutData,
                yAxisCalloutData: ele.yAxisCalloutData,
                callOutAccessibilityData: ele.callOutAccessibilityData,
                index: ele.index,
            });
        }
        else {
            xValToDataPoints[xValue] = [
                {
                    legend: ele.legend,
                    y: ele.y,
                    color: ele.color,
                    xAxisCalloutData: ele.xAxisCalloutData,
                    yAxisCalloutData: ele.yAxisCalloutData,
                    callOutAccessibilityData: ele.callOutAccessibilityData,
                    index: ele.index,
                },
            ];
        }
    });
    var result = Object.keys(xValToDataPoints).map(function (xValue) {
        var originalXValue = isNaN(Number(xValue)) ? xValue : Number(xValue);
        return { x: originalXValue, values: xValToDataPoints[xValue] };
    });
    return result;
}
exports.calloutData = calloutData;
function getUnique(arr, comp) {
    var unique = arr
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        .map(function (e) { return e[comp]; })
        // store the keys of the unique objects
        .map(function (e, i, final) { return final.indexOf(e) === i && i; })
        // eliminate the dead keys & store unique objects
        .filter(function (e) { return arr[e]; })
        .map(function (e) { return arr[e]; });
    return unique;
}
exports.getUnique = getUnique;
/**
 * This function takes two paramerter
 * 1. an array of strings
 * 2. a string value
 * if the value is not present in the given array then it will return the new
 * array by appending the value to the present arrray.
 *
 * if the value is already present in  the given array then it will return the new
 * array by deleteing the value from the the array
 * @param array
 * @param value
 */
function silceOrAppendToArray(array, value) {
    var pos = array.indexOf(value);
    if (pos === -1) {
        return tslib_1.__spreadArray(tslib_1.__spreadArray([], array, true), [value], false);
    }
    else {
        return array.slice(0, pos).concat(array.slice(pos + 1));
    }
}
exports.silceOrAppendToArray = silceOrAppendToArray;
exports.DEFAULT_WRAP_WIDTH = 10;
/**
 * This method used for wrapping of x axis labels (tick values).
 * It breaks down given text value by space separated and calculates the total height needed to display all the words.
 * That value = removal value. This value needs to be remove from total svg height, svg will shrink and
 * total text will be displayed.
 * @export
 * @param {IWrapLabelProps} wrapLabelProps
 * @returns
 */
function createWrapOfXLabels(wrapLabelProps) {
    var node = wrapLabelProps.node, xAxis = wrapLabelProps.xAxis, noOfCharsToTruncate = wrapLabelProps.noOfCharsToTruncate, showXAxisLablesTooltip = wrapLabelProps.showXAxisLablesTooltip, _a = wrapLabelProps.width, width = _a === void 0 ? exports.DEFAULT_WRAP_WIDTH : _a;
    if (node === null) {
        return;
    }
    var axisNode = (0, d3_selection_1.select)(node).call(xAxis);
    var removeVal = 0;
    var maxLines = 1;
    axisNode.selectAll('.tick text').each(function () {
        var text = (0, d3_selection_1.select)(this);
        var totalWord = text.text();
        var truncatedWord = "".concat(text.text().slice(0, noOfCharsToTruncate), "...");
        var totalWordLength = text.text().length;
        var words = text.text().split(/\s+/).reverse();
        var word = '';
        var line = [];
        var lineNumber = 0;
        var lineHeight = 1.1; // ems
        var y = text.attr('y');
        var dy = parseFloat(text.attr('dy'));
        var tspan = text
            .text(null)
            .append('tspan')
            .attr('x', 0)
            .attr('y', y)
            .attr('id', 'BaseSpan')
            .attr('dy', dy + 'em')
            .attr('data-', totalWord);
        if (showXAxisLablesTooltip && totalWordLength > noOfCharsToTruncate) {
            tspan = text
                .append('tspan')
                .attr('id', 'showDots')
                .attr('x', 0)
                .attr('y', y)
                .attr('dy', dy + 'em')
                .text(truncatedWord);
        }
        else if (showXAxisLablesTooltip && totalWordLength <= noOfCharsToTruncate) {
            tspan = text
                .append('tspan')
                .attr('id', 'LessLength')
                .attr('x', 0)
                .attr('y', y)
                .attr('dy', dy + 'em')
                .text(totalWord);
        }
        else {
            while ((word = words.pop())) {
                line.push(word);
                tspan.text(line.join(' '));
                if (tspan.node().getComputedTextLength() > width && line.length > 1) {
                    line.pop();
                    tspan.text(line.join(' '));
                    line = [word];
                    tspan = text
                        .append('tspan')
                        .attr('id', 'WordBreakId')
                        .attr('x', 0)
                        .attr('y', y)
                        .attr('dy', ++lineNumber * lineHeight + dy + 'em')
                        .text(word);
                }
            }
        }
        maxLines = Math.max(maxLines, lineNumber + 1);
    });
    if (!showXAxisLablesTooltip) {
        var maxHeight = 12; // intial value to render corretly first time
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        var outerHTMLElement = document.getElementById('WordBreakId');
        var BoxCordinates = outerHTMLElement && outerHTMLElement.getBoundingClientRect();
        var boxHeight = BoxCordinates && BoxCordinates.height;
        if (boxHeight > maxHeight) {
            maxHeight = boxHeight;
        }
        removeVal = (maxLines - 1) * maxHeight;
    }
    return removeVal > 0 ? removeVal : 0;
}
exports.createWrapOfXLabels = createWrapOfXLabels;
/**
 * This method used for wrapping of y axis labels (tick values).
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function createYAxisLabels(node, 
// eslint-disable-next-line @typescript-eslint/no-explicit-any
yAxis, noOfCharsToTruncate, truncateLabel, isRtl) {
    if (node === null) {
        return;
    }
    var axisNode = (0, d3_selection_1.select)(node).call(yAxis);
    axisNode.selectAll('.tick text').each(function () {
        var text = (0, d3_selection_1.select)(this);
        var totalWord = text.text();
        var truncatedWord = isRtl
            ? "...".concat(text.text().slice(0, noOfCharsToTruncate))
            : "".concat(text.text().slice(0, noOfCharsToTruncate), "...");
        var totalWordLength = text.text().length;
        var padding = 0; // ems
        var y = text.attr('y');
        var x = text.attr('x');
        var dy = parseFloat(text.attr('dy'));
        var dx = 0;
        text
            .text(null)
            .append('tspan')
            .attr('x', x)
            .attr('y', y)
            .attr('id', 'BaseSpan')
            .attr('dy', dy + 'em')
            .attr('data-', totalWord);
        if (truncateLabel && totalWordLength > noOfCharsToTruncate) {
            text
                .append('tspan')
                .attr('id', 'showDots')
                .attr('x', x)
                .attr('y', y)
                .attr('dy', dy + 'em')
                .attr('dx', padding + dx + 'em')
                .text(truncatedWord);
        }
        else {
            text
                .append('tspan')
                .attr('id', 'LessLength')
                .attr('x', x)
                .attr('y', y)
                .attr('dx', padding + dx + 'em')
                .text(totalWord);
        }
    });
}
exports.createYAxisLabels = createYAxisLabels;
var wrapContent = function (content, id, maxWidth) {
    var textElement = (0, d3_selection_1.select)("#".concat(id));
    textElement.text(content);
    if (!textElement.node()) {
        return false;
    }
    var isOverflowing = false;
    var textLength = textElement.node().getComputedTextLength();
    while (textLength > maxWidth && content.length > 0) {
        content = content.slice(0, -1);
        textElement.text(content + '...');
        isOverflowing = true;
        textLength = textElement.node().getComputedTextLength();
    }
    return isOverflowing;
};
exports.wrapContent = wrapContent;
/**
 * Calculates the width of the longest axis label in pixels
 */
var calculateLongestLabelWidth = function (labels, query) {
    if (query === void 0) { query = 'none'; }
    var maxLabelWidth = 0;
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    if (ctx) {
        var axisText = document.querySelector(query);
        if (axisText) {
            var styles = window.getComputedStyle(axisText, null);
            var fontWeight = styles.getPropertyValue('font-weight');
            var fontSize = styles.getPropertyValue('font-size');
            var fontFamily = styles.getPropertyValue('font-family');
            ctx.font = "".concat(fontWeight, " ").concat(fontSize, " ").concat(fontFamily);
        }
        else {
            ctx.font = '600 10px "Segoe UI"';
        }
        labels.forEach(function (label) {
            maxLabelWidth = Math.max(ctx.measureText(label.toString()).width, maxLabelWidth);
        });
    }
    return maxLabelWidth;
};
exports.calculateLongestLabelWidth = calculateLongestLabelWidth;
/**
 * This method displays a tooltip to the x axis lables(tick values)
 * when prop 'showXAxisLablesTooltip' enables to the respected chart.
 * On hover of the truncated word(at x axis labels tick), a tooltip will be appeared.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function tooltipOfAxislabels(axistooltipProps) {
    var tooltipCls = axistooltipProps.tooltipCls, axis = axistooltipProps.axis, id = axistooltipProps.id;
    if (axis === null) {
        return null;
    }
    var div = (0, d3_selection_1.select)('body').append('div').attr('id', id).attr('class', tooltipCls).style('opacity', 0);
    var aa = axis.selectAll('#BaseSpan')._groups[0];
    var baseSpanLength = aa && Object.keys(aa).length;
    var originalDataArray = [];
    for (var i = 0; i < baseSpanLength; i++) {
        var originalData = aa[i].dataset && Object.values(aa[i].dataset)[0];
        originalDataArray.push(originalData);
    }
    var tickObject = axis.selectAll('.tick')._groups[0];
    var tickObjectLength = tickObject && Object.keys(tickObject).length;
    var _loop_1 = function (i) {
        var d1 = tickObject[i];
        (0, d3_selection_1.select)(d1)
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            .on('mouseover', function (event, d) {
            div.style('opacity', 0.9);
            div
                .text(originalDataArray[i])
                .style('left', event.pageX + 'px')
                .style('top', event.pageY - 28 + 'px');
        })
            .on('mouseout', function (d) {
            div.style('opacity', 0);
        });
    };
    for (var i = 0; i < tickObjectLength; i++) {
        _loop_1(i);
    }
}
exports.tooltipOfAxislabels = tooltipOfAxislabels;
/**
 * Find the axis type of line chart and area chart from given data
 * @param points
 */
function getXAxisType(points) {
    var isXAxisDateType = false;
    if (points && points.length > 0) {
        points.forEach(function (chartData) {
            if (chartData.data.length > 0) {
                isXAxisDateType = chartData.data[0].x instanceof Date;
                return;
            }
        });
    }
    return isXAxisDateType;
}
exports.getXAxisType = getXAxisType;
/**
 * Calculates Domain and range values for Numeric X axis.
 * This method calculates Area cart and line chart.
 * @export
 * @param {ILineChartPoints[]} points
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @returns {IDomainNRange}
 */
function domainRangeOfNumericForAreaChart(points, margins, width, isRTL) {
    var isScatterPolar = isScatterPolarSeries(points);
    var xMin = (0, d3_array_1.min)(points, function (point) {
        return (0, d3_array_1.min)(point.data, function (item) { return item.x; });
    });
    var xMax = (0, d3_array_1.max)(points, function (point) {
        return (0, d3_array_1.max)(point.data, function (item) {
            return item.x;
        });
    });
    var rStartValue = margins.left;
    var rEndValue = width - margins.right;
    return isRTL
        ? { dStartValue: isScatterPolar ? 1 : xMax, dEndValue: isScatterPolar ? -1 : xMin, rStartValue: rStartValue, rEndValue: rEndValue }
        : { dStartValue: isScatterPolar ? -1 : xMin, dEndValue: isScatterPolar ? 1 : xMax, rStartValue: rStartValue, rEndValue: rEndValue };
}
exports.domainRangeOfNumericForAreaChart = domainRangeOfNumericForAreaChart;
/**
 * Groups HorizontalBarChart With Axis data based on YValue
 * Used for stacked case
 * @param {IHorizontalBarChartWithAxisDataPoint[]} chartData
 * @returns {IHorizontalBarChartWithAxisDataPoint[][]}
 */
function groupChartDataByYValue(chartData) {
    var map = {};
    chartData.forEach(function (dataPoint) {
        var key = dataPoint.y;
        if (!map[key]) {
            map[key] = [];
        }
        map[key].push(dataPoint);
    });
    return Object.values(map);
}
exports.groupChartDataByYValue = groupChartDataByYValue;
/**
 * Calculates maximum domain values for Numeric x axis for both positive and negative values
 * works for Horizontal Bar Chart With axis
 * @param {IHorizontalBarChartWithAxisDataPoint[][]} stackedChartData
 * @returns {number}
 */
function computeLongestBars(stackedChartData, X_ORIGIN) {
    var longestPositiveBar = 0;
    var longestNegativeBar = 0;
    stackedChartData.forEach(function (group) {
        var positiveBarTotal = group.reduce(function (acc, point) { return acc + (point.x > 0 ? point.x : 0); }, X_ORIGIN);
        var negativeBarTotal = group.reduce(function (acc, point) { return acc + (point.x < 0 ? point.x : 0); }, X_ORIGIN);
        longestPositiveBar = Math.max(longestPositiveBar, positiveBarTotal);
        longestNegativeBar = Math.min(longestNegativeBar, negativeBarTotal);
    });
    return { longestPositiveBar: longestPositiveBar, longestNegativeBar: longestNegativeBar };
}
exports.computeLongestBars = computeLongestBars;
/**
 * Calculates Domain and range values for Numeric X axis.
 * This method calculates Horizontal Chart with Axis
 * @export
 * @param {ILineChartPoints[]} points
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @returns {IDomainNRange}
 */
function domainRangeOfNumericForHorizontalBarChartWithAxis(points, margins, containerWidth, isRTL, shiftX, X_ORIGIN) {
    var longestBars = computeLongestBars(groupChartDataByYValue(points), X_ORIGIN);
    var xMax = longestBars.longestPositiveBar;
    var xMin = longestBars.longestNegativeBar;
    var rMin = isRTL ? margins.left : margins.left + shiftX;
    var rMax = isRTL ? containerWidth - margins.right - shiftX : containerWidth - margins.right;
    return isRTL
        ? { dStartValue: xMax, dEndValue: Math.min(xMin, X_ORIGIN), rStartValue: rMin, rEndValue: rMax }
        : { dStartValue: Math.min(xMin, X_ORIGIN), dEndValue: xMax, rStartValue: rMin, rEndValue: rMax };
}
exports.domainRangeOfNumericForHorizontalBarChartWithAxis = domainRangeOfNumericForHorizontalBarChartWithAxis;
/**
 * Calculates Range values of x Axis string axis
 * For String axis, we need to give domain values (Not start and end array values)
 * So sending 0 as domain values. Domain will be handled at creation of string axis
 * For charts stacked bar chart, grouped vertical bar chart, HeatMapChart and Vertical bar chart
 * @export
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @returns {IDomainNRange}
 */
function domainRangeOfXStringAxis(margins, width, isRTL) {
    var rMin = margins.left;
    var rMax = width - margins.right;
    return isRTL
        ? { dStartValue: 0, dEndValue: 0, rStartValue: rMax, rEndValue: rMin }
        : { dStartValue: 0, dEndValue: 0, rStartValue: rMin, rEndValue: rMax };
}
exports.domainRangeOfXStringAxis = domainRangeOfXStringAxis;
/**
 * Calculate domain and range values to the Vertical stacked bar chart - For Numeric axis
 * @export
 * @param {IDataPoint[]} points
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @param {number} barWidth
 * @returns {IDomainNRange}
 */
function domainRangeOfVSBCNumeric(points, margins, width, isRTL, barWidth) {
    var xMin = (0, d3_array_1.min)(points, function (point) { return point.x; });
    var xMax = (0, d3_array_1.max)(points, function (point) { return point.x; });
    var rMax = margins.left;
    var rMin = width - margins.right;
    return isRTL
        ? { dStartValue: xMax, dEndValue: xMin, rStartValue: rMax, rEndValue: rMin }
        : { dStartValue: xMin, dEndValue: xMax, rStartValue: rMax, rEndValue: rMin };
}
exports.domainRangeOfVSBCNumeric = domainRangeOfVSBCNumeric;
/**
 * Calculates Domain and range values for Date X axis.
 * This method calculates Bar chart.
 * @export
 * @param {IVerticalBarChartDataPoint[]} points
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @param {Date[] | number[]} tickValues
 * @returns {IDomainNRange}
 */
function domainRangeOfDateForAreaLineVerticalBarChart(points, margins, width, isRTL, tickValues, chartType, barWidth) {
    if (tickValues === void 0) { tickValues = []; }
    var sDate;
    var lDate;
    if (chartType === ChartTypes.AreaChart || chartType === ChartTypes.LineChart) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        sDate = (0, d3_array_1.min)(points, function (point) {
            return (0, d3_array_1.min)(point.data, function (item) {
                return item.x;
            });
        });
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        lDate = (0, d3_array_1.max)(points, function (point) {
            return (0, d3_array_1.max)(point.data, function (item) {
                return item.x;
            });
        });
        // Need to draw graph with given small and large date
        // (Which Involves customization of date axis tick values)
        // That may be Either from given graph data or from prop 'tickValues' date values.
        // So, Finding smallest and largest dates
        sDate = (0, d3_array_1.min)(tslib_1.__spreadArray(tslib_1.__spreadArray([], tickValues, true), [sDate], false));
        lDate = (0, d3_array_1.max)(tslib_1.__spreadArray(tslib_1.__spreadArray([], tickValues, true), [lDate], false));
    }
    else {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        sDate = (0, d3_array_1.min)(points, function (point) { return point.x; });
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        lDate = (0, d3_array_1.max)(points, function (point) { return point.x; });
    }
    var rStartValue = margins.left;
    var rEndValue = width - margins.right;
    return isRTL
        ? { dStartValue: lDate, dEndValue: sDate, rStartValue: rStartValue, rEndValue: rEndValue }
        : { dStartValue: sDate, dEndValue: lDate, rStartValue: rStartValue, rEndValue: rEndValue };
}
exports.domainRangeOfDateForAreaLineVerticalBarChart = domainRangeOfDateForAreaLineVerticalBarChart;
/**
 * Calculate domain and range values to the Vertical bar chart - For Numeric axis
 * @export
 * @param {IDataPoint[]} points
 * @param {IMargins} margins
 * @param {number} containerWidth
 * @param {boolean} isRTL
 * @param {number} barWidth
 * @returns {IDomainNRange}
 */
function domainRageOfVerticalNumeric(points, margins, containerWidth, isRTL, barWidth) {
    var xMax = (0, d3_array_1.max)(points, function (point) { return point.x; });
    var xMin = (0, d3_array_1.min)(points, function (point) { return point.x; });
    var rMin = margins.left;
    var rMax = containerWidth - margins.right;
    return isRTL
        ? { dStartValue: xMax, dEndValue: xMin, rStartValue: rMin, rEndValue: rMax }
        : { dStartValue: xMin, dEndValue: xMax, rStartValue: rMin, rEndValue: rMax };
}
exports.domainRageOfVerticalNumeric = domainRageOfVerticalNumeric;
/**
 * Calculating start and ending values of the Area chart and LineChart
 * @export
 * @param {ILineChartPoints[]} points
 * @returns {{ startValue: number; endValue: number }}
 */
function findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale) {
    var values = [];
    points.forEach(function (point) {
        if (!useSecondaryYScale === !point.useSecondaryYScale) {
            point.data.forEach(function (data) {
                values.push(data.y);
            });
        }
    });
    return {
        startValue: (0, d3_array_1.min)(values),
        endValue: (0, d3_array_1.max)(values),
    };
}
exports.findNumericMinMaxOfY = findNumericMinMaxOfY;
/**
 * Find the minimum and maximum values of the vertical stacked bar chart y axis data point. Used for create y axis.
 * @export
 * @param {IDataPoint[]} dataset
 * @returns {{ startValue: number; endValue: number }}
 */
function findVSBCNumericMinMaxOfY(dataset) {
    var yMax = (0, d3_array_1.max)(dataset, function (point) { return point.y; });
    var yMin = (0, d3_array_1.min)(dataset, function (point) { return point.y; });
    return { startValue: yMin, endValue: yMax };
}
exports.findVSBCNumericMinMaxOfY = findVSBCNumericMinMaxOfY;
/**
 * Fins the min and max values of the vertical bar chart y axis data point.
 * @export
 * @param {IVerticalBarChartDataPoint[]} points
 * @returns {{ startValue: number; endValue: number }}
 */
function findVerticalNumericMinMaxOfY(points, yAxisType, useSecondaryYScale) {
    var values = [];
    points.forEach(function (point) {
        if (!useSecondaryYScale) {
            values.push(point.y);
        }
        if (typeof point.lineData !== 'undefined') {
            if (!useSecondaryYScale === !point.lineData.useSecondaryYScale) {
                values.push(point.lineData.y);
            }
        }
    });
    return { startValue: (0, d3_array_1.min)(values), endValue: (0, d3_array_1.max)(values) };
}
exports.findVerticalNumericMinMaxOfY = findVerticalNumericMinMaxOfY;
/**
 * Fins the min and max values of the horizontal bar chart y axis data point.
 * @export
 * @param {IHorizontalBarChartWithAxisDataPoint[]|IGanttChartDataPoint[]} points
 * @returns {{ startValue: number; endValue: number }}
 */
function findHBCWANumericMinMaxOfY(points, yAxisType) {
    if (yAxisType !== undefined && yAxisType === YAxisType.NumericAxis) {
        var yMax = (0, d3_array_1.max)(points, function (point) { return point.y; });
        var yMin = (0, d3_array_1.min)(points, function (point) { return point.y; });
        return { startValue: yMin, endValue: yMax };
    }
    return { startValue: 0, endValue: 0 };
}
exports.findHBCWANumericMinMaxOfY = findHBCWANumericMinMaxOfY;
/**
 * @param p string or number or Date
 *
 * This function takes the single data point of the x-aixs
 * and decides what is the x-axis
 */
var getTypeOfAxis = function (p, isXAxis) {
    if (isXAxis) {
        switch (typeof p) {
            case 'string':
                return XAxisTypes.StringAxis;
            case 'number':
                return XAxisTypes.NumericAxis;
            default:
                return XAxisTypes.DateAxis;
        }
    }
    else {
        switch (typeof p) {
            case 'string':
                return YAxisType.StringAxis;
            case 'number':
                return YAxisType.NumericAxis;
            default:
                return YAxisType.DateAxis;
        }
    }
};
exports.getTypeOfAxis = getTypeOfAxis;
/**
 * we need to make sure that if we add any property to this, then
 * we need to also add that in  pointTypes below and vise-versa
 */
var Points;
(function (Points) {
    Points[Points["circle"] = 0] = "circle";
    Points[Points["square"] = 1] = "square";
    Points[Points["triangle"] = 2] = "triangle";
    Points[Points["diamond"] = 3] = "diamond";
    Points[Points["pyramid"] = 4] = "pyramid";
    Points[Points["hexagon"] = 5] = "hexagon";
    Points[Points["pentagon"] = 6] = "pentagon";
    Points[Points["octagon"] = 7] = "octagon";
})(Points || (exports.Points = Points = {}));
var CustomPoints;
(function (CustomPoints) {
    CustomPoints[CustomPoints["dottedLine"] = 0] = "dottedLine";
})(CustomPoints || (exports.CustomPoints = CustomPoints = {}));
/**
 * we need to make sure that if we add any property to this, then
 * we need to also add that in enum Point and vise-versa
 */
exports.pointTypes = (_a = {},
    _a[Points.circle] = {
        widthRatio: 1,
    },
    _a[Points.square] = {
        widthRatio: 1,
    },
    _a[Points.triangle] = {
        widthRatio: 1,
    },
    _a[Points.diamond] = {
        widthRatio: 1,
    },
    _a[Points.pyramid] = {
        widthRatio: 1,
    },
    _a[Points.hexagon] = {
        widthRatio: 2,
    },
    _a[Points.pentagon] = {
        widthRatio: 1.168,
    },
    _a[Points.octagon] = {
        widthRatio: 2.414,
    },
    _a);
/**
 * @param accessibleData accessible data
 * @param role string to define role of tag
 * @param isDataFocusable boolean
 * function returns the accessibility data object
 */
var getAccessibleDataObject = function (accessibleData, role, isDataFocusable) {
    if (role === void 0) { role = 'text'; }
    if (isDataFocusable === void 0) { isDataFocusable = true; }
    accessibleData = accessibleData !== null && accessibleData !== void 0 ? accessibleData : {};
    return {
        role: role,
        'data-is-focusable': isDataFocusable,
        'aria-label': accessibleData.ariaLabel,
        'aria-labelledby': accessibleData.ariaLabelledBy,
        'aria-describedby': accessibleData.ariaDescribedBy,
    };
};
exports.getAccessibleDataObject = getAccessibleDataObject;
function rotateXAxisLabels(rotateLabelProps) {
    var node = rotateLabelProps.node, xAxis = rotateLabelProps.xAxis;
    if (node === null || xAxis === null) {
        return;
    }
    var maxHeight = 0;
    var xAxisTranslations = [];
    (0, d3_selection_1.select)(node)
        .call(xAxis)
        .selectAll('.tick')
        .each(function () {
        var translateValue = this.getAttribute('transform');
        if ((translateValue === null || translateValue === void 0 ? void 0 : translateValue.indexOf('rotate')) === -1) {
            var translatePair = translateValue
                .substring(translateValue.indexOf('(') + 1, translateValue.indexOf(')'))
                .split(',');
            if (translatePair.length === 2) {
                xAxisTranslations.push(translatePair[0]);
                this.setAttribute('transform', "translate(".concat(translatePair[0], ",0)rotate(-45)"));
            }
        }
        var BoxCordinates = this.getBoundingClientRect();
        var boxHeight = BoxCordinates && BoxCordinates.height;
        if (boxHeight > maxHeight) {
            maxHeight = boxHeight;
        }
    });
    var idx = 0;
    (0, d3_selection_1.select)(node)
        .call(xAxis)
        .selectAll('.tick')
        .each(function () {
        if (xAxisTranslations.length > idx) {
            this.setAttribute('transform', "translate(".concat(xAxisTranslations[idx], ",").concat(maxHeight / 2, ")rotate(-45)")); // Translate y by max height/2
            idx += 1;
        }
    });
    return Math.floor(maxHeight / 1.414); // Compute maxHeight/tanInverse(45) to get the vertical height of labels.
}
exports.rotateXAxisLabels = rotateXAxisLabels;
function wrapTextInsideDonut(selectorClass, maxWidth) {
    var idx = 0;
    (0, d3_selection_1.selectAll)(".".concat(selectorClass)).each(function () {
        var text = (0, d3_selection_1.select)(this);
        var words = text.text().split(/\s+/).reverse();
        var word = '';
        var line = [];
        var lineNumber = 0;
        var lineHeight = 1.1; // ems
        var y = text.attr('y');
        var tspan = text
            .text(null)
            .append('tspan')
            .attr('id', "WordBreakId-".concat(idx, "-").concat(lineNumber))
            .attr('x', 0)
            .attr('y', y)
            .attr('dy', lineNumber++ * lineHeight + 'em');
        while ((word = words.pop())) {
            line.push(word);
            tspan.text(line.join(' ') + ' ');
            if (tspan.node().getComputedTextLength() > maxWidth && line.length > 1) {
                line.pop();
                tspan.text(line.join(' ') + ' ');
                line = [word];
                tspan = text
                    .append('tspan')
                    .attr('id', "WordBreakId-".concat(idx, "-").concat(lineNumber))
                    .attr('x', 0)
                    .attr('y', y)
                    .attr('dy', lineNumber++ * lineHeight + 'em')
                    .text(word);
            }
        }
        idx += 1;
    });
}
exports.wrapTextInsideDonut = wrapTextInsideDonut;
function formatScientificLimitWidth(value) {
    return yAxisTickFormatterInternal(value, true);
}
exports.formatScientificLimitWidth = formatScientificLimitWidth;
var DEFAULT_BAR_WIDTH = 16;
var MIN_BAR_WIDTH = 1;
var getBarWidth = function (barWidthProp, maxBarWidthProp, adjustedValue, modeProp) {
    if (adjustedValue === void 0) { adjustedValue = DEFAULT_BAR_WIDTH; }
    var barWidth;
    if (barWidthProp === 'auto' || modeProp === 'histogram') {
        barWidth = adjustedValue;
    }
    else if (typeof barWidthProp === 'number') {
        barWidth = barWidthProp;
    }
    else {
        barWidth = Math.min(adjustedValue, DEFAULT_BAR_WIDTH);
    }
    if (typeof maxBarWidthProp === 'number') {
        barWidth = Math.min(barWidth, maxBarWidthProp);
    }
    barWidth = Math.max(barWidth, MIN_BAR_WIDTH);
    return barWidth;
};
exports.getBarWidth = getBarWidth;
var getScalePadding = function (prop, shorthandProp, defaultValue) {
    if (defaultValue === void 0) { defaultValue = 0; }
    var padding = typeof prop === 'number' ? prop : typeof shorthandProp === 'number' ? shorthandProp : defaultValue;
    padding = Math.max(0, Math.min(padding, 1));
    return padding;
};
exports.getScalePadding = getScalePadding;
var isScalePaddingDefined = function (prop, shorthandProp) {
    return typeof prop === 'number' || typeof shorthandProp === 'number';
};
exports.isScalePaddingDefined = isScalePaddingDefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function getSecureProps(props) {
    if (props === void 0) { props = {}; }
    var dangerouslySetInnerHTML = props.dangerouslySetInnerHTML, result = tslib_1.__rest(props, ["dangerouslySetInnerHTML"]);
    return result;
}
exports.getSecureProps = getSecureProps;
function areArraysEqual(arr1, arr2) {
    if (arr1 === arr2) {
        return true;
    }
    if (!arr1 && !arr2) {
        return true;
    }
    if (!arr1 || !arr2 || arr1.length !== arr2.length) {
        return false;
    }
    for (var i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i]) {
            return false;
        }
    }
    return true;
}
exports.areArraysEqual = areArraysEqual;
var cssVarRegExp = /var\((--[a-zA-Z0-9\-]+)\)/g;
function resolveCSSVariables(chartContainer, styleRules) {
    var containerStyles = getComputedStyle(chartContainer);
    return styleRules.replace(cssVarRegExp, function (match, group1) {
        return containerStyles.getPropertyValue(group1);
    });
}
exports.resolveCSSVariables = resolveCSSVariables;
function copyStyle(properties, fromEl, toEl) {
    var styles = getComputedStyle(fromEl);
    if (Array.isArray(properties)) {
        properties.forEach(function (prop) {
            (0, d3_selection_1.select)(toEl).style(prop, styles.getPropertyValue(prop));
        });
    }
    else {
        Object.entries(properties).forEach(function (_a) {
            var fromProp = _a[0], toProp = _a[1];
            (0, d3_selection_1.select)(toEl).style(toProp, styles.getPropertyValue(fromProp));
        });
    }
}
exports.copyStyle = copyStyle;
var MEASUREMENT_SPAN_STYLE = {
    position: 'absolute',
    visibility: 'hidden',
    top: '-20000px',
    left: 0,
    padding: 0,
    margin: 0,
    border: 'none',
    whiteSpace: 'pre',
};
var MEASUREMENT_SPAN_ID = (0, react_1.getId)('measurement_span_');
var createMeasurementSpan = function (text, className, parentElement) {
    var measurementSpan = document.getElementById(MEASUREMENT_SPAN_ID);
    if (!measurementSpan) {
        measurementSpan = document.createElement('span');
        measurementSpan.setAttribute('id', MEASUREMENT_SPAN_ID);
        measurementSpan.setAttribute('aria-hidden', 'true');
        if (parentElement) {
            parentElement.appendChild(measurementSpan);
        }
        else {
            document.body.appendChild(measurementSpan);
        }
    }
    measurementSpan.setAttribute('class', className);
    Object.assign(measurementSpan.style, MEASUREMENT_SPAN_STYLE);
    measurementSpan.textContent = "".concat(text);
    return measurementSpan;
};
exports.createMeasurementSpan = createMeasurementSpan;
function getCurveFactory(curve, defaultFactory) {
    if (defaultFactory === void 0) { defaultFactory = d3_shape_1.curveLinear; }
    if (typeof curve === 'function') {
        return curve;
    }
    switch (curve) {
        case 'linear':
            return d3_shape_1.curveLinear;
        case 'natural':
            return d3_shape_1.curveNatural;
        case 'step':
            return d3_shape_1.curveStep;
        case 'stepAfter':
            return d3_shape_1.curveStepAfter;
        case 'stepBefore':
            return d3_shape_1.curveStepBefore;
        default:
            return defaultFactory;
    }
}
exports.getCurveFactory = getCurveFactory;
/**
 * Calculates Domain and range values for Date X axis for scatter chart.
 * @export
 * @param {LineChartPoints[]} points
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @param {Date[] | number[]} tickValues
 * @returns {IDomainNRange}
 */
function domainRangeOfDateForScatterChart(points, margins, width, isRTL, tickValues) {
    if (tickValues === void 0) { tickValues = []; }
    var sDate;
    var lDate;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    sDate = (0, d3_array_1.min)(points, function (point) {
        return (0, d3_array_1.min)(point.data, function (item) {
            return item.x;
        });
    });
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    lDate = (0, d3_array_1.max)(points, function (point) {
        return (0, d3_array_1.max)(point.data, function (item) {
            return item.x;
        });
    });
    var xPadding = (lDate.getTime() - sDate.getTime()) * 0.1;
    sDate = new Date(sDate.getTime() - xPadding);
    lDate = new Date(lDate.getTime() + xPadding);
    // Need to draw graph with given small and large date
    // (Which Involves customization of date axis tick values)
    // That may be Either from given graph data or from prop 'tickValues' date values.
    // So, Finding smallest and largest dates
    sDate = (0, d3_array_1.min)(tslib_1.__spreadArray(tslib_1.__spreadArray([], tickValues, true), [sDate], false));
    lDate = (0, d3_array_1.max)(tslib_1.__spreadArray(tslib_1.__spreadArray([], tickValues, true), [lDate], false));
    var rStartValue = margins.left;
    var rEndValue = width - margins.right;
    return isRTL
        ? { dStartValue: lDate, dEndValue: sDate, rStartValue: rStartValue, rEndValue: rEndValue }
        : { dStartValue: sDate, dEndValue: lDate, rStartValue: rStartValue, rEndValue: rEndValue };
}
exports.domainRangeOfDateForScatterChart = domainRangeOfDateForScatterChart;
/**
 * Calculates Domain and range values for Numeric X axis for scatter chart.
 * @export
 * @param {LineChartPoints[]} points
 * @param {IMargins} margins
 * @param {number} width
 * @param {boolean} isRTL
 * @returns {IDomainNRange}
 */
function domainRangeOfNumericForScatterChart(points, margins, width, isRTL) {
    var isScatterPolar = isScatterPolarSeries(points);
    var xMin = (0, d3_array_1.min)(points, function (point) {
        return (0, d3_array_1.min)(point.data, function (item) { return item.x; });
    });
    var xMax = (0, d3_array_1.max)(points, function (point) {
        return (0, d3_array_1.max)(point.data, function (item) {
            return item.x;
        });
    });
    var xPadding = (xMax - xMin) * 0.1;
    xMin = xMin - xPadding;
    xMax = xMax + xPadding;
    var rStartValue = margins.left;
    var rEndValue = width - margins.right;
    return isRTL
        ? { dStartValue: isScatterPolar ? 1 : xMax, dEndValue: isScatterPolar ? -1 : xMin, rStartValue: rStartValue, rEndValue: rEndValue }
        : { dStartValue: isScatterPolar ? -1 : xMin, dEndValue: isScatterPolar ? 1 : xMax, rStartValue: rStartValue, rEndValue: rEndValue };
}
exports.domainRangeOfNumericForScatterChart = domainRangeOfNumericForScatterChart;
var truncateString = function (str, maxLength, ellipsis) {
    if (ellipsis === void 0) { ellipsis = '...'; }
    if (str.length <= maxLength) {
        return str;
    }
    return str.slice(0, maxLength) + ellipsis;
};
exports.truncateString = truncateString;
var categoryOrderRegex = /(category|total|sum|min|max|mean|median) (ascending|descending)/;
/**
 * @see {@link https://github.com/plotly/plotly.js/blob/master/src/plots/plots.js#L3041}
 */
var sortAxisCategories = function (categoryToValues, categoryOrder) {
    if (Array.isArray(categoryOrder)) {
        var result_1 = [];
        var seen_1 = new Set();
        // Add elements from categoryOrder array that are in categoryToValues, in the array's order
        categoryOrder.forEach(function (category) {
            if (categoryToValues[category] && !seen_1.has(category)) {
                result_1.push(category);
                seen_1.add(category);
            }
        });
        // Append any keys from categoryToValues not already in result
        Object.keys(categoryToValues).forEach(function (category) {
            if (!seen_1.has(category)) {
                result_1.push(category);
            }
        });
        return result_1;
    }
    var match = categoryOrder === null || categoryOrder === void 0 ? void 0 : categoryOrder.match(categoryOrderRegex);
    if (match) {
        var aggregator_1 = match[1];
        var order = match[2];
        if (aggregator_1 === 'category') {
            var result = Object.keys(categoryToValues).sort();
            return order === 'descending' ? result.reverse() : result;
        }
        var aggFn_1 = {
            min: d3_array_1.min,
            max: d3_array_1.max,
            sum: d3_array_1.sum,
            total: d3_array_1.sum,
            mean: d3_array_1.mean,
            median: d3_array_1.median,
        };
        var sortAscending = function (a, b) {
            return a[1] - b[1];
        };
        var sortDescending = function (a, b) {
            return b[1] - a[1];
        };
        var categoriesAggregatedValue_1 = [];
        Object.keys(categoryToValues).forEach(function (category) {
            categoriesAggregatedValue_1.push([category, aggFn_1[aggregator_1](categoryToValues[category]) || 0]);
        });
        categoriesAggregatedValue_1.sort(order === 'descending' ? sortDescending : sortAscending);
        return categoriesAggregatedValue_1.map(function (_a) {
            var category = _a[0];
            return category;
        });
    }
    return Object.keys(categoryToValues);
};
exports.sortAxisCategories = sortAxisCategories;
var getInvertedTextColor = function (color, theme) {
    return color === theme.semanticColors.bodyText
        ? theme.semanticColors.bodyBackground
        : theme.semanticColors.bodyText;
};
exports.getInvertedTextColor = getInvertedTextColor;
function getContrastTextColor(backgroundColor, theme) {
    var textColor = theme.semanticColors.bodyText;
    var contrastRatio = (0, colors_1.getColorContrast)(textColor, backgroundColor);
    if (contrastRatio < 3) {
        textColor = (0, exports.getInvertedTextColor)(textColor, theme);
    }
    return textColor;
}
exports.getContrastTextColor = getContrastTextColor;
/**
 * Utility function to check if an array of points is scatterpolar
 * @param points - Array of chart points
 * @returns true if any point has lineOptions.mode as 'scatterpolar'
 */
function isScatterPolarSeries(points) {
    return points.some(
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    function (item) { var _a; return typeof ((_a = item.lineOptions) === null || _a === void 0 ? void 0 : _a.mode) === 'string' && item.lineOptions.mode === 'scatterpolar'; });
}
exports.isScatterPolarSeries = isScatterPolarSeries;
/**
 * Utility function to check if an array of points contains mode as 'text' only
 * @param points - Array of chart points
 * @returns true if any point has lineOptions.mode as 'text'
 */
function isTextMode(points) {
    return points.some(
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    function (item) { var _a; return typeof ((_a = item.lineOptions) === null || _a === void 0 ? void 0 : _a.mode) === 'string' && item.lineOptions.mode === 'text'; });
}
exports.isTextMode = isTextMode;
//# sourceMappingURL=utilities.js.map