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:
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user