@hpcc-js/wasm-graphviz 1.24.0 → 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 +75 -43
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +3 -3
- package/src/graphviz.ts +276 -40
- package/src/types.ts +6 -0
- package/types/graphviz.d.ts +100 -27
- package/types/graphvizlib.d.ts +52 -0
- package/types/types.d.ts +3 -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
|
|
@@ -37,8 +39,15 @@ document.body.innerHTML = svg;
|
|
|
37
39
|
## Programmatic Graph Construction
|
|
38
40
|
|
|
39
41
|
Instead of writing DOT source by hand you can build graphs programmatically using
|
|
40
|
-
`createGraph`.
|
|
41
|
-
`graph.layout()` or serialised to DOT first with `graph.toDot()`.
|
|
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).
|
|
42
51
|
|
|
43
52
|
### Basic usage
|
|
44
53
|
|
|
@@ -51,18 +60,24 @@ const graphviz = await Graphviz.load();
|
|
|
51
60
|
using graph = graphviz.createGraph("G");
|
|
52
61
|
|
|
53
62
|
graph
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
.addNode("a")
|
|
64
|
+
.addNode("b")
|
|
65
|
+
.addEdge("a", "b")
|
|
66
|
+
.setNodeAttr("a", "shape", "box")
|
|
67
|
+
.setNodeAttr("a", "color", "red")
|
|
68
|
+
.setGraphAttr("rankdir", "LR");
|
|
60
69
|
|
|
61
70
|
// Render directly — no DOT round-trip needed
|
|
62
71
|
const svg = graph.layout("svg", "dot");
|
|
63
72
|
document.body.innerHTML = svg;
|
|
64
73
|
```
|
|
65
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
|
+
|
|
66
81
|
### Graph types
|
|
67
82
|
|
|
68
83
|
```typescript
|
|
@@ -89,14 +104,14 @@ const svg2 = graph.layout(); // updated render
|
|
|
89
104
|
|
|
90
105
|
The full set of mutation methods on `Graph`:
|
|
91
106
|
|
|
92
|
-
| Method
|
|
93
|
-
|
|
94
|
-
| `removeNode(name)`
|
|
95
|
-
| `removeEdge(tail, head, key?)`
|
|
96
|
-
| `removeSubgraph(name)`
|
|
97
|
-
| `removeGraphAttr(attr)`
|
|
98
|
-
| `removeNodeAttr(node, attr)`
|
|
99
|
-
| `removeEdgeAttr(tail, head, key, attr)` | Resets an edge attribute to its default
|
|
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 |
|
|
100
115
|
|
|
101
116
|
`Subgraph` has the same `removeNode` / `removeEdge` pair (scoped to the
|
|
102
117
|
subgraph only — root graph is unaffected) plus `removeAttr` /
|
|
@@ -115,19 +130,19 @@ graph.addNode("alice");
|
|
|
115
130
|
graph.addEdge("alice", "bob");
|
|
116
131
|
graph.addSubgraph("cluster_a");
|
|
117
132
|
|
|
118
|
-
graph.hasNode("alice");
|
|
119
|
-
graph.hasNode("charlie");
|
|
120
|
-
graph.hasEdge("alice", "bob");
|
|
121
|
-
graph.hasEdge("bob", "alice");
|
|
122
|
-
graph.hasSubgraph("cluster_a");
|
|
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
|
|
123
138
|
```
|
|
124
139
|
|
|
125
140
|
#### Count queries
|
|
126
141
|
|
|
127
142
|
```typescript
|
|
128
|
-
graph.nodeCount();
|
|
129
|
-
graph.edgeCount();
|
|
130
|
-
graph.subgraphCount();
|
|
143
|
+
graph.nodeCount(); // number of nodes
|
|
144
|
+
graph.edgeCount(); // number of edges
|
|
145
|
+
graph.subgraphCount(); // number of direct subgraphs
|
|
131
146
|
```
|
|
132
147
|
|
|
133
148
|
#### Reading attributes
|
|
@@ -137,10 +152,26 @@ graph.setNodeAttr("alice", "color", "red");
|
|
|
137
152
|
graph.setEdgeAttr("alice", "bob", "", "label", "hello");
|
|
138
153
|
graph.setGraphAttr("rankdir", "LR");
|
|
139
154
|
|
|
140
|
-
graph.getNodeAttr("alice", "color");
|
|
155
|
+
graph.getNodeAttr("alice", "color"); // "red"
|
|
141
156
|
graph.getEdgeAttr("alice", "bob", "", "label"); // "hello"
|
|
142
|
-
graph.getGraphAttr("rankdir");
|
|
143
|
-
graph.getNodeAttr("alice", "missing");
|
|
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>");
|
|
144
175
|
```
|
|
145
176
|
|
|
146
177
|
#### Node / edge / subgraph lists
|
|
@@ -151,9 +182,9 @@ const nodes = graph.nodeNames();
|
|
|
151
182
|
const subgraphs = graph.subgraphNames();
|
|
152
183
|
|
|
153
184
|
// Returns EdgeInfo[] — { tail: string, head: string, key: string }
|
|
154
|
-
const allEdges = graph.edges();
|
|
185
|
+
const allEdges = graph.edges(); // every edge exactly once
|
|
155
186
|
const outgoing = graph.outEdges("alice"); // edges leaving alice
|
|
156
|
-
const incoming = graph.inEdges("bob");
|
|
187
|
+
const incoming = graph.inEdges("bob"); // edges entering bob
|
|
157
188
|
const incident = graph.nodeEdges("alice"); // all edges on alice (in + out)
|
|
158
189
|
```
|
|
159
190
|
|
|
@@ -171,12 +202,12 @@ using graph = graphviz.createGraph("G");
|
|
|
171
202
|
|
|
172
203
|
// Each Subgraph wrapper also needs to be deleted (or use `using`)
|
|
173
204
|
{
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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");
|
|
180
211
|
}
|
|
181
212
|
|
|
182
213
|
const svg = graph.layout();
|
|
@@ -184,14 +215,15 @@ const svg = graph.layout();
|
|
|
184
215
|
|
|
185
216
|
### Memory management
|
|
186
217
|
|
|
187
|
-
Every `Graph` and `Subgraph` wraps a native WASM object.
|
|
218
|
+
Every `Graph` and `Subgraph` wraps a native WASM object. You must release it
|
|
188
219
|
when finished to avoid memory leaks:
|
|
189
220
|
|
|
190
221
|
- **Preferred — `using` keyword** (TypeScript ≥ 5.2 with `"target": "ES2022"` or later):
|
|
222
|
+
|
|
191
223
|
```typescript
|
|
192
224
|
{
|
|
193
|
-
|
|
194
|
-
|
|
225
|
+
using graph = graphviz.createGraph("G");
|
|
226
|
+
// ... graph is automatically deleted when the block exits
|
|
195
227
|
}
|
|
196
228
|
```
|
|
197
229
|
|
|
@@ -199,13 +231,13 @@ when finished to avoid memory leaks:
|
|
|
199
231
|
```typescript
|
|
200
232
|
const graph = graphviz.createGraph("G");
|
|
201
233
|
try {
|
|
202
|
-
|
|
234
|
+
// ...
|
|
203
235
|
} finally {
|
|
204
|
-
|
|
236
|
+
graph.delete();
|
|
205
237
|
}
|
|
206
238
|
```
|
|
207
239
|
|
|
208
|
-
Subgraph wrappers follow the same rule.
|
|
240
|
+
Subgraph wrappers follow the same rule. The underlying subgraph _data_ is
|
|
209
241
|
owned by the parent `Graph` and freed automatically when the parent is deleted;
|
|
210
242
|
only the thin JS wrapper needs an explicit `delete()` / `using` block.
|
|
211
243
|
|
|
@@ -213,4 +245,4 @@ only the thin JS wrapper needs an explicit `delete()` / `using` block.
|
|
|
213
245
|
|
|
214
246
|
## Reference
|
|
215
247
|
|
|
216
|
-
|
|
248
|
+
- [API Documentation](https://hpcc-systems.github.io/hpcc-js-wasm/docs/graphviz/src/graphviz/classes/Graphviz.html)
|