Skip to content

多重エッジ(同じノード間に複数エッジ)をUI上で重ならずに可視化・編集できるようにする #48

@illionillion

Description

@illionillion

概要

flowchartで同じノード間に複数のエッジ(多重エッジ)が存在する場合、インポート・エクスポートは可能だが、UI上ではエッジが重なって表示され、個別に選択・編集できない問題がある。

現象・原因

  • 例: A --> B が2本以上存在する場合、全てのエッジが同じ直線上に重なって描画される
  • 既存のエッジ描画ロジック(adjustEdgeLabelPosition/calculateEdgeOffset)は循環参照や自ループには対応しているが、source/targetが同じ多重エッジのグループ化・分散描画には未対応
  • そのため、importで多重エッジを読み込んでもUI上で重なり、編集・可視化が困難

解決策(実装例)

  1. 多重エッジ(source/targetが同じエッジが複数本)をグループ化し、インデックスごとにオフセットを割り当てて分散描画する
  2. 具体的には、edge-layout.tsに下記のような関数を追加・修正する
// 多重エッジグループ化
export function detectMultiEdges(edges: Edge[]): Map<string, Edge[]> {
  const multiEdgeGroups = new Map<string, Edge[]>();
  edges.forEach((edge) => {
    const key = `${edge.source}--${edge.target}`;
    if (!multiEdgeGroups.has(key)) {
      multiEdgeGroups.set(key, []);
    }
    multiEdgeGroups.get(key)!.push(edge);
  });
  return multiEdgeGroups;
}

// オフセット計算の修正
export function calculateEdgeOffset(
  edge: Edge,
  allEdges: Edge[],
  offsetDistance: number = 20
): { offsetX: number; offsetY: number } {
  const multiEdgeGroups = detectMultiEdges(allEdges);
  const key = `${edge.source}--${edge.target}`;
  const groupEdges = multiEdgeGroups.get(key) || [];
  if (groupEdges.length > 1) {
    const edgeIndex = groupEdges.findIndex((e) => e.id === edge.id);
    const offset = ((edgeIndex % 2 === 0 ? 1 : -1) * Math.ceil(edgeIndex / 2)) * offsetDistance;
    return { offsetX: 0, offsetY: offset };
  }
  // ...既存の循環参照ロジック...
  return { offsetX: 0, offsetY: 0 };
}
  • これにより、同じノード間の複数エッジが上下にずれて可視化・編集できるようになる
  • 曲線化したい場合はgetBezierPathの制御点をオフセットに応じて調整することも可能

備考

  • 既存の循環参照・自ループの分散描画ロジックとの競合に注意
  • テストやStorybookで多重エッジの可視化・編集ができることを確認する

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions