@knowvah/dot-engine 1.3.0 → 1.4.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 +30 -0
- package/dist/api/geometry.d.ts.map +1 -1
- package/dist/api.js +13 -0
- package/dist/api.js.map +2 -2
- package/dist/index.js +13 -0
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/src/api/geometry.ts +51 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knowvah/dot-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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,13 +106,37 @@ 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
|
+
* `sp`/`ep` are the arrow attachment points. When an end carries an arrow the
|
|
110
|
+
* spline is shortened to leave room for it, and the arrow spans from the
|
|
111
|
+
* terminal control point out to this point — so a consumer drawing its own
|
|
112
|
+
* arrowheads reads the tip here instead of extrapolating one. Each is present
|
|
113
|
+
* only when that end actually has an arrow (C `sflag`/`eflag`); with no arrow
|
|
114
|
+
* the field holds the calloc-zero point, which is not geometry.
|
|
115
|
+
*
|
|
116
|
+
* These are the *attachment* points on the node boundary, verbatim from the
|
|
117
|
+
* bezier — with `arrowhead=none` the spline simply ends there. Graphviz's own
|
|
118
|
+
* renderer insets the arrow polygon it draws by a penwidth-dependent amount
|
|
119
|
+
* (measured: ~1.5pt at `penwidth=1`, ~6.2pt at `penwidth=5`), so `ep` is the
|
|
120
|
+
* point to draw an arrow *to*, not a copy of the rendered polygon's tip.
|
|
121
|
+
*
|
|
109
122
|
* @see lib/common/types.h:ED_spl, ED_label, ED_tail_label, ED_head_label
|
|
123
|
+
* @see lib/common/types.h:bezier (sflag/eflag, sp/ep)
|
|
110
124
|
*/
|
|
111
125
|
export interface EdgeGeometry {
|
|
112
126
|
tail: string;
|
|
113
127
|
head: string;
|
|
114
128
|
/** Bezier control points for the edge spline, in points. */
|
|
115
129
|
points: { x: number; y: number }[];
|
|
130
|
+
/**
|
|
131
|
+
* Arrow attachment point at the tail end, if that end carries an arrow.
|
|
132
|
+
* @see lib/common/types.h:bezier.sp
|
|
133
|
+
*/
|
|
134
|
+
sp?: { x: number; y: number };
|
|
135
|
+
/**
|
|
136
|
+
* Arrow attachment point at the head end, if that end carries an arrow.
|
|
137
|
+
* @see lib/common/types.h:bezier.ep
|
|
138
|
+
*/
|
|
139
|
+
ep?: { x: number; y: number };
|
|
116
140
|
/** Centre edge label position, if present. @see lib/common/types.h:ED_label */
|
|
117
141
|
label?: { x: number; y: number };
|
|
118
142
|
/**
|
|
@@ -237,10 +261,33 @@ function placedLabelPos(
|
|
|
237
261
|
return { x: lbl.pos.x, y: flipY(lbl.pos.y) };
|
|
238
262
|
}
|
|
239
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Arrow attachment points, one per end that actually carries an arrow.
|
|
266
|
+
* C keeps `sp`/`ep` beside the control points and gates them on
|
|
267
|
+
* `sflag`/`eflag`; with no arrow at that end the flag is 0 and the point is
|
|
268
|
+
* still calloc-zero, so an ungated read would publish (0, 0) as geometry.
|
|
269
|
+
* Indexes the bezier array by `spl.size` (not `list.length`), matching C.
|
|
270
|
+
* @see lib/common/types.h:bezier
|
|
271
|
+
* @see lib/common/postproc.c:endPoints
|
|
272
|
+
*/
|
|
273
|
+
function arrowAttachPoints(
|
|
274
|
+
edge: Edge,
|
|
275
|
+
flipY: (y: number) => number,
|
|
276
|
+
): { sp?: { x: number; y: number }; ep?: { x: number; y: number } } {
|
|
277
|
+
const spl = edge.info.spl;
|
|
278
|
+
if (spl === undefined || spl.size === 0) return {};
|
|
279
|
+
const out: { sp?: { x: number; y: number }; ep?: { x: number; y: number } } = {};
|
|
280
|
+
const first = spl.list[0];
|
|
281
|
+
if (first.sflag !== 0) out.sp = { x: first.sp.x, y: flipY(first.sp.y) };
|
|
282
|
+
const last = spl.list[spl.size - 1];
|
|
283
|
+
if (last.eflag !== 0) out.ep = { x: last.ep.x, y: flipY(last.ep.y) };
|
|
284
|
+
return out;
|
|
285
|
+
}
|
|
286
|
+
|
|
240
287
|
/**
|
|
241
288
|
* Snapshot one edge's geometry.
|
|
242
289
|
* @see lib/common/types.h:ED_spl, ED_label, ED_tail_label, ED_head_label
|
|
243
|
-
* (textlabel_t.pos)
|
|
290
|
+
* (textlabel_t.pos), bezier.sp/ep
|
|
244
291
|
*/
|
|
245
292
|
function snapshotEdge(edge: Edge, flipY: (y: number) => number): EdgeGeometry {
|
|
246
293
|
const geom: EdgeGeometry = {
|
|
@@ -256,6 +303,9 @@ function snapshotEdge(edge: Edge, flipY: (y: number) => number): EdgeGeometry {
|
|
|
256
303
|
if (tailLabel !== undefined) geom.tailLabel = tailLabel;
|
|
257
304
|
const headLabel = placedLabelPos(edge.info.head_label, flipY);
|
|
258
305
|
if (headLabel !== undefined) geom.headLabel = headLabel;
|
|
306
|
+
const { sp, ep } = arrowAttachPoints(edge, flipY);
|
|
307
|
+
if (sp !== undefined) geom.sp = sp;
|
|
308
|
+
if (ep !== undefined) geom.ep = ep;
|
|
259
309
|
return geom;
|
|
260
310
|
}
|
|
261
311
|
|