| import { useEffect, useRef } from 'react'; |
| import * as d3 from 'd3'; |
|
|
| |
| |
| |
| export function useZoomV2(svgRef, darkMode = false) { |
| const zoomRef = useRef(null); |
| const isInitializedRef = useRef(false); |
|
|
| useEffect(() => { |
| if (isInitializedRef.current) { |
| return; |
| } |
|
|
| const initializeZoom = () => { |
| if (!svgRef.current) { |
| console.log('useZoomV2: SVG not ready, retrying...'); |
| return false; |
| } |
|
|
| const svg = d3.select(svgRef.current); |
|
|
| const viewportGroup = svg.select('.viewport-group'); |
| if (viewportGroup.empty()) { |
| console.error('useZoomV2: viewport-group not found! Zoom will not work.'); |
| return false; |
| } |
|
|
| console.log('useZoomV2: Found viewport-group, setting up zoom...'); |
|
|
| |
| const zoom = d3.zoom() |
| .scaleExtent([0.3, 5.0]) |
| .on('zoom', (event) => { |
| viewportGroup.attr('transform', event.transform); |
| }); |
|
|
| |
| svg.call(zoom); |
|
|
| |
| const svgRect = svg.node().getBoundingClientRect(); |
| const centerX = svgRect.width / 2; |
| const centerY = svgRect.height / 2; |
|
|
| |
| const initialScale = 0.8; |
| const initialTransform = d3.zoomIdentity |
| .translate(centerX, centerY) |
| .scale(initialScale) |
| .translate(-1000, -1000); |
|
|
| svg.call(zoom.transform, initialTransform); |
|
|
| zoomRef.current = zoom; |
| isInitializedRef.current = true; |
| console.log('useZoomV2: Zoom initialized successfully'); |
| return true; |
| }; |
|
|
| |
| if (!initializeZoom()) { |
| |
| const timer = setTimeout(() => { |
| initializeZoom(); |
| }, 100); |
|
|
| return () => clearTimeout(timer); |
| } |
|
|
| return () => { |
| if (svgRef.current) { |
| d3.select(svgRef.current).on('.zoom', null); |
| } |
| zoomRef.current = null; |
| isInitializedRef.current = false; |
| }; |
| }, [svgRef, darkMode]); |
|
|
| const resetZoom = () => { |
| if (zoomRef.current && svgRef.current) { |
| const svg = d3.select(svgRef.current); |
| const width = svg.node().clientWidth; |
| const height = svg.node().clientHeight; |
|
|
| const centerX = width / 2; |
| const centerY = height / 2; |
| const scale = 0.8; |
|
|
| const resetTransform = d3.zoomIdentity |
| .translate(centerX, centerY) |
| .scale(scale) |
| .translate(-1000, -1000); |
|
|
| svg.transition().duration(750).call(zoomRef.current.transform, resetTransform); |
| } |
| }; |
|
|
| return { resetZoom }; |
| } |
|
|