This commit is contained in:
2026-06-13 21:51:01 +02:00
parent 0128f3c685
commit 4922249108
2 changed files with 63 additions and 34 deletions

View File

@@ -64,40 +64,59 @@ export default function CableMap({ locations }: CableMapProps) {
[locations] [locations]
); );
const initialEdges = useMemo( const initialEdges = useMemo(() => {
() => const edges = locations.flatMap((location) =>
locations.flatMap((location) => location.startCables.flatMap((cable) => {
location.startCables.flatMap((cable) => { const route = [
const route = [ { id: String(cable.startLocationId), name: location.name },
{ id: String(cable.startLocationId), name: location.name }, ...cable.intermediateStops.map((stop) => ({
...cable.intermediateStops.map((stop) => ({ id: String(stop.location.id),
id: String(stop.location.id), name: stop.location.name,
name: stop.location.name, })),
})), { id: String(cable.endLocationId), name: cable.endLocation.name },
{ id: String(cable.endLocationId), name: cable.endLocation.name }, ];
];
return route.slice(1).map((target, index) => { return route.slice(1).map((target, index) => {
const source = route[index]; const source = route[index];
return { return {
id: `cable-${cable.id}-${index}`, id: `cable-${cable.id}-${index}`,
type: "cable", type: "cable",
source: source.id, source: source.id,
target: target.id, target: target.id,
data: { data: {
label: cable.identifier, label: cable.identifier,
coreCount: cable._count.cores, coreCount: cable._count.cores,
cableId: cable.id, cableId: cable.id,
sourceName: source.name, sourceName: source.name,
targetName: target.name, targetName: target.name,
onEdgeClick: () => setSelectedEdgeId(cable.id), onEdgeClick: () => setSelectedEdgeId(cable.id),
}, },
}; };
}); });
}) })
), );
[locations]
); const counts = new Map<string, number>();
edges.forEach((edge) => {
const key = `${edge.source}->${edge.target}`;
counts.set(key, (counts.get(key) ?? 0) + 1);
});
const indexes = new Map<string, number>();
return edges.map((edge) => {
const key = `${edge.source}->${edge.target}`;
const index = indexes.get(key) ?? 0;
indexes.set(key, index + 1);
return {
...edge,
data: {
...edge.data,
parallelIndex: index,
parallelCount: counts.get(key) ?? 1,
},
};
});
}, [locations]);
const [nodes,, onNodesChange] = useNodesState(initialNodes); const [nodes,, onNodesChange] = useNodesState(initialNodes);
const [edges,, onEdgesChange] = useEdgesState(initialEdges); const [edges,, onEdgesChange] = useEdgesState(initialEdges);

View File

@@ -9,6 +9,8 @@ type CableEdgeData = {
sourceName?: string; sourceName?: string;
targetName?: string; targetName?: string;
onEdgeClick?: () => void; onEdgeClick?: () => void;
parallelIndex?: number;
parallelCount?: number;
}; };
export default function CableMapEdge({ export default function CableMapEdge({
@@ -33,6 +35,9 @@ export default function CableMapEdge({
const edgeId = `edge-${id}`; const edgeId = `edge-${id}`;
const strokeWidth = 1 + Math.min(data.coreCount, 8) * 0.4; const strokeWidth = 1 + Math.min(data.coreCount, 8) * 0.4;
const strokeColor = selected ? "#1d4ed8" : "#64748b"; const strokeColor = selected ? "#1d4ed8" : "#64748b";
const parallelCount = typeof data.parallelCount === "number" ? data.parallelCount : 1;
const parallelIndex = typeof data.parallelIndex === "number" ? data.parallelIndex : 0;
const startOffset = `${((parallelIndex + 1) / (parallelCount + 1)) * 100}%`;
return ( return (
<> <>
@@ -46,7 +51,12 @@ export default function CableMapEdge({
onClick={() => data.onEdgeClick?.()} onClick={() => data.onEdgeClick?.()}
/> />
<text> <text>
<textPath href={`#${edgeId}`} startOffset="50%" textAnchor="middle" className="text-xs fill-slate-700"> <textPath
href={`#${edgeId}`}
startOffset={startOffset}
textAnchor="middle"
className="text-xs fill-slate-700"
>
{data.label} {data.label}
</textPath> </textPath>
</text> </text>