@knowvah/dot-engine 1.4.0 → 1.6.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/dist/api/geometry.d.ts +36 -1
- package/dist/api/geometry.d.ts.map +1 -1
- package/dist/api.js +13 -1
- package/dist/api.js.map +2 -2
- package/dist/index.js +13 -1
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/src/api/geometry.ts +48 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knowvah/dot-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.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",
|
package/src/api/geometry.ts
CHANGED
|
@@ -106,6 +106,12 @@ export interface NodeGeometry {
|
|
|
106
106
|
* type) still holds calloc-zero coordinates, so it is reported as absent
|
|
107
107
|
* rather than as a label at the origin.
|
|
108
108
|
*
|
|
109
|
+
* `xlabel` is the `xlabel` external label, positioned by the force-placement
|
|
110
|
+
* search rather than by spline midpoint arithmetic, so it is not derivable
|
|
111
|
+
* from `label` or `points`. It carries the same `lp->set` gate: a declared
|
|
112
|
+
* xlabel the search could not fit is reported as absent, exactly as
|
|
113
|
+
* `render()` declines to draw it.
|
|
114
|
+
*
|
|
109
115
|
* `sp`/`ep` are the arrow attachment points. When an end carries an arrow the
|
|
110
116
|
* spline is shortened to leave room for it, and the arrow spans from the
|
|
111
117
|
* terminal control point out to this point — so a consumer drawing its own
|
|
@@ -119,7 +125,8 @@ export interface NodeGeometry {
|
|
|
119
125
|
* (measured: ~1.5pt at `penwidth=1`, ~6.2pt at `penwidth=5`), so `ep` is the
|
|
120
126
|
* point to draw an arrow *to*, not a copy of the rendered polygon's tip.
|
|
121
127
|
*
|
|
122
|
-
* @see lib/common/types.h:ED_spl, ED_label, ED_tail_label, ED_head_label
|
|
128
|
+
* @see lib/common/types.h:ED_spl, ED_label, ED_tail_label, ED_head_label,
|
|
129
|
+
* ED_xlabel
|
|
123
130
|
* @see lib/common/types.h:bezier (sflag/eflag, sp/ep)
|
|
124
131
|
*/
|
|
125
132
|
export interface EdgeGeometry {
|
|
@@ -149,6 +156,11 @@ export interface EdgeGeometry {
|
|
|
149
156
|
* @see lib/common/types.h:ED_head_label
|
|
150
157
|
*/
|
|
151
158
|
headLabel?: { x: number; y: number };
|
|
159
|
+
/**
|
|
160
|
+
* `xlabel` (external label) position, if placed.
|
|
161
|
+
* @see lib/common/types.h:ED_xlabel
|
|
162
|
+
*/
|
|
163
|
+
xlabel?: { x: number; y: number };
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
/**
|
|
@@ -164,7 +176,15 @@ export interface EdgeGeometry {
|
|
|
164
176
|
* `class="cluster"` polygon, so a consumer quantizing to SVG precision gets
|
|
165
177
|
* byte-conformant geometry.
|
|
166
178
|
*
|
|
179
|
+
* `label` is the cluster title's placed position and measured size, present
|
|
180
|
+
* only when the cluster declares a label. Unlike the edge port labels, it is
|
|
181
|
+
* *not* gated on the label's `set` flag: C draws a cluster label on existence
|
|
182
|
+
* alone (emit.c:3920 has no `->set` test, unlike emit_edge_label:2891), so an
|
|
183
|
+
* unplaced one still renders at whatever pos it holds. Gating here would hide
|
|
184
|
+
* geometry `render()` acts on.
|
|
185
|
+
*
|
|
167
186
|
* @see lib/common/types.h:GD_bb (of a cluster subgraph)
|
|
187
|
+
* @see lib/common/types.h:GD_label (textlabel_t.pos / .dimen)
|
|
168
188
|
*/
|
|
169
189
|
export interface ClusterGeometry {
|
|
170
190
|
/** Cluster subgraph name (e.g. `cluster6`); encodes nesting. */
|
|
@@ -173,6 +193,13 @@ export interface ClusterGeometry {
|
|
|
173
193
|
y: number;
|
|
174
194
|
width: number;
|
|
175
195
|
height: number;
|
|
196
|
+
/**
|
|
197
|
+
* Cluster label placement, if the cluster has one. `x`/`y` are the **centre**
|
|
198
|
+
* of the label space (matching `EdgeGeometry.label`, not the box corner
|
|
199
|
+
* `x`/`y` above); `width`/`height` are its measured size.
|
|
200
|
+
* @see lib/common/postproc.c:place_graph_label
|
|
201
|
+
*/
|
|
202
|
+
label?: { x: number; y: number; width: number; height: number };
|
|
176
203
|
}
|
|
177
204
|
|
|
178
205
|
/**
|
|
@@ -286,8 +313,8 @@ function arrowAttachPoints(
|
|
|
286
313
|
|
|
287
314
|
/**
|
|
288
315
|
* Snapshot one edge's geometry.
|
|
289
|
-
* @see lib/common/types.h:ED_spl, ED_label, ED_tail_label, ED_head_label
|
|
290
|
-
* (textlabel_t.pos), bezier.sp/ep
|
|
316
|
+
* @see lib/common/types.h:ED_spl, ED_label, ED_tail_label, ED_head_label,
|
|
317
|
+
* ED_xlabel (textlabel_t.pos), bezier.sp/ep
|
|
291
318
|
*/
|
|
292
319
|
function snapshotEdge(edge: Edge, flipY: (y: number) => number): EdgeGeometry {
|
|
293
320
|
const geom: EdgeGeometry = {
|
|
@@ -303,6 +330,8 @@ function snapshotEdge(edge: Edge, flipY: (y: number) => number): EdgeGeometry {
|
|
|
303
330
|
if (tailLabel !== undefined) geom.tailLabel = tailLabel;
|
|
304
331
|
const headLabel = placedLabelPos(edge.info.head_label, flipY);
|
|
305
332
|
if (headLabel !== undefined) geom.headLabel = headLabel;
|
|
333
|
+
const xlabel = placedLabelPos(edge.info.xlabel, flipY);
|
|
334
|
+
if (xlabel !== undefined) geom.xlabel = xlabel;
|
|
306
335
|
const { sp, ep } = arrowAttachPoints(edge, flipY);
|
|
307
336
|
if (sp !== undefined) geom.sp = sp;
|
|
308
337
|
if (ep !== undefined) geom.ep = ep;
|
|
@@ -316,13 +345,18 @@ function snapshotEdge(edge: Edge, flipY: (y: number) => number): EdgeGeometry {
|
|
|
316
345
|
* native lower-left corner (ll); `yAxis:'down'` returns the top-left corner
|
|
317
346
|
* (ll.x, flipped ur.y). `width`/`height` are frame-independent (ur - ll).
|
|
318
347
|
*
|
|
348
|
+
* The label rides in the same call because place_graph_label runs on the same
|
|
349
|
+
* layout pass that fills GD_bb; `pos` is the centre of the label space, so it
|
|
350
|
+
* flips like any other coordinate rather than like the box corner.
|
|
351
|
+
*
|
|
319
352
|
* @see lib/common/types.h:GD_bb (cluster subgraph)
|
|
353
|
+
* @see lib/common/postproc.c:place_graph_label
|
|
320
354
|
*/
|
|
321
355
|
function snapshotCluster(
|
|
322
356
|
sg: Graph, yAxis: YAxis, flipY: (y: number) => number,
|
|
323
357
|
): ClusterGeometry {
|
|
324
358
|
const bb = sg.info.bb;
|
|
325
|
-
|
|
359
|
+
const geom: ClusterGeometry = {
|
|
326
360
|
name: sg.name,
|
|
327
361
|
x: bb.ll.x,
|
|
328
362
|
// 'up' keeps the lower-left y; 'down' flips the upper-right y to the
|
|
@@ -331,6 +365,16 @@ function snapshotCluster(
|
|
|
331
365
|
width: bb.ur.x - bb.ll.x,
|
|
332
366
|
height: bb.ur.y - bb.ll.y,
|
|
333
367
|
};
|
|
368
|
+
const lab = sg.info.label as TextlabelT | undefined;
|
|
369
|
+
if (lab !== undefined) {
|
|
370
|
+
geom.label = {
|
|
371
|
+
x: lab.pos.x,
|
|
372
|
+
y: flipY(lab.pos.y),
|
|
373
|
+
width: lab.dimen.x,
|
|
374
|
+
height: lab.dimen.y,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
return geom;
|
|
334
378
|
}
|
|
335
379
|
|
|
336
380
|
/**
|