synergycodes/ng-diagram/ng-diagram-viewport
Claude Code and agent skill by synergycodes/ng-diagram
- community
Checking that the SKILL.md file is still in the repository.
Use when an ng-diagram must pan or zoom from code (zoomToFit, centerOnNode, setViewport, zoom buttons, zoom limit warnings), convert mouse coordinates to diagram positions, disable panning, or save and restore the view.
Install
npx vskill@latest install synergycodes/ng-diagram/ng-diagram-viewportSKILL.md
Viewport: pan, zoom, fit, coordinates
NgDiagramViewportService and the viewport settings. Image export is in ng-diagram-export, virtualization in ng-diagram-performance, every config key in ng-diagram-config, keyboard shortcuts in ng-diagram-shortcuts, touch gestures in ng-diagram-touch.
How the viewport works
- Diagram (flow) coordinates:
node.positionis the top-left corner, edges havepoints. They do not change when the user pans or zooms. Children of a group keep global positions. metadata.viewportis{ x, y, scale, width?, height? }.x/yis the pan offset: where the flow origin(0, 0)is drawn, in px from the top-left corner of<ng-diagram>(theViewportTSDoc calls it the viewport center; it is not).width/heightis the size of that element. A flow point is drawn atpoint * scale + (x, y).- Service signals:
viewport(),scale(),canZoomIn(),canZoomOut(). Getters:minZoom,maxZoom(configzoom.min0.01,zoom.max10).
Rules
- Use the services inside the
provideNgDiagram()tree, after<ng-diagram>has created its engine. Before that, the methods andminZoom/maxZoom/canZoomIn()/canZoomOut()throw[ngDiagram] Library engine not initialized yet. Wait for(diagramInit)orNgDiagramService.isInitialized(). - Every pan/zoom/fit method returns a
Promise<void>(since 1.3.0; before,void).awaitit when the next line needs the new view.viewport()/scale()refresh with change detection, so right after anawaitreadmodelService.getModel().getMetadata().viewport. - Fit and center use measured sizes. After adding or resizing elements,
awaitthe change with{ waitForMeasurements: true }first (per-method option since 1.3.0; before, use it on atransaction). Unmeasured elements are left out, andcenterOnNodedoes nothing for a node withoutsize. - Convert pointer coordinates first:
clientToFlowPositionfor anything stored in the model (position,paste()),clientToFlowViewportPositionfor overlays placed inside the diagram area. zoom(factor)does not clamp. A result outsidezoom.min/zoom.maxlogsZoom scale <s> is out of bounds [min, max]and nothing changes. It keepsx/y, so it zooms around the flow origin, and its optional second argument is written as the newx/y(it is not a zoom center). It also reads the scale and offset from the laggingscale()/viewport()signals, so right after anawaitit can undo a pan you just made. For zoom buttons usesetViewportas below.- Change settings at runtime with
NgDiagramService.updateConfig(...). A new object in[config]reaches the engine only when the model is initialized again.
Zoom toolbar
setViewport(x, y, scale) (since 1.2.0) clamps scale and logs [ngDiagram] setViewport: scale <s> is outside configured bounds [min, max] and will be clamped. when it has to. Wheel, pinch and keyboard zoom clamp without a warning.
Fit and focus
zoomToFit({ nodeIds?, edgeIds?, padding? }):paddingdefaults tozoom.zoomToFit.padding(50) and takesn,[v, h],[t, h, b]or[t, r, b, l]. The scale is clamped tozoom.min/zoom.max, so one small node can zoom in up tozoom.max. To cap it, seereferences/custom-viewport.md.- Since 1.4.0,
nodeIdswithoutedgeIdsfits those nodes and only the edges between them (before, every edge counted, so the fit showed the whole connected diagram). An emptynodeIdsarray counts as not given: the whole diagram is fitted. Hidden elements are left out. With nothing measurable (empty diagram, unmeasured or only hidden elements) it does nothing. centerOnNode(idOrNode)andcenterOnRect(rect)only pan; the scale stays.- Fit on load:
zoom: { zoomToFit: { onInit: true, padding: 80 } }. It runs after every model initialization, right after your(diagramInit)handler starts. A handler that awaits work (an auto layout, a fetch) finishes later, so callzoomToFit()at the end of that handler instead.
Coordinates: drop, paste, context menu
| Method | Converts | |
|---|---|---|
clientToFlowPosition(p) | clientX/Y → diagram coordinates ((p - elementTopLeft - (x, y)) / scale) | |
clientToFlowViewportPosition(p) | clientX/Y → px from the top-left of <ng-diagram>; pan and zoom do not matter | |
flowToClientPosition(p) | diagram coordinates → clientX/Y (for position: fixed popups) |
The visible area in flow coordinates is { x: -x / scale, y: -y / scale, width: width / scale, height: height / scale } (from getModel().getMetadata().viewport): use its center to add a node in the middle of the view. moveViewportBy(dx, dy) pans by screen px, e.g. for arrow buttons.
Save and restore the view
toJSON() already contains metadata.viewport, so a saved model restores its view (see ng-diagram-persistence). width/height are read again from the element at init.
Panning settings
viewportPanningEnabled: false(since 0.9.0) turns off dragging the background, wheel and trackpad panning, touch panning, arrow-key panning and edge panning. Zoom and all service methods keep working, and so does the minimap (it pans through the service).- Edge panning: dragging nodes, or drawing or relinking an edge, near the diagram border moves the view toward that side. Keys and defaults:
ng-diagram-config. - Input: the mouse wheel pans (Shift+wheel: horizontally); Ctrl/Cmd+wheel and trackpad pinch zoom at the pointer; a two-finger trackpad swipe pans (trackpad handling improved in 1.2.4). A wheel step or the
=/-keys zoom byzoom.step(default 0.03); key bindings are inng-diagram-shortcuts.
Custom fit (zoom cap, own bounds, virtualization) and an animated pan: read references/custom-viewport.md.
Edge cases
zoomToFit()is disabled while virtualization is on: it logs[ngDiagram] zoomToFit is disabled when virtualization is enabled.and does nothing. This includeszoom.zoomToFit.onInit. Use the custom fit inreferences/custom-viewport.md.zoomToFit()does nothing while<ng-diagram>has no size (width/heightunknown) or when the padding is larger than the element.centerOnNodeusesposition+sizeand ignores rotation and ports;zoomToFitusesmeasuredBounds(ports and rotation included).- Hidden elements:
zoomToFitskips them,centerOnNodedoes not (it centers on the last position). moveViewport(x, y)sets the offset of the flow origin, not "center on this point". To center a point, usecenterOnRectwith a small rect around it.- While the user pans, viewport moves skip the middleware chain (custom middlewares do not see them);
viewportChangedstill fires. canZoomIn()/canZoomOut()track only the scale: afterupdateConfig({ zoom: { min, max } })they update with the next zoom. If you change the limits at runtime, compute the flags fromdiagram.config().zoomandviewport.scale().- After
updateConfig({ viewportPanningEnabled: false })the grab cursor stays: thepannablehost class comes from[config]at model init. Override it, e.g..read-only ng-diagram.pannable { cursor: default; }.
Symptom → fix
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-viewport/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-viewport)