diff --git a/frontend/src/GraphView.jsx b/frontend/src/GraphView.jsx index 1d826de..5e35c6e 100644 --- a/frontend/src/GraphView.jsx +++ b/frontend/src/GraphView.jsx @@ -97,17 +97,18 @@ function GraphView({ servers, connections }) { const current = d3.zoomTransform(svgEl); const cx = svgEl.clientWidth / 2; const cy = svgEl.clientHeight / 2; - dbg('zoomBy click', { factor, current: { k: current.k, x: current.x, y: current.y }, center: { cx, cy } }); - const next = d3.zoomIdentity - .translate(current.x, current.y) - .scale(current.k) - .translate(cx, cy) - .scale(factor) - .translate(-cx, -cy); - d3.select(svgEl) + const minK = 0.3; + const maxK = 3; + let nextK = current.k * factor; + if (nextK < minK) nextK = minK; + if (nextK > maxK) nextK = maxK; + dbg('zoomBy click', { factor, current: { k: current.k, x: current.x, y: current.y }, nextK, center: { cx, cy } }); + const svgSel = d3.select(svgEl); + svgSel.interrupt(); + svgSel .transition() .duration(220) - .call(zoomRef.current.transform, next) + .call(zoomRef.current.scaleTo, nextK, [cx, cy]) .on('end', () => { const nt = d3.zoomTransform(svgEl); dbg('zoomBy end', { next: { k: nt.k, x: nt.x, y: nt.y } }); @@ -459,17 +460,15 @@ function GraphView({ servers, connections }) { fill="#fff" stroke={countryColor} /> + {/* Рендер флага через foreignObject как в HTML (надёжнее для Windows/Chrome) */} + +
+ {flag} +
+
- {flag} - -