@hpcc-js/wasm-graphviz 1.22.1 → 1.24.0

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 CHANGED
@@ -34,8 +34,183 @@ const svg = graphviz.dot(`digraph { a -> b; }`);
34
34
  document.body.innerHTML = svg;
35
35
  ```
36
36
 
37
+ ## Programmatic Graph Construction
38
+
39
+ Instead of writing DOT source by hand you can build graphs programmatically using
40
+ `createGraph`. The resulting `Graph` object can be rendered directly via
41
+ `graph.layout()` or serialised to DOT first with `graph.toDot()`.
42
+
43
+ ### Basic usage
44
+
45
+ ```typescript
46
+ import { Graphviz } from "@hpcc-js/wasm-graphviz";
47
+
48
+ const graphviz = await Graphviz.load();
49
+
50
+ // createGraph returns a Graph; always call delete() when done (or use `using`)
51
+ using graph = graphviz.createGraph("G");
52
+
53
+ graph
54
+ .addNode("a")
55
+ .addNode("b")
56
+ .addEdge("a", "b")
57
+ .setNodeAttr("a", "shape", "box")
58
+ .setNodeAttr("a", "color", "red")
59
+ .setGraphAttr("rankdir", "LR");
60
+
61
+ // Render directly — no DOT round-trip needed
62
+ const svg = graph.layout("svg", "dot");
63
+ document.body.innerHTML = svg;
64
+ ```
65
+
66
+ ### Graph types
67
+
68
+ ```typescript
69
+ // "directed" (default) | "undirected" | "strict directed" | "strict undirected"
70
+ using graph = graphviz.createGraph("G", "undirected");
71
+ graph.addEdge("x", "y");
72
+ ```
73
+
74
+ ### Mutating a graph between layouts
75
+
76
+ Nodes, edges, subgraphs, and attributes can all be removed after an initial
77
+ `layout()` call, allowing the graph to be updated and re-rendered without
78
+ rebuilding from scratch.
79
+
80
+ ```typescript
81
+ using graph = graphviz.createGraph("G");
82
+ graph.addEdge("a", "b").addEdge("b", "c");
83
+ const svg1 = graph.layout(); // initial render
84
+
85
+ // Remove the middle node (also removes its edges), add a direct edge
86
+ graph.removeNode("b").addEdge("a", "c");
87
+ const svg2 = graph.layout(); // updated render
88
+ ```
89
+
90
+ The full set of mutation methods on `Graph`:
91
+
92
+ | Method | Effect |
93
+ |---|---|
94
+ | `removeNode(name)` | Removes the node and all its edges from the root graph |
95
+ | `removeEdge(tail, head, key?)` | Removes a single edge |
96
+ | `removeSubgraph(name)` | Dissolves a cluster boundary (nodes/edges remain in the root graph) |
97
+ | `removeGraphAttr(attr)` | Resets a graph-level attribute to its default |
98
+ | `removeNodeAttr(node, attr)` | Resets a node attribute to its default |
99
+ | `removeEdgeAttr(tail, head, key, attr)` | Resets an edge attribute to its default |
100
+
101
+ `Subgraph` has the same `removeNode` / `removeEdge` pair (scoped to the
102
+ subgraph only — root graph is unaffected) plus `removeAttr` /
103
+ `removeNodeAttr` / `removeEdgeAttr`.
104
+
105
+ ### Existence checks and graph traversal
106
+
107
+ `Graph` and `Subgraph` expose methods for querying membership and iterating
108
+ the contents of a graph without serialising to DOT.
109
+
110
+ #### Existence checks
111
+
112
+ ```typescript
113
+ using graph = graphviz.createGraph("G");
114
+ graph.addNode("alice");
115
+ graph.addEdge("alice", "bob");
116
+ graph.addSubgraph("cluster_a");
117
+
118
+ graph.hasNode("alice"); // true
119
+ graph.hasNode("charlie"); // false
120
+ graph.hasEdge("alice", "bob"); // true (key defaults to "")
121
+ graph.hasEdge("bob", "alice"); // false (directed)
122
+ graph.hasSubgraph("cluster_a"); // true
123
+ ```
124
+
125
+ #### Count queries
126
+
127
+ ```typescript
128
+ graph.nodeCount(); // number of nodes
129
+ graph.edgeCount(); // number of edges
130
+ graph.subgraphCount(); // number of direct subgraphs
131
+ ```
132
+
133
+ #### Reading attributes
134
+
135
+ ```typescript
136
+ graph.setNodeAttr("alice", "color", "red");
137
+ graph.setEdgeAttr("alice", "bob", "", "label", "hello");
138
+ graph.setGraphAttr("rankdir", "LR");
139
+
140
+ graph.getNodeAttr("alice", "color"); // "red"
141
+ graph.getEdgeAttr("alice", "bob", "", "label"); // "hello"
142
+ graph.getGraphAttr("rankdir"); // "LR"
143
+ graph.getNodeAttr("alice", "missing"); // "" (unknown attr)
144
+ ```
145
+
146
+ #### Node / edge / subgraph lists
147
+
148
+ ```typescript
149
+ // Returns string[]
150
+ const nodes = graph.nodeNames();
151
+ const subgraphs = graph.subgraphNames();
152
+
153
+ // Returns EdgeInfo[] — { tail: string, head: string, key: string }
154
+ const allEdges = graph.edges(); // every edge exactly once
155
+ const outgoing = graph.outEdges("alice"); // edges leaving alice
156
+ const incoming = graph.inEdges("bob"); // edges entering bob
157
+ const incident = graph.nodeEdges("alice"); // all edges on alice (in + out)
158
+ ```
159
+
160
+ `Subgraph` exposes the same traversal API (scoped to the subgraph's node/edge
161
+ set), except `hasSubgraph` / `subgraphCount` / `subgraphNames` which are only
162
+ on `Graph`.
163
+
164
+ ### Subgraphs and clusters
165
+
166
+ Names beginning with `"cluster"` are drawn as bounded rectangles by most
167
+ layout engines.
168
+
169
+ ```typescript
170
+ using graph = graphviz.createGraph("G");
171
+
172
+ // Each Subgraph wrapper also needs to be deleted (or use `using`)
173
+ {
174
+ using cluster = graph.addSubgraph("cluster_0");
175
+ cluster
176
+ .setAttr("label", "My Cluster")
177
+ .setAttr("style", "filled")
178
+ .setAttr("color", "lightblue")
179
+ .addEdge("a", "b");
180
+ }
181
+
182
+ const svg = graph.layout();
183
+ ```
184
+
185
+ ### Memory management
186
+
187
+ Every `Graph` and `Subgraph` wraps a native WASM object. You must release it
188
+ when finished to avoid memory leaks:
189
+
190
+ - **Preferred — `using` keyword** (TypeScript ≥ 5.2 with `"target": "ES2022"` or later):
191
+ ```typescript
192
+ {
193
+ using graph = graphviz.createGraph("G");
194
+ // ... graph is automatically deleted when the block exits
195
+ }
196
+ ```
197
+
198
+ - **Manual `delete()`**:
199
+ ```typescript
200
+ const graph = graphviz.createGraph("G");
201
+ try {
202
+ // ...
203
+ } finally {
204
+ graph.delete();
205
+ }
206
+ ```
207
+
208
+ Subgraph wrappers follow the same rule. The underlying subgraph _data_ is
209
+ owned by the parent `Graph` and freed automatically when the parent is deleted;
210
+ only the thin JS wrapper needs an explicit `delete()` / `using` block.
211
+
37
212
  <!--@include: ../../docs/graphviz/src/graphviz/README.md-->
38
213
 
39
214
  ## Reference
40
215
 
41
- * [API Documentation](https://hpcc-systems.github.io/hpcc-js-wasm/graphviz/src/graphviz/classes/Graphviz.html)
216
+ * [API Documentation](https://hpcc-systems.github.io/hpcc-js-wasm/docs/graphviz/src/graphviz/classes/Graphviz.html)