@knowvah/dot-engine 1.4.0 → 1.5.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": "@knowvah/dot-engine",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Faithful TypeScript port of Graphviz (dot, neato, fdp, sfdp, circo, twopi, osage, patchwork) — no C: no native binary, no WASM. Oracle-verified against the C implementation, runs in the browser.",
5
5
  "keywords": [
6
6
  "graphviz",
@@ -164,7 +164,15 @@ export interface EdgeGeometry {
164
164
  * `class="cluster"` polygon, so a consumer quantizing to SVG precision gets
165
165
  * byte-conformant geometry.
166
166
  *
167
+ * `label` is the cluster title's placed position and measured size, present
168
+ * only when the cluster declares a label. Unlike the edge port labels, it is
169
+ * *not* gated on the label's `set` flag: C draws a cluster label on existence
170
+ * alone (emit.c:3920 has no `->set` test, unlike emit_edge_label:2891), so an
171
+ * unplaced one still renders at whatever pos it holds. Gating here would hide
172
+ * geometry `render()` acts on.
173
+ *
167
174
  * @see lib/common/types.h:GD_bb (of a cluster subgraph)
175
+ * @see lib/common/types.h:GD_label (textlabel_t.pos / .dimen)
168
176
  */
169
177
  export interface ClusterGeometry {
170
178
  /** Cluster subgraph name (e.g. `cluster6`); encodes nesting. */
@@ -173,6 +181,13 @@ export interface ClusterGeometry {
173
181
  y: number;
174
182
  width: number;
175
183
  height: number;
184
+ /**
185
+ * Cluster label placement, if the cluster has one. `x`/`y` are the **centre**
186
+ * of the label space (matching `EdgeGeometry.label`, not the box corner
187
+ * `x`/`y` above); `width`/`height` are its measured size.
188
+ * @see lib/common/postproc.c:place_graph_label
189
+ */
190
+ label?: { x: number; y: number; width: number; height: number };
176
191
  }
177
192
 
178
193
  /**
@@ -316,13 +331,18 @@ function snapshotEdge(edge: Edge, flipY: (y: number) => number): EdgeGeometry {
316
331
  * native lower-left corner (ll); `yAxis:'down'` returns the top-left corner
317
332
  * (ll.x, flipped ur.y). `width`/`height` are frame-independent (ur - ll).
318
333
  *
334
+ * The label rides in the same call because place_graph_label runs on the same
335
+ * layout pass that fills GD_bb; `pos` is the centre of the label space, so it
336
+ * flips like any other coordinate rather than like the box corner.
337
+ *
319
338
  * @see lib/common/types.h:GD_bb (cluster subgraph)
339
+ * @see lib/common/postproc.c:place_graph_label
320
340
  */
321
341
  function snapshotCluster(
322
342
  sg: Graph, yAxis: YAxis, flipY: (y: number) => number,
323
343
  ): ClusterGeometry {
324
344
  const bb = sg.info.bb;
325
- return {
345
+ const geom: ClusterGeometry = {
326
346
  name: sg.name,
327
347
  x: bb.ll.x,
328
348
  // 'up' keeps the lower-left y; 'down' flips the upper-right y to the
@@ -331,6 +351,16 @@ function snapshotCluster(
331
351
  width: bb.ur.x - bb.ll.x,
332
352
  height: bb.ur.y - bb.ll.y,
333
353
  };
354
+ const lab = sg.info.label as TextlabelT | undefined;
355
+ if (lab !== undefined) {
356
+ geom.label = {
357
+ x: lab.pos.x,
358
+ y: flipY(lab.pos.y),
359
+ width: lab.dimen.x,
360
+ height: lab.dimen.y,
361
+ };
362
+ }
363
+ return geom;
334
364
  }
335
365
 
336
366
  /**