Skip to content

fix(graph): prevent relation-label overlap when selecting nodes #618

Description

@d-oit

Summary

Selecting a graph node can make the adjacent relationship label hard or impossible to read. The relation text is rendered near the midpoint of the highlighted edge, while the selected node grows and adds an animated dashed selection ring. In short edges or dense regions, these visual elements overlap.

Affected area

  • View: Knowledge Graph
  • Component: src/components/studio/views/graph-view.tsx
  • Render path: highlighted edge relation <text> and selected-node selection ring

Current behavior

When an entity is selected:

  1. The node radius grows from 11 to 14.
  2. A dashed selection ring is rendered with radius r + 6.
  3. Connected edges are highlighted and their relation label is drawn at the edge midpoint:
<text
  x={(s.x + t.x) / 2}
  y={(s.y + t.y) / 2 - 4}
  textAnchor="middle"
  className="fill-ink-mute font-sans text-badge italic"
>
  {e.relation}
</text>

For tightly positioned nodes, the midpoint relation label can collide with the selected node / its ring or with nearby labels. The text has no backing surface or collision avoidance, so the line makes it visually unreadable.

Expected behavior

Highlighted relationship labels should remain readable regardless of whether either connected node is selected.

Suggested implementation

  • Move relation labels away from the direct edge midpoint by calculating a perpendicular offset from the edge vector.
  • Increase the offset for edges attached to the selected node, accounting for the selected node’s outer selection ring.
  • Render a small, theme-aware background behind each relation label, for example an SVG <rect> or paint-order/stroke treatment, so lines cannot run through glyphs.
  • Preserve accessibility: relation labels are decorative context unless exposed through an accessible graph description; do not introduce nested interactive SVG controls.
  • Keep the layout stable and avoid altering graph node coordinates.

Example direction

const dx = t.x - s.x
const dy = t.y - s.y
const length = Math.hypot(dx, dy) || 1
const labelOffset = isHighlight ? 12 : 8

const labelX = (s.x + t.x) / 2 + (-dy / length) * labelOffset
const labelY = (s.y + t.y) / 2 + (dx / length) * labelOffset

Then place the relation label at labelX / labelY and give it a background or stroke matching var(--background).

Acceptance criteria

  • A selected node never visually overlaps the text of an adjacent highlighted relation.
  • An edge line cannot reduce the legibility of its relation label.
  • Relation labels are offset consistently for horizontal, vertical, and diagonal edges.
  • The change works in force, circular, and hierarchical layouts.
  • Keyboard selection (Enter / Space) has the same visual result as pointer selection.
  • The graph remains usable with reduced-motion preferences enabled.
  • Add or update tests in graph-view.test.tsx and/or graph-view-coverage.test.tsx for the selected-node label rendering path.

Reproduction

  1. Open Graph in DO Knowledge Studio.
  2. Select a node that has one or more visible connections.
  3. Observe the highlighted edge and its relation label, especially where nodes are close together.
  4. The relation text may intersect with the selected node’s dashed ring, node glyph, or edge line, making it difficult to read.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is not workingjules

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions