'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    CARTESIAN_XAXIS_CLASSNAME: function() {
        return CARTESIAN_XAXIS_CLASSNAME;
    },
    ChartTypes: function() {
        return ChartTypes;
    },
    CustomPoints: function() {
        return CustomPoints;
    },
    DEFAULT_DATE_STRING: function() {
        return DEFAULT_DATE_STRING;
    },
    DEFAULT_WRAP_WIDTH: function() {
        return DEFAULT_WRAP_WIDTH;
    },
    HighContrastSelector: function() {
        return HighContrastSelector;
    },
    HighContrastSelectorBlack: function() {
        return HighContrastSelectorBlack;
    },
    HighContrastSelectorWhite: function() {
        return HighContrastSelectorWhite;
    },
    MIN_DOMAIN_MARGIN: function() {
        return MIN_DOMAIN_MARGIN;
    },
    MIN_DONUT_RADIUS: function() {
        return MIN_DONUT_RADIUS;
    },
    Points: function() {
        return Points;
    },
    XAxisTypes: function() {
        return XAxisTypes;
    },
    YAxisType: function() {
        return YAxisType;
    },
    areArraysEqual: function() {
        return areArraysEqual;
    },
    autoLayoutXAxisLabels: function() {
        return autoLayoutXAxisLabels;
    },
    calculateLongestLabelWidth: function() {
        return calculateLongestLabelWidth;
    },
    calculateMarkerRadius: function() {
        return calculateMarkerRadius;
    },
    calculatePrecision: function() {
        return calculatePrecision;
    },
    calloutData: function() {
        return calloutData;
    },
    computeLongestBars: function() {
        return computeLongestBars;
    },
    copyStyle: function() {
        return copyStyle;
    },
    createDateXAxis: function() {
        return createDateXAxis;
    },
    createNumericXAxis: function() {
        return createNumericXAxis;
    },
    createNumericYAxis: function() {
        return createNumericYAxis;
    },
    createStringXAxis: function() {
        return createStringXAxis;
    },
    createStringYAxis: function() {
        return createStringYAxis;
    },
    createStringYAxisForHorizontalBarChartWithAxis: function() {
        return createStringYAxisForHorizontalBarChartWithAxis;
    },
    createWrapOfXLabels: function() {
        return createWrapOfXLabels;
    },
    createYAxisForHorizontalBarChartWithAxis: function() {
        return createYAxisForHorizontalBarChartWithAxis;
    },
    createYAxisLabels: function() {
        return createYAxisLabels;
    },
    defaultYAxisTickFormatter: function() {
        return defaultYAxisTickFormatter;
    },
    domainRangeOfDateForAreaLineScatterVerticalBarCharts: function() {
        return domainRangeOfDateForAreaLineScatterVerticalBarCharts;
    },
    domainRangeOfNumericForAreaLineScatterCharts: function() {
        return domainRangeOfNumericForAreaLineScatterCharts;
    },
    domainRangeOfNumericForHorizontalBarChartWithAxis: function() {
        return domainRangeOfNumericForHorizontalBarChartWithAxis;
    },
    domainRangeOfVSBCNumeric: function() {
        return domainRangeOfVSBCNumeric;
    },
    domainRangeOfVerticalNumeric: function() {
        return domainRangeOfVerticalNumeric;
    },
    domainRangeOfXStringAxis: function() {
        return domainRangeOfXStringAxis;
    },
    find: function() {
        return find;
    },
    findCalloutPoints: function() {
        return findCalloutPoints;
    },
    findHBCWANumericMinMaxOfY: function() {
        return findHBCWANumericMinMaxOfY;
    },
    findIndex: function() {
        return findIndex;
    },
    findNumericMinMaxOfY: function() {
        return findNumericMinMaxOfY;
    },
    findVSBCNumericMinMaxOfY: function() {
        return findVSBCNumericMinMaxOfY;
    },
    findVerticalNumericMinMaxOfY: function() {
        return findVerticalNumericMinMaxOfY;
    },
    formatDate: function() {
        return formatDate;
    },
    formatScientificLimitWidth: function() {
        return formatScientificLimitWidth;
    },
    generateDateTicks: function() {
        return generateDateTicks;
    },
    generateLinearTicks: function() {
        return generateLinearTicks;
    },
    generateMonthlyTicks: function() {
        return generateMonthlyTicks;
    },
    generateNumericTicks: function() {
        return generateNumericTicks;
    },
    getAccessibleDataObject: function() {
        return getAccessibleDataObject;
    },
    getBarWidth: function() {
        return getBarWidth;
    },
    getCurveFactory: function() {
        return getCurveFactory;
    },
    getDateFormatLevel: function() {
        return getDateFormatLevel;
    },
    getDomainPaddingForMarkers: function() {
        return getDomainPaddingForMarkers;
    },
    getRangeForScatterMarkerSize: function() {
        return getRangeForScatterMarkerSize;
    },
    getScalePadding: function() {
        return getScalePadding;
    },
    getScatterXDomainExtent: function() {
        return getScatterXDomainExtent;
    },
    getSecureProps: function() {
        return getSecureProps;
    },
    getTextSize: function() {
        return getTextSize;
    },
    getTypeOfAxis: function() {
        return getTypeOfAxis;
    },
    getUnique: function() {
        return getUnique;
    },
    getXAxisType: function() {
        return getXAxisType;
    },
    groupChartDataByYValue: function() {
        return groupChartDataByYValue;
    },
    isPlottable: function() {
        return isPlottable;
    },
    isScalePaddingDefined: function() {
        return isScalePaddingDefined;
    },
    isScatterPolarSeries: function() {
        return isScatterPolarSeries;
    },
    isTextMode: function() {
        return isTextMode;
    },
    isValidDomainValue: function() {
        return isValidDomainValue;
    },
    measureTextWithDOM: function() {
        return measureTextWithDOM;
    },
    pointTypes: function() {
        return pointTypes;
    },
    precisionRound: function() {
        return precisionRound;
    },
    prepareDatapoints: function() {
        return prepareDatapoints;
    },
    resolveCSSVariables: function() {
        return resolveCSSVariables;
    },
    rotateXAxisLabels: function() {
        return rotateXAxisLabels;
    },
    silceOrAppendToArray: function() {
        return silceOrAppendToArray;
    },
    sortAxisCategories: function() {
        return sortAxisCategories;
    },
    tooltipOfAxislabels: function() {
        return tooltipOfAxislabels;
    },
    truncateString: function() {
        return truncateString;
    },
    useRtl: function() {
        return useRtl;
    },
    wrapContent: function() {
        return wrapContent;
    },
    wrapTextInsideDonut: function() {
        return wrapTextInsideDonut;
    }
});
const _d3axis = require("d3-axis");
const _d3array = require("d3-array");
const _d3scale = require("d3-scale");
const _d3selection = require("d3-selection");
const _d3format = require("d3-format");
const _d3timeformat = require("d3-time-format");
const _d3time = require("d3-time");
const _d3shape = require("d3-shape");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _chartutilities = require("@fluentui/chart-utilities");
const MIN_DOMAIN_MARGIN = 8;
const MIN_DONUT_RADIUS = 1;
const DEFAULT_DATE_STRING = '2000-01-01';
const CARTESIAN_XAXIS_CLASSNAME = 'fui-cart__xAxis';
const CARTESIAN_XAXIS_TEXT_SELECTOR = `.${CARTESIAN_XAXIS_CLASSNAME} text`;
var ChartTypes = /*#__PURE__*/ 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";
    return ChartTypes;
}({});
var XAxisTypes = /*#__PURE__*/ function(XAxisTypes) {
    XAxisTypes[XAxisTypes["NumericAxis"] = 0] = "NumericAxis";
    XAxisTypes[XAxisTypes["DateAxis"] = 1] = "DateAxis";
    XAxisTypes[XAxisTypes["StringAxis"] = 2] = "StringAxis";
    return XAxisTypes;
}({});
var YAxisType = /*#__PURE__*/ function(YAxisType) {
    YAxisType[YAxisType["NumericAxis"] = 0] = "NumericAxis";
    YAxisType[YAxisType["DateAxis"] = 1] = "DateAxis";
    YAxisType[YAxisType["StringAxis"] = 2] = "StringAxis";
    return YAxisType;
}({});
function yAxisTickFormatterInternal(value, limitWidth = false) {
    // Use SI format prefix with 2 decimal places without insignificant trailing zeros
    let formatter = (0, _d3format.formatPrefix)('.2~', value);
    if (Math.abs(value) < 1) {
        // Don't use SI notation for small numbers as it is less readable
        formatter = (0, _d3format.format)('.2~g');
    } else if (limitWidth && Math.abs(value) >= 1000) {
        // If width is limited, use SI format prefix with 1 point precision
        formatter = (0, _d3format.formatPrefix)('.1~', value);
    }
    const 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;
}
function defaultYAxisTickFormatter(value) {
    return yAxisTickFormatterInternal(value);
}
function createNumericXAxis(xAxisParams, tickParams, chartType, culture, scaleType, _useRtl) {
    const { domainNRangeValues, showRoundOffXTickValues = false, xAxistickSize = 6, tickPadding = 10, xAxisCount, xAxisElement, hideTickOverlap, calcMaxLabelWidth, tickStep, tick0, tickText } = xAxisParams;
    const dStartValue = domainNRangeValues.dStartValue;
    const dEndValue = domainNRangeValues.dEndValue;
    const finalXmin = xAxisParams.xMinValue !== undefined ? Math.min(dStartValue, xAxisParams.xMinValue) : dStartValue;
    const finalXmax = xAxisParams.xMaxValue !== undefined ? Math.max(dEndValue, xAxisParams.xMaxValue) : dEndValue;
    const xAxisScale = createNumericScale(scaleType).domain([
        finalXmin,
        finalXmax
    ]).range([
        domainNRangeValues.rStartValue,
        domainNRangeValues.rEndValue
    ]);
    showRoundOffXTickValues && xAxisScale.nice();
    let tickCount = xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : 6;
    const tickFormat = (domainValue, _index, defaultFormat)=>{
        if (tickParams.tickValues && tickText && typeof tickText[_index] !== 'undefined') {
            return tickText[_index];
        }
        if (tickParams.tickFormat) {
            return (0, _d3format.format)(tickParams.tickFormat)(domainValue);
        }
        const xAxisValue = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
        return (defaultFormat === null || defaultFormat === void 0 ? void 0 : defaultFormat(xAxisValue)) === '' ? '' : (0, _chartutilities.formatToLocaleString)(xAxisValue, culture);
    };
    if (hideTickOverlap) {
        const longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map((v, i)=>tickFormat(v, i))) + 20;
        const [start, end] = xAxisScale.range();
        tickCount = Math.min(Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)), 10);
    }
    const xAxis = (0, _d3axis.axisBottom)(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(tickCount).tickFormat((v, i)=>tickFormat(v, i, xAxisScale.tickFormat(tickCount)));
    if ([
        6,
        8
    ].includes(chartType)) {
        xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top));
    }
    let customTickValues;
    if (tickParams.tickValues) {
        customTickValues = tickParams.tickValues;
    } else if (tickStep) {
        customTickValues = generateNumericTicks(scaleType, tickStep, tick0, xAxisScale.domain());
    }
    if (customTickValues) {
        xAxis.tickValues(customTickValues);
    }
    if (xAxisElement) {
        (0, _d3selection.select)(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true').style('direction', 'ltr').style('unicode-bidi', 'isolate');
    }
    const tickValues = customTickValues !== null && customTickValues !== void 0 ? customTickValues : xAxisScale.ticks(tickCount);
    const tickLabels = tickValues.map(xAxis.tickFormat());
    return {
        xScale: xAxisScale,
        tickValues,
        tickLabels
    };
}
/**
 * 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) {
    const timeFormat = locale ? useUTC ? locale.utcFormat : locale.format : useUTC ? _d3timeformat.utcFormat : _d3timeformat.timeFormat;
    // Refer to https://d3js.org/d3-time-format#locale_format to see explanation about each format specifier
    const DEFAULT = '%c';
    const MS = '.%L';
    const MS_S = ':%S.%L';
    const MS_S_MIN = '%M:%S.%L';
    const MS_S_MIN_H = '%-I:%M:%S.%L %p';
    const MS_S_MIN_H_D = '%a %d, %X';
    const MS_S_MIN_H_D_W = '%b %d, %X';
    const MS_S_MIN_H_D_W_M = MS_S_MIN_H_D_W;
    const MS_S_MIN_H_D_W_M_Y = DEFAULT;
    const S = ':%S';
    const S_MIN = '%-I:%M:%S';
    const S_MIN_H = '%X';
    const S_MIN_H_D = MS_S_MIN_H_D;
    const S_MIN_H_D_W = MS_S_MIN_H_D_W;
    const S_MIN_H_D_W_M = MS_S_MIN_H_D_W_M;
    const S_MIN_H_D_W_M_Y = DEFAULT;
    const MIN = '%-I:%M %p';
    const MIN_H = MIN;
    const MIN_H_D = '%a %d, %-I:%M %p';
    const MIN_H_D_W = '%b %d, %-I:%M %p';
    const MIN_H_D_W_M = MIN_H_D_W;
    const MIN_H_D_W_M_Y = '%x, %-I:%M %p';
    const H = '%-I %p';
    const H_D = '%a %d, %-I %p';
    const H_D_W = '%b %d, %-I %p';
    const H_D_W_M = H_D_W;
    const H_D_W_M_Y = '%x, %-I %p';
    const D = '%a %d';
    const D_W = '%b %d';
    const D_W_M = D_W;
    const D_W_M_Y = '%x';
    const W = D_W;
    const W_M = W;
    const W_M_Y = D_W_M_Y;
    const M = '%B';
    const M_Y = '%b %Y';
    const Y = '%Y';
    const 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
        ],
        [
            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
        ],
        [
            DEFAULT,
            DEFAULT,
            MIN,
            MIN_H,
            MIN_H_D,
            MIN_H_D_W,
            MIN_H_D_W_M,
            MIN_H_D_W_M_Y
        ],
        [
            DEFAULT,
            DEFAULT,
            DEFAULT,
            H,
            H_D,
            H_D_W,
            H_D_W_M,
            H_D_W_M_Y
        ],
        [
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            D,
            D_W,
            D_W_M,
            D_W_M_Y
        ],
        [
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            W,
            W_M,
            W_M_Y
        ],
        [
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            M,
            M_Y
        ],
        [
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            DEFAULT,
            Y
        ]
    ];
    const formatter = timeFormat(MULTI_LEVEL_DATE_TIME_FORMATS[startLevel][endLevel]);
    return formatter;
}
function getDateFormatLevel(date, useUTC) {
    const timeSecond = useUTC ? _d3time.utcSecond : _d3time.timeSecond;
    const timeMinute = useUTC ? _d3time.utcMinute : _d3time.timeMinute;
    const timeHour = useUTC ? _d3time.utcHour : _d3time.timeHour;
    const timeDay = useUTC ? _d3time.utcDay : _d3time.timeDay;
    const timeMonth = useUTC ? _d3time.utcMonth : _d3time.timeMonth;
    const timeWeek = useUTC ? _d3time.utcWeek : _d3time.timeWeek;
    const timeYear = useUTC ? _d3time.utcYear : _d3time.timeYear;
    const formats = [
        {
            formatLevel: 0,
            condition: (d)=>timeSecond(d) < d
        },
        {
            formatLevel: 1,
            condition: (d)=>timeMinute(d) < d
        },
        {
            formatLevel: 2,
            condition: (d)=>timeHour(d) < d
        },
        {
            formatLevel: 3,
            condition: (d)=>timeDay(d) < d
        },
        {
            formatLevel: 4,
            condition: (d)=>timeMonth(d) < d && timeWeek(d) < d
        },
        {
            formatLevel: 5,
            condition: (d)=>timeMonth(d) < d
        },
        {
            formatLevel: 6,
            condition: (d)=>timeYear(d) < d
        },
        {
            formatLevel: 7,
            condition: ()=>true
        }
    ];
    const matchedFormat = formats.find(({ condition })=>condition(date));
    var _matchedFormat_formatLevel;
    return (_matchedFormat_formatLevel = matchedFormat === null || matchedFormat === void 0 ? void 0 : matchedFormat.formatLevel) !== null && _matchedFormat_formatLevel !== void 0 ? _matchedFormat_formatLevel : 7;
}
function createDateXAxis(xAxisParams, tickParams, culture, options, timeFormatLocale, customDateTimeFormatter, useUTC, chartType) {
    const { domainNRangeValues, xAxisElement, tickPadding = 6, xAxistickSize = 6, xAxisCount, hideTickOverlap, calcMaxLabelWidth, tickStep, tick0, tickText } = xAxisParams;
    const isUtcSet = useUTC === true || useUTC === 'utc';
    const xAxisScale = isUtcSet ? (0, _d3scale.scaleUtc)() : (0, _d3scale.scaleTime)();
    xAxisScale.domain([
        domainNRangeValues.dStartValue,
        domainNRangeValues.dEndValue
    ]).range([
        domainNRangeValues.rStartValue,
        domainNRangeValues.rEndValue
    ]).nice();
    let tickCount = xAxisCount !== null && xAxisCount !== void 0 ? xAxisCount : 6;
    let lowestFormatLevel = 100;
    let highestFormatLevel = -1;
    const locale = timeFormatLocale ? (0, _d3timeformat.timeFormatLocale)(timeFormatLocale) : undefined;
    xAxisScale.ticks().forEach((domainValue)=>{
        const formatLevel = getDateFormatLevel(domainValue, isUtcSet);
        if (formatLevel > highestFormatLevel) {
            highestFormatLevel = formatLevel;
        }
        if (formatLevel < lowestFormatLevel) {
            lowestFormatLevel = formatLevel;
        }
    });
    const formatOptions = options !== null && options !== void 0 ? options : (0, _chartutilities.getMultiLevelDateTimeFormatOptions)(lowestFormatLevel, highestFormatLevel);
    const formatFn = getMultiLevelD3DateFormatter(lowestFormatLevel, highestFormatLevel, locale, isUtcSet);
    const tickFormat = (domainValue, _index)=>{
        if (tickParams.tickValues && tickText && typeof tickText[_index] !== 'undefined') {
            return tickText[_index];
        }
        if (customDateTimeFormatter) {
            return customDateTimeFormatter(domainValue);
        }
        if (timeFormatLocale) {
            return formatFn(domainValue);
        }
        if (culture === undefined && tickParams.tickFormat) {
            if (useUTC) {
                return (0, _d3timeformat.utcFormat)(tickParams.tickFormat)(domainValue);
            } else {
                return (0, _d3timeformat.timeFormat)(tickParams.tickFormat)(domainValue);
            }
        }
        return (0, _chartutilities.formatDateToLocaleString)(domainValue, culture, useUTC ? true : false, false, formatOptions);
    };
    if (hideTickOverlap) {
        const longestLabelWidth = calcMaxLabelWidth(xAxisScale.ticks().map(tickFormat)) + 40;
        const [start, end] = xAxisScale.range();
        tickCount = Math.min(Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)), 10);
    }
    const xAxis = (0, _d3axis.axisBottom)(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(tickCount).tickFormat(tickFormat);
    if ([
        8
    ].includes(chartType)) {
        xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top));
    }
    let customTickValues;
    if (tickParams.tickValues) {
        customTickValues = tickParams.tickValues;
    } else if (tickStep) {
        customTickValues = generateDateTicks(tickStep, tick0, xAxisScale.domain(), useUTC);
    }
    if (customTickValues) {
        xAxis.tickValues(customTickValues);
    }
    if (xAxisElement) {
        (0, _d3selection.select)(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true');
    }
    const tickValues = customTickValues !== null && customTickValues !== void 0 ? customTickValues : xAxisScale.ticks(tickCount);
    const tickLabels = tickValues.map(xAxis.tickFormat());
    return {
        xScale: xAxisScale,
        tickValues,
        tickLabels
    };
}
function createStringXAxis(xAxisParams, tickParams, dataset, culture, _useRtl) {
    const { domainNRangeValues, xAxistickSize = 6, tickPadding = 10, xAxisPadding = 0.1, xAxisInnerPadding, xAxisOuterPadding, containerWidth, hideTickOverlap, calcMaxLabelWidth, tickText } = xAxisParams;
    const xAxisScale = (0, _d3scale.scaleBand)().domain(dataset).range([
        domainNRangeValues.rStartValue,
        domainNRangeValues.rEndValue
    ]).paddingInner(typeof xAxisInnerPadding !== 'undefined' ? xAxisInnerPadding : xAxisPadding).paddingOuter(typeof xAxisOuterPadding !== 'undefined' ? xAxisOuterPadding : xAxisPadding);
    var _tickParams_tickValues;
    let tickValues = (_tickParams_tickValues = tickParams.tickValues) !== null && _tickParams_tickValues !== void 0 ? _tickParams_tickValues : dataset;
    const tickFormat = (domainValue, _index)=>{
        if (tickParams.tickValues && tickText && typeof tickText[_index] !== 'undefined') {
            return tickText[_index];
        }
        return domainValue;
    };
    if (hideTickOverlap) {
        let nonOverlappingTickValues = [];
        const tickSizes = tickValues.map((value)=>calcMaxLabelWidth([
                value
            ]));
        // for LTR
        let start = 0;
        let end = containerWidth;
        let sign = 1;
        const range = xAxisScale.range();
        if (range[1] - range[0] < 0) {
            // for RTL
            start = containerWidth;
            end = 0;
            sign = -1;
        }
        for(let i = tickValues.length - 1; i >= 0; i--){
            const 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;
    }
    const xAxis = (0, _d3axis.axisBottom)(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).tickValues(tickValues).tickFormat(tickFormat);
    if (xAxisParams.xAxisElement) {
        (0, _d3selection.select)(xAxisParams.xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true').style('direction', 'ltr').style('unicode-bidi', 'isolate');
    }
    return {
        xScale: xAxisScale,
        tickValues,
        tickLabels: tickValues.map(xAxis.tickFormat())
    };
}
function useRtl() {
    const { dir } = (0, _reactsharedcontexts.useFluent_unstable)(); // "dir" returns "ltr" or "rtl"
    return dir === 'rtl';
}
function isPowerOf10(num) {
    const roundedfinalYMax = handleFloatingPointPrecisionError(num);
    return Math.log10(roundedfinalYMax) % 1 === 0;
}
//for reference, go through this 'https://docs.python.org/release/2.5.1/tut/node16.html'
function handleFloatingPointPrecisionError(num) {
    const rounded = Math.round(num);
    return Math.abs(num - rounded) < 1e-6 ? rounded : num;
}
/**
 * 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) {
    const finalYmin = minVal >= 0 && minVal === maxVal ? 0 : minVal;
    const finalYmax = minVal < 0 && minVal === maxVal ? 0 : maxVal;
    const ticksInterval = (0, _d3array.nice)(finalYmin, finalYmax, splitInto);
    const ticks = (0, _d3array.ticks)(ticksInterval[0], ticksInterval[ticksInterval.length - 1], splitInto);
    if (ticks[ticks.length - 1] > finalYmax && isPowerOf10(finalYmax)) {
        ticks.pop();
    }
    return ticks;
}
function prepareDatapoints(maxVal, minVal, splitInto, isIntegralDataset, roundedTicks) {
    if (roundedTicks) {
        return calculateRoundedTicks(minVal, maxVal, splitInto);
    }
    const 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
  */ const 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;
}
function createYAxisForHorizontalBarChartWithAxis(yAxisParams, isRtl, axisData) {
    const { yMinMaxValues = {
        startValue: 0,
        endValue: 0
    }, yAxisElement = null, yMaxValue = 0, yMinValue = 0, containerHeight, margins, tickPadding = 12, maxOfYVal = 0, yAxisTickFormat, yAxisTickCount = 4, tickValues, tickStep, tick0, tickText } = yAxisParams;
    // maxOfYVal coming from horizontal bar chart with axis (Calculation done at base file)
    const tempVal = maxOfYVal || yMinMaxValues.endValue;
    const finalYmax = tempVal > yMaxValue ? tempVal : yMaxValue;
    const finalYmin = yMinMaxValues.startValue < yMinValue ? Math.min(0, yMinMaxValues.startValue) : yMinValue;
    const yAxisScale = (0, _d3scale.scaleLinear)().domain([
        finalYmin,
        finalYmax
    ]).range([
        containerHeight - margins.bottom,
        margins.top
    ]);
    const axis = isRtl ? (0, _d3axis.axisRight)(yAxisScale) : (0, _d3axis.axisLeft)(yAxisScale);
    const yAxis = axis.tickPadding(tickPadding).ticks(yAxisTickCount);
    const tickFormat = (domainValue, index)=>{
        if (tickValues && tickText && typeof tickText[index] !== 'undefined') {
            return tickText[index];
        }
        if (typeof yAxisTickFormat === 'function') {
            return yAxisTickFormat(domainValue, index);
        }
        if (typeof yAxisTickFormat === 'string') {
            return (0, _d3format.format)(yAxisTickFormat)(domainValue);
        }
        const value = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
        return defaultYAxisTickFormatter(value);
    };
    yAxis.tickFormat(tickFormat);
    let customTickValues;
    if (tickValues) {
        customTickValues = tickValues;
    } else if (tickStep) {
        customTickValues = generateNumericTicks(undefined, tickStep, tick0, yAxisScale.domain());
    }
    if (customTickValues) {
        yAxis.tickValues(customTickValues);
    }
    yAxisElement ? (0, _d3selection.select)(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true') : '';
    axisData.yAxisDomainValues = yAxisScale.domain();
    var _yAxis_tickValues;
    axisData.yAxisTickText = ((_yAxis_tickValues = yAxis.tickValues()) !== null && _yAxis_tickValues !== void 0 ? _yAxis_tickValues : yAxisScale.ticks(yAxisTickCount)).map(yAxis.tickFormat());
    return yAxisScale;
}
function createNumericYAxis(yAxisParams, isRtl, axisData, isIntegralDataset, chartType, useSecondaryYScale = false, roundedTicks = false, scaleType, _useRtl) {
    const { yMinMaxValues = {
        startValue: 0,
        endValue: 0
    }, yAxisElement = null, yMaxValue = 0, yMinValue = 0, containerHeight, containerWidth, margins, tickPadding = 12, maxOfYVal = 0, yAxisTickFormat, yAxisTickCount = 4, eventAnnotationProps, eventLabelHeight, tickValues, tickStep, tick0, tickText } = yAxisParams;
    // maxOfYVal coming from only area chart and Grouped vertical bar chart(Calculation done at base file)
    const tempVal = maxOfYVal || yMinMaxValues.endValue || 0;
    const finalYmax = tempVal > yMaxValue ? tempVal : yMaxValue;
    const finalYmin = Math.min(yMinMaxValues.startValue || 0, yMinValue || 0);
    const domainValues = prepareDatapoints(finalYmax, finalYmin, yAxisTickCount, isIntegralDataset, roundedTicks);
    let yMin = finalYmin;
    let yMax = domainValues[domainValues.length - 1];
    if (chartType === 7) {
        const yPadding = (yMax - yMin) * 0.1;
        yMin = yMin - yPadding;
        yMax = yMax + yPadding;
    }
    let scaleDomain = [
        domainValues[0],
        domainValues[domainValues.length - 1]
    ];
    if (scaleType === 'log') {
        let domainStart = yMinMaxValues.startValue;
        let domainEnd = yMinMaxValues.endValue;
        if (yMinValue > 0) {
            domainStart = Math.min(domainStart, yMinValue);
        }
        if (yMaxValue > 0) {
            domainEnd = Math.max(domainEnd, yMaxValue);
        }
        scaleDomain = [
            domainStart,
            domainEnd
        ];
    }
    const yAxisScale = createNumericScale(scaleType).domain(scaleDomain).range([
        containerHeight - margins.bottom,
        margins.top + (eventAnnotationProps ? eventLabelHeight : 0)
    ]);
    const axis = !isRtl && useSecondaryYScale || isRtl && !useSecondaryYScale ? (0, _d3axis.axisRight)(yAxisScale) : (0, _d3axis.axisLeft)(yAxisScale);
    const yAxis = axis.tickPadding(tickPadding).tickSizeInner(-(containerWidth - margins.left - margins.right));
    let customTickValues;
    if (tickValues) {
        customTickValues = tickValues;
    } else if (tickStep) {
        customTickValues = generateNumericTicks(scaleType, tickStep, tick0, yAxisScale.domain());
    }
    if (customTickValues) {
        yAxis.tickValues(customTickValues);
        axisData.yAxisDomainValues = customTickValues;
    } else if (scaleType !== 'log') {
        yAxis.tickValues(domainValues);
    }
    const tickFormat = (domainValue, index, defaultFormat)=>{
        if (tickValues && tickText && typeof tickText[index] !== 'undefined') {
            return tickText[index];
        }
        if (typeof yAxisTickFormat === 'function') {
            return yAxisTickFormat(domainValue, index);
        }
        if (typeof yAxisTickFormat === 'string') {
            return (0, _d3format.format)(yAxisTickFormat)(domainValue);
        }
        const value = typeof domainValue === 'number' ? domainValue : domainValue.valueOf();
        return (defaultFormat === null || defaultFormat === void 0 ? void 0 : defaultFormat(value)) === '' ? '' : defaultYAxisTickFormatter(value);
    };
    yAxis.tickFormat((v, i)=>tickFormat(v, i, yAxisScale.tickFormat(yAxisTickCount)));
    yAxisElement ? (0, _d3selection.select)(yAxisElement).call(yAxis).selectAll('text').attr('aria-hidden', 'true').style('direction', 'ltr').style('unicode-bidi', 'isolate').style('text-anchor', !useSecondaryYScale && (_useRtl ? 'start' : 'end')) : '';
    axisData.yAxisDomainValues = yAxisScale.domain();
    var _yAxis_tickValues;
    axisData.yAxisTickText = ((_yAxis_tickValues = yAxis.tickValues()) !== null && _yAxis_tickValues !== void 0 ? _yAxis_tickValues : yAxisScale.ticks(yAxisTickCount)).map(yAxis.tickFormat());
    return yAxisScale;
}
const createStringYAxisForHorizontalBarChartWithAxis = (yAxisParams, dataPoints, isRtl, axisData, barWidth)=>{
    const { containerHeight, tickPadding = 12, margins, yAxisTickFormat, yAxisElement, yAxisPadding, tickValues, tickText } = yAxisParams;
    let yAxisPaddingValue = yAxisPadding !== null && yAxisPadding !== void 0 ? yAxisPadding : 0.5;
    yAxisPaddingValue = yAxisPaddingValue === 1 ? 0.99 : yAxisPaddingValue;
    const yAxisScale = (0, _d3scale.scaleBand)().domain(dataPoints).range([
        containerHeight - margins.bottom,
        margins.top
    ]).padding(yAxisPaddingValue);
    const axis = isRtl ? (0, _d3axis.axisRight)(yAxisScale) : (0, _d3axis.axisLeft)(yAxisScale);
    const customTickValues = tickValues !== null && tickValues !== void 0 ? tickValues : dataPoints;
    const tickFormat = (domainValue, _index)=>{
        if (tickValues && tickText && typeof tickText[_index] !== 'undefined') {
            return tickText[_index];
        }
        if (typeof yAxisTickFormat === 'function') {
            return yAxisTickFormat(domainValue, _index);
        }
        return domainValue;
    };
    const yAxis = axis.tickPadding(tickPadding).tickValues(customTickValues).tickFormat(tickFormat);
    yAxisElement ? (0, _d3selection.select)(yAxisElement).call(yAxis).selectAll('text') : '';
    axisData.yAxisTickText = yAxis.tickValues().map(yAxis.tickFormat());
    return yAxisScale;
};
const createStringYAxis = (yAxisParams, dataPoints, isRtl, axisData, barWidth, chartType)=>{
    const { containerHeight, tickPadding = 12, margins, yAxisTickFormat, yAxisElement, yAxisPadding = 0, containerWidth, tickValues, tickText } = yAxisParams;
    const yAxisScale = (0, _d3scale.scaleBand)().domain(dataPoints).range([
        containerHeight - margins.bottom,
        margins.top
    ]).padding(yAxisPadding);
    if (chartType === 3) {
        yAxisScale.paddingInner(1).paddingOuter(0);
    }
    const axis = isRtl ? (0, _d3axis.axisRight)(yAxisScale) : (0, _d3axis.axisLeft)(yAxisScale);
    const customTickValues = tickValues !== null && tickValues !== void 0 ? tickValues : dataPoints;
    const tickFormat = (domainValue, _index)=>{
        if (tickValues && tickText && typeof tickText[_index] !== 'undefined') {
            return tickText[_index];
        }
        if (typeof yAxisTickFormat === 'function') {
            return yAxisTickFormat(domainValue, _index);
        }
        return domainValue;
    };
    const yAxis = axis.tickPadding(tickPadding).tickValues(customTickValues).tickFormat(tickFormat).tickSize(0);
    if (chartType === 3) {
        axis.tickSizeInner(-(containerWidth - margins.left - margins.right));
    }
    yAxisElement ? (0, _d3selection.select)(yAxisElement).call(yAxis).selectAll('text') : '';
    axisData.yAxisTickText = yAxis.tickValues().map(yAxis.tickFormat());
    return yAxisScale;
};
function calloutData(values) {
    let combinedResult = [];
    values.forEach((line)=>{
        const elements = line.data.filter((point)=>!point.hideCallout).map((point)=>{
            return {
                ...point,
                legend: line.legend,
                color: line.color,
                index: line.index
            };
        });
        combinedResult = combinedResult.concat(elements);
    });
    const xValToDataPoints = {};
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    combinedResult.forEach((ele)=>{
        const xValue = ele.x instanceof Date ? ele.x.getTime() : ele.x;
        const newPoint = {
            legend: ele.legend,
            y: ele.y,
            color: ele.color,
            xAxisCalloutData: ele.xAxisCalloutData,
            yAxisCalloutData: ele.yAxisCalloutData,
            callOutAccessibilityData: ele.callOutAccessibilityData,
            index: ele.index
        };
        if (xValue in xValToDataPoints) {
            // Check if a point with the same legend and y-value already exists
            const existingPoint = xValToDataPoints[xValue].find((p)=>p.legend === newPoint.legend && p.y === newPoint.y);
            if (!existingPoint) {
                xValToDataPoints[xValue].push(newPoint);
            }
        } else {
            xValToDataPoints[xValue] = [
                newPoint
            ];
        }
    });
    return xValToDataPoints;
}
function getUnique(arr, comp) {
    const unique = arr // eslint-disable-next-line @typescript-eslint/no-explicit-any
    .map((e)=>e[comp]) // store the keys of the unique objects
    .map((e, i, final)=>final.indexOf(e) === i && i) // eliminate the dead keys & store unique objects
    .filter((e)=>arr[e]).map((e)=>arr[e]);
    return unique;
}
function silceOrAppendToArray(array, value) {
    const pos = array.indexOf(value);
    if (pos === -1) {
        return [
            ...array,
            value
        ];
    } else {
        return array.slice(0, pos).concat(array.slice(pos + 1));
    }
}
const DEFAULT_WRAP_WIDTH = 10;
function createWrapOfXLabels(wrapLabelProps) {
    const { node, xAxis, noOfCharsToTruncate, showXAxisLablesTooltip, width = DEFAULT_WRAP_WIDTH, container } = wrapLabelProps;
    if (node === null) {
        return;
    }
    const axisNode = (0, _d3selection.select)(node).call(xAxis);
    let removeVal = 0;
    let maxLines = 1;
    axisNode.selectAll('.tick text').each(function(_, tickIndex) {
        const text = (0, _d3selection.select)(this);
        const totalWord = text.text();
        const truncatedWord = `${text.text().slice(0, noOfCharsToTruncate)}...`;
        const totalWordLength = text.text().length;
        const words = text.text().split(/\s+/).reverse();
        let word = '';
        let line = [];
        let lineNumber = 0;
        const lineHeight = 1.1; // ems
        const y = text.attr('y');
        const dy = parseFloat(text.attr('dy'));
        let tspan = text.text(null).attr('data-full', totalWord).append('tspan').attr('x', 0).attr('y', y).attr('dy', dy + 'em');
        if (showXAxisLablesTooltip) {
            tspan.text(totalWordLength > noOfCharsToTruncate ? truncatedWord : totalWord);
        } else {
            const maxWidth = Array.isArray(width) ? width[tickIndex] : width;
            while(word = words.pop()){
                line.push(word);
                const label = line.join(' ');
                tspan.text(label);
                const labelWidth = getTextSize(label, CARTESIAN_XAXIS_TEXT_SELECTOR, container).width;
                if (labelWidth > maxWidth && line.length > 1) {
                    line.pop();
                    tspan.text(line.join(' '));
                    line = [
                        word
                    ];
                    tspan = text.append('tspan').attr('x', 0).attr('y', y).attr('dy', ++lineNumber * lineHeight + dy + 'em').text(word);
                }
            }
        }
        maxLines = Math.max(maxLines, lineNumber + 1);
    });
    if (!showXAxisLablesTooltip) {
        var _querySelector;
        let maxHeight = 12; // intial value to render corretly first time
        var _querySelector_getBoundingClientRect_height;
        const boxHeight = (_querySelector_getBoundingClientRect_height = (_querySelector = (container !== null && container !== void 0 ? container : document).querySelector(`.${CARTESIAN_XAXIS_CLASSNAME} tspan`)) === null || _querySelector === void 0 ? void 0 : _querySelector.getBoundingClientRect().height) !== null && _querySelector_getBoundingClientRect_height !== void 0 ? _querySelector_getBoundingClientRect_height : 0;
        if (boxHeight > maxHeight) {
            maxHeight = boxHeight;
        }
        removeVal = (maxLines - 1) * maxHeight;
    }
    return removeVal > 0 ? removeVal : 0;
}
function createYAxisLabels(node, yAxis, noOfCharsToTruncate, truncateLabel, isRtl) {
    if (node === null) {
        return;
    }
    const axisNode = (0, _d3selection.select)(node).call(yAxis);
    axisNode.selectAll('.tick text').each(function() {
        const text = (0, _d3selection.select)(this);
        const totalWord = text.text();
        const truncatedWord = isRtl ? `...${text.text().slice(0, noOfCharsToTruncate)}` : `${text.text().slice(0, noOfCharsToTruncate)}...`;
        const totalWordLength = text.text().length;
        const y = text.attr('y');
        const x = text.attr('x');
        const dy = parseFloat(text.attr('dy'));
        const tspan = text.text(null).attr('data-full', totalWord).append('tspan').attr('x', x).attr('y', y).attr('dy', dy + 'em');
        if (truncateLabel) {
            tspan.text(totalWordLength > noOfCharsToTruncate ? truncatedWord : totalWord);
        }
    });
}
const wrapContent = (content, id, maxWidth)=>{
    const textElement = (0, _d3selection.select)(`#${id}`);
    textElement.text(content);
    if (!textElement.node()) {
        return false;
    }
    let isOverflowing = false;
    let 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;
};
const calculateLongestLabelWidth = (labels, query = 'none')=>{
    let maxLabelWidth = 0;
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    if (ctx) {
        const axisText = document.querySelector(query);
        if (axisText) {
            const styles = window.getComputedStyle(axisText, null);
            const fontWeight = styles.getPropertyValue('font-weight');
            const fontSize = styles.getPropertyValue('font-size');
            const fontFamily = styles.getPropertyValue('font-family');
            ctx.font = `${fontWeight} ${fontSize} ${fontFamily}`;
        } else {
            ctx.font = '600 10px "Segoe UI"';
        }
        labels.forEach((label)=>{
            maxLabelWidth = Math.max(ctx.measureText(label.toString()).width, maxLabelWidth);
        });
    }
    return maxLabelWidth;
};
function tooltipOfAxislabels(axistooltipProps) {
    const { tooltipCls, axis, id, container } = axistooltipProps;
    if (axis === null) {
        return null;
    }
    const div = (container ? (0, _d3selection.select)(container) : (0, _d3selection.select)('body')).append('div').attr('id', id).attr('class', tooltipCls).style('opacity', 0);
    axis.selectAll('.tick text').each(function() {
        const tickSelection = (0, _d3selection.select)(this);
        const fullLabel = tickSelection.attr('data-full');
        if (tickSelection.text() === fullLabel) {
            return;
        }
        const tickEl = this;
        tickSelection // eslint-disable-next-line @typescript-eslint/no-explicit-any
        .on('mouseover', (event, d)=>{
            const containerBounds = container === null || container === void 0 ? void 0 : container.getBoundingClientRect();
            const tickBounds = tickEl.getBoundingClientRect();
            const tooltipBottom = containerBounds ? containerBounds.bottom - (tickBounds.top - 4) : tickBounds.top - 4;
            var _containerBounds_left;
            const tooltipLeft = (tickBounds.left + tickBounds.right) / 2 - ((_containerBounds_left = containerBounds === null || containerBounds === void 0 ? void 0 : containerBounds.left) !== null && _containerBounds_left !== void 0 ? _containerBounds_left : 0);
            div.text(fullLabel).style('bottom', `${tooltipBottom}px`).style('left', `${tooltipLeft}px`).style('transform', 'translateX(-50%)').style('opacity', 0.9);
        }).on('mouseout', (d)=>{
            div.style('opacity', 0);
        });
    });
}
function getXAxisType(points) {
    let isXAxisDateType = false;
    if (points && points.length > 0) {
        points.forEach((chartData)=>{
            if (chartData.data.length > 0) {
                isXAxisDateType = chartData.data[0].x instanceof Date;
                return;
            }
        });
    }
    return isXAxisDateType;
}
function domainRangeOfNumericForAreaLineScatterCharts(points, margins, width, isRTL, scaleType, hasMarkersMode, xMinVal, xMaxVal) {
    const isScatterPolar = isScatterPolarSeries(points);
    let [xMin, xMax] = getScatterXDomainExtent(points, scaleType);
    if (hasMarkersMode) {
        const xPadding = getDomainPaddingForMarkers(xMin, xMax, scaleType, xMinVal, xMaxVal);
        xMin = xMin - xPadding.start;
        xMax = xMax + xPadding.end;
    }
    const rStartValue = margins.left;
    const rEndValue = width - margins.right;
    return isRTL ? {
        dStartValue: isScatterPolar ? 1 : xMax,
        dEndValue: isScatterPolar ? -1 : xMin,
        rStartValue,
        rEndValue
    } : {
        dStartValue: isScatterPolar ? -1 : xMin,
        dEndValue: isScatterPolar ? 1 : xMax,
        rStartValue,
        rEndValue
    };
}
function groupChartDataByYValue(chartData) {
    const map = {};
    chartData.forEach((dataPoint)=>{
        const key = dataPoint.y;
        if (!map[key]) {
            map[key] = [];
        }
        map[key].push(dataPoint);
    });
    return Object.values(map);
}
function computeLongestBars(stackedChartData, X_ORIGIN) {
    let longestPositiveBar = 0;
    let longestNegativeBar = 0;
    stackedChartData.forEach((group)=>{
        const positiveBarTotal = group.reduce((acc, point)=>acc + (point.x > 0 ? point.x : 0), X_ORIGIN);
        const negativeBarTotal = group.reduce((acc, point)=>acc + (point.x < 0 ? point.x : 0), X_ORIGIN);
        longestPositiveBar = Math.max(longestPositiveBar, positiveBarTotal);
        longestNegativeBar = Math.min(longestNegativeBar, negativeBarTotal);
    });
    return {
        longestPositiveBar,
        longestNegativeBar
    };
}
function domainRangeOfNumericForHorizontalBarChartWithAxis(points, margins, containerWidth, isRTL, X_ORIGIN) {
    const longestBars = computeLongestBars(groupChartDataByYValue(points), X_ORIGIN);
    const xMax = longestBars.longestPositiveBar;
    const xMin = longestBars.longestNegativeBar;
    const rMin = margins.left;
    const rMax = 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
    };
}
function domainRangeOfXStringAxis(margins, width, isRTL) {
    const rMin = margins.left;
    const rMax = width - margins.right;
    return isRTL ? {
        dStartValue: 0,
        dEndValue: 0,
        rStartValue: rMax,
        rEndValue: rMin
    } : {
        dStartValue: 0,
        dEndValue: 0,
        rStartValue: rMin,
        rEndValue: rMax
    };
}
function domainRangeOfVSBCNumeric(points, margins, width, isRTL, barWidth) {
    const xMin = (0, _d3array.min)(points, (point)=>point.x);
    const xMax = (0, _d3array.max)(points, (point)=>point.x);
    const rMax = margins.left;
    const rMin = width - margins.right;
    return isRTL ? {
        dStartValue: xMax,
        dEndValue: xMin,
        rStartValue: rMax,
        rEndValue: rMin
    } : {
        dStartValue: xMin,
        dEndValue: xMax,
        rStartValue: rMax,
        rEndValue: rMin
    };
}
function domainRangeOfDateForAreaLineScatterVerticalBarCharts(points, margins, width, isRTL, tickValues = [], chartType, barWidth, hasMarkersMode) {
    let sDate;
    let lDate;
    if ([
        0,
        1,
        7
    ].includes(chartType)) {
        [sDate, lDate] = getScatterXDomainExtent(points);
        // 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, _d3array.min)([
            ...tickValues,
            sDate
        ]);
        lDate = (0, _d3array.max)([
            ...tickValues,
            lDate
        ]);
        if (hasMarkersMode || chartType === 7) {
            const xPadding = getDomainPaddingForMarkers(sDate.getTime(), lDate.getTime());
            sDate = new Date(sDate.getTime() - xPadding.start);
            lDate = new Date(lDate.getTime() + xPadding.end);
        }
    } else {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        sDate = (0, _d3array.min)(points, (point)=>point.x);
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        lDate = (0, _d3array.max)(points, (point)=>point.x);
    }
    const rStartValue = margins.left;
    const rEndValue = width - margins.right;
    return isRTL ? {
        dStartValue: lDate,
        dEndValue: sDate,
        rStartValue,
        rEndValue
    } : {
        dStartValue: sDate,
        dEndValue: lDate,
        rStartValue,
        rEndValue
    };
}
function domainRangeOfVerticalNumeric(points, margins, containerWidth, isRTL, barWidth) {
    const xMax = (0, _d3array.max)(points, (point)=>point.x);
    const xMin = (0, _d3array.min)(points, (point)=>point.x);
    const rMin = margins.left;
    const rMax = containerWidth - margins.right;
    return isRTL ? {
        dStartValue: xMax,
        dEndValue: xMin,
        rStartValue: rMin,
        rEndValue: rMax
    } : {
        dStartValue: xMin,
        dEndValue: xMax,
        rStartValue: rMin,
        rEndValue: rMax
    };
}
function findNumericMinMaxOfY(points, yAxisType, useSecondaryYScale, scaleType) {
    const values = [];
    points.forEach((point)=>{
        if (!useSecondaryYScale === !point.useSecondaryYScale) {
            point.data.forEach((data)=>{
                if (isValidDomainValue(data.y, scaleType)) {
                    values.push(data.y);
                }
            });
        }
    });
    return {
        startValue: (0, _d3array.min)(values),
        endValue: (0, _d3array.max)(values)
    };
}
function findVSBCNumericMinMaxOfY(dataset) {
    const yMax = (0, _d3array.max)(dataset, (point)=>point.y);
    const yMin = (0, _d3array.min)(dataset, (point)=>point.y);
    return {
        startValue: yMin,
        endValue: yMax
    };
}
function findVerticalNumericMinMaxOfY(points, yAxisType, useSecondaryYScale) {
    const values = [];
    points.forEach((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, _d3array.min)(values),
        endValue: (0, _d3array.max)(values)
    };
}
function findHBCWANumericMinMaxOfY(points, yAxisType) {
    if (yAxisType !== undefined && yAxisType === 0) {
        const yMax = (0, _d3array.max)(points, (point)=>point.y);
        const yMin = (0, _d3array.min)(points, (point)=>point.y);
        return {
            startValue: yMin,
            endValue: yMax
        };
    }
    return {
        startValue: 0,
        endValue: 0
    };
}
const getTypeOfAxis = (p, isXAxis)=>{
    if (isXAxis) {
        switch(typeof p){
            case 'string':
                return 2;
            case 'number':
                return 0;
            default:
                return 1;
        }
    } else {
        switch(typeof p){
            case 'string':
                return 2;
            case 'number':
                return 0;
            default:
                return 1;
        }
    }
};
var Points = /*#__PURE__*/ 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";
    return Points;
}({});
var CustomPoints = /*#__PURE__*/ function(CustomPoints) {
    CustomPoints[CustomPoints["dottedLine"] = 0] = "dottedLine";
    return CustomPoints;
}({});
const pointTypes = {
    [0]: {
        widthRatio: 1
    },
    [1]: {
        widthRatio: 1
    },
    [2]: {
        widthRatio: 1
    },
    [3]: {
        widthRatio: 1
    },
    [4]: {
        widthRatio: 1
    },
    [5]: {
        widthRatio: 2
    },
    [6]: {
        widthRatio: 1.168
    },
    [7]: {
        widthRatio: 2.414
    }
};
const getAccessibleDataObject = (accessibleData, role = 'text', isDataFocusable = true)=>{
    accessibleData = accessibleData !== null && accessibleData !== void 0 ? accessibleData : {};
    return {
        role,
        'data-is-focusable': isDataFocusable,
        'aria-label': accessibleData.ariaLabel,
        'aria-labelledby': accessibleData.ariaLabelledBy,
        'aria-describedby': accessibleData.ariaDescribedBy
    };
};
function rotateXAxisLabels(rotateLabelProps) {
    const { node, xAxis } = rotateLabelProps;
    if (node === null || xAxis === null) {
        return;
    }
    let maxHeight = 0;
    const xAxisTranslations = [];
    (0, _d3selection.select)(node).call(xAxis).selectAll('.tick').each(function() {
        const translateValue = this.getAttribute('transform');
        if ((translateValue === null || translateValue === void 0 ? void 0 : translateValue.indexOf('rotate')) === -1) {
            const translatePair = translateValue.substring(translateValue.indexOf('(') + 1, translateValue.indexOf(')')).split(',');
            if (translatePair.length === 2) {
                xAxisTranslations.push(translatePair[0]);
                this.setAttribute('transform', `translate(${translatePair[0]},0)rotate(-45)`);
            }
        }
        const BoxCordinates = this.getBoundingClientRect();
        const boxHeight = BoxCordinates && BoxCordinates.height;
        if (boxHeight > maxHeight) {
            maxHeight = boxHeight;
        }
    });
    let idx = 0;
    (0, _d3selection.select)(node).call(xAxis).selectAll('.tick').each(function() {
        if (xAxisTranslations.length > idx) {
            this.setAttribute('transform', `translate(${xAxisTranslations[idx]},${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.
}
function wrapTextInsideDonut(selectorClass, maxWidth) {
    let idx = 0;
    (0, _d3selection.selectAll)(`.${selectorClass}`).each(function() {
        const text = (0, _d3selection.select)(this);
        const words = text.text().split(/\s+/).reverse();
        let word = '';
        let line = [];
        let lineNumber = 0;
        const lineHeight = 1.1; // ems
        const y = text.attr('y');
        let tspan = text.text(null).append('tspan').attr('id', `WordBreakId-${idx}-${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-${idx}-${lineNumber}`).attr('x', 0).attr('y', y).attr('dy', lineNumber++ * lineHeight + 'em').text(word);
            }
        }
        idx += 1;
    });
}
function formatScientificLimitWidth(value) {
    return yAxisTickFormatterInternal(value, true);
}
const DEFAULT_BAR_WIDTH = 16;
const MIN_BAR_WIDTH = 1;
const getBarWidth = (barWidthProp, maxBarWidthProp, adjustedValue = DEFAULT_BAR_WIDTH, modeProp)=>{
    let 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;
};
const getScalePadding = (prop, shorthandProp, defaultValue = 0)=>{
    let padding = typeof prop === 'number' ? prop : typeof shorthandProp === 'number' ? shorthandProp : defaultValue;
    padding = Math.max(0, Math.min(padding, 1));
    return padding;
};
const isScalePaddingDefined = (prop, shorthandProp)=>{
    return typeof prop === 'number' || typeof shorthandProp === 'number';
};
function findIndex(array, cb, fromIndex = 0) {
    let index = -1;
    for(let i = fromIndex; array && i < array.length; i++){
        if (cb(array[i], i)) {
            index = i;
            break;
        }
    }
    return index;
}
function find(array, cb) {
    const index = findIndex(array, cb);
    if (index < 0) {
        return undefined;
    }
    return array[index];
}
const HighContrastSelector = '@media screen and (-ms-high-contrast: active), screen and (forced-colors: active)';
const HighContrastSelectorWhite = '@media screen and (-ms-high-contrast: black-on-white), screen and (forced-colors: active) and (prefers-color-scheme: light)';
const HighContrastSelectorBlack = '@media screen and (-ms-high-contrast: white-on-black), screen and (forced-colors: active) and (prefers-color-scheme: dark)';
const formatDate = (date, useUTC)=>{
    const timeFormat = useUTC ? _d3timeformat.utcFormat : _d3timeformat.timeFormat;
    return timeFormat('%-e %b %Y, %H:%M')(date) + (useUTC ? ' GMT' : '');
};
function areArraysEqual(arr1, arr2) {
    if (arr1 === arr2 || !arr1 && !arr2) {
        return true;
    }
    if (!arr1 || !arr2 || arr1.length !== arr2.length) {
        return false;
    }
    for(let i = 0; i < arr1.length; i++){
        if (arr1[i] !== arr2[i]) {
            return false;
        }
    }
    return true;
}
const cssVarRegExp = /var\((--[a-zA-Z0-9\-]+)\)/g;
function resolveCSSVariables(container, styleRules) {
    const containerStyles = getComputedStyle(container);
    return styleRules.replace(cssVarRegExp, (match, group1)=>{
        return containerStyles.getPropertyValue(group1);
    });
}
function getSecureProps(props = {}) {
    const { dangerouslySetInnerHTML, ...result } = props;
    return result;
}
function getCurveFactory(curve, defaultFactory = _d3shape.curveLinear) {
    if (typeof curve === 'function') {
        return curve;
    }
    switch(curve){
        case 'linear':
            return _d3shape.curveLinear;
        case 'natural':
            return _d3shape.curveNatural;
        case 'step':
            return _d3shape.curveStep;
        case 'stepAfter':
            return _d3shape.curveStepAfter;
        case 'stepBefore':
            return _d3shape.curveStepBefore;
        default:
            return defaultFactory;
    }
}
const truncateString = (str, maxLength, ellipsis = '...')=>{
    if (str.length <= maxLength) {
        return str;
    }
    return str.slice(0, maxLength) + ellipsis;
};
const categoryOrderRegex = /(category|total|sum|min|max|mean|median) (ascending|descending)/;
const sortAxisCategories = (categoryToValues, categoryOrder)=>{
    if (Array.isArray(categoryOrder)) {
        const result = [];
        const seen = new Set();
        // Add elements from categoryOrder array that are in categoryToValues, in the array's order
        categoryOrder.forEach((category)=>{
            if (categoryToValues[category] && !seen.has(category)) {
                result.push(category);
                seen.add(category);
            }
        });
        // Append any keys from categoryToValues not already in result
        Object.keys(categoryToValues).forEach((category)=>{
            if (!seen.has(category)) {
                result.push(category);
            }
        });
        return result;
    }
    const match = categoryOrder === null || categoryOrder === void 0 ? void 0 : categoryOrder.match(categoryOrderRegex);
    if (match) {
        const aggregator = match[1];
        const order = match[2];
        if (aggregator === 'category') {
            const result = Object.keys(categoryToValues).sort();
            return order === 'descending' ? result.reverse() : result;
        }
        const aggFn = {
            min: _d3array.min,
            max: _d3array.max,
            sum: _d3array.sum,
            total: _d3array.sum,
            mean: _d3array.mean,
            median: _d3array.median
        };
        const sortAscending = (a, b)=>{
            return a[1] - b[1];
        };
        const sortDescending = (a, b)=>{
            return b[1] - a[1];
        };
        const categoriesAggregatedValue = [];
        Object.keys(categoryToValues).forEach((category)=>{
            categoriesAggregatedValue.push([
                category,
                aggFn[aggregator](categoryToValues[category]) || 0
            ]);
        });
        categoriesAggregatedValue.sort(order === 'descending' ? sortDescending : sortAscending);
        return categoriesAggregatedValue.map(([category])=>category);
    }
    return Object.keys(categoryToValues);
};
function copyStyle(properties, fromEl, toEl) {
    const styles = getComputedStyle(fromEl);
    if (Array.isArray(properties)) {
        properties.forEach((prop)=>{
            (0, _d3selection.select)(toEl).style(prop, styles.getPropertyValue(prop));
        });
    } else {
        Object.entries(properties).forEach(([fromProp, toProp])=>{
            (0, _d3selection.select)(toEl).style(toProp, styles.getPropertyValue(fromProp));
        });
    }
}
const MEASUREMENT_SPAN_STYLE = {
    position: 'absolute',
    visibility: 'hidden',
    top: '-20000px',
    left: 0,
    padding: 0,
    margin: 0,
    border: 'none',
    whiteSpace: 'pre'
};
const MEASUREMENT_SPAN_ID = 'fui_measurement_span';
const TEXT_STYLE_PROPERTIES = [
    'font-size',
    'font-family',
    'font-weight',
    'font-style',
    'letter-spacing',
    'text-transform'
];
const measureTextWithDOM = (text, cssSelector, container)=>{
    let measurementSpan = document.getElementById(MEASUREMENT_SPAN_ID);
    if (!measurementSpan) {
        measurementSpan = document.createElement('span');
        measurementSpan.setAttribute('id', MEASUREMENT_SPAN_ID);
        measurementSpan.setAttribute('aria-hidden', 'true');
        (container !== null && container !== void 0 ? container : document.body).appendChild(measurementSpan);
    }
    Object.assign(measurementSpan.style, MEASUREMENT_SPAN_STYLE);
    const refEl = (container !== null && container !== void 0 ? container : document).querySelector(cssSelector);
    if (refEl) {
        copyStyle(TEXT_STYLE_PROPERTIES, refEl, measurementSpan);
    }
    measurementSpan.textContent = `${text}`;
    const rect = measurementSpan.getBoundingClientRect();
    return {
        node: measurementSpan,
        width: rect.width,
        height: rect.height
    };
};
const CACHE_SIZE = 2000;
const textSizeCache = new Map();
const getTextSize = (text, cssSelector, container)=>{
    const cacheKey = `${text}|${cssSelector}`;
    const cachedResult = textSizeCache.get(cacheKey);
    if (cachedResult) {
        return cachedResult;
    }
    const { width, height } = measureTextWithDOM(text, cssSelector, container);
    // TODO: Improve cache eviction strategy if needed (e.g., LRU)
    if (textSizeCache.size >= CACHE_SIZE) {
        const firstKey = textSizeCache.keys().next().value;
        if (!(0, _chartutilities.isInvalidValue)(firstKey)) {
            textSizeCache.delete(firstKey);
        }
    }
    textSizeCache.set(cacheKey, {
        width,
        height
    });
    return {
        width,
        height
    };
};
function isScatterPolarSeries(points) {
    return points.some((item)=>{
        var _item_lineOptions;
        return typeof ((_item_lineOptions = item.lineOptions) === null || _item_lineOptions === void 0 ? void 0 : _item_lineOptions.mode) === 'string' && item.lineOptions.mode === 'scatterpolar';
    });
}
function isTextMode(points) {
    return points.some((item)=>{
        var _item_lineOptions;
        return typeof ((_item_lineOptions = item.lineOptions) === null || _item_lineOptions === void 0 ? void 0 : _item_lineOptions.mode) === 'string' && item.lineOptions.mode === 'text';
    });
}
// TODO: Refactor to encapsulate the complete numeric scale creation logic here, including setting domain and range.
const createNumericScale = (scaleType)=>{
    if (scaleType === 'log') {
        return (0, _d3scale.scaleLog)();
    } else {
        return (0, _d3scale.scaleLinear)();
    }
};
const getDomainPaddingForMarkers = (minVal, maxVal, scaleType, userMinVal, userMaxVal)=>{
    if (scaleType === 'log') {
        return {
            start: minVal * 0.5,
            end: maxVal
        };
    }
    /* if user explicitly sets userMinVal or userMaxVal, we will check that to avoid excessive padding on either side.
     If the difference between minVal and userMinVal is more than 10% of the data range, we set padding to 0 on that side.
     this is to avoid cases where userMinVal is significantly smaller than minVal or userMaxVal is significantly larger than
     maxVal, which would lead to excessive padding. In other cases, we apply the default 10% padding on both sides.
  */ const rangePadding = (maxVal - minVal) * 0.1;
    // If explicit bounds are set and they're far from the data range, don't add extra padding
    const paddingAlreadySatisfiedAtMin = userMinVal !== undefined && rangePadding > Math.abs(minVal - Math.min(minVal, userMinVal));
    const paddingAlreadySatisfiedAtMax = userMaxVal !== undefined && rangePadding > Math.abs(maxVal - Math.max(maxVal, userMaxVal));
    const startPadding = paddingAlreadySatisfiedAtMin ? 0 : rangePadding;
    const endPadding = paddingAlreadySatisfiedAtMax ? 0 : rangePadding;
    return {
        start: startPadding,
        end: endPadding
    };
};
const isValidDomainValue = (value, scaleType)=>{
    return typeof value !== 'number' || scaleType !== 'log' || value > 0;
};
const isPlottable = (x, y)=>{
    return !(0, _chartutilities.isInvalidValue)(x) && !(0, _chartutilities.isInvalidValue)(y);
};
const getScatterXDomainExtent = (points, scaleType)=>{
    const isValidDataPointForScale = (item)=>isValidDomainValue(item.x, scaleType);
    const xMin = (0, _d3array.min)(points, (point)=>{
        return (0, _d3array.min)(point.data.filter(isValidDataPointForScale), (item)=>item.x);
    });
    const xMax = (0, _d3array.max)(points, (point)=>{
        return (0, _d3array.max)(point.data.filter(isValidDataPointForScale), (item)=>{
            return item.x;
        });
    });
    return [
        xMin,
        xMax
    ];
};
const calculateMarkerRadius = ({ pointMarkerSize, minMarkerSize, maxMarkerSize, extraMaxPixels, isContinuousXY, isActive = false, defaultRadius = 3.5, activeRadius = 5.5, minRadius = 4 })=>{
    const minPixel = 4;
    const maxPixel = 16;
    // If no marker size is specified, use default or active radius
    if (!pointMarkerSize) {
        return isActive ? activeRadius : defaultRadius;
    }
    let radius;
    if (isContinuousXY && maxMarkerSize !== 0) {
        // For continuous axes: scale markers based on available space
        radius = maxMarkerSize < extraMaxPixels ? pointMarkerSize : pointMarkerSize / maxMarkerSize * extraMaxPixels;
    } else if (!isContinuousXY && maxMarkerSize !== minMarkerSize) {
        // For categorical axes: normalize to pixel range [minPixel, maxPixel]
        radius = minPixel + (pointMarkerSize - minMarkerSize) / (maxMarkerSize - minMarkerSize) * (maxPixel - minPixel);
    } else {
        // Fallback to default/active radius
        return isActive ? activeRadius : defaultRadius;
    }
    // Ensure minimum radius for visibility
    return Math.max(radius, minRadius);
};
const getRangeForScatterMarkerSize = ({ data, xScale, yScalePrimary, yScaleSecondary, useSecondaryYScale, xScaleType, yScaleType: primaryYScaleType, secondaryYScaleType })=>{
    // Note: This function is executed after the scale is created, so the actual padding can be
    // obtained by calculating the difference between the respective minimums or maximums of the
    // scale domain and the data. However, doing so often causes the marker size to scale up
    // unnecessarily when the scale uses a wider domain than required (due to the use of D3's nice
    // function or our own tick value calculations).
    // A better approach could be to treat the marker size as a fixed pixel value and adjust the
    // scale domain with sufficient padding to accommodate the maximum marker size—instead of doing
    // it the other way around (i.e., adjusting the scale domain first with padding and then scaling
    // the markers to fit inside the plot area).
    const [xMin, xMax] = getScatterXDomainExtent(data, xScaleType);
    const xPadding = getDomainPaddingForMarkers(+xMin, +xMax, xScaleType);
    const scaleXMin = xMin instanceof Date ? new Date(+xMin - xPadding.start) : xMin - xPadding.start;
    const scaleXMax = xMax instanceof Date ? new Date(+xMax + xPadding.end) : xMax + xPadding.end;
    const extraXPixels = Math.min(Math.abs(xScale(xMin) - xScale(scaleXMin)), Math.abs(xScale(scaleXMax) - xScale(xMax)));
    const yScaleType = useSecondaryYScale ? secondaryYScaleType : primaryYScaleType;
    const { startValue: yMin, endValue: yMax } = findNumericMinMaxOfY(data, undefined, useSecondaryYScale, yScaleType);
    const yPadding = getDomainPaddingForMarkers(yMin, yMax, yScaleType);
    const scaleYMin = yMin - yPadding.start;
    const scaleYMax = yMax + yPadding.end;
    const yScale = useSecondaryYScale ? yScaleSecondary : yScalePrimary;
    const extraYPixels = Math.min(Math.abs(yScale(scaleYMin) - yScale(yMin)), Math.abs(yScale(yMax) - yScale(scaleYMax)));
    return Math.min(extraXPixels, extraYPixels);
};
const generateLinearTicks = (tick0, tickStep, scaleDomain)=>{
    const domainMin = (0, _d3array.min)(scaleDomain);
    const domainMax = (0, _d3array.max)(scaleDomain);
    const precision = Math.max(calculatePrecision(tick0), calculatePrecision(tickStep));
    const start = Math.ceil(precisionRound((domainMin - tick0) / tickStep, precision));
    const end = Math.floor(precisionRound((domainMax - tick0) / tickStep, precision));
    const ticks = [];
    for(let i = start; i <= end; i++){
        ticks.push(precisionRound(tick0 + i * tickStep, precision));
    }
    return ticks;
};
const generateMonthlyTicks = (tick0, tickStepInMonths, scaleDomain, useUTC)=>{
    const domainMin = +(0, _d3array.min)(scaleDomain);
    const domainMax = +(0, _d3array.max)(scaleDomain);
    const getMonth = (d)=>useUTC ? d.getUTCMonth() : d.getMonth();
    const setMonth = (d, month)=>useUTC ? new Date(d.setUTCMonth(month)) : new Date(d.setMonth(month));
    // Find the earliest tick <= domainMin
    let start = 0;
    for(let firstTick = new Date(+tick0); +firstTick > domainMin;){
        firstTick = setMonth(firstTick, getMonth(firstTick) - tickStepInMonths);
        start -= tickStepInMonths;
    }
    const baseMonth = getMonth(tick0);
    const ticks = [];
    // Generate ticks forward until domainMax
    for(let i = start;; i += tickStepInMonths){
        let tickDate = setMonth(new Date(+tick0), baseMonth + i);
        // Handle month rollover (e.g., Jan 31 + 1 month → Mar 3 instead of Feb)
        if (getMonth(tickDate) !== ((baseMonth + i) % 12 + 12) % 12) {
            tickDate = useUTC ? new Date(tickDate.setUTCDate(0)) : new Date(tickDate.setDate(0));
        }
        if (+tickDate > domainMax) {
            break;
        }
        if (+tickDate >= domainMin) {
            ticks.push(tickDate);
        }
    }
    return ticks;
};
const generateNumericTicks = (scaleType, tickStep, tick0, scaleDomain)=>{
    const refTick = typeof tick0 === 'number' ? tick0 : 0;
    if (scaleType === 'log') {
        if (typeof tickStep === 'number' && tickStep > 0) {
            return generateLinearTicks(refTick, tickStep, scaleDomain.map((d)=>Math.log10(d))).map((t)=>10 ** t);
        }
        if (typeof tickStep === 'string') {
            const prefix = tickStep[0];
            const num = (0, _chartutilities.isNumber)(tickStep.slice(1)) ? Number(tickStep.slice(1)) : 0;
            if (prefix === 'L' && num > 0) {
                return generateLinearTicks(refTick, num, scaleDomain);
            }
        }
        return;
    }
    if (typeof tickStep === 'number' && tickStep > 0) {
        return generateLinearTicks(refTick, tickStep, scaleDomain);
    }
};
const generateDateTicks = (tickStep, tick0, scaleDomain, useUTC)=>{
    const refTick = tick0 instanceof Date ? tick0 : new Date(DEFAULT_DATE_STRING);
    if (typeof tickStep === 'number' && tickStep > 0) {
        return generateLinearTicks(+refTick, tickStep, scaleDomain.map((d)=>+d)).map((t)=>new Date(t));
    }
    if (typeof tickStep === 'string') {
        const prefix = tickStep[0];
        const num = (0, _chartutilities.isNumber)(tickStep.slice(1)) ? Number(tickStep.slice(1)) : 0;
        if (prefix === 'M' && num > 0 && num === Math.round(num)) {
            return generateMonthlyTicks(refTick, num, scaleDomain, useUTC);
        }
    }
};
function calculatePrecision(value) {
    /**
   * Group 1:
   * [1-9]([0]+$) matches trailing zeros
   * Group 2:
   * \.([0-9]*) matches all digits after a decimal point.
   */ const groups = /[1-9]([0]+$)|\.([0-9]*)/.exec(String(value));
    if (!groups) {
        return 0;
    }
    if (groups[1]) {
        return -groups[1].length;
    }
    if (groups[2]) {
        return groups[2].length;
    }
    return 0;
}
function precisionRound(value, precision, base = 10) {
    const exp = base ** precision;
    return Math.round(value * exp) / exp;
}
const findCalloutPoints = (calloutPointsByX, x)=>{
    if (x === null) {
        return undefined;
    }
    const key = x instanceof Date ? x.getTime() : x;
    if (!calloutPointsByX[key]) {
        return undefined;
    }
    return {
        x,
        values: calloutPointsByX[key]
    };
};
const autoLayoutXAxisLabels = (tickValues, tickLabels, scale, axisNode, containerWidth, container)=>{
    let requiresWrap = false;
    let requiresTruncate = false;
    const maxWidths = [];
    const [rangeStart, rangeEnd] = scale.range();
    const isRTL = rangeEnd - rangeStart < 0;
    const start = isRTL ? containerWidth : 0;
    const end = isRTL ? 0 : containerWidth;
    const getTickPosition = (index)=>{
        var _scale;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return ((_scale = scale(tickValues[index])) !== null && _scale !== void 0 ? _scale : 0) + ('bandwidth' in scale ? scale.bandwidth() / 2 : 0);
    };
    const getLabelWidth = (text)=>{
        return getTextSize(text, CARTESIAN_XAXIS_TEXT_SELECTOR, container).width;
    };
    for(let i = 0; i < tickValues.length; i++){
        const position = getTickPosition(i);
        const leftSpace = Math.abs(i > 0 ? (position - getTickPosition(i - 1)) / 2 : position - start);
        const rightSpace = Math.abs(i + 1 < tickValues.length ? (getTickPosition(i + 1) - position) / 2 : end - position);
        const maxAvailableWidth = Math.min(leftSpace, rightSpace) * 2 - 8; // 4px padding on both sides
        const label = tickLabels[i];
        const labelWidth = getLabelWidth(label);
        maxWidths.push(maxAvailableWidth);
        if (labelWidth > maxAvailableWidth) {
            const longestWordWidth = Math.max(...label.split(/\s+/).map((word)=>getLabelWidth(word)));
            if (longestWordWidth <= maxAvailableWidth) {
                requiresWrap = true;
            } else {
                requiresTruncate = true;
            }
        }
    }
    if (requiresTruncate) {
        return truncateAndStaggerXAxisLabels(tickValues, tickLabels, scale, axisNode, containerWidth, container);
    }
    if (requiresWrap) {
        var _createWrapOfXLabels;
        return (_createWrapOfXLabels = createWrapOfXLabels({
            node: axisNode,
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            xAxis: scale,
            noOfCharsToTruncate: 100,
            showXAxisLablesTooltip: false,
            width: maxWidths,
            container
        })) !== null && _createWrapOfXLabels !== void 0 ? _createWrapOfXLabels : 0;
    }
    return 0;
};
const truncateAndStaggerXAxisLabels = (tickValues, tickLabels, scale, axisNode, containerWidth, container)=>{
    if (!axisNode) {
        return 0;
    }
    let maxHeight = 12;
    const [rangeStart, rangeEnd] = scale.range();
    const isRTL = rangeEnd - rangeStart < 0;
    const start = isRTL ? containerWidth : 0;
    const end = isRTL ? 0 : containerWidth;
    const getTickPosition = (index)=>{
        var _scale;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return ((_scale = scale(tickValues[index])) !== null && _scale !== void 0 ? _scale : 0) + ('bandwidth' in scale ? scale.bandwidth() / 2 : 0);
    };
    const getLabelSize = (text)=>{
        return getTextSize(text, CARTESIAN_XAXIS_TEXT_SELECTOR, container);
    };
    (0, _d3selection.select)(axisNode).selectAll('.tick text').each(function(_, i) {
        const position = getTickPosition(i);
        const leftSpace = Math.abs(i > 0 ? position - getTickPosition(i - 1) : position - start);
        const rightSpace = Math.abs(i + 1 < tickValues.length ? getTickPosition(i + 1) - position : end - position);
        const maxAvailableWidth = Math.min(leftSpace, rightSpace) * 2 - 8; // 4px padding on both sides
        const label = tickLabels[i];
        const textNode = (0, _d3selection.select)(this).text(null).attr('data-full', label);
        const lineHeight = 1.1; // ems
        const y = textNode.attr('y');
        const dy = parseFloat(textNode.attr('dy'));
        textNode.append('tspan').attr('x', 0).attr('y', y).attr('dy', (i % 2 === 1 ? lineHeight : 0) + dy + 'em').text(truncateTextToFitWidth(label, maxAvailableWidth, (s)=>getLabelSize(s).width));
        maxHeight = Math.max(maxHeight, getLabelSize(label).height);
    });
    return tickValues.length > 1 ? maxHeight : 0;
};
const truncateTextToFitWidth = (text, maxWidth, measure)=>{
    if (measure(text) <= maxWidth) {
        return text;
    }
    let lo = 1;
    let hi = text.length;
    while(lo < hi){
        const mid = Math.floor((lo + hi + 1) / 2);
        const candidate = text.slice(0, mid) + '...';
        if (measure(candidate) <= maxWidth) {
            lo = mid;
        } else {
            hi = mid - 1;
        }
    }
    return text.slice(0, lo) + '...';
};
