import { Component } from '@angular/core';
import { WrGraph, WrGraphNodeTemplate } from 'ngwr/graph';
@Component({ imports: [WrGraph, WrGraphNodeTemplate] })
export class MyComponent {}Graph
Draws blocks joined parent to child, top to bottom, for display only.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Nodes and edges
Pass nodes and edges; each edge is { from, to }, from parent to child. A node can have several parents.
<wr-graph [nodes]="nodes" [edges]="edges" ariaLabel="Writing workflow" />Custom nodes
<ng-template wrGraphNode let-node> replaces the card. Render node.label in it: screen readers name the node by it.
<wr-graph [nodes]="nodes" [edges]="edges" [nodeWidth]="176" [nodeHeight]="56" ariaLabel="Team structure">
<ng-template wrGraphNode let-node>
@if (node.data.kind === 'unit') {
<div class="unit">{{ node.label }}</div>
} @else {
<div class="person">
<wr-avatar class="person__avatar" [size]="32" shape="circle">
<span aria-hidden="true">{{ node.data.initials }}</span>
</wr-avatar>
<div class="person__text">
<span class="person__name">{{ node.label }}</span>
<span class="person__role">{{ node.data.role }}</span>
</div>
</div>
}
</ng-template>
</wr-graph>Shared dependencies
Cycles and repeated edges between two nodes are allowed.
<wr-graph [nodes]="nodes" [edges]="edges" [nodeWidth]="184" [nodeHeight]="52" ariaLabel="Dependencies">
<ng-template wrGraphNode let-node>
<div class="package">
<code class="package__name">{{ node.label }}</code>
<span class="package__version">{{ node.data.version }}</span>
</div>
</ng-template>
</wr-graph>Accessibility
Each node reads out its parents and children. Give every graph on a page its own ariaLabel.
What it does not do
No selection, zoom, editing or edge labels. Content larger than its node box spills over, so size the box.
API
| Name | Description | Type | Default |
|---|---|---|---|
nodes | The nodes, in any order. Input order breaks layout ties, so the same arrays always produce the same picture. Never mutated. | readonly WrGraphNode<TData>[] | [] |
edges | Parent-child links, from the parent and to the child. Never mutated. | readonly WrGraphEdge[] | [] |
nodeWidth | Width in pixels of a node that sets none of its own. | number | 160 |
nodeHeight | Height in pixels of a node that sets none of its own. | number | 48 |
ariaLabel | Accessible name of the scrolling viewport. Falls back to graph.label, then 'Graph'. | string | null | null |
Types
| Name | Description | Type | Default |
|---|---|---|---|
WrGraphNode | One block. TData is whatever data carries. | interface | — |
idrequired | Unique within the graph. A repeated id is skipped after its first occurrence, with a warning in dev mode. | string | — |
labelrequired | The node’s name, read by screen readers; render it in a custom template. | string | — |
width | Width in pixels. Falls back to nodeWidth when absent, non-finite or not positive. | number | — |
height | Height in pixels. Falls back to nodeHeight when absent, non-finite or not positive. | number | — |
data | Anything the node template needs. Never read by the graph or its layout. | TData | — |
WrGraphEdge | A parent-child link; repeated edges and cycles are allowed. | interface | — |
fromrequired | Id of the parent. An edge naming a node that does not exist is skipped, with a warning in dev mode. | string | — |
torequired | Id of the child. | string | — |
WrGraphNodeContext | What an ng-template wrGraphNode receives. | interface | — |
$implicitrequired | The node, bound with let-node. | WrGraphNode<TData> | — |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/graph's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-graph-background | var(--wr-color-surface) | .wr-graph |
--wr-graph-card-background | var(--wr-color-surface) | .wr-graph |
--wr-graph-card-border | var(--wr-border-base) | .wr-graph |
--wr-graph-card-color | var(--wr-color-on-surface) | .wr-graph |
--wr-graph-card-font-size | var(--wr-text-sm) | .wr-graph |
--wr-graph-card-line-height | var(--wr-leading-tight) | .wr-graph |
--wr-graph-card-padding | var(--wr-space-sm) var(--wr-space-md) | .wr-graph |
--wr-graph-card-radius | var(--wr-border-radius-base) | .wr-graph |
--wr-graph-edge-color | color-mix(in srgb, var(--wr-color-on-surface-muted) 60%, var(--wr-color-surface)) | .wr-graph |
--wr-graph-edge-width | 1px | .wr-graph |
--wr-graph-font-family | var(--wr-font-family-base) | .wr-graph |
--wr-graph-padding | var(--wr-space-lg) | .wr-graph |
--wr-graph-viewport-radius | var(--wr-border-radius-base) | .wr-graph |