|
|
@@ -196,7 +196,7 @@ import * as d3 from 'd3'
|
|
|
import { useGraphStore } from '../stores/graph'
|
|
|
import { getNodeStyle, applyNodeShape, dimColors } from '../config/nodeStyle'
|
|
|
import { getEdgeStyle, edgeTypeColors } from '../config/edgeStyle'
|
|
|
-import { applyHighlight, findPath, applyHoverHighlight } from '../utils/highlight'
|
|
|
+import { applyHighlight, applyHoverHighlight } from '../utils/highlight'
|
|
|
|
|
|
const props = defineProps({
|
|
|
showExpand: {
|
|
|
@@ -925,48 +925,17 @@ function setupHoverHandlers() {
|
|
|
if (!svgRef.value || !store.selectedNodeId) return
|
|
|
|
|
|
const svg = d3.select(svgRef.value)
|
|
|
-
|
|
|
- // 选择所有节点和边(使用 SVG 级别选择器)
|
|
|
const allNodes = svg.selectAll('.tree-node, .match-node, .walked-node')
|
|
|
- const allLinks = svg.selectAll('.tree-link, .match-link, .walked-link')
|
|
|
- const allLabels = svg.selectAll('.match-score, .walked-score')
|
|
|
-
|
|
|
- // 获取起始节点(当前选中的节点)
|
|
|
const startNodeId = store.selectedNodeId
|
|
|
|
|
|
- // 获取高亮的边集合(只在高亮的子图中查找路径)
|
|
|
- const edgeSet = store.postWalkedEdgeSet.size > 0 ? store.postWalkedEdgeSet : store.walkedEdgeSet
|
|
|
- if (edgeSet.size === 0) return // 没有高亮的边,不需要 hover 效果
|
|
|
-
|
|
|
- // 将边集合转换为 findPath 需要的格式
|
|
|
- const highlightedLinks = []
|
|
|
- for (const edgeKey of edgeSet) {
|
|
|
- // edgeKey 格式: "sourceId->targetId"
|
|
|
- const [source, target] = edgeKey.split('->')
|
|
|
- if (source && target) {
|
|
|
- highlightedLinks.push({ source, target })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 添加 hover 处理器
|
|
|
+ // 添加 hover 处理器(路径计算由 store 统一处理)
|
|
|
allNodes
|
|
|
.on('mouseenter', (event, d) => {
|
|
|
- // 获取节点 ID
|
|
|
const nodeId = d.data?.id || d.id
|
|
|
- if (nodeId === startNodeId) return // 起点不需要高亮路径
|
|
|
-
|
|
|
- // 只在高亮的节点中才响应 hover
|
|
|
- if (!store.highlightedNodeIds.has(nodeId)) return
|
|
|
-
|
|
|
- // 计算从起点到 hover 节点的路径(只在高亮的边中查找)
|
|
|
- const pathNodes = findPath(startNodeId, nodeId, highlightedLinks)
|
|
|
- if (pathNodes.size > 0) {
|
|
|
- applyHoverHighlight(allNodes, allLinks, allLabels, pathNodes)
|
|
|
- }
|
|
|
+ store.computeHoverPath(startNodeId, nodeId)
|
|
|
})
|
|
|
.on('mouseleave', () => {
|
|
|
- // 恢复之前的高亮状态,而不是全部变亮
|
|
|
- updateHighlight()
|
|
|
+ store.clearHover()
|
|
|
})
|
|
|
}
|
|
|
|
|
|
@@ -1154,6 +1123,24 @@ watch(() => store.focusEdgeEndpoints, (endpoints) => {
|
|
|
|
|
|
watch(() => store.highlightedNodeIds.size, updateHighlight)
|
|
|
|
|
|
+// 监听 hover 状态变化(用于左右联动)
|
|
|
+watch(() => store.hoverPathNodes.size, () => {
|
|
|
+ if (!svgRef.value) return
|
|
|
+ const svg = d3.select(svgRef.value)
|
|
|
+
|
|
|
+ const allNodes = svg.selectAll('.tree-node, .match-node, .walked-node')
|
|
|
+ const allLinks = svg.selectAll('.tree-link, .match-link, .walked-link')
|
|
|
+ const allLabels = svg.selectAll('.match-score, .walked-score')
|
|
|
+
|
|
|
+ if (store.hoverPathNodes.size > 0) {
|
|
|
+ // 应用 hover 高亮
|
|
|
+ applyHoverHighlight(allNodes, allLinks, allLabels, store.hoverPathNodes)
|
|
|
+ } else {
|
|
|
+ // 清除 hover,恢复原有高亮
|
|
|
+ updateHighlight()
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
// 监听帖子游走结果变化,渲染游走层
|
|
|
watch(() => store.postWalkedNodes.length, () => {
|
|
|
nextTick(renderWalkedLayer)
|