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]
);
const initialEdges = useMemo(
() =>
locations.flatMap((location) =>
location.startCables.flatMap((cable) => {
const route = [
{ id: String(cable.startLocationId), name: location.name },
...cable.intermediateStops.map((stop) => ({
id: String(stop.location.id),
name: stop.location.name,
})),
{ id: String(cable.endLocationId), name: cable.endLocation.name },
];
const initialEdges = useMemo(() => {
const edges = locations.flatMap((location) =>
location.startCables.flatMap((cable) => {
const route = [
{ id: String(cable.startLocationId), name: location.name },
...cable.intermediateStops.map((stop) => ({
id: String(stop.location.id),
name: stop.location.name,
})),
{ id: String(cable.endLocationId), name: cable.endLocation.name },
];
return route.slice(1).map((target, index) => {
const source = route[index];
return {
id: `cable-${cable.id}-${index}`,
type: "cable",
source: source.id,
target: target.id,
data: {
label: cable.identifier,
coreCount: cable._count.cores,
cableId: cable.id,
sourceName: source.name,
targetName: target.name,
onEdgeClick: () => setSelectedEdgeId(cable.id),
},
};
});
})
),
[locations]
);
return route.slice(1).map((target, index) => {
const source = route[index];
return {
id: `cable-${cable.id}-${index}`,
type: "cable",
source: source.id,
target: target.id,
data: {
label: cable.identifier,
coreCount: cable._count.cores,
cableId: cable.id,
sourceName: source.name,
targetName: target.name,
onEdgeClick: () => setSelectedEdgeId(cable.id),
},
};
});
})
);
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 [edges,, onEdgesChange] = useEdgesState(initialEdges);

View File

@@ -9,6 +9,8 @@ type CableEdgeData = {
sourceName?: string;
targetName?: string;
onEdgeClick?: () => void;
parallelIndex?: number;
parallelCount?: number;
};
export default function CableMapEdge({
@@ -33,6 +35,9 @@ export default function CableMapEdge({
const edgeId = `edge-${id}`;
const strokeWidth = 1 + Math.min(data.coreCount, 8) * 0.4;
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 (
<>
@@ -46,7 +51,12 @@ export default function CableMapEdge({
onClick={() => data.onEdgeClick?.()}
/>
<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}
</textPath>
</text>