| 662 | const DATA_ZOOM_SLIDER_RESERVE_CSS_PX = DATA_ZOOM_SLIDER_HEIGHT_CSS_PX + DATA_ZOOM_SLIDER_MARGIN_TOP_CSS_PX; |
| 663 | |
| 664 | const ensureDataZoomSliderHost = (): HTMLDivElement => { |
| 665 | if (dataZoomSliderHost) return dataZoomSliderHost; |
| 666 | |
| 667 | // Ensure the host's absolute positioning is anchored to the chart container. |
| 668 | // If the container is already positioned, avoid overwriting user styles. |
| 669 | try { |
| 670 | const pos = window.getComputedStyle(container).position; |
| 671 | if (pos === 'static') container.style.position = 'relative'; |
| 672 | } catch { |
| 673 | // best-effort |
| 674 | } |
| 675 | |
| 676 | const host = document.createElement('div'); |
| 677 | host.style.position = 'absolute'; |
| 678 | host.style.left = '0'; |
| 679 | host.style.right = '0'; |
| 680 | host.style.bottom = '0'; |
| 681 | host.style.height = `${DATA_ZOOM_SLIDER_RESERVE_CSS_PX}px`; |
| 682 | host.style.paddingTop = `${DATA_ZOOM_SLIDER_MARGIN_TOP_CSS_PX}px`; |
| 683 | host.style.boxSizing = 'border-box'; |
| 684 | host.style.pointerEvents = 'auto'; |
| 685 | host.style.zIndex = '5'; |
| 686 | container.appendChild(host); |
| 687 | dataZoomSliderHost = host; |
| 688 | return host; |
| 689 | }; |
| 690 | |
| 691 | const computeZoomInOutAnchorRatio = (range: ZoomRange, center: number): number => { |
| 692 | const span = range.end - range.start; |