Part Diagram

An exploded view that breaks an object into its parts. Drag to pull it apart, pick a system to highlight it and read what it does.

Pattern

≈ 3,696 tokens per use (tool 1,612 · guidance 309 · typical payload 1,775)How token costs are estimated

Example: Part Diagram

Break down the design of a 7-speed bike

7-Speed Bicycle

7-Speed Bicycle: 16 parts in 5 systems.

Arrow keys move between parts and show each one on the drawing.

Main triangle, Frame
Rear triangle, Frame
Fork, Frame
Rear wheel, Wheels
Front wheel, Wheels
Crankset, Drivetrain
Chain, Drivetrain
Cassette, Drivetrain
Rear derailleur, Drivetrain
Shifter, Drivetrain
Front brake, Brakes
Rear brake, Brakes
Brake lever, Brakes
Stem, Cockpit
Handlebar, Cockpit
Saddle and seatpost, Cockpit
Explode view
Highlight a system

Five connected systems

The frame holds everything in place. Pedalling drives the rear wheel through 7 gears, and the cockpit and brakes are how you steer and stop.

When to use

  • The user asks how a physical object or machine is built or works: "break down a bike", "how does a coffee grinder work?", "parts of a keyboard".
  • The answer is parts and how they group into systems, and seeing them in place helps.

When not to use

  • The parts are abstract, such as software services or teams. Use a Relationship Explorer.
  • Steps in order matter more than parts. Use a Timeline.
  • You can't draw it recognisably with simple lines and circles. Use a list.

How the agent should use it

  • Draw simple, recognisable line art. Circles, rects, lines and polylines cover most objects; use path only for curves. Every part sits where it belongs when assembled, inside the viewBox.
  • Point explode vectors outward from the object's centre, so parts don't land on each other. Stacked objects (a keyboard, a burger, a battery cell) explode along dy only. Leave margin in the viewBox for where parts end up.
  • Use 2 to 8 systems and give every part one. Labels are short ("Rear derailleur"); summaries are one or two plain sentences.
  • Set overview for the "All" view: a short heading ("Five connected systems") and how the systems work together.
  • Only set askable when you'll follow up. On explain, explain that part or system.
  • Lifecycle: none needed. The diagram doesn't go stale or expire; use supersede if you redraw it.

Reading the diagram

  • The canvas is a rounded panel with the object as light line art in the foreground color, so it reads in both themes. strokeWidth is in screen pixels (default 1.5) and stays the same at any card width. fill adds a light tint inside closed shapes.
  • Explode view runs from Assembled (0%) to Exploded (100%). Every part moves along its own explode vector, scaled by the slider; parts glide there, and with reduced motion they jump straight to the slider's position. The canvas frame covers the parts both assembled and fully exploded, so dragging never zooms the drawing.
  • System chips (All plus one per system) highlight that system's parts and dim the rest to 20%. The explanation under the chips shows the system's label and summary, or the overview for All.
  • Hovering a part shows its label as a pill at labelAt (or the part's centre), following the part as it moves. Tapping a part pins its label; tapping empty space clears it.
  • Ask about this (with askable) sits next to the explanation. It asks about the pinned part when there is one ("Ask about Chain"), otherwise about the selected system. It's hidden on All with nothing pinned. After asking, everything stays explorable.

Safety and limits

Geometry comes from the model or a tool, so it's checked before drawing. Path data must be strict SVG path syntax: the commands M L H V C S Q T A Z (either case) and numbers, with the right number of parameters per command and arc flags of 0 or 1. Anything else, such as url( or javascript:, drops that shape, and the check runs in linear time. Shapes with missing or non-finite numbers are skipped, explode vectors are capped at the viewBox size, and only the first 40 parts and 12 shapes per part are drawn. Validation, bounds, interpolation and label placement live in part-diagram-utils.ts, with no dependencies.

Accessibility

The canvas is hidden from assistive tech. A visually hidden role="listbox" mirrors it, with one role="group" per system. Arrow keys move through the parts (Home and End jump, Escape clears), and selection follows focus: the focused part is pinned on the canvas with its label and a dashed focus ring, even when its system is dimmed. The slider is labelled "Explode view" and announces "Assembled", "40% exploded" or "Fully exploded". The chips are native radios, and the explanation and the asked-about confirmation are live regions.

Installation

npx shadcn@latest add https://your-site.com/r/part-diagram.json

Usage

app/api/chat/route.ts
import { tool } from "ai"
import { partDiagramTool } from "@/components/genui/part-diagram.schema"

const tools = {
  [partDiagramTool.name]: tool({
    description: partDiagramTool.description,
    inputSchema: partDiagramTool.inputSchema,
  }),
}

Without askable the diagram is the whole answer, so give the tool an execute that returns immediately. With it, the agent receives one of:

{ action: "explain", partId: "derailleur" }
{ action: "explain", systemId: "drivetrain" }

With LangGraph

Push it from a graph node with ui.push({ name: "show_part_diagram", props: { toolCallId, ...args } }, { message }), and render the thread's UI messages with the Renderer.

Restoring from history

Pass the stored tool output as result. The diagram selects that system (or pins that part), shows what was asked, and never calls onResult again. The slider, chips and hover still work:

<PartDiagram
  {...part.input}
  result={part.state === "output-available" ? part.output : undefined}
/>

Schema

PropTypeNotes
titlestringThe object, e.g. "7-Speed Bicycle"
viewBox{ width, height }?Drawing coordinates. Default 400 × 260
systems{ id, label, summary }[]2–8. label up to 24 characters, summary up to 200
parts{ id, label, system, shapes, explode, labelAt? }[]2–40, drawn in order. shapes: 1–12. explode: { dx, dy } at full explode, in viewBox units. labelAt: { x, y }, assembled
overview{ heading, summary }?Shown for All
askablebooleanAdds Ask about this. Default false

Shapes are a union on type, each with optional strokeWidth (0.25–6) and fill:

typeFields
circlecx, cy, r
rectx, y, width, height, rx?
linex1, y1, x2, y2
polylinepoints: [x, y][], at least 2. Repeat the first point to close it
pathd: path commands and numbers only

Host props: status (streaming, ready, submitted), onResult, result and className. While streaming, the canvas is a skeleton until two parts are complete, and parts fade in as they arrive.

Source

On this page