diff --git a/miniapp/pages/index/index.js b/miniapp/pages/index/index.js index 19385d2..d86cc20 100644 --- a/miniapp/pages/index/index.js +++ b/miniapp/pages/index/index.js @@ -496,6 +496,23 @@ function buildSankeyLayout(links, width, height, renderOptions) { } } + // 与 Web 端 nodeAlign='justify' 对齐: + // - 无入边节点固定在最左列 + // - 无出边节点固定在最右列 + // 这样可避免“短路径末端节点停在中间列”的视觉差异。 + const baseMaxDepth = nodeNames.reduce((max, name) => Math.max(max, depthMap[name] || 0), 0); + nodeNames.forEach((name) => { + const incomingCount = incomingCountMap[name] || 0; + const outgoingCount = outgoingCountMap[name] || 0; + if (incomingCount === 0 && outgoingCount > 0) { + depthMap[name] = 0; + return; + } + if (outgoingCount === 0 && incomingCount > 0) { + depthMap[name] = baseMaxDepth; + } + }); + const maxDepth = nodeNames.reduce((max, name) => Math.max(max, depthMap[name] || 0), 0); const columns = Array.from({ length: maxDepth + 1 }, () => []); nodeNames.forEach((name) => { @@ -591,7 +608,9 @@ function buildSankeyLayout(links, width, height, renderOptions) { x: nodeX, y: cursorY, h: nodeHeight, - colorIndex: Number.isFinite(nodeColorIndexMap[name]) ? nodeColorIndexMap[name] : 0 + colorIndex: Number.isFinite(nodeColorIndexMap[name]) ? nodeColorIndexMap[name] : 0, + incomingCount: incomingCountMap[name] || 0, + outgoingCount: outgoingCountMap[name] || 0 }; nodes.push(node); nodePositionMap[name] = node; @@ -696,8 +715,8 @@ function buildSankeySvgText(links, width, height, renderOptions) { }); layout.nodes.forEach((node) => { - const isSource = node.depth === 0; - const isTarget = node.depth === layout.maxDepth; + const isSource = node.incomingCount === 0 && node.outgoingCount > 0; + const isTarget = node.outgoingCount === 0 && node.incomingCount > 0; const textY = getClampedLabelY( node.y, node.h, @@ -1407,8 +1426,8 @@ Page({ }); layout.nodes.forEach((node) => { - const isSource = node.depth === 0; - const isTarget = node.depth === layout.maxDepth; + const isSource = node.incomingCount === 0 && node.outgoingCount > 0; + const isTarget = node.outgoingCount === 0 && node.incomingCount > 0; const labelPlacement = getCanvasLabelPlacement( node.x, layout.nodeWidth,