synergycodes/ng-diagram/ng-diagram-custom-edges
Claude Code and agent skill by synergycodes/ng-diagram
- community
- ext:[{"type":"template","description":"Custom templates for code generation"}]
Checking that the SKILL.md file is still in the repository.
Use when customizing how ng-diagram edges look - edge templates (NgDiagramEdgeTemplate, ng-diagram-base-edge), edge labels, arrowheads and custom markers, selected or temporary edge CSS, or the "Edge template ... is not registered" warning.
Install
npx vskill@latest install synergycodes/ng-diagram/ng-diagram-custom-edgesSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
Custom edges, labels and arrowheads
How edges look: edge templates, <ng-diagram-base-edge> inputs and CSS variables, labels, markers and state classes. Path shapes are in ng-diagram-edge-routing, user-drawn edges in ng-diagram-linking, relink handles in ng-diagram-edge-relinking, free ends in ng-diagram-dangling-edges, themes in ng-diagram-styling, hiding in ng-diagram-visibility.
Rules
- A custom edge is a standalone component that implements
NgDiagramEdgeTemplate<T>withedge = input.required<Edge<T>>()and renders<ng-diagram-base-edge [edge]="...">. The base edge draws the path and markers, makes the edge clickable and selectable, positions labels and shows relink handles. A template without it gets none of that. - Registration has three parts that must match: a key in
new NgDiagramEdgeTemplateMap([['key', Cmp]]), the map on<ng-diagram [edgeTemplateMap]="...">, andedge.type === 'key'. An unknowntyperenders the default edge and logs a warning once per type. An edge withouttyperenders the default edge without a warning. - Edges drawn by users get no
typeunless a linking builder sets one. Add it inlinking.finalEdgeDataBuilder(seeng-diagram-linking), or drawn edges keep the default look. updateEdgeData(id, data)replaces the wholedataobject. Spread the old data:{ ...edge.data, label }.- Use
<ng-diagram-base-edge-label>and<ng-diagram-default-edge-label>only inside<ng-diagram-base-edge>: both inject the surrounding base edge and fail with a DI error anywhere else. Give each label of an edge its ownid, because its position is looked up by id. - Read, never write, the system-computed edge fields:
measuredLabels,points(auto routing),sourcePosition/targetPositionof connected ends,computedZIndex,computedHidden. - Know the precedence:
edge.sourceArrowhead/targetArrowheadin the model beat the[sourceArrowhead]/[targetArrowhead]inputs.[routing]works the other way: the input beatsedge.routingand is written into the model.[stroke],[strokeWidth],[strokeOpacity]and[strokeDasharray]beat the CSS variables. - Recolor the default edge with the variables
--ngd-default-edge-stroke,--ngd-default-edge-stroke-hoverand--ngd-default-edge-stroke-selected(onng-diagramor:root). The default edge sets--edge-strokein its own encapsulated rules, which are more specific than a page rule onng-diagram-base-edge.default-edge. These variables do not followdata-theme="dark", so set dark values yourself.
Minimal custom edge + registration
Style by state
Set CSS variables on ng-diagram-base-edge in the edge component's styles. The host gets state classes:
The <ng-diagram-edge> element that wraps your template gets ng-diagram-edge--temporary and ng-diagram-edge--dangling (since 1.4.0). For styles driven by logic, bind the inputs from a computed(), for example [stroke]="edge().selected ? '#2563eb' : '#334155'". Read references/edge-css-reference.md when you need every input, variable, default or label chip variable.
The <path> belongs to the base edge's own view, so your component styles reach it only through the --edge-* variables and the inputs. For other path properties (for example an animated stroke-dashoffset), put a rule in a global stylesheet, such as ng-diagram-base-edge.flowing path { ... } with class="flowing" on your <ng-diagram-base-edge>.
Labels in a custom edge
ng-diagram-base-edge-labelplaces and measures the label.ng-diagram-default-edge-label(since 1.3.0) only gives the content the default chip look, with hover and selected borders (--edge-label-border-color-hover,--edge-label-border-color-selected, since 1.3.0).positionOnEdge: a number0..1is relative (0 = source, 1 = target, clamped). A string'30px'is measured from the source and'-20px'from the target, clamped to the path length (since 1.1.0).[hidden](since 1.4.0) hides one label. The label stays in the DOM, keeps its size and never blocks initialization.data-no-pan="true"/data-no-drag="true"on an element or its container stop a drag on it from panning the canvas or dragging nodes. Put them on inputs and buttons.
Default edge labels
The default edge shows edge.data.label (nothing when empty) at edge.data.positionOnEdge (default 0.5; this key since 1.1.0).
Labels are measured with a ResizeObserver, so size changes need nothing. invalidateMeasurements exists since 1.2.3 and returns a Promise since 1.3.0.
Arrowheads and custom markers
The built-in marker id is 'ng-diagram-arrow'. For your own markers:
- Put one
<marker>with anidin each<ng-diagram-marker>: only the first marker inside is registered. - Render markers inside the component that provides
provideNgDiagram(), next to<ng-diagram>.<ng-diagram-marker>needs the diagram's injector. fill="context-stroke"/stroke="context-stroke"make the marker follow the edge color. Safari has nocontext-stroke, so there the library copies each registered marker per edge and replacesstroke="context-stroke",fill="context-stroke"andfill="context-fill"with the edge color (stroke="context-fill"is not replaced). Values inside astyleattribute are not replaced either, and a plain<marker>outside<ng-diagram-marker>does not show in Safari.orient="auto-start-reverse"(as in the built-in arrow) turns the marker with the edge and flips it at the source end, so one id works at both ends. Withoutorientthe marker never rotates.
Edge cases
- Edges drawn by users carry
targetArrowhead: 'ng-diagram-arrow'in the model (copied from the preview edge). Model data wins, so your[targetArrowhead]input is ignored for them unless the builder setstargetArrowhead: undefined. - A relink preview renders your template with the relinked edge's
type,dataand labels, plus thetemporaryclass. A draw preview uses your template only whentemporaryEdgeDataBuildersetstype. - The labels of the preview edge (draw or relink) ignore the pointer (since 1.4.0); labels of other edges still catch it. Do the same for other interactive parts of your template:
:host-context(.ng-diagram-edge--temporary) .toolbar { pointer-events: none; }. [strokeWidth]="0"and[strokeOpacity]="0"are ignored (they fall back to the CSS variable). To hide an edge, use itshiddenflag (ng-diagram-visibility).- A label stays invisible until the edge has a routed path and the label has a measured position.
- Selected edges show relink handles from
ng-diagram-base-edgewhen relinking is on, also in custom templates (ng-diagram-edge-relinking).
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ng-diagram-custom-edges/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Extension points
templateCustom templates for code generation
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/synergycodes/ng-diagram/ng-diagram-custom-edges)