| 2531 | }; |
| 2532 | |
| 2533 | const getZoomOptionsConfig = ( |
| 2534 | opts: ResolvedChartGPUOptions |
| 2535 | ): { readonly start: number; readonly end: number; readonly hasInside: boolean } | null => { |
| 2536 | // Zoom is enabled when *either* inside or slider exists. A single shared percent-space |
| 2537 | // window is used for both. |
| 2538 | const insideCfg = opts.dataZoom?.find((z) => z?.type === 'inside'); |
| 2539 | const sliderCfg = opts.dataZoom?.find((z) => z?.type === 'slider'); |
| 2540 | const cfg = insideCfg ?? sliderCfg; |
| 2541 | if (!cfg) return null; |
| 2542 | const start = Number.isFinite(cfg.start) ? cfg.start! : 0; |
| 2543 | const end = Number.isFinite(cfg.end) ? cfg.end! : 100; |
| 2544 | return { start, end, hasInside: !!insideCfg }; |
| 2545 | }; |
| 2546 | |
| 2547 | const clampPercent = (v: number): number => Math.min(100, Math.max(0, v)); |
| 2548 | |