fix: 级联/因果视角切换 — 跨层箭头方向+SVG三角+ConnectionLines联动

This commit is contained in:
Hermes CI Fix
2026-07-14 16:22:29 +08:00
parent f821ee2c9d
commit 1a08e801f4
2 changed files with 32 additions and 15 deletions
@@ -147,6 +147,8 @@ const props = defineProps({
tempLine: { type: Object, default: null }, tempLine: { type: Object, default: null },
/** 容器尺寸变化触发重算 */ /** 容器尺寸变化触发重算 */
containerKey: { type: Number, default: 0 }, containerKey: { type: Number, default: 0 },
/** 视角方向:cascade(级联,上层→下层) / causal(因果,下层→上层) */
viewDirection: { type: String, default: 'cascade' },
}) })
const emit = defineEmits(['select-connection', 'delete-connection']) const emit = defineEmits(['select-connection', 'delete-connection'])
@@ -159,28 +161,41 @@ const crossLayerLines = ref([])
/** /**
* 计算跨层固定箭头 * 计算跨层固定箭头
* 从上层底部中心 → 下层顶部中心 * cascade: 从上层底部中心 → 下层顶部中心(管理视角,上层驱动下层)
* causal: 从下层顶部中心 → 上层底部中心(因果视角,下层驱动上层)
*/ */
function calcCrossLayerLines() { function calcCrossLayerLines() {
const lines = [] const lines = []
const keys = props.layerKeys const keys = props.layerKeys
const isCausal = props.viewDirection === 'causal'
for (let i = 0; i < keys.length - 1; i++) { for (let i = 0; i < keys.length - 1; i++) {
const fromEl = props.layerRefs[keys[i]] const upperEl = props.layerRefs[keys[i]]
const toEl = props.layerRefs[keys[i + 1]] const lowerEl = props.layerRefs[keys[i + 1]]
if (!fromEl || !toEl) continue if (!upperEl || !lowerEl) continue
const fr = fromEl.getBoundingClientRect() const ur = upperEl.getBoundingClientRect()
const tr = toEl.getBoundingClientRect() const lr = lowerEl.getBoundingClientRect()
const svg = svgRef.value const svg = svgRef.value
if (!svg) continue if (!svg) continue
const svgRect = svg.getBoundingClientRect() const svgRect = svg.getBoundingClientRect()
lines.push({ if (isCausal) {
x1: fr.left + fr.width / 2 - svgRect.left, // 因果视角:从下层顶 → 上层底(箭头向上)
y1: fr.bottom - svgRect.top, lines.push({
x2: tr.left + tr.width / 2 - svgRect.left, x1: lr.left + lr.width / 2 - svgRect.left,
y2: tr.top - svgRect.top, y1: lr.top - svgRect.top,
}) x2: ur.left + ur.width / 2 - svgRect.left,
y2: ur.bottom - svgRect.top,
})
} else {
// 级联视角:从上层底 → 下层顶(箭头向下)
lines.push({
x1: ur.left + ur.width / 2 - svgRect.left,
y1: ur.bottom - svgRect.top,
x2: lr.left + lr.width / 2 - svgRect.left,
y2: lr.top - svgRect.top,
})
}
} }
crossLayerLines.value = lines crossLayerLines.value = lines
} }
+5 -3
View File
@@ -92,11 +92,12 @@
@reorder="(dk: string) => onLayerReorder(dk)" @reorder="(dk: string) => onLayerReorder(dk)"
/> />
<!-- 跨层箭头指示器(本层→下层 --> <!-- 跨层箭头指示器(根据视角切换方向 -->
<div v-if="idx < orderedLayerConfigs.length - 1" class="cross-layer-arrow"> <div v-if="idx < orderedLayerConfigs.length - 1" class="cross-layer-arrow">
<svg width="24" height="32" viewBox="0 0 24 32"> <svg width="24" height="32" viewBox="0 0 24 32">
<line x1="12" y1="0" x2="12" y2="24" stroke="#909399" stroke-width="2" stroke-dasharray="4,3" /> <line x1="12" y1="0" x2="12" y2="24" stroke="#909399" stroke-width="2" stroke-dasharray="4,3" />
<polygon points="4,22 12,30 20,22" fill="#909399" /> <polygon v-if="viewDirection === 'cascade'" points="4,22 12,30 20,22" fill="#909399" />
<polygon v-else points="4,8 12,0 20,8" fill="#909399" />
</svg> </svg>
</div> </div>
</div> </div>
@@ -107,11 +108,12 @@
<ConnectionLines <ConnectionLines
ref="connectionLinesRef" ref="connectionLinesRef"
:layer-refs="layerRefs" :layer-refs="layerRefs"
:node-refs="nodeRefs" :node-refs="compiledNodeRefs"
:layer-keys="layerKeysOrdered" :layer-keys="layerKeysOrdered"
:connections="connections" :connections="connections"
:temp-line="tempLine" :temp-line="tempLine"
:container-key="recalcTrigger" :container-key="recalcTrigger"
:view-direction="viewDirection"
@select-connection="onSelectConnection" @select-connection="onSelectConnection"
@delete-connection="onDeleteConnection" @delete-connection="onDeleteConnection"
/> />