Improve topology layout spacing and edge label readability

- Increase LayerSpacing from 60 to 120 and NodeSpacing from 40 to 60
  for wider promotion arrows between environments
- Increase CompoundPadding from 30 to 40 for better region container
  separation
- Replace inline edge labels with tooltip callout pattern: truncated
  text in a background box with dashed leader line to the edge
- Edge labels capped at 30 chars with ellipsis

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-28 20:44:20 +02:00
parent 0998c89616
commit f57b5efb31
2 changed files with 63 additions and 6 deletions

View File

@@ -143,8 +143,10 @@ public sealed class TopologyLayoutService
new ElkLayoutOptions
{
Direction = direction,
NodeSpacing = 40,
LayerSpacing = 60,
NodeSpacing = 60,
LayerSpacing = 120,
CompoundPadding = 40,
CompoundHeaderHeight = 32,
Effort = effort,
},
cancellationToken).ConfigureAwait(false);

View File

@@ -106,11 +106,28 @@ import {
[attr.marker-end]="selectedEdgeId() === edge.id ? 'url(#arrow-promotion-selected)' : 'url(#arrow-promotion)'"
/>
@if (edge.label) {
<!-- Tooltip callout: dashed leader line + label box offset above edge -->
<line
[attr.x1]="getEdgeLabelX(edge)"
[attr.y1]="getEdgeLabelAnchorY(edge)"
[attr.x2]="getEdgeLabelX(edge)"
[attr.y2]="getEdgeLabelY(edge) + 6"
class="edge-leader"
/>
<rect
[attr.x]="getEdgeLabelX(edge) - getEdgeLabelWidth(edge) / 2 - 4"
[attr.y]="getEdgeLabelY(edge) - 6"
[attr.width]="getEdgeLabelWidth(edge) + 8"
height="14"
rx="3"
ry="3"
class="edge-label-bg"
/>
<text
[attr.x]="getEdgeLabelX(edge)"
[attr.y]="getEdgeLabelY(edge)"
[attr.y]="getEdgeLabelY(edge) + 4"
class="edge-label"
>{{ edge.label }}</text>
>{{ truncateEdgeLabel(edge.label) }}</text>
}
</g>
}
@@ -341,8 +358,32 @@ import {
stroke-width: 2.5;
}
.edge-leader {
stroke: var(--color-text-muted);
stroke-width: 0.5;
stroke-dasharray: 2 2;
opacity: 0.5;
pointer-events: none;
}
.edge-group:hover .edge-leader {
opacity: 0.8;
}
.edge-label-bg {
fill: var(--color-surface-primary);
stroke: var(--color-border-primary);
stroke-width: 0.5;
opacity: 0.9;
pointer-events: none;
}
.edge-group--selected .edge-label-bg {
stroke: var(--color-brand-primary);
}
.edge-label {
font-size: 9px;
font-size: 8px;
fill: var(--color-text-muted);
text-anchor: middle;
pointer-events: none;
@@ -553,7 +594,21 @@ export class TopologyGraphComponent {
}
getEdgeLabelY(edge: TopologyRoutedEdge): number {
return this.edgeMidpoint(edge).y - 6;
return this.edgeMidpoint(edge).y - 22;
}
getEdgeLabelAnchorY(edge: TopologyRoutedEdge): number {
return this.edgeMidpoint(edge).y;
}
getEdgeLabelWidth(edge: TopologyRoutedEdge): number {
const label = this.truncateEdgeLabel(edge.label);
return label.length * 4.5;
}
truncateEdgeLabel(label: string | undefined | null): string {
if (!label) return '';
return label.length > 30 ? label.substring(0, 29) + '\u2026' : label;
}
truncate(text: string | undefined | null, max: number): string {