@hpcc-js/wasm-graphviz 1.24.1 → 1.26.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hpcc-js/wasm-graphviz",
3
- "version": "1.24.1",
3
+ "version": "1.26.0",
4
4
  "description": "hpcc-js - WASM Graphviz",
5
5
  "type": "module",
6
6
  "exports": {
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "scripts": {
20
20
  "clean": "rimraf coverage dist dist-test types .nyc_output",
21
- "gen-types": "tsgo --project tsconfig.json --emitDeclarationOnly",
21
+ "gen-types": "tsc --project tsconfig.json --emitDeclarationOnly",
22
22
  "gen-types-watch": "npm run gen-types -- --watch",
23
23
  "bundle": "node esbuild.js",
24
24
  "bundle-dev": "npm run bundle -- --development",
@@ -56,5 +56,5 @@
56
56
  },
57
57
  "homepage": "https://hpcc-systems.github.io/hpcc-js-wasm/",
58
58
  "license": "Apache-2.0",
59
- "gitHead": "66515f510e2045ad74b336a52f3ab55974ebed9e"
59
+ "gitHead": "b173ceec45fa54ec60a1642655d4f785ade8165c"
60
60
  }
package/src/graphviz.ts CHANGED
@@ -5,13 +5,25 @@ import type {
5
5
  NodeDotAttr, NodeAttrs,
6
6
  EdgeDotAttr, EdgeAttrs,
7
7
  ClusterDotAttr, ClusterAttrs,
8
- GraphDotAttr, GraphAttrs as GraphAttrs
8
+ GraphDotAttr, GraphAttrs,
9
+ Format, Engine
9
10
  } from "./types.ts";
10
11
 
11
- /**
12
- * Various graphic and data formats for end user, web, documents and other applications. See [Output Formats](https://graphviz.org/docs/outputs/) for more information.
13
- */
14
- export type Format = "svg" | "svg_inline" | "dot" | "json" | "dot_json" | "xdot_json" | "plain" | "plain-ext" | "canon";
12
+ type AttrValues<T> = Partial<{ [K in keyof T]: NonNullable<T[K]> }>;
13
+
14
+ function applyAttrs<T extends object>(
15
+ attrs: AttrValues<T> | undefined,
16
+ apply: (attr: string, value: string | number | boolean) => void
17
+ ): void {
18
+ if (!attrs) {
19
+ return;
20
+ }
21
+ for (const [attr, value] of Object.entries(attrs)) {
22
+ if (value !== undefined) {
23
+ apply(attr, value as string | number | boolean);
24
+ }
25
+ }
26
+ }
15
27
 
16
28
  /**
17
29
  * An edge returned by graph-traversal methods.
@@ -42,11 +54,6 @@ function parseEdges(json: string): EdgeInfo[] {
42
54
  return result;
43
55
  }
44
56
 
45
- /**
46
- * Various algorithms for projecting abstract graphs into a space for visualization. See [Layout Engines](https://graphviz.org/docs/layouts/) for more details.
47
- */
48
- export type Engine = "circo" | "dot" | "fdp" | "sfdp" | "neato" | "osage" | "patchwork" | "twopi" | "nop" | "nop2";
49
-
50
57
  /**
51
58
  * Example: Passing a web hosted Image to GraphViz:
52
59
  * ```ts
@@ -117,10 +124,39 @@ let g_graphviz: Promise<Graphviz> | undefined;
117
124
  */
118
125
  export type GraphType = "directed" | "undirected" | "strict directed" | "strict undirected";
119
126
 
127
+ export interface GraphInit {
128
+ name?: string;
129
+ type?: GraphType;
130
+ attrs?: AttrValues<GraphAttrs>;
131
+ htmlAttrs?: AttrValues<GraphAttrs>;
132
+ }
133
+
134
+ export interface NodeInit {
135
+ name: string;
136
+ attrs?: AttrValues<NodeAttrs>;
137
+ htmlAttrs?: AttrValues<NodeAttrs>;
138
+ }
139
+
140
+ export interface EdgeInit {
141
+ tail: string;
142
+ head: string;
143
+ key?: string;
144
+ attrs?: AttrValues<EdgeAttrs>;
145
+ htmlAttrs?: AttrValues<EdgeAttrs>;
146
+ }
147
+
148
+ export interface SubgraphInit {
149
+ name: string;
150
+ attrs?: AttrValues<ClusterAttrs>;
151
+ htmlAttrs?: AttrValues<ClusterAttrs>;
152
+ }
153
+
154
+ export type ClusterInit = SubgraphInit;
155
+
120
156
  /**
121
157
  * A subgraph (or cluster) inside a {@link Graph}.
122
158
  *
123
- * Obtain via {@link Graph.addSubgraph}. All mutation methods return `this`
159
+ * Obtain via {@link Graph.addSubgraph} or {@link Subgraph.addSubgraph}. All mutation methods return `this`
124
160
  * for chaining. **Call {@link Subgraph.delete} (or use the `using` keyword)
125
161
  * when finished** to free the underlying WASM wrapper — the actual subgraph
126
162
  * data is owned by the parent {@link Graph} and is freed with it.
@@ -148,8 +184,15 @@ export class Subgraph {
148
184
  /**
149
185
  * Create (or find) a node and add it to this subgraph.
150
186
  */
151
- addNode(name: string): this {
187
+ addNode(name: string): this;
188
+ addNode(init: NodeInit): this;
189
+ addNode(nameOrInit: string | NodeInit): this {
190
+ const init = typeof nameOrInit === "string" ? { name: nameOrInit } : nameOrInit;
191
+ const { name, attrs, htmlAttrs } = init;
192
+
152
193
  this._sg.addNode(name);
194
+ applyAttrs<NodeAttrs>(attrs, (attr, value) => this.setNodeAttr(name, attr, value));
195
+ applyAttrs<NodeAttrs>(htmlAttrs, (attr, value) => this.setNodeHtmlAttr(name, attr, value));
153
196
  return this;
154
197
  }
155
198
 
@@ -157,8 +200,35 @@ export class Subgraph {
157
200
  * Create an edge inside this subgraph. Both endpoints are created
158
201
  * automatically if they do not already exist.
159
202
  */
160
- addEdge(tail: string, head: string, key: string = ""): this {
161
- this._sg.addEdge(tail, head, key);
203
+ addEdge(tail: string, head: string, key?: string): this;
204
+ addEdge(init: EdgeInit): this;
205
+ addEdge(tailOrInit: string | EdgeInit, head?: string, key: string = ""): this {
206
+ const init = typeof tailOrInit === "string"
207
+ ? { tail: tailOrInit, head: head!, key }
208
+ : tailOrInit;
209
+ const { tail, head: resolvedHead, key: resolvedKey = "", attrs, htmlAttrs } = init;
210
+
211
+ this._sg.addEdge(tail, resolvedHead, resolvedKey);
212
+ applyAttrs<EdgeAttrs>(attrs, (attr, value) => this.setEdgeAttr(tail, resolvedHead, resolvedKey, attr, value));
213
+ applyAttrs<EdgeAttrs>(htmlAttrs, (attr, value) => this.setEdgeHtmlAttr(tail, resolvedHead, resolvedKey, attr, value));
214
+ return this;
215
+ }
216
+
217
+ /**
218
+ * Create (or return an existing) named subgraph under this subgraph.
219
+ */
220
+ addSubgraph(name: string): Subgraph;
221
+ addSubgraph(init: SubgraphInit): Subgraph;
222
+ addSubgraph(nameOrInit: string | SubgraphInit): Subgraph {
223
+ const init = typeof nameOrInit === "string" ? { name: nameOrInit } : nameOrInit;
224
+ // addSubgraph only returns null when the internal subgraph pointer is null,
225
+ // which cannot happen while this Subgraph instance is alive.
226
+ return new Subgraph(this._sg.addSubgraph(init.name)!).applyInit(init);
227
+ }
228
+
229
+ applyInit(init: SubgraphInit): this {
230
+ applyAttrs<ClusterAttrs>(init.attrs, (attr, value) => this.setAttr(attr, value));
231
+ applyAttrs<ClusterAttrs>(init.htmlAttrs, (attr, value) => this.setHtmlAttr(attr, value));
162
232
  return this;
163
233
  }
164
234
 
@@ -493,12 +563,30 @@ export class Graph {
493
563
  this._module = module;
494
564
  }
495
565
 
566
+ private ensureDefaultFonts(includeNodeAndEdgeDefaults: boolean): void {
567
+ if (this.getGraphAttr("fontname") === "") {
568
+ this.setGraphAttr("fontname", "Arial");
569
+ }
570
+ this.setDefaultGraphAttr("fontname", "Arial");
571
+ if (includeNodeAndEdgeDefaults) {
572
+ this.setDefaultNodeAttr("fontname", "Arial");
573
+ this.setDefaultEdgeAttr("fontname", "Arial");
574
+ }
575
+ }
576
+
496
577
  /**
497
578
  * Create a node. If a node with this name already exists it is returned
498
579
  * unchanged.
499
580
  */
500
- addNode(name: string): this {
581
+ addNode(name: string): this;
582
+ addNode(init: NodeInit): this;
583
+ addNode(nameOrInit: string | NodeInit): this {
584
+ const init = typeof nameOrInit === "string" ? { name: nameOrInit } : nameOrInit;
585
+ const { name, attrs, htmlAttrs } = init;
586
+
501
587
  this._graph.addNode(name);
588
+ applyAttrs<NodeAttrs>(attrs, (attr, value) => this.setNodeAttr(name, attr, value));
589
+ applyAttrs<NodeAttrs>(htmlAttrs, (attr, value) => this.setNodeHtmlAttr(name, attr, value));
502
590
  return this;
503
591
  }
504
592
 
@@ -508,8 +596,24 @@ export class Graph {
508
596
  * parallel edges between the same pair of nodes; omit (or pass `""`) for
509
597
  * an anonymous edge.
510
598
  */
511
- addEdge(tail: string, head: string, key: string = ""): this {
512
- this._graph.addEdge(tail, head, key);
599
+ addEdge(tail: string, head: string, key?: string): this;
600
+ addEdge(init: EdgeInit): this;
601
+ addEdge(tailOrInit: string | EdgeInit, head?: string, key: string = ""): this {
602
+ const init = typeof tailOrInit === "string"
603
+ ? { tail: tailOrInit, head: head!, key }
604
+ : tailOrInit;
605
+ const { tail, head: resolvedHead, key: resolvedKey = "", attrs, htmlAttrs } = init;
606
+
607
+ this._graph.addEdge(tail, resolvedHead, resolvedKey);
608
+ applyAttrs<EdgeAttrs>(attrs, (attr, value) => this.setEdgeAttr(tail, resolvedHead, resolvedKey, attr, value));
609
+ applyAttrs<EdgeAttrs>(htmlAttrs, (attr, value) => this.setEdgeHtmlAttr(tail, resolvedHead, resolvedKey, attr, value));
610
+ return this;
611
+ }
612
+
613
+ applyInit(init: GraphInit): this {
614
+ this.ensureDefaultFonts(true);
615
+ applyAttrs<GraphAttrs>(init.attrs, (attr, value) => this.setGraphAttr(attr, value));
616
+ applyAttrs<GraphAttrs>(init.htmlAttrs, (attr, value) => this.setGraphHtmlAttr(attr, value));
513
617
  return this;
514
618
  }
515
619
 
@@ -521,6 +625,7 @@ export class Graph {
521
625
  if (!this._graph.read(dotSource)) {
522
626
  throw new Error("Invalid DOT source");
523
627
  }
628
+ this.ensureDefaultFonts(false);
524
629
  return this;
525
630
  }
526
631
 
@@ -790,18 +895,18 @@ export class Graph {
790
895
  // ---- Graph traversal ------------------------------------------------
791
896
 
792
897
  /**
793
- * Returns the names of all nodes in the graph (in internal iteration
794
- * order).
898
+ * Returns the names of all direct subgraphs.
795
899
  */
796
- nodeNames(): string[] {
797
- return parseNames(this._graph.nodeNames());
900
+ subgraphNames(): string[] {
901
+ return parseNames(this._graph.subgraphNames());
798
902
  }
799
903
 
800
904
  /**
801
- * Returns the names of all direct subgraphs.
905
+ * Returns the names of all nodes in the graph (in internal iteration
906
+ * order).
802
907
  */
803
- subgraphNames(): string[] {
804
- return parseNames(this._graph.subgraphNames());
908
+ nodeNames(): string[] {
909
+ return parseNames(this._graph.nodeNames());
805
910
  }
806
911
 
807
912
  /**
@@ -849,10 +954,13 @@ export class Graph {
849
954
  * cluster.setAttr("label", "My Cluster").addEdge("a", "b");
850
955
  * ```
851
956
  */
852
- addSubgraph(name: string): Subgraph {
957
+ addSubgraph(name: string): Subgraph;
958
+ addSubgraph(init: SubgraphInit): Subgraph;
959
+ addSubgraph(nameOrInit: string | SubgraphInit): Subgraph {
960
+ const init = typeof nameOrInit === "string" ? { name: nameOrInit } : nameOrInit;
853
961
  // addSubgraph only returns null when the internal graph pointer is null,
854
962
  // which cannot happen while this Graph instance is alive.
855
- return new Subgraph(this._graph.addSubgraph(name)!);
963
+ return new Subgraph(this._graph.addSubgraph(init.name)!).applyInit(init);
856
964
  }
857
965
 
858
966
  /**
@@ -1287,10 +1395,17 @@ export class Graphviz {
1287
1395
  * const svg = graphviz.dot(graph.toDot());
1288
1396
  * ```
1289
1397
  */
1290
- createGraph(name: string = "G", type: GraphType = "directed"): Graph {
1291
- const directed = !type.includes("undirected") ? 1 : 0;
1292
- const strict = type.startsWith("strict") ? 1 : 0;
1293
- return new Graph(new this._module.CGraph(name, directed, strict), this._module);
1398
+ createGraph(name?: string, type?: GraphType): Graph;
1399
+ createGraph(init: GraphInit): Graph;
1400
+ createGraph(nameOrInit: string | GraphInit = "G", type: GraphType = "directed"): Graph {
1401
+ const init = typeof nameOrInit === "string"
1402
+ ? { name: nameOrInit, type }
1403
+ : nameOrInit;
1404
+ const resolvedName = init.name ?? "G";
1405
+ const resolvedType = init.type ?? "directed";
1406
+ const directed = !resolvedType.includes("undirected") ? 1 : 0;
1407
+ const strict = resolvedType.startsWith("strict") ? 1 : 0;
1408
+ return new Graph(new this._module.CGraph(resolvedName, directed, strict), this._module).applyInit(init);
1294
1409
  }
1295
1410
 
1296
1411
  /**
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
+ export * from "./types.ts";
1
2
  export * from "./graphviz.ts";
package/src/types.ts CHANGED
@@ -611,3 +611,13 @@ export const GRAPH_DOT_ATTRS: readonly GraphDotAttr[] = attrsOf<GraphDotAttr>({
611
611
  voro_margin: true,
612
612
  xdotversion: true,
613
613
  });
614
+
615
+ /**
616
+ * Various graphic and data formats for end user, web, documents and other applications. See [Output Formats](https://graphviz.org/docs/outputs/) for more information.
617
+ */
618
+ export type Format = "svg" | "svg_inline" | "dot" | "json" | "dot_json" | "xdot_json" | "plain" | "plain-ext" | "canon";
619
+
620
+ /**
621
+ * Various algorithms for projecting abstract graphs into a space for visualization. See [Layout Engines](https://graphviz.org/docs/layouts/) for more details.
622
+ */
623
+ export type Engine = "circo" | "dot" | "fdp" | "sfdp" | "neato" | "osage" | "patchwork" | "twopi" | "nop" | "nop2";
@@ -1,9 +1,8 @@
1
1
  import type { MainModule, CGraph as CGraphWasm, CSubgraph as CSubgraphWasm } from "../types/graphvizlib.js";
2
- import type { NodeDotAttr, NodeAttrs, EdgeDotAttr, EdgeAttrs, ClusterDotAttr, ClusterAttrs, GraphDotAttr, GraphAttrs as GraphAttrs } from "./types.ts";
3
- /**
4
- * Various graphic and data formats for end user, web, documents and other applications. See [Output Formats](https://graphviz.org/docs/outputs/) for more information.
5
- */
6
- export type Format = "svg" | "svg_inline" | "dot" | "json" | "dot_json" | "xdot_json" | "plain" | "plain-ext" | "canon";
2
+ import type { NodeDotAttr, NodeAttrs, EdgeDotAttr, EdgeAttrs, ClusterDotAttr, ClusterAttrs, GraphDotAttr, GraphAttrs, Format, Engine } from "./types.ts";
3
+ type AttrValues<T> = Partial<{
4
+ [K in keyof T]: NonNullable<T[K]>;
5
+ }>;
7
6
  /**
8
7
  * An edge returned by graph-traversal methods.
9
8
  */
@@ -18,10 +17,6 @@ export interface EdgeInfo {
18
17
  */
19
18
  key: string;
20
19
  }
21
- /**
22
- * Various algorithms for projecting abstract graphs into a space for visualization. See [Layout Engines](https://graphviz.org/docs/layouts/) for more details.
23
- */
24
- export type Engine = "circo" | "dot" | "fdp" | "sfdp" | "neato" | "osage" | "patchwork" | "twopi" | "nop" | "nop2";
25
20
  /**
26
21
  * Example: Passing a web hosted Image to GraphViz:
27
22
  * ```ts
@@ -64,10 +59,34 @@ export interface Options {
64
59
  * - `"strict undirected"` – undirected graph that disallows parallel edges and self-loops
65
60
  */
66
61
  export type GraphType = "directed" | "undirected" | "strict directed" | "strict undirected";
62
+ export interface GraphInit {
63
+ name?: string;
64
+ type?: GraphType;
65
+ attrs?: AttrValues<GraphAttrs>;
66
+ htmlAttrs?: AttrValues<GraphAttrs>;
67
+ }
68
+ export interface NodeInit {
69
+ name: string;
70
+ attrs?: AttrValues<NodeAttrs>;
71
+ htmlAttrs?: AttrValues<NodeAttrs>;
72
+ }
73
+ export interface EdgeInit {
74
+ tail: string;
75
+ head: string;
76
+ key?: string;
77
+ attrs?: AttrValues<EdgeAttrs>;
78
+ htmlAttrs?: AttrValues<EdgeAttrs>;
79
+ }
80
+ export interface SubgraphInit {
81
+ name: string;
82
+ attrs?: AttrValues<ClusterAttrs>;
83
+ htmlAttrs?: AttrValues<ClusterAttrs>;
84
+ }
85
+ export type ClusterInit = SubgraphInit;
67
86
  /**
68
87
  * A subgraph (or cluster) inside a {@link Graph}.
69
88
  *
70
- * Obtain via {@link Graph.addSubgraph}. All mutation methods return `this`
89
+ * Obtain via {@link Graph.addSubgraph} or {@link Subgraph.addSubgraph}. All mutation methods return `this`
71
90
  * for chaining. **Call {@link Subgraph.delete} (or use the `using` keyword)
72
91
  * when finished** to free the underlying WASM wrapper — the actual subgraph
73
92
  * data is owned by the parent {@link Graph} and is freed with it.
@@ -92,11 +111,19 @@ export declare class Subgraph {
92
111
  * Create (or find) a node and add it to this subgraph.
93
112
  */
94
113
  addNode(name: string): this;
114
+ addNode(init: NodeInit): this;
95
115
  /**
96
116
  * Create an edge inside this subgraph. Both endpoints are created
97
117
  * automatically if they do not already exist.
98
118
  */
99
119
  addEdge(tail: string, head: string, key?: string): this;
120
+ addEdge(init: EdgeInit): this;
121
+ /**
122
+ * Create (or return an existing) named subgraph under this subgraph.
123
+ */
124
+ addSubgraph(name: string): Subgraph;
125
+ addSubgraph(init: SubgraphInit): Subgraph;
126
+ applyInit(init: SubgraphInit): this;
100
127
  /**
101
128
  * Remove a node from this subgraph only. The node (and any edges
102
129
  * connecting it) remains in the root graph and all other subgraphs.
@@ -273,11 +300,13 @@ export declare class Graph {
273
300
  private _module;
274
301
  /** @internal */
275
302
  constructor(g: CGraphWasm, module: MainModule);
303
+ private ensureDefaultFonts;
276
304
  /**
277
305
  * Create a node. If a node with this name already exists it is returned
278
306
  * unchanged.
279
307
  */
280
308
  addNode(name: string): this;
309
+ addNode(init: NodeInit): this;
281
310
  /**
282
311
  * Create an edge from `tail` to `head`. Both nodes are created
283
312
  * automatically if they do not already exist. `key` distinguishes
@@ -285,6 +314,8 @@ export declare class Graph {
285
314
  * an anonymous edge.
286
315
  */
287
316
  addEdge(tail: string, head: string, key?: string): this;
317
+ addEdge(init: EdgeInit): this;
318
+ applyInit(init: GraphInit): this;
288
319
  /**
289
320
  * Replace this graph with one parsed from DOT source using Graphviz cgraph
290
321
  * reading support.
@@ -418,15 +449,15 @@ export declare class Graph {
418
449
  * Pass `key = ""` for the first (or only) edge between `tail` and `head`.
419
450
  */
420
451
  getEdgeAttr(tail: string, head: string, key: string, attr: string): string;
452
+ /**
453
+ * Returns the names of all direct subgraphs.
454
+ */
455
+ subgraphNames(): string[];
421
456
  /**
422
457
  * Returns the names of all nodes in the graph (in internal iteration
423
458
  * order).
424
459
  */
425
460
  nodeNames(): string[];
426
- /**
427
- * Returns the names of all direct subgraphs.
428
- */
429
- subgraphNames(): string[];
430
461
  /**
431
462
  * Returns all edges in the graph. Each unique edge is listed exactly
432
463
  * once.
@@ -461,6 +492,7 @@ export declare class Graph {
461
492
  * ```
462
493
  */
463
494
  addSubgraph(name: string): Subgraph;
495
+ addSubgraph(init: SubgraphInit): Subgraph;
464
496
  /**
465
497
  * Look up an existing subgraph by name without creating a new one.
466
498
  * Returns a {@link Subgraph} wrapper if a subgraph with that name exists,
@@ -722,6 +754,7 @@ export declare class Graphviz {
722
754
  * ```
723
755
  */
724
756
  createGraph(name?: string, type?: GraphType): Graph;
757
+ createGraph(init: GraphInit): Graph;
725
758
  /**
726
759
  * Parse DOT source into a mutable {@link Graph}. The returned graph can
727
760
  * be queried, modified, rendered directly, or serialised back to DOT with
@@ -729,3 +762,4 @@ export declare class Graphviz {
729
762
  */
730
763
  read(dotSource: string): Graph;
731
764
  }
765
+ export {};
@@ -122,6 +122,7 @@ export interface CSubgraph extends ClassHandle {
122
122
  addNode(_0: EmbindString): void;
123
123
  addEdge(_0: EmbindString, _1: EmbindString): void;
124
124
  addEdge(_0: EmbindString, _1: EmbindString, _2: EmbindString): void;
125
+ addSubgraph(_0: EmbindString): CSubgraph | null;
125
126
  setAttr(_0: EmbindString, _1: EmbindString): void;
126
127
  setAttr(_0: EmbindString, _1: EmbindString, _2: EmbindString): void;
127
128
  setHtmlAttr(_0: EmbindString, _1: EmbindString): void;
package/types/index.d.ts CHANGED
@@ -1 +1,2 @@
1
+ export * from "./types.ts";
1
2
  export * from "./graphviz.ts";
package/types/types.d.ts CHANGED
@@ -299,4 +299,12 @@ export declare const EDGE_DOT_ATTRS: readonly EdgeDotAttr[];
299
299
  export declare const CLUSTER_DOT_ATTRS: readonly ClusterDotAttr[];
300
300
  /** Graph DOT attributes (excludes write-only: bb, lheight, lp, lwidth; and non-DOT: type) */
301
301
  export declare const GRAPH_DOT_ATTRS: readonly GraphDotAttr[];
302
+ /**
303
+ * Various graphic and data formats for end user, web, documents and other applications. See [Output Formats](https://graphviz.org/docs/outputs/) for more information.
304
+ */
305
+ export type Format = "svg" | "svg_inline" | "dot" | "json" | "dot_json" | "xdot_json" | "plain" | "plain-ext" | "canon";
306
+ /**
307
+ * Various algorithms for projecting abstract graphs into a space for visualization. See [Layout Engines](https://graphviz.org/docs/layouts/) for more details.
308
+ */
309
+ export type Engine = "circo" | "dot" | "fdp" | "sfdp" | "neato" | "osage" | "patchwork" | "twopi" | "nop" | "nop2";
302
310
  export {};