|
|
@@ -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()
|