Browse Source

feat: 中间视图自动适配显示所有内容

- 添加fitToView函数计算内容边界并自动缩放
- 模拟结束后自动调用适配视图
- 首次渲染100ms后也调用一次适配
- 确保三个圆都能完整显示在视口中

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
yangxiaohui 4 days ago
parent
commit
dc3f6b72c6
1 changed files with 39 additions and 0 deletions
  1. 39 0
      script/data_processing/visualize_match_graph.py

+ 39 - 0
script/data_processing/visualize_match_graph.py

@@ -3605,6 +3605,45 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
                 node.attr("transform", d => `translate(${{d.x}},${{d.y}})`);
             }});
 
+            // 模拟结束后自动适配视图
+            simulation.on("end", () => {{
+                fitToView();
+            }});
+
+            // 适配视图:缩放并平移使所有内容可见
+            function fitToView() {{
+                const container = document.getElementById("graph");
+                const containerWidth = container.clientWidth;
+                const containerHeight = container.clientHeight;
+
+                // 计算内容边界(三个圆的范围)
+                const minX = layerCenterX[0] - layerRadius[0] - 50;
+                const maxX = layerCenterX[0] + layerRadius[0] + 50;
+                const minY = layerCenterY[0] - layerRadius[0] - 30;
+                const maxY = layerCenterY[2] + layerRadius[2] + 30;
+
+                const contentWidth = maxX - minX;
+                const contentHeight = maxY - minY;
+
+                // 计算缩放比例(留出边距)
+                const padding = 20;
+                const scaleX = (containerWidth - padding * 2) / contentWidth;
+                const scaleY = (containerHeight - padding * 2) / contentHeight;
+                const scale = Math.min(scaleX, scaleY, 1);  // 最大不超过1
+
+                // 计算平移使内容居中
+                const contentCenterX = (minX + maxX) / 2;
+                const contentCenterY = (minY + maxY) / 2;
+                const translateX = containerWidth / 2 - contentCenterX * scale;
+                const translateY = containerHeight / 2 - contentCenterY * scale;
+
+                // 应用变换
+                svg.call(zoom.transform, d3.zoomIdentity.translate(translateX, translateY).scale(scale));
+            }}
+
+            // 首次渲染也调用一次适配(不等模拟结束)
+            setTimeout(fitToView, 100);
+
             // 拖拽函数
             function dragstarted(event, d) {{
                 if (!event.active) simulation.alphaTarget(0.3).restart();