yangdx
commited on
Commit
·
418d5a7
1
Parent(s):
cd4e8de
feat: Improve graph zoom reset to fit all nodes with proper scaling
Browse files- Add smarter node boundary calculation
- Include padding around graph nodes
- Calculate optimal scale ratio
- Add error handling and null checks
- Animate transition to new zoom level
lightrag_webui/src/components/graph/ZoomControl.tsx
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
import { useCamera } from '@react-sigma/core'
|
2 |
import { useCallback } from 'react'
|
3 |
import Button from '@/components/ui/Button'
|
4 |
import { ZoomInIcon, ZoomOutIcon, FullscreenIcon } from 'lucide-react'
|
@@ -10,11 +10,71 @@ import { useTranslation } from 'react-i18next';
|
|
10 |
*/
|
11 |
const ZoomControl = () => {
|
12 |
const { zoomIn, zoomOut, reset } = useCamera({ duration: 200, factor: 1.5 })
|
|
|
13 |
const { t } = useTranslation();
|
14 |
|
15 |
const handleZoomIn = useCallback(() => zoomIn(), [zoomIn])
|
16 |
const handleZoomOut = useCallback(() => zoomOut(), [zoomOut])
|
17 |
-
const handleResetZoom = useCallback(() =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
return (
|
20 |
<>
|
|
|
1 |
+
import { useCamera, useSigma } from '@react-sigma/core'
|
2 |
import { useCallback } from 'react'
|
3 |
import Button from '@/components/ui/Button'
|
4 |
import { ZoomInIcon, ZoomOutIcon, FullscreenIcon } from 'lucide-react'
|
|
|
10 |
*/
|
11 |
const ZoomControl = () => {
|
12 |
const { zoomIn, zoomOut, reset } = useCamera({ duration: 200, factor: 1.5 })
|
13 |
+
const sigma = useSigma()
|
14 |
const { t } = useTranslation();
|
15 |
|
16 |
const handleZoomIn = useCallback(() => zoomIn(), [zoomIn])
|
17 |
const handleZoomOut = useCallback(() => zoomOut(), [zoomOut])
|
18 |
+
const handleResetZoom = useCallback(() => {
|
19 |
+
if (!sigma) return
|
20 |
+
|
21 |
+
try {
|
22 |
+
// First clear any custom bounding box and refresh
|
23 |
+
sigma.setCustomBBox(null)
|
24 |
+
sigma.refresh()
|
25 |
+
|
26 |
+
// Get graph after refresh
|
27 |
+
const graph = sigma.getGraph()
|
28 |
+
|
29 |
+
// Check if graph has nodes before accessing them
|
30 |
+
if (!graph || graph.nodes().length === 0) {
|
31 |
+
reset()
|
32 |
+
return
|
33 |
+
}
|
34 |
+
|
35 |
+
// Get container dimensions for aspect ratio
|
36 |
+
const container = sigma.getContainer()
|
37 |
+
const containerWidth = container.offsetWidth
|
38 |
+
const containerHeight = container.offsetHeight
|
39 |
+
console.log('Container W:', containerWidth, 'H:', containerHeight)
|
40 |
+
|
41 |
+
// Get all node positions
|
42 |
+
const nodePositions = graph.nodes().map(node => ({
|
43 |
+
x: graph.getNodeAttribute(node, 'x'),
|
44 |
+
y: graph.getNodeAttribute(node, 'y')
|
45 |
+
}))
|
46 |
+
|
47 |
+
// Calculate bounding box
|
48 |
+
const minX = Math.min(...nodePositions.map(pos => pos.x))
|
49 |
+
const maxX = Math.max(...nodePositions.map(pos => pos.x))
|
50 |
+
const minY = Math.min(...nodePositions.map(pos => pos.y))
|
51 |
+
const maxY = Math.max(...nodePositions.map(pos => pos.y))
|
52 |
+
|
53 |
+
// Calculate graph dimensions with minimal padding
|
54 |
+
const width = maxX - minX
|
55 |
+
const height = maxY - minY
|
56 |
+
const padding = Math.max(width, height) * 0.05
|
57 |
+
console.log('Graph W:', Math.round(width*100)/100, 'H:', Math.round(height*100)/100)
|
58 |
+
|
59 |
+
// Calculate base scale
|
60 |
+
const scale = Math.min(
|
61 |
+
containerWidth / (width + padding * 2),
|
62 |
+
containerHeight / (height + padding * 2)
|
63 |
+
)
|
64 |
+
// Apply scaling factor (just don't know why)
|
65 |
+
const ratio = (1 / scale) * 10
|
66 |
+
|
67 |
+
console.log('scale:', Math.round(scale*100)/100, 'ratio:', Math.round(ratio*100)/100)
|
68 |
+
|
69 |
+
// Animate to center with calculated ratio
|
70 |
+
sigma.getCamera().animate(
|
71 |
+
{ x: 0.5, y: 0.5, ratio },
|
72 |
+
{ duration: 500 }
|
73 |
+
)
|
74 |
+
} catch (error) {
|
75 |
+
console.error('Error resetting zoom:', error)
|
76 |
+
}
|
77 |
+
}, [sigma, reset])
|
78 |
|
79 |
return (
|
80 |
<>
|