/* @oracle/oraclejet-preact: undefined */
import { jsxs, Fragment, jsx } from 'preact/jsx-runtime';
import { styles as styles$1, dimensionStyle } from './PRIVATE_Chart/themes/ChartStyles.css.js';
import { T as TrackResizeContainer } from './TrackResizeContainer-3d7b18b7.js';
import { VisInvalidDataError } from './UNSAFE_visErrors.js';
import { u as useTextDimensions } from './useTextDimensions-45f79df4.js';
import { u as useCssVars } from './useCssVars-bc2527ac.js';
import { useState, useRef, useEffect, useMemo, useImperativeHandle } from 'preact/hooks';
import { R as ReferenceLineArea, G as Gridlines, P as PlotArea } from './ReferenceLineArea-53129f72.js';
import { u as updateViewportFromOverview, h as hasInvalidData, g as getAxesPosition, a as getScrollBarSpace, b as getLayoutInfo, c as updateScrollBarSpace, d as hasData, e as getActiveInfo, i as getAvailSpace, j as getOuterGaps } from './utils-24c54d43.js';
import { u as useUser } from './useUser-06d34d19.js';
import './PlotAreaStyles.styles.css';
import { u as useId } from './useId-03dbfdf0.js';
import { A as Axis } from './Axis-e23d7b41.js';
import { u as useChartViewport } from './useChartViewport-03efd960.js';
import { u as useChartNav } from './useChartNav-49b52017.js';
import { m as mergeProps } from './mergeProps-88ea8306.js';
import { S as ScrollBar } from './ScrollBar-c7a5d361.js';
import { a as useSelectDrill, u as useChartDatatipAndCursor } from './useSelectDrill-f669e729.js';
import { u as useTestId } from './useTestId-f24ac480.js';
import { g as getChartVars } from './cssUtils-9e0e0351.js';
import { u as useChartContextMenu } from './useChartContextMenu-5de82cd7.js';
import { u as useChartDnd } from './useChartDnd-aa8bc33b.js';
import { a as getElementData } from './eventsUtils-14cb0a49.js';
import './accUtils-9d5183c4.js';
import { c as calculateOffset } from './layoutUtils-ec5be703.js';
import { u as useTooltip } from './useTooltip-94af94d4.js';
import './logger-c92f309c.js';
import './LayerHost-7931b424.js';
import { forwardRef } from 'preact/compat';
import './TooltipContentStyles.styles.css';
import './hooks/UNSAFE_useTooltip/themes/redwood/TooltipContentBaseTheme.styles.css';
import './hooks/UNSAFE_useTooltip/themes/redwood/TooltipContentVariants.css.js';
import './tooltipUtils-af0abd38.js';
import { u as useChartMarquee } from './useChartMarquee-761eb7db.js';
import { u as useVisTouchResponse } from './useVisTouchResponse-a59ab166.js';
import { O as OverviewContext, u as useOverviewContext } from './useOverviewContext-79377674.js';
import { a as ScaleLinear } from './scale-9a834124.js';
import { O as OverviewSlidingWindow } from './OverviewSlidingWindow-a8a4c9ef.js';
import { styles } from './PRIVATE_VisOverview/themes/VisOverview.css.js';
import { u as useTranslationBundle } from './useTranslationBundle-4822502f.js';
import { g as getTextAndDimsInfo, a as getAriaLabelGenerator, b as getTextAndBoundsUtil } from './useChartDatatip-8dd22b71.js';
import { createElement } from 'preact';
import { l } from './stringUtils-0fe25200.js';

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
/**
 * Returns the parent group for the navigable item.
 * @param levelsArray The levels array.
 * @param levelIndex The levelIndex of current naviable group..
 * @param groupIndex The groupIndex of current navigable group.
 * @returns
 */
function getParentGroup(levelsArray, levelIndex, groupIndex, isGroupNavigable) {
    const path = levelsArray[levelIndex][groupIndex].path;
    if (path.length === 1) {
        return {
            levelIndex,
            groupIndex
        };
    }
    let lIndex = Math.max(0, levelIndex - 1);
    const groupItem = levelsArray[levelIndex][groupIndex];
    const { start, end } = groupItem;
    while (lIndex >= 0) {
        for (let i = 0; i < levelsArray[lIndex].length; i++) {
            const { start: s, end: e } = levelsArray[lIndex][i];
            if (s <= start && end <= e) {
                if (isGroupNavigable(lIndex, i)) {
                    return { groupIndex: i, levelIndex: lIndex };
                }
            }
        }
        lIndex -= 1;
    }
    return {
        levelIndex,
        groupIndex
    };
}
/**
 * @param levelsArray The levels array.
 * @param levelIndex The levelIndex of current navigable item.
 * @param groupIndex The groupIndex of current navigable item.
 * @returns
 */
function getChildGroup(levelsArray, levelIndex, groupIndex, isGroupNavigable) {
    if (levelIndex === levelsArray.length - 1) {
        return { levelIndex, groupIndex };
    }
    const lIndex = Math.min(levelsArray.length - 1, levelIndex + 1);
    const groupItem = levelsArray[levelIndex][groupIndex];
    const { start, end } = groupItem;
    while (lIndex <= levelsArray.length - 1) {
        for (let i = 0; i < levelsArray[lIndex].length; i++) {
            const { start: s, end: e } = levelsArray[lIndex][i];
            if (start <= s && e <= end) {
                if (isGroupNavigable(lIndex, i)) {
                    return { groupIndex: i, levelIndex: lIndex };
                }
            }
        }
    }
    return {
        levelIndex,
        groupIndex
    };
}
function getNextGroup(levelsArray, info, isGroupNavigable) {
    const groupIndex = info.groupIndex + 1;
    const levelIndex = info.levelIndex;
    const maxgroup = levelsArray[levelIndex].length - 1;
    if (groupIndex > maxgroup) {
        return;
    }
    if (isGroupNavigable(levelIndex, groupIndex)) {
        return { groupIndex, levelIndex };
    }
    return getNextGroup(levelsArray, { groupIndex, levelIndex }, isGroupNavigable);
}
function getPreviousGroup(info, isGroupNavigable) {
    const groupIndex = info.groupIndex - 1;
    const levelIndex = info.levelIndex;
    if (groupIndex < 0) {
        return;
    }
    if (isGroupNavigable(levelIndex, groupIndex)) {
        return { groupIndex, levelIndex };
    }
    return getPreviousGroup({ groupIndex, levelIndex }, isGroupNavigable);
}
function getGroupNavUtil(levelsArray, drilling, isRtl, isHoriz, isGroupLabelRendered) {
    const isGroupNavigable = (levelIndex, groupIndex) => {
        const group = levelsArray[levelIndex][groupIndex].item;
        const groupName = group.name || group.id;
        const groupsDrilling = group.drilling;
        const isLabelRendered = !!isGroupLabelRendered?.(levelIndex, groupIndex);
        return (isLabelRendered &&
            groupName != null &&
            (drilling === 'on' || drilling === 'groupsOnly') &&
            groupsDrilling != 'off');
    };
    const getDefaultNavGroup = () => {
        for (let levelIndex = 0; levelIndex < levelsArray.length; levelIndex++) {
            const numGroups = levelsArray[levelIndex].length;
            for (let groupIndex = 0; groupIndex < numGroups; groupIndex++) {
                if (isGroupNavigable(levelIndex, groupIndex)) {
                    return { groupIndex, levelIndex };
                }
            }
        }
        return { groupIndex: 0, levelIndex: 0 };
    };
    const getNextNavGroup = (info, arrow) => {
        let nextGroup;
        if (arrow === 'ArrowRight') {
            if (isHoriz) {
                nextGroup = !isRtl
                    ? getChildGroup(levelsArray, info.levelIndex, info.groupIndex, isGroupNavigable)
                    : getParentGroup(levelsArray, info.levelIndex, info.groupIndex, isGroupNavigable);
            }
            else {
                nextGroup = isRtl
                    ? getPreviousGroup(info, isGroupNavigable)
                    : getNextGroup(levelsArray, info, isGroupNavigable);
            }
        }
        else if (arrow === 'ArrowLeft') {
            if (isHoriz) {
                nextGroup = isRtl
                    ? getChildGroup(levelsArray, info.levelIndex, info.groupIndex, isGroupNavigable)
                    : getParentGroup(levelsArray, info.levelIndex, info.groupIndex, isGroupNavigable);
            }
            else {
                nextGroup = isRtl
                    ? getNextGroup(levelsArray, info, isGroupNavigable)
                    : getPreviousGroup(info, isGroupNavigable);
            }
        }
        else if (arrow === 'ArrowDown') {
            nextGroup = isHoriz
                ? getNextGroup(levelsArray, info, isGroupNavigable)
                : getParentGroup(levelsArray, info.levelIndex, info.groupIndex, isGroupNavigable);
        }
        else if (arrow === 'ArrowUp') {
            nextGroup = isHoriz
                ? getPreviousGroup(info, isGroupNavigable)
                : getChildGroup(levelsArray, info.levelIndex, info.groupIndex, isGroupNavigable);
        }
        return nextGroup || info;
    };
    return { getNextNavGroup, getDefaultNavGroup };
}

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
function getRefObjectPosition(object) {
    if (object.type === 'line') {
        return object.value;
    }
    if (object.type === 'area') {
        if (object.low != null && object.high != null) {
            return (object.low + object.high) / 2;
        }
    }
    return undefined;
}
function buildNavigableRefObjects(xRefs, yRefs, y2Refs) {
    const normalize = (arr) => (arr ?? [])
        .map((obj) => ({ id: obj.id, val: getRefObjectPosition(obj) }))
        .filter((obj) => obj.id != null && obj.val != null)
        .sort((a, b) => a.val - b.val);
    const xList = normalize(xRefs);
    const yList = normalize(yRefs);
    const y2List = normalize(y2Refs);
    return [...xList, ...yList, ...y2List];
}
/**
 * Compute an anchor bounds for a reference object by id. Returns a 1x1 box positioned
 * at a reasonable anchor point for the ref so datatips can use element anchoring.
 */
function getRefObjectBounds(id, xRefs, yRefs, y2Refs, xScale, yScale, y2Scale, orientation, plotAreaSpace) {
    const ref = xRefs?.find((item) => item.id === id) ??
        yRefs?.find((item) => item.id === id) ??
        y2Refs?.find((item) => item.id === id);
    if (!ref)
        return undefined;
    const isInX = xRefs?.some((item) => item.id === id);
    const isInY2 = y2Refs?.some((item) => item.id === id);
    const isXRef = !!isInX;
    const targetScale = isXRef ? xScale : isInY2 ? y2Scale : yScale;
    const spanningScale = isXRef ? yScale : xScale;
    const asPoint = (cx, cy) => ({ x: cx, y: cy, width: 1, height: 1 });
    if (ref.type === 'line' && ref.value != null) {
        const pos = targetScale?.transform(ref.value);
        const range = spanningScale?.range?.();
        const span1 = range?.[0];
        const span2 = range?.[1];
        if (typeof pos !== 'number' || isNaN(pos) || span1 == null || span2 == null)
            return undefined;
        const mid = (span1 + span2) / 2;
        const isHorizontalLine = (orientation === 'vertical' && !isXRef) || (orientation === 'horizontal' && isXRef);
        return isHorizontalLine ? asPoint(mid, pos) : asPoint(pos, mid);
    }
    // Constant area (low/high)
    if (ref.type === 'area') {
        const domain = targetScale?.domain?.();
        const domMin = domain ? Math.min(domain[0], domain[1]) : -Infinity;
        const domMax = domain ? Math.max(domain[0], domain[1]) : Infinity;
        const clampedLow = ref.low != null ? Math.max(ref.low, domMin) : domMin;
        const clampedHigh = ref.high != null ? Math.min(ref.high, domMax) : domMax;
        const pos1 = targetScale?.transform(clampedLow);
        const pos2 = targetScale?.transform(clampedHigh);
        const range = spanningScale?.range?.();
        const span1 = range?.[0];
        const span2 = range?.[1];
        if (typeof pos1 !== 'number' ||
            typeof pos2 !== 'number' ||
            isNaN(pos1) ||
            isNaN(pos2) ||
            span1 == null ||
            span2 == null) {
            return undefined;
        }
        const midSpan = (span1 + span2) / 2;
        const midPos = (pos1 + pos2) / 2;
        const isHorizontalArea = (orientation === 'vertical' && !isXRef) || (orientation === 'horizontal' && isXRef);
        return isHorizontalArea ? asPoint(midSpan, midPos) : asPoint(midPos, midSpan);
    }
    const centerX = plotAreaSpace.x + plotAreaSpace.width / 2;
    const centerY = plotAreaSpace.y + plotAreaSpace.height / 2;
    return asPoint(centerX, centerY);
}

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
function useTextTruncation({ getTextAndBounds, width, isRtl, textAndBounds }) {
    const [text, setText] = useState();
    const bounds = useRef();
    const hoveredRef = useRef(false);
    useEffect(() => {
        if (textAndBounds.text) {
            bounds.current = textAndBounds.bounds;
            setText(textAndBounds.text);
        }
        else if (!hoveredRef.current) {
            setText(undefined);
        }
    }, [textAndBounds]);
    const { tooltipContent, tooltipProps } = useTooltip({
        text,
        position: 'top-start',
        offset: calculateOffset(isRtl, width, bounds.current)
    });
    const onPointerMove = (event) => {
        const textAndBounds = getTextAndBounds(event.target);
        if (textAndBounds) {
            bounds.current = textAndBounds.bounds;
            setText(textAndBounds.text);
            hoveredRef.current = true;
        }
        else {
            setText(undefined);
            hoveredRef.current = false;
        }
    };
    return {
        tooltipContent,
        tooltipProps: mergeProps({ onPointerMove }, tooltipProps)
    };
}

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
function getWindowCoords(isRtl, xViewportExtent, xAxisExtent, yViewportExtent, yAxisExtent, plotAreaSpace) {
    const xDomain = [xAxisExtent.min, xAxisExtent.max];
    const xRange = (isRtl
        ? [plotAreaSpace.x + plotAreaSpace.width, plotAreaSpace.x]
        : [plotAreaSpace.x, plotAreaSpace.x + plotAreaSpace.width]);
    const xScale = new ScaleLinear(xDomain, xRange);
    const yDomain = [yAxisExtent.min, yAxisExtent.max];
    const yRange = [plotAreaSpace.y + plotAreaSpace.height, plotAreaSpace.y];
    const yScale = new ScaleLinear(yDomain, yRange);
    const windowX = xScale.transform(xViewportExtent.viewportMin);
    const windowWidth = Math.abs(xScale.transform(xViewportExtent.viewportMax) - xScale.transform(xViewportExtent.viewportMin));
    return {
        windowX: isRtl ? windowX - windowWidth : windowX,
        windowWidth: windowWidth,
        windowY: yScale.transform(yViewportExtent.viewportMax),
        windowHeight: Math.abs(yScale.transform(yViewportExtent.viewportMax) - yScale.transform(yViewportExtent.viewportMin)),
        xScale,
        yScale
    };
}

function OverviewBackground({ x, width, height, y, windowX, windowHeight, windowWidth, windowY }) {
    return (jsxs(Fragment, { children: [jsx("rect", { x: x, y: y, width: Math.max(0, windowX - x), height: height, class: styles.overviewBackground }), jsx("rect", { x: windowX + windowWidth, width: Math.max(0, x + width - windowX - windowWidth), y: y, height: height, class: styles.overviewBackground }), jsx("rect", { x: windowX, y: y, height: Math.max(0, windowY - y), width: windowWidth, class: styles.overviewBackground }), jsx("rect", { x: windowX, y: windowY + windowHeight, width: windowWidth, class: styles.overviewBackground, height: Math.max(y + height - windowY - windowHeight, 0) })] }));
}

function getRenderer(xAxisExtent, isRtl, overviewXScale, plotAreaSpace, windowCoords, hasHandles, onViewportChange) {
    return {
        slidingWindow: (jsx(OverviewSlidingWindow, { ...plotAreaSpace, ...windowCoords, hasHandles: hasHandles, onWindowDimsChange: (props) => {
                updateViewportFromOverview(xAxisExtent, isRtl, windowCoords.windowX, windowCoords.windowWidth, props.deltaX, props.deltaWidth, overviewXScale, onViewportChange);
            } })),
        background: jsx(OverviewBackground, { ...plotAreaSpace, ...windowCoords })
    };
}

// Main renderer component
function ReferenceObjects({ location, xAxis, yAxis, y2Axis, xScale, yScale, y2Scale, orientation, xAxisInfo, groups, activeId, activeInfo }) {
    const filterFunc = (item) => location === 'front' ? item.location === 'front' : item.location !== 'front';
    return (jsxs(Fragment, { children: [xAxis?.referenceObjects
                ?.filter(filterFunc)
                .map((item, index) => (createElement(ReferenceLineArea, { ...item, key: item.id, xScale: xScale, yScale: yScale, orientation: orientation, groups: groups, xStartIndex: xAxisInfo.startIndex, xEndIndex: xAxisInfo.endIndex, seriesIndex: index, isXRef: true, activeId: item.id === activeInfo?.refObjId ? activeId : undefined }))), yAxis?.referenceObjects
                ?.filter(filterFunc)
                .map((item, index) => (jsx(ReferenceLineArea, { ...item, xScale: xScale, yScale: yScale, orientation: orientation, groups: groups, xStartIndex: xAxisInfo.startIndex, xEndIndex: xAxisInfo.endIndex, seriesIndex: index, activeId: item.id === activeInfo?.refObjId ? activeId : undefined }))), y2Axis?.referenceObjects
                ?.filter(filterFunc)
                .map((item, index) => (jsx(ReferenceLineArea, { ...item, xScale: xScale, yScale: y2Scale, orientation: orientation, groups: groups, xStartIndex: xAxisInfo.startIndex, xEndIndex: xAxisInfo.endIndex, seriesIndex: index, activeId: item.id === activeInfo?.refObjId ? activeId : undefined })))] }));
}

const OVERVIEW_GAP = 10;
const chartVars = getChartVars();
const ChartWithDimensions = forwardRef(({ width, height, selectedIds, hiddenIds, hideAndShowBehavior = 'none', orientation = 'vertical', xAxis, yAxis, y2Axis, plotArea, dragMode = 'user', series, groups, isStacked = false, stackLabelStyle, getStackGroup, getDataItem, selectionMode = 'none', drilling = 'off', dataCursorPosition, onSelectionChange, isDataCursorEnabled, dataCursorStyle, onViewportChange, onDataCursorPositionChange, onItemDrill, onGroupDrill, onItemHover, onItemFocus, datatip, zoomAndScroll = 'off', getNavUtil, getDataItemPos, getGapRatio, valueFormats, findNearest, getMarkerInfo, isRtl, children, testId, renderGridLinesInFront, isDataXAxis, contextMenuConfig, overview = 'off', getStartAndEndAxesOffset, defaultOverviewContentRenderer, isOverview, yAxisSize, overviewRenderer, initialZooming = 'none', ...props }, ref = null) => {
    const timeAxisType = xAxis?.timeAxisType;
    const isTimeAxis = timeAxisType != null;
    if (hasInvalidData(timeAxisType, series, groups, getDataItem)) {
        throw new VisInvalidDataError('Chart received invalid data');
    }
    const testIdProps = useTestId(testId);
    const rootRef = useRef(null);
    const isTestEnv = testIdProps['data-testid'] !== undefined;
    const isHoriz = orientation === 'horizontal';
    const { xAxisPosition, yAxisPosition, y2AxisPosition } = getAxesPosition(yAxis, y2Axis, isHoriz, isRtl);
    const { resolvedVars, cssContent } = useCssVars(chartVars);
    const resolvedColors = Array.from(Array(12)).map((_, index) => {
        return resolvedVars[`color${index + 1}`];
    });
    const { textMeasureContent, getTextDimensions } = useTextDimensions();
    let availSpace = getAvailSpace(width, height);
    if (isOverview && yAxisSize) {
        const w = availSpace.width - yAxisSize;
        const gaps = getOuterGaps(w, height);
        availSpace.width -= yAxisSize - 2 * gaps.width;
        availSpace.x += yAxisSize - gaps.width;
    }
    const updatedSpace = getScrollBarSpace(isTimeAxis, availSpace, zoomAndScroll, xAxisPosition, overview);
    let scrollDims = updatedSpace.scrollDims;
    availSpace = updatedSpace.availSpace;
    const { locale } = useUser();
    const { x, y, width: _width, height: _height } = availSpace;
    const labelFontSize = resolvedVars['labelFontSize'];
    const split = y2Axis?.split ?? 'off';
    const isSplitDualY = split !== 'off';
    const splitterPosition = split !== 'off' ? split : 0.5;
    const layoutInfo = useMemo(() => {
        const hiddenSet = new Set(hiddenIds);
        return getLayoutInfo(series, groups, getDataItem, xAxis, yAxis, y2Axis, { x, y, width: _width, height: _height }, // availSpace
        hiddenSet, hideAndShowBehavior, isHoriz, isRtl, isStacked, labelFontSize, getStartAndEndAxesOffset, locale, isSplitDualY, splitterPosition, getStackGroup, getTextDimensions, isTestEnv, isDataXAxis, initialZooming, zoomAndScroll);
    }, [
        x,
        y,
        _width,
        _height,
        getDataItem,
        getTextDimensions,
        groups,
        hiddenIds,
        hideAndShowBehavior,
        isDataXAxis,
        isHoriz,
        isRtl,
        isStacked,
        isTestEnv,
        locale,
        getStartAndEndAxesOffset,
        labelFontSize,
        series,
        xAxis,
        yAxis,
        y2Axis,
        splitterPosition,
        isSplitDualY,
        getStackGroup,
        initialZooming,
        zoomAndScroll
    ]);
    const { getGroupFromPath, levelsArray, xAxisInfo, xProps, xScale, yProps, y2Props, yScale, y2Scale, yMaxDim, yAxisInfo, plotAreaSpace, xSpace, ySpace, y2Space, idToDataMap, y2AxisInfo, getYPreferredSize, getY2PreferredSize, getXPreferredSize } = layoutInfo;
    useImperativeHandle(ref, () => ({
        _getYaxis: () => {
            return { getPreferredSize: getYPreferredSize, bounds: ySpace };
        },
        _getY2axis: () => {
            return { getPreferredSize: getY2PreferredSize, bounds: y2Space };
        },
        _getXaxis: () => {
            return { getPreferredSize: getXPreferredSize, bounds: xSpace };
        }
    }));
    const leafGroupsInfo = levelsArray.length > 0 ? levelsArray[levelsArray.length - 1] : [];
    scrollDims = updateScrollBarSpace(scrollDims, xAxisPosition === 'bottom', isRtl, yMaxDim);
    const gapRatio = getGapRatio(xAxisInfo.startIndex, xAxisInfo.endIndex);
    const getNextChartItem = getNavUtil(xAxisInfo.startIndex, xAxisInfo.endIndex);
    const { getNextNavGroup, getDefaultNavGroup } = getGroupNavUtil(levelsArray, drilling, isRtl, isHoriz, xProps.isGroupLabelRendered);
    const navigableRefObjects = useMemo(() => buildNavigableRefObjects(xAxis?.referenceObjects, yAxis?.referenceObjects, y2Axis?.referenceObjects), [xAxis?.referenceObjects, yAxis?.referenceObjects, y2Axis?.referenceObjects]);
    const getNextRefObject = (info, arrow) => {
        const list = navigableRefObjects;
        if (!list || list.length === 0) {
            return {};
        }
        const dir = arrow === 'ArrowLeft' || arrow === 'ArrowUp' ? -1 : 1;
        const idx = info.refObjId != null
            ? list.findIndex((o) => o.id === info.refObjId)
            : dir > 0
                ? -1
                : list.length;
        // Move one step in the desired direction. Clamp at the ends.
        let nextIdx = idx + dir;
        if (nextIdx < 0)
            nextIdx = 0;
        if (nextIdx >= list.length)
            nextIdx = list.length - 1;
        return { refObjId: list[nextIdx].id };
    };
    const { ignoreSelectPointerUp, cursor, yAxisCursor, marqueeProps, marqueeContent, toggleButtonContent, isPointInsideMarquee, dragMode: mode } = useChartMarquee({
        rootRef,
        plotAreaSpace,
        xSpace,
        ySpace,
        dragMode,
        chartWidth: width,
        isMultiSelection: selectionMode === 'multiple',
        onViewportChange,
        isZoomScroll: zoomAndScroll === 'live',
        xScale,
        selectedIds,
        getDataById: (id) => idToDataMap.get(id),
        onSelectionChange,
        isRtl,
        xAxisInfo
    });
    const { touchResponse, touchResponseStyle } = useVisTouchResponse({
        type: 'auto',
        supportsTouchDragGestures: mode !== 'off',
        rootRef
    });
    const { activeId, focusedItemInfo, hoveredItemInfo, focusedGroupInfo, navProps, onFocusUpdate } = useChartNav({
        rootRef,
        getNextChartItem,
        getNextRefObject,
        getNextNavGroup,
        getDefaultNavGroup,
        touchResponse,
        onItemHover,
        onItemFocus,
        drilling,
        xAxisInfo
    });
    const onContextMenuDismissed = (gesture) => {
        if (gesture === 'keyboard') {
            onFocusUpdate();
        }
    };
    const translations = useTranslationBundle('@oracle/oraclejet-preact');
    const getTextAndBounds = (target) => {
        return getTextAndBoundsUtil(target, rootRef, xAxis?.title, yAxis?.title, y2Axis?.title, xProps.titleProps?.dims, yProps.titleProps?.dims, y2Props.titleProps?.dims, xProps.tickLabels, focusedGroupInfo);
    };
    const dimsAndTextInfo = getTextAndDimsInfo(xProps.tickLabels, focusedGroupInfo.groupIndex, focusedGroupInfo.levelIndex);
    const { tooltipContent, tooltipProps } = useTextTruncation({
        getTextAndBounds,
        width,
        isRtl,
        textAndBounds: {
            bounds: dimsAndTextInfo?.dims,
            text: dimsAndTextInfo?.text
        }
    });
    const viewportProps = useChartViewport({
        rootRef,
        width,
        height,
        xAxisInfo,
        yAxisInfo,
        y2AxisInfo,
        xScale,
        yScale,
        y2Scale,
        plotAreaSpace,
        isRtl,
        isHoriz,
        zoomAndScroll,
        onViewportChange
    });
    const ignoreAsTrigger = (target) => {
        if (!target) {
            return false;
        }
        const dataset = getElementData(rootRef, target);
        if ((dataset &&
            (dataset['ojPrivateObject'] === 'marquee' ||
                dataset['ojPrivateObject'] === 'dragModeControls' ||
                dataset['ojPrivateObject'] === 'scrollBar')) ||
            ignoreSelectPointerUp) {
            return true;
        }
        return false;
    };
    const { selectDrillProps, selectionContent } = useSelectDrill({
        selectionMode,
        selection: [...selectedIds],
        onChange: onSelectionChange,
        rootRef,
        drilling,
        onItemDrill,
        onGroupDrill,
        focusedGroupInfo,
        focusedItemInfo,
        levelsArray,
        getDataItem,
        getDataById: (id) => idToDataMap.get(id),
        ignoreAsTrigger
    });
    const findNearestData = findNearest(xScale, yScale, y2Scale, xProps.axisStepWidth, xProps.averageGroupZ, gapRatio);
    const getDataItemPosition = getDataItemPos(xScale, yScale, y2Scale, xProps.axisStepWidth, xProps.averageGroupZ, gapRatio);
    const [datatipDisabled, setDatatipDisabled] = useState(false);
    const getItemAriaLabel = getAriaLabelGenerator(series, translations, valueFormats, leafGroupsInfo, xAxis, !!isDataXAxis, getGroupFromPath, xProps.defaultLabelFormatter, yProps.defaultLabelFormatter, y2Props.defaultLabelFormatter);
    const getRefItem = (id) => {
        return (xAxis?.referenceObjects?.find((item) => item.id === id) ??
            yAxis?.referenceObjects?.find((item) => item.id === id) ??
            y2Axis?.referenceObjects?.find((item) => item.id === id));
    };
    const getRefObjectBounds$1 = (id) => {
        return getRefObjectBounds(id, xAxis?.referenceObjects, yAxis?.referenceObjects, y2Axis?.referenceObjects, xScale, yScale, y2Scale, orientation, plotAreaSpace);
    };
    const getRefAxis = (id) => {
        if (xAxis?.referenceObjects?.some((item) => item.id === id))
            return 'x';
        if (yAxis?.referenceObjects?.some((item) => item.id === id))
            return 'y';
        if (y2Axis?.referenceObjects?.some((item) => item.id === id))
            return 'y2';
        return undefined;
    };
    const { datatipContent, dataCursorContent, datatipProps: { 'aria-describedby': datatipAriaDescribedby, ...datatipProps } } = useChartDatatipAndCursor({
        series,
        leafGroupsInfo,
        width,
        height,
        findNearest: findNearestData,
        plotAreaSpace,
        onDataCursorPositionChange,
        isDataCursorEnabled,
        dataCursorPosition,
        dataCursorStyle,
        hoveredItemInfo,
        focusedItemInfo,
        getDataItem,
        getRefItem,
        getRefObjectBounds: getRefObjectBounds$1,
        getRefAxis,
        getMarkerInfo,
        getDataItemPos: getDataItemPosition,
        datatip,
        valueFormats,
        isHoriz,
        touchResponse,
        isDisabled: datatipDisabled,
        xScale: xScale,
        yScale,
        y2Scale,
        timeAxisType,
        defaultXFormatter: xProps.defaultLabelFormatter,
        defaultYFormatter: yProps.defaultLabelFormatter,
        defaultY2Formatter: y2Props.defaultLabelFormatter,
        hasXYValues: isDataXAxis,
        getGroupFromPath,
        translations
    });
    const isGroupInteractive = (index) => {
        if (isTimeAxis) {
            return false;
        }
        const groupDrill = groups[index]?.drilling;
        if (groupDrill === 'on') {
            return true;
        }
        if (groupDrill != 'off' && (drilling === 'on' || drilling === 'groupsOnly')) {
            return true;
        }
        return false;
    };
    const plotAreaClipPathId = useId();
    //  const { yTicks, y2Ticks } = getYY2Ticks(yAxisInfo.ticks, y2AxisInfo.ticks, isHoriz, isSplitDualY);
    const gridLines = (jsx(Gridlines, { plotArea: plotArea, availSpace: plotAreaSpace, xAxisPosition: xAxisPosition, isRtl: isRtl, yMinorTicks: yAxisInfo.minorTicks, xMinorTicks: xAxisInfo.minorTicks, xScale: xScale, yScale: yScale, y2Scale: y2Scale, isLog: yAxis?.scale === 'log', yAxisPosition: yAxisPosition, isDataXAxis: isDataXAxis, xAxis: xAxis, yAxis: yAxis, y2Axis: y2Axis, hasAxisLine: !isOverview, y2MinorTicks: y2AxisInfo?.minorTicks, y2Ticks: y2AxisInfo.ticks, yTicks: yAxisInfo.ticks, xTicks: xAxisInfo.ticks, isSplitDualY: isSplitDualY }));
    const { contextMenuContent, contextMenuProps } = useChartContextMenu({
        isRtl,
        width,
        height,
        getDataItemPosition,
        series,
        levelsArray,
        focusedGroupInfo,
        getDataItem,
        focusedItemInfo,
        rootRef,
        xAxisTitle: xAxis?.title,
        yAxisTitle: yAxis?.title,
        contextMenuConfig: hasData(series, groups) ? contextMenuConfig : undefined,
        onContextMenuDismissed
    });
    const [dragOver, setDragOver] = useState({
        accepted: undefined,
        type: ''
    });
    const { draggable, dndProps, dndContent } = useChartDnd({
        onDrag: props.onDrag,
        onDragStart: props.onDragStart,
        onDragEnd: props.onDragEnd,
        onDragEnter: props.onDragEnter,
        onDragLeave: props.onDragLeave,
        onDragOver: props.onDragOver,
        onDrop: props.onDrop,
        itemsDraggable: props.itemsDraggable,
        groupDraggable: props.groupDraggable,
        rootRef,
        levelsArray,
        series,
        selectedIds,
        getDataItem,
        xSpace,
        ySpace,
        plotAreaSpace,
        setDragOver,
        setDatatipDisabled,
        onSelectionChange
    });
    const eventsProps = mergeProps(navProps, selectDrillProps, viewportProps, datatipProps, marqueeProps, tooltipProps, contextMenuProps, dndProps);
    const overviewContentRenderer = overview != 'off' && (overview === 'on' || !overview.renderer)
        ? defaultOverviewContentRenderer
        : undefined;
    const { background, slidingWindow } = overviewRenderer(plotAreaSpace);
    const isActiveInfoRef = focusedItemInfo.refObjId != null && focusedItemInfo.isFocusVisible;
    const activeInfo = getActiveInfo(focusedItemInfo, hoveredItemInfo);
    return (jsxs(Fragment, { children: [getTextDimensions && resolvedVars['labelFontSize'] != undefined && (jsxs("div", { tabIndex: isOverview ? undefined : 0, draggable: draggable, ref: rootRef, "aria-activedescendant": activeId, "aria-label": props['aria-label'], "aria-labelledby": props['aria-labelledby'], "aria-describedby": l([props['aria-describedby'], datatipAriaDescribedby]), style: { ...touchResponseStyle }, role: isOverview ? undefined : 'application', className: styles$1.baseChartStyle, "data-oj-private-selection-mode": isTestEnv ? selectionMode : undefined, ...testIdProps, ...(isOverview ? {} : eventsProps), children: [jsxs("svg", { width: "100%", height: scrollDims.height != 0 && overview != 'off'
                            ? `${Math.ceil((updatedSpace.availSpace.height + OVERVIEW_GAP) * 100) / height}%`
                            : '100%', children: [jsx("clipPath", { id: `${plotAreaClipPathId}`, children: jsx("rect", { ...plotAreaSpace }) }), background, jsx(PlotArea, { color: plotArea?.color, dragOverStyle: dragOver.type !== 'plotArea' ? 'none' : dragOver.accepted ? 'accept' : 'reject', cursor: cursor, availSpace: plotAreaSpace }), !renderGridLinesInFront && gridLines, jsx(Axis, { ...yProps, axisPosition: yAxisPosition, isRtl: isRtl, cursor: yAxisCursor, availSpace: ySpace, dragOverStyle: dragOver.type !== 'yAxis' ? 'none' : dragOver.accepted ? 'accept' : 'reject' }), jsx(Axis, { ...y2Props, axisPosition: y2AxisPosition, isRtl: isRtl, cursor: yAxisCursor, availSpace: y2Space, dragOverStyle: dragOver.type !== 'y2Axis' ? 'none' : dragOver.accepted ? 'accept' : 'reject' }), jsx(Axis, { ...xProps, isRtl: isRtl, axisPosition: xAxisPosition, isTextInteractive: isGroupInteractive, activeId: activeId, cursor: cursor, focusedGroupIndex: focusedGroupInfo.isFocusVisible ? focusedGroupInfo.groupIndex : undefined, focusedGroupLevelIndex: focusedGroupInfo.isFocusVisible ? focusedGroupInfo.levelIndex : undefined, availSpace: xSpace, dragOverStyle: dragOver.type !== 'xAxis' ? 'none' : dragOver.accepted ? 'accept' : 'reject', separatorColor: xAxis?.groupSeparators?.color }), jsxs("g", { "clip-path": `url(#${plotAreaClipPathId})`, children: [jsx(ReferenceObjects, { location: "back", activeId: isActiveInfoRef ? activeId : undefined, activeInfo: activeInfo, xAxis: xAxis, yAxis: yAxis, y2Axis: y2Axis, xScale: xScale, yScale: yScale, y2Scale: y2Scale, orientation: orientation, xAxisInfo: xAxisInfo, groups: groups }), children({
                                        xStartIndex: xAxisInfo.startIndex,
                                        xEndIndex: xAxisInfo.endIndex,
                                        getItemAriaLabel,
                                        groupsInfo: leafGroupsInfo,
                                        resolvedColors,
                                        xScale: xScale,
                                        yScale,
                                        y2Scale,
                                        isPointInsideMarquee,
                                        defaultFontSize: resolvedVars['labelFontSize'],
                                        gapRatio,
                                        activeId,
                                        focusedItemInfo,
                                        hoveredItemInfo,
                                        getTextDimensions,
                                        axisStepWidth: xProps.axisStepWidth,
                                        averageGroupZ: xProps.averageGroupZ,
                                        plotAreaClipPathId
                                    }), renderGridLinesInFront && gridLines, jsx(ReferenceObjects, { location: "front", xAxis: xAxis, yAxis: yAxis, y2Axis: y2Axis, activeId: activeId, activeInfo: activeInfo, xScale: xScale, yScale: yScale, y2Scale: y2Scale, orientation: orientation, xAxisInfo: xAxisInfo, groups: groups }), dataCursorContent] }), slidingWindow, zoomAndScroll === 'live' && !isOverview && (jsx(ScrollBar, { availSpace: scrollDims, isRtl: isRtl, viewport: xAxisInfo, axisExtent: xAxisInfo, isHoriz: xAxisPosition === 'bottom' })), marqueeContent] }), jsx(OverviewContext.Provider, { value: {
                            yAxisSize: ySpace.width,
                            isOverview: true,
                            width,
                            height: scrollDims.height,
                            overviewRenderer: (overviewChartPlotArea) => {
                                const { xScale: overviewXScale, ...windowCoords } = getWindowCoords(isRtl, xAxisInfo, xAxisInfo, yAxisInfo, yAxisInfo, overviewChartPlotArea);
                                return getRenderer(xAxisInfo, isRtl, overviewXScale, overviewChartPlotArea, windowCoords, true, onViewportChange);
                            }
                        }, children: !isOverview && overview !== 'off' && overviewContentRenderer && (jsx("div", { style: { width, height: scrollDims.height }, children: overviewContentRenderer() })) }), toggleButtonContent, datatipContent, tooltipContent, contextMenuContent, selectionContent, dndContent] })), textMeasureContent, cssContent] }));
});

const Chart = forwardRef(({ width, height, ...props }, ref = null) => {
    // TODO: reevaluate how we handle empty data
    const { isOverview, overviewRenderer, yAxisSize, width: overviewWidth, height: overviewHeight } = useOverviewContext();
    let chartWidth = width;
    let chartHeight = height;
    if (chartWidth === undefined && isOverview && overviewWidth !== undefined) {
        chartWidth = `${overviewWidth}px`;
    }
    if (chartHeight === undefined && isOverview && overviewHeight !== undefined) {
        chartHeight = `${overviewHeight}px`;
    }
    return (jsx(TrackResizeContainer, { width: chartWidth, height: chartHeight, class: dimensionStyle, children: (width, height) => width || height ? (jsx(ChartWithDimensions, { ref: ref, width: width, height: height, ...props, yAxisSize: yAxisSize, isOverview: isOverview, overviewRenderer: overviewRenderer })) : undefined }));
});

export { Chart as C };
//# sourceMappingURL=Chart-8c63da28.js.map
