Explorar o código

fix: 人设树hover联动缩放到上下游节点都可见

添加zoomToNodes函数,计算所有上下游节点的边界框后
缩放视图使父节点、当前节点、子节点都在可视范围内

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

Co-Authored-By: Claude <noreply@anthropic.com>
yangxiaohui hai 16 horas
pai
achega
4c1ce8762a
Modificáronse 1 ficheiros con 51 adicións e 2 borrados
  1. 51 2
      script/visualization/src/components/TreeView.vue

+ 51 - 2
script/visualization/src/components/TreeView.vue

@@ -301,6 +301,55 @@ function zoomToNode(nodeId) {
   )
 }
 
+// 缩放到多个节点(使它们都可见)
+function zoomToNodes(nodeIds) {
+  if (!zoom || !containerRef.value || nodeIds.size === 0) return
+
+  // 收集所有节点的位置
+  const positions = []
+  for (const nodeId of nodeIds) {
+    const nodeInfo = nodeElements[nodeId]
+    if (nodeInfo) {
+      positions.push({ x: nodeInfo.x, y: nodeInfo.y })
+    }
+  }
+
+  if (positions.length === 0) return
+
+  // 计算边界框
+  const minX = Math.min(...positions.map(p => p.x))
+  const maxX = Math.max(...positions.map(p => p.x))
+  const minY = Math.min(...positions.map(p => p.y))
+  const maxY = Math.max(...positions.map(p => p.y))
+
+  const container = containerRef.value
+  const width = container.clientWidth
+  const height = container.clientHeight
+
+  // 计算缩放比例(留边距)
+  const padding = 60
+  const contentWidth = maxX - minX + padding * 2
+  const contentHeight = maxY - minY + padding * 2
+
+  const scaleX = width / contentWidth
+  const scaleY = height / contentHeight
+  const scale = Math.min(scaleX, scaleY, 1.5) // 最大放大1.5倍
+
+  // 计算中心点
+  const centerX = (minX + maxX) / 2
+  const centerY = (minY + maxY) / 2
+
+  // 计算平移使内容居中
+  const translateX = width / 2 - centerX * scale
+  const translateY = height / 2 - centerY * scale
+
+  const svg = d3.select(svgRef.value)
+  svg.transition().duration(300).call(
+    zoom.transform,
+    d3.zoomIdentity.translate(translateX, translateY).scale(scale)
+  )
+}
+
 // 更新选中/高亮状态
 function updateSelection() {
   applyHighlight(svgRef.value, store.highlightedNodeIds, store.walkedEdgeSet, store.selectedNodeId)
@@ -361,8 +410,8 @@ watch(() => store.hoverNodeId, (hoverNodeId) => {
     // 应用高亮(只高亮上下游节点和连接它们的边)
     applyHoverHighlight(allNodes, allLinks, null, neighborNodes)
 
-    // 居中显示hover节点
-    zoomToNode(hoverNodeId)
+    // 缩放到所有上下游节点都可见
+    zoomToNodes(neighborNodes)
   } else {
     // 恢复原有高亮
     updateSelection()