Skip to content

Faithful vertex shape preview matching the canvas#1929

Open
kmcginnes wants to merge 7 commits into
mainfrom
node-preview
Open

Faithful vertex shape preview matching the canvas#1929
kmcginnes wants to merge 7 commits into
mainfrom
node-preview

Conversation

@kmcginnes

@kmcginnes kmcginnes commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Description

Replaces the fixed-circle VertexSymbol with an SVG renderer that draws the actual cytoscape node shape, fill, border, and clipped icon — matching the canvas appearance across all 24 shape values.

Every place that previously showed a blue circle (search results, legend, schema sidebar, style dialog) now shows the vertex's true shape, color, opacity, border, and icon at the correct proportions.

Core change

A new deep module components/VertexSymbol/ replaces the old VertexSymbol implementation:

  • Geometry — verbatim port of cytoscape 3.34's shape math: sharp polygons (13), round polygons (7), round-rectangle, cut-rectangle, and barrel. All 24 SHAPE_STYLES render correctly in SVG, including the canvas-broken round-* shapes.
  • Icon pipeline — TanStack Query hook sharing the canvas's icon cache (renderNode pipeline), so icons load instantly from cache after first fetch.
  • Clip + sizing — icon rendered at 60% of the shape box (matching the canvas's backgroundWidth/Height: "60%") and clipped to the shape outline.
  • Proportional — fixed 96-unit viewBox, CSS-driven display size via className. Border width scaled to match canvas proportions.

Tangential

  • nodeShape.ts gets a ShapeStyle type annotation so the picker values are compile-time checked.
  • Old VertexSymbol/VertexSymbolByType removed from VertexIcon.tsx; re-exported from the new module through the same barrel so all existing consumers work unchanged.

How to read

  1. nodeShapes.ts — start here; all shape geometry
  2. VertexSymbol.tsx — the SVG component
  3. useIconDataUrl.ts — icon query hook
  4. nodeShapes.test.ts — geometry coverage
  5. VertexIcon.tsx — removed old implementation
  6. nodeShape.ts — typing improvement

Validation

  • All 2149 tests pass, pnpm checks green
  • Visual comparison against live cytoscape nodes across all shapes
  • Tested in Graph View (legend, search results), Schema View (sidebar, style dialog), and the Connections screen

Screenshots

Each screenshot shows the same vertex style rendered in three places at once — the canvas (ground truth), the style dialog's icon swatch, and the Details View symbol — so shape, border, and icon parity can be checked directly.

Barrel shape with a dotted border — the barrel's curved top/bottom and the dotted border render identically on the canvas nodes and in the preview symbols:

Barrel shape with dotted blue border shown matching across canvas, dialog swatch, and Details View

Cut Rectangle with a solid magenta border — chamfered corners and border color match across all three renderings:

Cut rectangle shape with solid magenta border shown matching across canvas, dialog swatch, and Details View

Round Diamond with a dashed green border — one of the round-* shapes; the preview renders the correct rounded-diamond geometry with the thin dashed border:

Round diamond shape with dashed green border shown matching across canvas, dialog swatch, and Details View

Related Issues

Check List

  • I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • I have verified pnpm checks passes with no errors.
  • I have verified pnpm test passes with no failures.
  • I have covered new added functionality with unit tests if necessary.
  • I have updated documentation if necessary.

Replace the fixed-circle VertexSymbol with an SVG renderer that draws
the actual cytoscape node shape, fill, border, and icon — matching the
canvas appearance across all 24 SHAPE_STYLES values.

- Port cytoscape 3.34's geometry verbatim: sharp polygons, round polygons,
  round-rectangle, cut-rectangle, and barrel
- Icon loaded through the production pipeline via TanStack Query (same
  cache as the canvas), clipped to the shape at 60% sizing
- Proportional viewBox (96) with CSS-driven sizing via className
- New deep module: components/VertexSymbol/ (VertexSymbol.tsx, nodeShapes.ts,
  useIconDataUrl.ts, nodeShapes.test.ts)
- Delete spike scaffolding (SpikeNodePreview, spikeNodeShapes, spike doc)
Use React's useId() for the SVG clipPath ID instead of a type-derived
string. The old approach (vs-clip-${type}) collided when the same vertex
type rendered in multiple places (Graph View legend + Schema View sidebar),
causing the second instance's icon to clip against the wrong element.
Border width from VertexStyle is in canvas pixels (relative to a 24px
node). The SVG viewBox is 96 units, so a raw value of 1 rendered as
sub-pixel (0.375px at 36px display). Scale by viewBox/canvasNode (4x)
so a 1px canvas border appears proportionally correct in the preview.
- Clamp insetSize to minimum 1 so extreme borderWidth doesn't produce
  degenerate geometry
- Add exhaustive default to renderShape switch for type safety
- Skip icon query when iconUrl is empty (no pointless cache entries)
The queryFn receives the QueryClient as a parameter, eliminating the
need for useQueryClient and the eslint-disable comment. Matches the
pattern used in useBackgroundImageMap.
@kmcginnes kmcginnes marked this pull request as ready for review July 10, 2026 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant