@hpcc-js/wasm-graphviz 1.22.2 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +209 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +3 -3
- package/src/graphviz.ts +934 -3
- package/src/index.ts +1 -1
- package/src/types.ts +613 -0
- package/types/graphviz.d.ts +518 -2
- package/types/graphvizlib.d.ts +115 -0
- package/types/types.d.ts +302 -0
package/README.md
CHANGED
|
@@ -6,11 +6,12 @@ outline: deep
|
|
|
6
6
|
|
|
7
7
|
# @hpcc-js/wasm-graphviz
|
|
8
8
|
|
|
9
|
-
This package provides a WebAssembly wrapper around the [Graphviz](https://www.graphviz.org/) library.
|
|
9
|
+
This package provides a WebAssembly wrapper around the [Graphviz](https://www.graphviz.org/) library. This allows for the rendering of DOT language graphs directly within a browser or NodeJS type environment.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
13
|
::: code-group
|
|
14
|
+
|
|
14
15
|
```sh [npm]
|
|
15
16
|
npm install @hpcc-js/wasm-graphviz
|
|
16
17
|
```
|
|
@@ -22,6 +23,7 @@ yarn add @hpcc-js/wasm-graphviz
|
|
|
22
23
|
```sh [pnpm]
|
|
23
24
|
pnpm add @hpcc-js/wasm-graphviz
|
|
24
25
|
```
|
|
26
|
+
|
|
25
27
|
:::
|
|
26
28
|
|
|
27
29
|
## Quick Start
|
|
@@ -34,8 +36,213 @@ const svg = graphviz.dot(`digraph { a -> b; }`);
|
|
|
34
36
|
document.body.innerHTML = svg;
|
|
35
37
|
```
|
|
36
38
|
|
|
39
|
+
## Programmatic Graph Construction
|
|
40
|
+
|
|
41
|
+
Instead of writing DOT source by hand you can build graphs programmatically using
|
|
42
|
+
`createGraph`. The resulting `Graph` object can be rendered directly via
|
|
43
|
+
`graph.layout()` or serialised to DOT first with `graph.write()` / `graph.toDot()`.
|
|
44
|
+
|
|
45
|
+
Attribute names and values follow Graphviz itself; see the official Graphviz
|
|
46
|
+
[attribute reference](https://graphviz.org/docs/attrs/) for the supported graph,
|
|
47
|
+
node, edge, and cluster attributes.
|
|
48
|
+
|
|
49
|
+
Existing DOT can also be parsed into a mutable graph with `read`, and any
|
|
50
|
+
programmatic graph can be written back to DOT with `write` (`toDot` is an alias).
|
|
51
|
+
|
|
52
|
+
### Basic usage
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { Graphviz } from "@hpcc-js/wasm-graphviz";
|
|
56
|
+
|
|
57
|
+
const graphviz = await Graphviz.load();
|
|
58
|
+
|
|
59
|
+
// createGraph returns a Graph; always call delete() when done (or use `using`)
|
|
60
|
+
using graph = graphviz.createGraph("G");
|
|
61
|
+
|
|
62
|
+
graph
|
|
63
|
+
.addNode("a")
|
|
64
|
+
.addNode("b")
|
|
65
|
+
.addEdge("a", "b")
|
|
66
|
+
.setNodeAttr("a", "shape", "box")
|
|
67
|
+
.setNodeAttr("a", "color", "red")
|
|
68
|
+
.setGraphAttr("rankdir", "LR");
|
|
69
|
+
|
|
70
|
+
// Render directly — no DOT round-trip needed
|
|
71
|
+
const svg = graph.layout("svg", "dot");
|
|
72
|
+
document.body.innerHTML = svg;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
using graph = graphviz.read(`digraph G { a -> b [label="hello"] }`);
|
|
77
|
+
graph.setGraphAttr("rankdir", "LR");
|
|
78
|
+
const dot = graph.write();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Graph types
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// "directed" (default) | "undirected" | "strict directed" | "strict undirected"
|
|
85
|
+
using graph = graphviz.createGraph("G", "undirected");
|
|
86
|
+
graph.addEdge("x", "y");
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Mutating a graph between layouts
|
|
90
|
+
|
|
91
|
+
Nodes, edges, subgraphs, and attributes can all be removed after an initial
|
|
92
|
+
`layout()` call, allowing the graph to be updated and re-rendered without
|
|
93
|
+
rebuilding from scratch.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
using graph = graphviz.createGraph("G");
|
|
97
|
+
graph.addEdge("a", "b").addEdge("b", "c");
|
|
98
|
+
const svg1 = graph.layout(); // initial render
|
|
99
|
+
|
|
100
|
+
// Remove the middle node (also removes its edges), add a direct edge
|
|
101
|
+
graph.removeNode("b").addEdge("a", "c");
|
|
102
|
+
const svg2 = graph.layout(); // updated render
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The full set of mutation methods on `Graph`:
|
|
106
|
+
|
|
107
|
+
| Method | Effect |
|
|
108
|
+
| --------------------------------------- | ------------------------------------------------------------------- |
|
|
109
|
+
| `removeNode(name)` | Removes the node and all its edges from the root graph |
|
|
110
|
+
| `removeEdge(tail, head, key?)` | Removes a single edge |
|
|
111
|
+
| `removeSubgraph(name)` | Dissolves a cluster boundary (nodes/edges remain in the root graph) |
|
|
112
|
+
| `removeGraphAttr(attr)` | Resets a graph-level attribute to its default |
|
|
113
|
+
| `removeNodeAttr(node, attr)` | Resets a node attribute to its default |
|
|
114
|
+
| `removeEdgeAttr(tail, head, key, attr)` | Resets an edge attribute to its default |
|
|
115
|
+
|
|
116
|
+
`Subgraph` has the same `removeNode` / `removeEdge` pair (scoped to the
|
|
117
|
+
subgraph only — root graph is unaffected) plus `removeAttr` /
|
|
118
|
+
`removeNodeAttr` / `removeEdgeAttr`.
|
|
119
|
+
|
|
120
|
+
### Existence checks and graph traversal
|
|
121
|
+
|
|
122
|
+
`Graph` and `Subgraph` expose methods for querying membership and iterating
|
|
123
|
+
the contents of a graph without serialising to DOT.
|
|
124
|
+
|
|
125
|
+
#### Existence checks
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
using graph = graphviz.createGraph("G");
|
|
129
|
+
graph.addNode("alice");
|
|
130
|
+
graph.addEdge("alice", "bob");
|
|
131
|
+
graph.addSubgraph("cluster_a");
|
|
132
|
+
|
|
133
|
+
graph.hasNode("alice"); // true
|
|
134
|
+
graph.hasNode("charlie"); // false
|
|
135
|
+
graph.hasEdge("alice", "bob"); // true (key defaults to "")
|
|
136
|
+
graph.hasEdge("bob", "alice"); // false (directed)
|
|
137
|
+
graph.hasSubgraph("cluster_a"); // true
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Count queries
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
graph.nodeCount(); // number of nodes
|
|
144
|
+
graph.edgeCount(); // number of edges
|
|
145
|
+
graph.subgraphCount(); // number of direct subgraphs
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Reading attributes
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
graph.setNodeAttr("alice", "color", "red");
|
|
152
|
+
graph.setEdgeAttr("alice", "bob", "", "label", "hello");
|
|
153
|
+
graph.setGraphAttr("rankdir", "LR");
|
|
154
|
+
|
|
155
|
+
graph.getNodeAttr("alice", "color"); // "red"
|
|
156
|
+
graph.getEdgeAttr("alice", "bob", "", "label"); // "hello"
|
|
157
|
+
graph.getGraphAttr("rankdir"); // "LR"
|
|
158
|
+
graph.getNodeAttr("alice", "missing"); // "" (unknown attr)
|
|
159
|
+
|
|
160
|
+
// Omit the value to reset an attribute to Graphviz's default empty value.
|
|
161
|
+
graph.setNodeAttr("alice", "color");
|
|
162
|
+
graph.getNodeAttr("alice", "color"); // ""
|
|
163
|
+
|
|
164
|
+
// Pass a final defaultValue argument to declare Graphviz's default for unset objects.
|
|
165
|
+
graph.addNode("charlie");
|
|
166
|
+
graph.setNodeAttr("alice", "color", "red", "blue");
|
|
167
|
+
graph.getNodeAttr("charlie", "color"); // "blue"
|
|
168
|
+
|
|
169
|
+
// Or declare defaults directly for graph, node, and edge attributes.
|
|
170
|
+
graph.setDefaultNodeAttr("shape", "box");
|
|
171
|
+
graph.setDefaultEdgeAttr("color", "red");
|
|
172
|
+
|
|
173
|
+
// Use HTML-like attributes for Graphviz HTML labels.
|
|
174
|
+
graph.setNodeHtmlAttr("alice", "label", "<B>Alice</B>");
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Node / edge / subgraph lists
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// Returns string[]
|
|
181
|
+
const nodes = graph.nodeNames();
|
|
182
|
+
const subgraphs = graph.subgraphNames();
|
|
183
|
+
|
|
184
|
+
// Returns EdgeInfo[] — { tail: string, head: string, key: string }
|
|
185
|
+
const allEdges = graph.edges(); // every edge exactly once
|
|
186
|
+
const outgoing = graph.outEdges("alice"); // edges leaving alice
|
|
187
|
+
const incoming = graph.inEdges("bob"); // edges entering bob
|
|
188
|
+
const incident = graph.nodeEdges("alice"); // all edges on alice (in + out)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`Subgraph` exposes the same traversal API (scoped to the subgraph's node/edge
|
|
192
|
+
set), except `hasSubgraph` / `subgraphCount` / `subgraphNames` which are only
|
|
193
|
+
on `Graph`.
|
|
194
|
+
|
|
195
|
+
### Subgraphs and clusters
|
|
196
|
+
|
|
197
|
+
Names beginning with `"cluster"` are drawn as bounded rectangles by most
|
|
198
|
+
layout engines.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
using graph = graphviz.createGraph("G");
|
|
202
|
+
|
|
203
|
+
// Each Subgraph wrapper also needs to be deleted (or use `using`)
|
|
204
|
+
{
|
|
205
|
+
using cluster = graph.addSubgraph("cluster_0");
|
|
206
|
+
cluster
|
|
207
|
+
.setAttr("label", "My Cluster")
|
|
208
|
+
.setAttr("style", "filled")
|
|
209
|
+
.setAttr("color", "lightblue")
|
|
210
|
+
.addEdge("a", "b");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const svg = graph.layout();
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Memory management
|
|
217
|
+
|
|
218
|
+
Every `Graph` and `Subgraph` wraps a native WASM object. You must release it
|
|
219
|
+
when finished to avoid memory leaks:
|
|
220
|
+
|
|
221
|
+
- **Preferred — `using` keyword** (TypeScript ≥ 5.2 with `"target": "ES2022"` or later):
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
{
|
|
225
|
+
using graph = graphviz.createGraph("G");
|
|
226
|
+
// ... graph is automatically deleted when the block exits
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
- **Manual `delete()`**:
|
|
231
|
+
```typescript
|
|
232
|
+
const graph = graphviz.createGraph("G");
|
|
233
|
+
try {
|
|
234
|
+
// ...
|
|
235
|
+
} finally {
|
|
236
|
+
graph.delete();
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Subgraph wrappers follow the same rule. The underlying subgraph _data_ is
|
|
241
|
+
owned by the parent `Graph` and freed automatically when the parent is deleted;
|
|
242
|
+
only the thin JS wrapper needs an explicit `delete()` / `using` block.
|
|
243
|
+
|
|
37
244
|
<!--@include: ../../docs/graphviz/src/graphviz/README.md-->
|
|
38
245
|
|
|
39
246
|
## Reference
|
|
40
247
|
|
|
41
|
-
|
|
248
|
+
- [API Documentation](https://hpcc-systems.github.io/hpcc-js-wasm/docs/graphviz/src/graphviz/classes/Graphviz.html)
|