synergycodes/ng-diagram/ng-diagram-layering
Claude Code and agent skill by synergycodes/ng-diagram
- community
Checking that the SKILL.md file is still in the repository.
Use when ng-diagram nodes or edges stack in the wrong order - bring to front / send to back, edges hidden behind nodes, a selected node jumping on top, zOrder vs computedZIndex, a dropdown covered by the next node, or the zIndex config.
Install
npx vskill@latest install synergycodes/ng-diagram/ng-diagram-layeringSKILL.md
Z-order and layering
How ng-diagram computes the stacking order of nodes and edges, how to change it (zOrder in the model, bringToFront / sendToBack), and the zIndex config. Group membership is in the ng-diagram-groups skill, hidden elements in ng-diagram-visibility.
Rules
- Write
zOrder, nevercomputedZIndex.computedZIndexis system-owned: it is recomputed on changes, andinitializeModelandtoJSON()strip it. zOrderis model data:toJSON()keeps it.bringToFront/sendToBackwritezOrder, so the user's arrangement survives save and load.- Children always render above their group.
zOrderorders siblings; it cannot move a child behind its parent. bringToFront()/sendToBack()without arguments act on the current selection. Any array argument replaces the selection, sobringToFront([])does nothing.- With edge relinking, keep
zIndex.enabledandzIndex.elevateOnSelectionon (the defaults). The relink handles are part of the edge, and without elevation a node can cover them so the user cannot grab them. - Set
zIndexoptions when the diagram is created.<ng-diagram>reads the[config]binding only when the model is (re)initialized, and a laterNgDiagramService.updateConfigonly affects elements that are recomputed afterwards (on selection,zOrder, group or endpoint changes, or when added).
How the order is computed
- Nodes and edges share one stacking context. The library writes
computedZIndexon every node and edge and applies it as an inlinez-indexon the node wrapper and onng-diagram-base-edge. - Root node:
zOrder ?? 0(negative values allowed). - Node in a group: each child gets its own slot above the parent (parent + 1, parent + 2, ... in sibling order).
zOrdercan raise a child above its slot, never below it. Siblings are ordered unselected first, then byzOrder(missing = 0). - Edge: its
zOrderif set, otherwise the higher z of its two nodes (+ 1 withedgesAboveConnectedNodes). - Selection (with
elevateOnSelection): a selected node addsselectedZIndex(default 10000) to itself and its descendants, so a selected child of a selected group gets it twice. A selected edge adds it too, and an edge with its ownzOrderalso gets the elevation of a selected endpoint node. - The edge being drawn gets
temporaryEdgeZIndex. - Equal z-index: DOM order decides. All edges come before all nodes, and nodes follow the order of the
nodesarray. So at equal z a node covers an edge, and a node added later covers one added earlier.
Bring to front / send to back
What the commands write (since 1.3.0 they return a Promise<void> that resolves when the model is updated):
bringToFront(nodeIds?, edgeIds?): the highest base z of all other nodes (selection elevation ignored) and of the other edges'zOrder(missing = 0, never below 0), plus 1. Every target node and edge gets this one value; the descendants of a target group get the next values in hierarchy order, so the group keeps its inner order.sendToBack(nodeIds?, edgeIds?): the lowest of the same values (never above 0), minus 1, for every target. Each ancestor of a target node gets one less per level (parent - 1, grandparent - 2), so the whole chain goes behind its siblings.
Set the order in the model
Selection elevation is temporary: a deselected node drops back to its zOrder position. The keepOnTop handler above makes the last clicked node stay on top; it skips box selections and select-all, which would all get one shared zOrder. updateEdge(id, { zOrder }) works the same way for edges.
Configuration
config.zIndex (ZIndexConfig; every key optional in NgDiagramConfig):
| Key | Default | Effect | |
|---|---|---|---|
enabled | true | false turns z-index computation off: every element gets z-index: 0, so DOM order decides (nodes always over edges, later nodes over earlier ones, a group listed after its children covers them), and zOrder, bringToFront and selection have no visible effect | |
selectedZIndex | 10000 | added to selected elements (was 1000 before 1.2.3) | |
elevateOnSelection | true | false keeps selected elements at their normal level | |
edgesAboveConnectedNodes | false | true puts each edge without zOrder 1 above the higher of its two nodes | |
temporaryEdgeZIndex | 2147483647 | z-index of the edge being drawn (was 1000 before 1.2.3); applied even with enabled: false |
Edge cases
- Big groups: children take the slots parent + 1 ... parent + n, so the children of one root group can stack above a neighboring root group with the same or a lower z. Use
bringToFronton the group that must be on top. - A node wrapper is its own stacking context (
position: absoluteplus az-index). Content inside a node template, such as a dropdown or a tooltip, cannot rise above a neighbor node with a higher z, or with the same z that comes later in thenodesarray (the default: root nodes all have z 0).position: fixeddoes not help: node wrappers and<ng-diagram>have CSS transforms, and the diagram clips its content. Bring the node to front while the overlay is open, or render the overlay outside the diagram (for example with the Angular CDK Overlay). - An edge with its own
zOrder(also one written bybringToFront/sendToBack) no longer follows its nodes and gets noedgesAboveConnectedNodes+ 1; only the elevation of a selected endpoint node is added. Remove thezOrderto make it follow them again. - Moving or resizing a node does not change the order. Only selection,
zOrder, group membership, endpoint changes and added elements trigger a recompute. - Since 1.4.0 the edge is layered again when its
sourceortargetchanges (updateEdge,attachEdge, relink). Before, it kept the layering of its old nodes. bringToFront,sendToBackandzOrderdo not skip hidden elements. A call without arguments also moves hidden elements that are still selected.- Each
bringToFrontwrites one more than the highest value of the other elements, so the numbers grow when different elements take turns; that is harmless.
Symptom → fix
| Symptom | Cause and fix | |
|---|---|---|
Setting computedZIndex does nothing | It is recomputed by the library. Set zOrder or call bringToFront / sendToBack. | |
bringToFront() does nothing | Nothing is selected and no ids were passed, an empty array was passed, or zIndex.enabled is false. | |
| Child cannot go behind its group | By design: children always render above their parent. | |
| Edges hidden behind nodes | Default: an edge sits at its higher node's level and the node wins the tie. Set zIndex.edgesAboveConnectedNodes: true, or give the edge a zOrder / bringToFront([], [edgeId]). | |
| Selected node jumps above everything | Selection elevation (selectedZIndex). Set elevateOnSelection: false, but not when you use edge relinking. | |
| Node drops back behind others after deselecting | Elevation applies only while selected. Call bringToFront (for example on selectionGestureEnded). | |
| Relink handle cannot be grabbed, a node covers it | Keep zIndex.enabled and elevateOnSelection on. See the ng-diagram-edge-relinking skill. | |
| Dropdown in a node is covered by the next node | Each node is a stacking context. Bring the node to front while open, or use an overlay outside the diagram. | |
| Order differs by a few between groups | Each child takes its own slot above its parent; count those slots when you pick cross-group zOrder values. | |
Changing zIndex options at runtime has no effect | A changed [config] binding is read only at model init, and updateConfig reaches only elements recomputed later. Set them at creation or reinitialize the model. | |
Edge keeps old layering after changing its source/target in code | Fixed in 1.4.0 - upgrade. | |
| Children render under their group, siblings not re-sorted | Fixed in 1.2.3 (z-ordering rework) - upgrade. |
Verify before you answer
- Check the installed version in
node_modules/ng-diagram/package.json(or the lockfile). This skill describes ng-diagram 1.4.0; anything marked "since vX.Y" does not exist in older versions. - Confirm exact names and signatures in
node_modules/ng-diagram/ng-diagram.d.ts(its TSDoc has@sincetags) instead of guessing. - For more detail, use the ng-diagram docs MCP tools (
search_docs,get_doc,search_symbols,get_symbol) when available, or https://www.ngdiagram.dev/docs.
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-layering/SKILL.md
Popularity
- Repository stars
- 583
- Repository forks
- 41
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
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-layering)