@retikz/core 0.2.0-alpha.2 → 0.2.0-alpha.4
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/es/compile/compile.d.ts +8 -1
- package/dist/es/compile/compile.d.ts.map +1 -1
- package/dist/es/compile/compile.js +89 -14
- package/dist/es/compile/node.d.ts +19 -10
- package/dist/es/compile/node.d.ts.map +1 -1
- package/dist/es/compile/node.js +121 -207
- package/dist/es/compile/scope.d.ts.map +1 -1
- package/dist/es/compile/scope.js +3 -1
- package/dist/es/index.d.ts +3 -1
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +4 -2
- package/dist/es/ir/node.d.ts +45 -12
- package/dist/es/ir/node.d.ts.map +1 -1
- package/dist/es/ir/node.js +10 -3
- package/dist/es/ir/path/path.d.ts +3 -0
- package/dist/es/ir/path/path.d.ts.map +1 -1
- package/dist/es/ir/path/path.js +1 -0
- package/dist/es/ir/scope.d.ts +44 -22
- package/dist/es/ir/scope.d.ts.map +1 -1
- package/dist/es/ir/scope.js +5 -2
- package/dist/es/shapes/_shared.d.ts +7 -0
- package/dist/es/shapes/_shared.d.ts.map +1 -0
- package/dist/es/shapes/_shared.js +11 -0
- package/dist/es/shapes/circle.d.ts +8 -0
- package/dist/es/shapes/circle.d.ts.map +1 -0
- package/dist/es/shapes/circle.js +33 -0
- package/dist/es/shapes/diamond.d.ts +8 -0
- package/dist/es/shapes/diamond.d.ts.map +1 -0
- package/dist/es/shapes/diamond.js +65 -0
- package/dist/es/shapes/ellipse.d.ts +8 -0
- package/dist/es/shapes/ellipse.d.ts.map +1 -0
- package/dist/es/shapes/ellipse.js +45 -0
- package/dist/es/shapes/index.d.ts +14 -0
- package/dist/es/shapes/index.d.ts.map +1 -0
- package/dist/es/shapes/index.js +15 -0
- package/dist/es/shapes/rectangle.d.ts +8 -0
- package/dist/es/shapes/rectangle.d.ts.map +1 -0
- package/dist/es/shapes/rectangle.js +40 -0
- package/dist/es/shapes/types.d.ts +44 -0
- package/dist/es/shapes/types.d.ts.map +1 -0
- package/dist/lib/compile/compile.cjs +91 -16
- package/dist/lib/compile/compile.d.ts +8 -1
- package/dist/lib/compile/compile.d.ts.map +1 -1
- package/dist/lib/compile/node.cjs +121 -207
- package/dist/lib/compile/node.d.ts +19 -10
- package/dist/lib/compile/node.d.ts.map +1 -1
- package/dist/lib/compile/scope.cjs +3 -1
- package/dist/lib/compile/scope.d.ts.map +1 -1
- package/dist/lib/index.cjs +6 -1
- package/dist/lib/index.d.ts +3 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/ir/node.cjs +10 -3
- package/dist/lib/ir/node.d.ts +45 -12
- package/dist/lib/ir/node.d.ts.map +1 -1
- package/dist/lib/ir/path/path.cjs +1 -0
- package/dist/lib/ir/path/path.d.ts +3 -0
- package/dist/lib/ir/path/path.d.ts.map +1 -1
- package/dist/lib/ir/scope.cjs +5 -2
- package/dist/lib/ir/scope.d.ts +44 -22
- package/dist/lib/ir/scope.d.ts.map +1 -1
- package/dist/lib/shapes/_shared.cjs +11 -0
- package/dist/lib/shapes/_shared.d.ts +7 -0
- package/dist/lib/shapes/_shared.d.ts.map +1 -0
- package/dist/lib/shapes/circle.cjs +33 -0
- package/dist/lib/shapes/circle.d.ts +8 -0
- package/dist/lib/shapes/circle.d.ts.map +1 -0
- package/dist/lib/shapes/diamond.cjs +65 -0
- package/dist/lib/shapes/diamond.d.ts +8 -0
- package/dist/lib/shapes/diamond.d.ts.map +1 -0
- package/dist/lib/shapes/ellipse.cjs +45 -0
- package/dist/lib/shapes/ellipse.d.ts +8 -0
- package/dist/lib/shapes/ellipse.d.ts.map +1 -0
- package/dist/lib/shapes/index.cjs +14 -0
- package/dist/lib/shapes/index.d.ts +14 -0
- package/dist/lib/shapes/index.d.ts.map +1 -0
- package/dist/lib/shapes/rectangle.cjs +40 -0
- package/dist/lib/shapes/rectangle.d.ts +8 -0
- package/dist/lib/shapes/rectangle.d.ts.map +1 -0
- package/dist/lib/shapes/types.d.ts +44 -0
- package/dist/lib/shapes/types.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const require_circle = require("../geometry/circle.cjs");
|
|
3
|
-
const require_diamond = require("../geometry/diamond.cjs");
|
|
4
|
-
const require_ellipse = require("../geometry/ellipse.cjs");
|
|
1
|
+
const require_index = require("../shapes/index.cjs");
|
|
5
2
|
const require_position = require("./position.cjs");
|
|
6
3
|
//#region src/compile/node.ts
|
|
7
4
|
var DEFAULT_FONT_SIZE = 14;
|
|
@@ -10,7 +7,6 @@ var DEFAULT_LINE_HEIGHT_FACTOR = 1.2;
|
|
|
10
7
|
var DEG_TO_RAD = Math.PI / 180;
|
|
11
8
|
/** Node label 与 node 边界默认距离(TikZ 默认 0pt 视觉太贴) */
|
|
12
9
|
var DEFAULT_LABEL_DISTANCE = 12;
|
|
13
|
-
var SQRT2 = Math.SQRT2;
|
|
14
10
|
/** dashed 预设:4 px 实线 + 2 px 间隙循环 */
|
|
15
11
|
var DASHED_PATTERN = [4, 2];
|
|
16
12
|
/** dotted 预设:1 px 圆点 + 2 px 间隙 */
|
|
@@ -23,61 +19,28 @@ var resolveDashArray = (dashArray, dashed, dotted) => {
|
|
|
23
19
|
};
|
|
24
20
|
/** IR align → 文字对齐锚点(start / middle / end) */
|
|
25
21
|
var alignToTextAnchor = (a) => a === "left" ? "start" : a === "right" ? "end" : "middle";
|
|
26
|
-
/**
|
|
27
|
-
var
|
|
28
|
-
x:
|
|
29
|
-
y:
|
|
30
|
-
width:
|
|
31
|
-
height:
|
|
32
|
-
rotate:
|
|
33
|
-
}
|
|
34
|
-
/** 从 layout 构造 Circle(radius=外接框边长/2 + margin) */
|
|
35
|
-
var circleOf = (layout, marginAdd) => ({
|
|
36
|
-
x: layout.rect.x,
|
|
37
|
-
y: layout.rect.y,
|
|
38
|
-
radius: layout.rect.width / 2 + marginAdd,
|
|
39
|
-
rotate: layout.rect.rotate
|
|
40
|
-
});
|
|
41
|
-
/** 从 layout 构造 Ellipse(rx/ry 各加 margin) */
|
|
42
|
-
var ellipseOf = (layout, marginAdd) => ({
|
|
43
|
-
x: layout.rect.x,
|
|
44
|
-
y: layout.rect.y,
|
|
45
|
-
rx: layout.rect.width / 2 + marginAdd,
|
|
46
|
-
ry: layout.rect.height / 2 + marginAdd,
|
|
47
|
-
rotate: layout.rect.rotate
|
|
48
|
-
});
|
|
49
|
-
/** 从 layout 构造 Diamond(halfA/halfB 各加 margin) */
|
|
50
|
-
var diamondOf = (layout, marginAdd) => ({
|
|
51
|
-
x: layout.rect.x,
|
|
52
|
-
y: layout.rect.y,
|
|
53
|
-
halfA: layout.rect.width / 2 + marginAdd,
|
|
54
|
-
halfB: layout.rect.height / 2 + marginAdd,
|
|
55
|
-
rotate: layout.rect.rotate
|
|
56
|
-
});
|
|
22
|
+
/** 把 Rect 各方向外扩 m(margin generic:所有 shape 都 w+2m, h+2m,由 boundaryPointOf 调用前膨胀) */
|
|
23
|
+
var inflateRect = (r, m) => m === 0 ? r : {
|
|
24
|
+
x: r.x,
|
|
25
|
+
y: r.y,
|
|
26
|
+
width: r.width + 2 * m,
|
|
27
|
+
height: r.height + 2 * m,
|
|
28
|
+
rotate: r.rotate
|
|
29
|
+
};
|
|
57
30
|
/**
|
|
58
31
|
* 取节点 shape 在 toward 方向的附着点(path 端点贴边用)
|
|
59
|
-
* @description
|
|
32
|
+
* @description 走 shapeDef.boundaryPoint;margin > 0 时先膨胀外接 Rect,让 path 在 border 外停 margin
|
|
60
33
|
*/
|
|
61
|
-
var boundaryPointOf = (layout, toward) =>
|
|
62
|
-
const m = layout.margin;
|
|
63
|
-
switch (layout.shape) {
|
|
64
|
-
case "rectangle": return require_rect.rect.boundaryPoint(rectOf(layout, m), toward);
|
|
65
|
-
case "circle": return require_circle.circle.boundaryPoint(circleOf(layout, m), toward);
|
|
66
|
-
case "ellipse": return require_ellipse.ellipse.boundaryPoint(ellipseOf(layout, m), toward);
|
|
67
|
-
case "diamond": return require_diamond.diamond.boundaryPoint(diamondOf(layout, m), toward);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
34
|
+
var boundaryPointOf = (layout, toward) => layout.shapeDef.boundaryPoint(inflateRect(layout.rect, layout.margin), toward);
|
|
70
35
|
/**
|
|
71
|
-
* 取节点 shape 命名 anchor(center / north / east / north-east
|
|
72
|
-
* @description 不应用 margin——TikZ 语义中 explicit anchor 取视觉边界点不涉及 outer sep;用于 `'A.north'`
|
|
36
|
+
* 取节点 shape 命名 anchor(center / north / east / north-east 等)
|
|
37
|
+
* @description 不应用 margin——TikZ 语义中 explicit anchor 取视觉边界点不涉及 outer sep;用于 `'A.north'` 落点。
|
|
38
|
+
* shapeDef.anchor 不认识的名字返回 undefined,此处抛 Unknown anchor(列出 shape 名)
|
|
73
39
|
*/
|
|
74
40
|
var anchorOf = (layout, name) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
case "ellipse": return require_ellipse.ellipse.anchor(ellipseOf(layout, 0), name);
|
|
79
|
-
case "diamond": return require_diamond.diamond.anchor(diamondOf(layout, 0), name);
|
|
80
|
-
}
|
|
41
|
+
const p = layout.shapeDef.anchor(layout.rect, name);
|
|
42
|
+
if (p === void 0) throw new Error(`Unknown anchor '${name}' for shape '${layout.shapeName}'`);
|
|
43
|
+
return p;
|
|
81
44
|
};
|
|
82
45
|
/** 8 方向 label position → (anchorName, 单位向量);above 视觉上方即 y 减小 */
|
|
83
46
|
var LABEL_DIRECTION_MAP = {
|
|
@@ -115,19 +78,51 @@ var LABEL_DIRECTION_MAP = {
|
|
|
115
78
|
}
|
|
116
79
|
};
|
|
117
80
|
/**
|
|
118
|
-
* 算 label
|
|
119
|
-
* @description 8 方向:节点对应 anchor 出发按单位向量 × distance 外推;数字角度:先取 angleBoundary 边界点再沿 (cos,sin) × distance
|
|
81
|
+
* 算 label 中心点(节点局部坐标系,未旋转)
|
|
82
|
+
* @description 8 方向:节点对应 anchor 出发按单位向量 × distance 外推;数字角度:先取 angleBoundary 边界点再沿 (cos,sin) × distance 外推。
|
|
83
|
+
* 两个分支都在 **axis-aligned rect(rotate=0)** 上算——node 自身 rotate 由外层 GroupPrim 统一施加;
|
|
84
|
+
* 若用带 rotate 的 rect,label 位置会被 anchorOf / angleBoundaryOf 旋转一次、再被外层 group 旋转一次(双重旋转)。
|
|
85
|
+
* anchorOf / angleBoundaryOf 本身不改(path anchor `'A.north'` / `'A.30'` 仍需带 rotate 的 rect)。
|
|
120
86
|
*/
|
|
121
87
|
var labelCenter = (layout, label) => {
|
|
88
|
+
const aaLayout = {
|
|
89
|
+
...layout,
|
|
90
|
+
rect: {
|
|
91
|
+
...layout.rect,
|
|
92
|
+
rotate: 0
|
|
93
|
+
}
|
|
94
|
+
};
|
|
122
95
|
if (typeof label.position === "number") {
|
|
123
96
|
const rad = label.position * Math.PI / 180;
|
|
124
|
-
const [bx, by] = angleBoundaryOf(
|
|
97
|
+
const [bx, by] = angleBoundaryOf(aaLayout, label.position);
|
|
125
98
|
return [bx + Math.cos(rad) * label.distance, by + Math.sin(rad) * label.distance];
|
|
126
99
|
}
|
|
127
100
|
const { anchor, vec } = LABEL_DIRECTION_MAP[label.position];
|
|
128
|
-
const [bx, by] = anchorOf(
|
|
101
|
+
const [bx, by] = anchorOf(aaLayout, anchor);
|
|
129
102
|
return [bx + vec[0] * label.distance, by + vec[1] * label.distance];
|
|
130
103
|
};
|
|
104
|
+
/** 角度换算常量(弧度 → 度) */
|
|
105
|
+
var RAD_TO_DEG = 180 / Math.PI;
|
|
106
|
+
/**
|
|
107
|
+
* 算 label 文本自旋角度(度,屏幕 y-down,节点局部系)
|
|
108
|
+
* @description radial = atan2(label中心 − node中心);tangent = radial + 90;number = 原值;none / 缺省 = 0。
|
|
109
|
+
* keepUpright 时把"偏离正立 > 90°"的角度翻 180° 保阅读方向。方向向量在局部坐标算,node 自身 rotate 由外层 group 叠加。
|
|
110
|
+
*/
|
|
111
|
+
var resolveLabelRotateDeg = (label, lx, ly, cx, cy) => {
|
|
112
|
+
const mode = label.rotate;
|
|
113
|
+
if (mode === void 0 || mode === "none") return 0;
|
|
114
|
+
let deg;
|
|
115
|
+
if (typeof mode === "number") deg = mode;
|
|
116
|
+
else {
|
|
117
|
+
const radial = Math.atan2(ly - cy, lx - cx) * RAD_TO_DEG;
|
|
118
|
+
deg = mode === "tangent" ? radial + 90 : radial;
|
|
119
|
+
}
|
|
120
|
+
if (label.keepUpright) {
|
|
121
|
+
const norm = (deg % 360 + 360) % 360;
|
|
122
|
+
if (norm > 90 && norm < 270) deg += 180;
|
|
123
|
+
}
|
|
124
|
+
return deg;
|
|
125
|
+
};
|
|
131
126
|
/**
|
|
132
127
|
* 取节点 shape 在指定角度方向的边界点
|
|
133
128
|
* @description 角度是节点**局部坐标系**下的极角(度数:0°=局部 +x,90°=局部 +y)。layout.rect.rotate 把局部基绕中心旋转,得到世界系下的视觉方向;shape boundaryPoint 内部用 rotate-aware 投影,所以这里把局部 (cos, sin) 经 rect.rotate 旋转后加到中心当作世界系 toward 传入。不应用 margin(同 anchorOf);用于 `'A.30'` 落点
|
|
@@ -140,12 +135,7 @@ var angleBoundaryOf = (layout, angleDeg) => {
|
|
|
140
135
|
const cosR = Math.cos(rot);
|
|
141
136
|
const sinR = Math.sin(rot);
|
|
142
137
|
const toward = [layout.rect.x + lx * cosR - ly * sinR, layout.rect.y + lx * sinR + ly * cosR];
|
|
143
|
-
|
|
144
|
-
case "rectangle": return require_rect.rect.boundaryPoint(rectOf(layout, 0), toward);
|
|
145
|
-
case "circle": return require_circle.circle.boundaryPoint(circleOf(layout, 0), toward);
|
|
146
|
-
case "ellipse": return require_ellipse.ellipse.boundaryPoint(ellipseOf(layout, 0), toward);
|
|
147
|
-
case "diamond": return require_diamond.diamond.boundaryPoint(diamondOf(layout, 0), toward);
|
|
148
|
-
}
|
|
138
|
+
return layout.shapeDef.boundaryPoint(layout.rect, toward);
|
|
149
139
|
};
|
|
150
140
|
/**
|
|
151
141
|
* IR Node → 内部 NodeLayout
|
|
@@ -154,7 +144,10 @@ var angleBoundaryOf = (layout, angleDeg) => {
|
|
|
154
144
|
* scope 局部度量),调用方负责后续 `projectLayoutToGlobal` / `applyTransformChain` 投回全局;
|
|
155
145
|
* 笛卡尔字面量 `Position` 已在 scope 局部度量,行为延续 v0.1。
|
|
156
146
|
*/
|
|
157
|
-
var layoutNode = (node, measureText, nameStack, nodeDistance, scopeChain = [], labelDefault) => {
|
|
147
|
+
var layoutNode = (node, measureText, nameStack, nodeDistance, scopeChain = [], labelDefault, shapes = require_index.BUILTIN_SHAPES) => {
|
|
148
|
+
const shapeName = node.shape ?? "rectangle";
|
|
149
|
+
const shapeDef = Object.prototype.hasOwnProperty.call(shapes, shapeName) ? shapes[shapeName] : void 0;
|
|
150
|
+
if (!shapeDef) throw new Error(`Unknown shape '${shapeName}'; registered shapes: ${Object.keys(shapes).sort().join(", ")}`);
|
|
158
151
|
const sx = node.xScale ?? node.scale ?? 1;
|
|
159
152
|
const sy = node.yScale ?? node.scale ?? 1;
|
|
160
153
|
const fontScale = Math.min(sx, sy);
|
|
@@ -201,29 +194,7 @@ var layoutNode = (node, measureText, nameStack, nodeDistance, scopeChain = [], l
|
|
|
201
194
|
const minH = node.minimumHeight ?? node.minimumSize ?? 0;
|
|
202
195
|
const innerHalfW = Math.max(textWidth / 2 + xSep, xSep, minW / 2);
|
|
203
196
|
const innerHalfH = Math.max(textHeight / 2 + ySep, ySep, minH / 2);
|
|
204
|
-
const
|
|
205
|
-
let boundsHalfW;
|
|
206
|
-
let boundsHalfH;
|
|
207
|
-
switch (shape) {
|
|
208
|
-
case "rectangle":
|
|
209
|
-
boundsHalfW = innerHalfW;
|
|
210
|
-
boundsHalfH = innerHalfH;
|
|
211
|
-
break;
|
|
212
|
-
case "circle": {
|
|
213
|
-
const r = Math.sqrt(innerHalfW * innerHalfW + innerHalfH * innerHalfH);
|
|
214
|
-
boundsHalfW = r;
|
|
215
|
-
boundsHalfH = r;
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
case "ellipse":
|
|
219
|
-
boundsHalfW = innerHalfW * SQRT2;
|
|
220
|
-
boundsHalfH = innerHalfH * SQRT2;
|
|
221
|
-
break;
|
|
222
|
-
case "diamond":
|
|
223
|
-
boundsHalfW = innerHalfW * 2;
|
|
224
|
-
boundsHalfH = innerHalfH * 2;
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
197
|
+
const { halfWidth: boundsHalfW, halfHeight: boundsHalfH } = shapeDef.circumscribe(innerHalfW, innerHalfH);
|
|
227
198
|
const rotateDeg = node.rotate ?? 0;
|
|
228
199
|
const center = require_position.resolvePosition(node.position, nameStack, nodeDistance, scopeChain);
|
|
229
200
|
if (!center) throw new Error(`Cannot resolve position for node ${node.id ?? "(unnamed)"}; polar.origin or at.of may reference an undefined node`);
|
|
@@ -238,12 +209,15 @@ var layoutNode = (node, measureText, nameStack, nodeDistance, scopeChain = [], l
|
|
|
238
209
|
fontSize: (labFont?.size ?? labelDefault?.font?.size ?? baseFontSize) * fontScale,
|
|
239
210
|
fontFamily: labFont?.family ?? labelDefault?.font?.family ?? fontFamily,
|
|
240
211
|
fontWeight: labFont?.weight ?? labelDefault?.font?.weight ?? fontWeight,
|
|
241
|
-
fontStyle: labFont?.style ?? labelDefault?.font?.style ?? fontStyle
|
|
212
|
+
fontStyle: labFont?.style ?? labelDefault?.font?.style ?? fontStyle,
|
|
213
|
+
rotate: lab.rotate,
|
|
214
|
+
keepUpright: lab.keepUpright
|
|
242
215
|
};
|
|
243
216
|
});
|
|
244
217
|
return {
|
|
245
218
|
id: node.id,
|
|
246
|
-
|
|
219
|
+
shapeName,
|
|
220
|
+
shapeDef,
|
|
247
221
|
rect: {
|
|
248
222
|
x: center[0],
|
|
249
223
|
y: center[1],
|
|
@@ -274,97 +248,28 @@ var layoutNode = (node, measureText, nameStack, nodeDistance, scopeChain = [], l
|
|
|
274
248
|
labels
|
|
275
249
|
};
|
|
276
250
|
};
|
|
277
|
-
/**
|
|
278
|
-
var
|
|
279
|
-
|
|
280
|
-
const halfH = layout.rect.height / 2;
|
|
281
|
-
return {
|
|
282
|
-
type: "rect",
|
|
283
|
-
x: round(layout.rect.x - halfW),
|
|
284
|
-
y: round(layout.rect.y - halfH),
|
|
285
|
-
width: round(layout.rect.width),
|
|
286
|
-
height: round(layout.rect.height),
|
|
287
|
-
fill: layout.fill ?? "transparent",
|
|
288
|
-
fillOpacity: layout.fillOpacity,
|
|
289
|
-
stroke: layout.stroke ?? "currentColor",
|
|
290
|
-
strokeOpacity: layout.strokeOpacity,
|
|
291
|
-
strokeWidth: layout.strokeWidth ?? 1,
|
|
292
|
-
dashPattern: layout.dashPattern,
|
|
293
|
-
cornerRadius: layout.roundedCorners,
|
|
294
|
-
opacity: layout.opacity
|
|
295
|
-
};
|
|
296
|
-
};
|
|
297
|
-
/** circle/ellipse → EllipsePrim(圆形 rx=ry) */
|
|
298
|
-
var emitEllipseShape = (layout, round) => ({
|
|
299
|
-
type: "ellipse",
|
|
300
|
-
cx: round(layout.rect.x),
|
|
301
|
-
cy: round(layout.rect.y),
|
|
302
|
-
rx: round(layout.rect.width / 2),
|
|
303
|
-
ry: round(layout.rect.height / 2),
|
|
304
|
-
fill: layout.fill ?? "transparent",
|
|
251
|
+
/** 从 NodeLayout 收敛 emit 所需的视觉样式子集(ShapeStyle,不含几何 / 文本) */
|
|
252
|
+
var toShapeStyle = (layout) => ({
|
|
253
|
+
fill: layout.fill,
|
|
305
254
|
fillOpacity: layout.fillOpacity,
|
|
306
|
-
stroke: layout.stroke
|
|
255
|
+
stroke: layout.stroke,
|
|
307
256
|
strokeOpacity: layout.strokeOpacity,
|
|
308
|
-
strokeWidth: layout.strokeWidth
|
|
257
|
+
strokeWidth: layout.strokeWidth,
|
|
309
258
|
dashPattern: layout.dashPattern,
|
|
259
|
+
roundedCorners: layout.roundedCorners,
|
|
310
260
|
opacity: layout.opacity
|
|
311
261
|
});
|
|
312
|
-
/** diamond → PathPrim(4 顶点 + close 闭合) */
|
|
313
|
-
var emitDiamondShape = (layout, round) => {
|
|
314
|
-
const diam = diamondOf(layout, 0);
|
|
315
|
-
const e = require_diamond.diamond.anchor(diam, "east");
|
|
316
|
-
const n = require_diamond.diamond.anchor(diam, "north");
|
|
317
|
-
const w = require_diamond.diamond.anchor(diam, "west");
|
|
318
|
-
const s = require_diamond.diamond.anchor(diam, "south");
|
|
319
|
-
return {
|
|
320
|
-
type: "path",
|
|
321
|
-
commands: [
|
|
322
|
-
{
|
|
323
|
-
kind: "move",
|
|
324
|
-
to: [round(e[0]), round(e[1])]
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
kind: "line",
|
|
328
|
-
to: [round(n[0]), round(n[1])]
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
kind: "line",
|
|
332
|
-
to: [round(w[0]), round(w[1])]
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
kind: "line",
|
|
336
|
-
to: [round(s[0]), round(s[1])]
|
|
337
|
-
},
|
|
338
|
-
{ kind: "close" }
|
|
339
|
-
],
|
|
340
|
-
fill: layout.fill ?? "transparent",
|
|
341
|
-
fillOpacity: layout.fillOpacity,
|
|
342
|
-
stroke: layout.stroke ?? "currentColor",
|
|
343
|
-
strokeOpacity: layout.strokeOpacity,
|
|
344
|
-
strokeWidth: layout.strokeWidth ?? 1,
|
|
345
|
-
dashPattern: layout.dashPattern,
|
|
346
|
-
opacity: layout.opacity
|
|
347
|
-
};
|
|
348
|
-
};
|
|
349
262
|
/**
|
|
350
263
|
* NodeLayout → Scene primitives
|
|
351
|
-
* @description shape
|
|
264
|
+
* @description shape 主体走 `shapeDef.emit`(收轴对齐 rect、可出多 primitive);text 始终走 TextPrim;
|
|
265
|
+
* 有旋转时外层 GroupPrim 用 `rotate(deg cx cy)` 统一包裹 shape + text(diamond 顶点 / text 都靠 group 旋转)
|
|
352
266
|
*/
|
|
353
267
|
var emitNodePrimitives = (layout, round) => {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
case "circle":
|
|
360
|
-
case "ellipse":
|
|
361
|
-
shapePrim = emitEllipseShape(layout, round);
|
|
362
|
-
break;
|
|
363
|
-
case "diamond":
|
|
364
|
-
shapePrim = emitDiamondShape(unrotated(layout), round);
|
|
365
|
-
break;
|
|
366
|
-
}
|
|
367
|
-
const inner = [shapePrim];
|
|
268
|
+
const axisAlignedRect = {
|
|
269
|
+
...layout.rect,
|
|
270
|
+
rotate: 0
|
|
271
|
+
};
|
|
272
|
+
const inner = [...layout.shapeDef.emit(axisAlignedRect, toShapeStyle(layout), round)];
|
|
368
273
|
if (layout.lines) {
|
|
369
274
|
const halfBlockW = layout.textWidth / 2;
|
|
370
275
|
const xOffset = layout.align === "start" ? -halfBlockW : layout.align === "end" ? halfBlockW : 0;
|
|
@@ -386,46 +291,55 @@ var emitNodePrimitives = (layout, round) => {
|
|
|
386
291
|
measuredHeight: round(layout.textHeight)
|
|
387
292
|
});
|
|
388
293
|
}
|
|
389
|
-
if (layout.labels)
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
294
|
+
if (layout.labels) {
|
|
295
|
+
const cx = layout.rect.x;
|
|
296
|
+
const cy = layout.rect.y;
|
|
297
|
+
for (const lab of layout.labels) {
|
|
298
|
+
const [lx, ly] = labelCenter(layout, lab);
|
|
299
|
+
const textPrim = {
|
|
300
|
+
type: "text",
|
|
301
|
+
x: round(lx),
|
|
302
|
+
y: round(ly),
|
|
303
|
+
lines: [{ text: lab.text }],
|
|
304
|
+
fontSize: lab.fontSize,
|
|
305
|
+
fontFamily: lab.fontFamily,
|
|
306
|
+
fontWeight: lab.fontWeight,
|
|
307
|
+
fontStyle: lab.fontStyle,
|
|
308
|
+
align: "middle",
|
|
309
|
+
baseline: "middle",
|
|
310
|
+
lineHeight: round(lab.fontSize * DEFAULT_LINE_HEIGHT_FACTOR),
|
|
311
|
+
fill: lab.textColor ?? "currentColor",
|
|
312
|
+
opacity: lab.opacity ?? layout.opacity,
|
|
313
|
+
measuredWidth: 0,
|
|
314
|
+
measuredHeight: round(lab.fontSize)
|
|
315
|
+
};
|
|
316
|
+
const deg = resolveLabelRotateDeg(lab, lx, ly, cx, cy);
|
|
317
|
+
if (deg === 0) inner.push(textPrim);
|
|
318
|
+
else inner.push({
|
|
319
|
+
type: "group",
|
|
320
|
+
transforms: [{
|
|
321
|
+
kind: "rotate",
|
|
322
|
+
degrees: round(deg),
|
|
323
|
+
cx: round(lx),
|
|
324
|
+
cy: round(ly)
|
|
325
|
+
}],
|
|
326
|
+
children: [textPrim]
|
|
327
|
+
});
|
|
328
|
+
}
|
|
408
329
|
}
|
|
409
|
-
if (layout.rotateDeg
|
|
410
|
-
|
|
330
|
+
if (!(layout.rotateDeg !== 0 || layout.lines !== void 0)) return inner;
|
|
331
|
+
const group = {
|
|
411
332
|
type: "group",
|
|
412
|
-
transforms: [{
|
|
413
|
-
kind: "rotate",
|
|
414
|
-
degrees: round(layout.rotateDeg),
|
|
415
|
-
cx: round(layout.rect.x),
|
|
416
|
-
cy: round(layout.rect.y)
|
|
417
|
-
}],
|
|
418
333
|
children: inner
|
|
334
|
+
};
|
|
335
|
+
if (layout.rotateDeg !== 0) group.transforms = [{
|
|
336
|
+
kind: "rotate",
|
|
337
|
+
degrees: round(layout.rotateDeg),
|
|
338
|
+
cx: round(layout.rect.x),
|
|
339
|
+
cy: round(layout.rect.y)
|
|
419
340
|
}];
|
|
341
|
+
return [group];
|
|
420
342
|
};
|
|
421
|
-
/** layout 的"未旋转"副本,让 diamond 顶点先按未旋转算,外层 group 统一旋转 */
|
|
422
|
-
var unrotated = (layout) => ({
|
|
423
|
-
...layout,
|
|
424
|
-
rect: {
|
|
425
|
-
...layout.rect,
|
|
426
|
-
rotate: 0
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
343
|
//#endregion
|
|
430
344
|
exports.anchorOf = anchorOf;
|
|
431
345
|
exports.angleBoundaryOf = angleBoundaryOf;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { Position } from '../geometry/point';
|
|
2
|
-
import { Rect
|
|
3
|
-
import { AtDirection, IRLabelDefault, IRNode
|
|
2
|
+
import { Rect } from '../geometry/rect';
|
|
3
|
+
import { AtDirection, IRLabelDefault, IRNode } from '../ir';
|
|
4
4
|
import { ScenePrimitive, TextLine, Transform } from '../primitive';
|
|
5
|
+
import { ShapeDefinition } from '../shapes';
|
|
5
6
|
import { NameStack } from './name-stack';
|
|
6
7
|
import { TextMeasurer } from './text-metrics';
|
|
7
8
|
export type NodeLayout = {
|
|
8
9
|
/** 节点 id(其他位置可引用) */
|
|
9
10
|
id?: string;
|
|
10
|
-
/**
|
|
11
|
-
|
|
11
|
+
/** 节点形状名(诊断 / 错误信息用;几何走 shapeDef) */
|
|
12
|
+
shapeName: string;
|
|
13
|
+
/** 已解析的 shape 定义;circumscribe / boundaryPoint / anchor / emit 多点复用,取代旧 switch */
|
|
14
|
+
shapeDef: ShapeDefinition;
|
|
12
15
|
/**
|
|
13
16
|
* 节点视觉边界框(所有 shape 共享语义)
|
|
14
17
|
* @description rectangle: rect 本身;circle: width=height=2×radius;ellipse: 2×rx,2×ry;diamond: 2×halfA,2×halfB。x,y 是几何中心,rotate 弧度
|
|
@@ -76,17 +79,22 @@ export type NodeLabelLayout = {
|
|
|
76
79
|
fontFamily?: string;
|
|
77
80
|
fontWeight?: string | number;
|
|
78
81
|
fontStyle?: 'normal' | 'italic' | 'oblique';
|
|
82
|
+
/** label 文本自旋模式(none / radial / tangent / 数字角度);缺省 = 不旋转 */
|
|
83
|
+
rotate?: 'none' | 'radial' | 'tangent' | number;
|
|
84
|
+
/** 自旋后若文字倒置则翻 180°;缺省 false */
|
|
85
|
+
keepUpright?: boolean;
|
|
79
86
|
};
|
|
80
87
|
/**
|
|
81
88
|
* 取节点 shape 在 toward 方向的附着点(path 端点贴边用)
|
|
82
|
-
* @description
|
|
89
|
+
* @description 走 shapeDef.boundaryPoint;margin > 0 时先膨胀外接 Rect,让 path 在 border 外停 margin
|
|
83
90
|
*/
|
|
84
91
|
export declare const boundaryPointOf: (layout: NodeLayout, toward: Position) => Position;
|
|
85
92
|
/**
|
|
86
|
-
* 取节点 shape 命名 anchor(center / north / east / north-east
|
|
87
|
-
* @description 不应用 margin——TikZ 语义中 explicit anchor 取视觉边界点不涉及 outer sep;用于 `'A.north'`
|
|
93
|
+
* 取节点 shape 命名 anchor(center / north / east / north-east 等)
|
|
94
|
+
* @description 不应用 margin——TikZ 语义中 explicit anchor 取视觉边界点不涉及 outer sep;用于 `'A.north'` 落点。
|
|
95
|
+
* shapeDef.anchor 不认识的名字返回 undefined,此处抛 Unknown anchor(列出 shape 名)
|
|
88
96
|
*/
|
|
89
|
-
export declare const anchorOf: (layout: NodeLayout, name:
|
|
97
|
+
export declare const anchorOf: (layout: NodeLayout, name: string) => Position;
|
|
90
98
|
/**
|
|
91
99
|
* 取节点 shape 在指定角度方向的边界点
|
|
92
100
|
* @description 角度是节点**局部坐标系**下的极角(度数:0°=局部 +x,90°=局部 +y)。layout.rect.rotate 把局部基绕中心旋转,得到世界系下的视觉方向;shape boundaryPoint 内部用 rotate-aware 投影,所以这里把局部 (cos, sin) 经 rect.rotate 旋转后加到中心当作世界系 toward 传入。不应用 margin(同 anchorOf);用于 `'A.30'` 落点
|
|
@@ -99,10 +107,11 @@ export declare const angleBoundaryOf: (layout: NodeLayout, angleDeg: number) =>
|
|
|
99
107
|
* scope 局部度量),调用方负责后续 `projectLayoutToGlobal` / `applyTransformChain` 投回全局;
|
|
100
108
|
* 笛卡尔字面量 `Position` 已在 scope 局部度量,行为延续 v0.1。
|
|
101
109
|
*/
|
|
102
|
-
export declare const layoutNode: (node: IRNode, measureText: TextMeasurer, nameStack: NameStack, nodeDistance?: number, scopeChain?: ReadonlyArray<Transform>, labelDefault?: IRLabelDefault) => NodeLayout;
|
|
110
|
+
export declare const layoutNode: (node: IRNode, measureText: TextMeasurer, nameStack: NameStack, nodeDistance?: number, scopeChain?: ReadonlyArray<Transform>, labelDefault?: IRLabelDefault, shapes?: Record<string, ShapeDefinition>) => NodeLayout;
|
|
103
111
|
/**
|
|
104
112
|
* NodeLayout → Scene primitives
|
|
105
|
-
* @description shape
|
|
113
|
+
* @description shape 主体走 `shapeDef.emit`(收轴对齐 rect、可出多 primitive);text 始终走 TextPrim;
|
|
114
|
+
* 有旋转时外层 GroupPrim 用 `rotate(deg cx cy)` 统一包裹 shape + text(diamond 顶点 / text 都靠 group 旋转)
|
|
106
115
|
*/
|
|
107
116
|
export declare const emitNodePrimitives: (layout: NodeLayout, round: (n: number) => number) => Array<ScenePrimitive>;
|
|
108
117
|
//# sourceMappingURL=node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/compile/node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/compile/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_rect = require("../geometry/rect.cjs");
|
|
2
|
+
const require_index = require("../shapes/index.cjs");
|
|
2
3
|
const require_position = require("./position.cjs");
|
|
3
4
|
//#region src/compile/scope.ts
|
|
4
5
|
/**
|
|
@@ -235,7 +236,8 @@ var registerScopeAsLayout = (id, bbox, fallbackOrigin) => {
|
|
|
235
236
|
};
|
|
236
237
|
return {
|
|
237
238
|
id,
|
|
238
|
-
|
|
239
|
+
shapeName: "rectangle",
|
|
240
|
+
shapeDef: require_index.BUILTIN_SHAPES.rectangle,
|
|
239
241
|
rect: {
|
|
240
242
|
x: box.x,
|
|
241
243
|
y: box.y,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/compile/scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EAEZ,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/compile/scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EAEZ,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGzC;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,aAAa,CAAC,WAAW,CAAC,EACtC,WAAW,SAAS,EACpB,eAAe,MAAM,KACpB,KAAK,CAAC,SAAS,CAAC,GAAG,IAiDrB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,OAAO,aAAa,CAAC,SAAS,CAAC,KAC9B,UAyBF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,UAAU,EAClB,OAAO,aAAa,CAAC,SAAS,CAAC,KAC9B,UAgCF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,UAAU,EAClB,OAAO,aAAa,CAAC,SAAS,CAAC,KAC9B,UAuBF,CAAC;AAEF,8EAA8E;AAC9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wBAAwB;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,wBAAwB;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAClC,SAAS,aAAa,CAAC,UAAU,CAAC,KACjC,gBAAgB,GAAG,IA2BrB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAChC,IAAI,MAAM,EACV,MAAM,gBAAgB,GAAG,IAAI,EAC7B,gBAAgB,UAAU,KACzB,UAgBF,CAAC"}
|
package/dist/lib/index.cjs
CHANGED
|
@@ -14,10 +14,12 @@ const require_coordinate = require("./ir/coordinate.cjs");
|
|
|
14
14
|
const require_transform = require("./ir/transform.cjs");
|
|
15
15
|
const require_scope = require("./ir/scope.cjs");
|
|
16
16
|
const require_scene = require("./ir/scene.cjs");
|
|
17
|
+
const require__transform = require("./geometry/_transform.cjs");
|
|
17
18
|
const require_rect = require("./geometry/rect.cjs");
|
|
18
19
|
const require_circle = require("./geometry/circle.cjs");
|
|
19
|
-
const require_diamond = require("./geometry/diamond.cjs");
|
|
20
20
|
const require_ellipse = require("./geometry/ellipse.cjs");
|
|
21
|
+
const require_diamond = require("./geometry/diamond.cjs");
|
|
22
|
+
const require_index = require("./shapes/index.cjs");
|
|
21
23
|
const require_text_metrics = require("./compile/text-metrics.cjs");
|
|
22
24
|
const require_layout = require("./compile/layout.cjs");
|
|
23
25
|
const require_compile = require("./compile/compile.cjs");
|
|
@@ -34,6 +36,7 @@ exports.ArrowDefaultSchema = require_scope.ArrowDefaultSchema;
|
|
|
34
36
|
exports.ArrowDetailSchema = require_arrow.ArrowDetailSchema;
|
|
35
37
|
exports.ArrowEndDetailSchema = require_arrow.ArrowEndDetailSchema;
|
|
36
38
|
exports.AtPositionSchema = require_at_position.AtPositionSchema;
|
|
39
|
+
exports.BUILTIN_SHAPES = require_index.BUILTIN_SHAPES;
|
|
37
40
|
exports.BendStepSchema = require_step.BendStepSchema;
|
|
38
41
|
exports.CURRENT_IR_VERSION = require_scene.CURRENT_IR_VERSION;
|
|
39
42
|
exports.ChildSchema = require_scene.ChildSchema;
|
|
@@ -79,8 +82,10 @@ exports.computeLayout = require_layout.computeLayout;
|
|
|
79
82
|
exports.diamond = require_diamond.diamond;
|
|
80
83
|
exports.ellipse = require_ellipse.ellipse;
|
|
81
84
|
exports.fallbackMeasurer = require_text_metrics.fallbackMeasurer;
|
|
85
|
+
exports.localToWorld = require__transform.localToWorld;
|
|
82
86
|
exports.parseTargetSugar = require_parseTargetSugar.parseTargetSugar;
|
|
83
87
|
exports.parseWay = require_parseWay.parseWay;
|
|
84
88
|
exports.point = require_point.point;
|
|
85
89
|
exports.polar = require_polar.polar;
|
|
86
90
|
exports.rect = require_rect.rect;
|
|
91
|
+
exports.worldToLocal = require__transform.worldToLocal;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @description 任何 framework adapter(@retikz/react、@retikz/vue、@retikz/canvas、@retikz/ssr)只能 import 本文件导出内容,不准走子路径。本包零 React/零 DOM 依赖
|
|
4
4
|
*/
|
|
5
5
|
export { PositionSchema, PolarPositionSchema, AtPositionSchema, OffsetPositionSchema, AT_DIRECTIONS, TargetSchema, RelativeTargetSchema, RelativeAccumulateTargetSchema, MoveStepSchema, LineStepSchema, FoldStepSchema, CycleStepSchema, CurveStepSchema, CubicStepSchema, BendStepSchema, ArcStepSchema, CirclePathStepSchema, EllipsePathStepSchema, ControlPointSchema, StepLabelSchema, StepSchema, NodeSchema, NodeLabelSchema, CoordinateSchema, FontSchema, TextBlockSchema, LineSpecSchema, PathSchema, ArrowDetailSchema, ArrowEndDetailSchema, ScopeSchema, NodeDefaultSchema, PathDefaultSchema, LabelDefaultSchema, ArrowDefaultSchema, TransformSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
|
|
6
|
-
export type { IRPosition, IRAtPosition, IROffsetPosition, AtDirection, IRTarget, IRRelativeTarget, IRRelativeAccumulateTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRCurveStep, IRCubicStep, IRBendStep, IRArcStep, IRCirclePathStep, IREllipsePathStep, IRControlPoint, IRStepLabel, IRStep, IRNode, IRNodeLabel, IRCoordinate, IRFont, IRLineSpec, IRTextBlock, IRPath, IRScope, IRNodeDefault, IRPathDefault, IRLabelDefault, IRArrowDefault, StyleChannel, IRTransform, IRTranslateTransform, IRPolarTranslateTransform, IRAtTranslateTransform, IROffsetTranslateTransform, IRRotateTransform, IRScaleTransform, IRChild, IR, ArrowShape, IRArrowDetail, IRArrowEndDetail, NodeShape, NodeTextAlign, } from './ir';
|
|
6
|
+
export type { IRPosition, IRAtPosition, IROffsetPosition, AtDirection, IRTarget, IRRelativeTarget, IRRelativeAccumulateTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRCurveStep, IRCubicStep, IRBendStep, IRArcStep, IRCirclePathStep, IREllipsePathStep, IRControlPoint, IRStepLabel, IRStep, IRNode, IRNodeLabel, IRCoordinate, IRFont, IRLineSpec, IRTextBlock, IRPath, IRScope, IRNodeDefault, IRPathDefault, IRLabelDefault, IRArrowDefault, StyleChannel, IRTransform, IRTranslateTransform, IRPolarTranslateTransform, IRAtTranslateTransform, IROffsetTranslateTransform, IRRotateTransform, IRScaleTransform, IRChild, IR, ArrowShape, IRArrowDetail, IRArrowEndDetail, NodeShape, BuiltinShapeName, NodeTextAlign, } from './ir';
|
|
7
7
|
export { ARROW_SHAPES, DEFAULT_ARROW_SHAPE, HOLLOW_ARROW_SHAPES, ARROW_MARKER_DEFAULT_SIZE, ARROW_MARKER_HOLLOW_DEFAULT_LINE_WIDTH, NODE_SHAPES, NODE_TEXT_ALIGNS, } from './ir';
|
|
8
8
|
export type { ScenePrimitive, RectPrim, EllipsePrim, TextPrim, TextLine, PathPrim, PathCommand,
|
|
9
9
|
/** 7 个 named PathCommand 分支(便于 wrapper / Pick<>) */
|
|
@@ -16,5 +16,7 @@ export type { WayItem, WayDSL, WayCycle, WayVia, WayRelativeItem, WayLabel, WayL
|
|
|
16
16
|
export { parseWay, DrawWay, parseTargetSugar } from './parsers';
|
|
17
17
|
export type { Position, Rect, RectAnchor, Circle, Ellipse, Diamond, PolarPosition, } from './geometry';
|
|
18
18
|
export { point, rect, circle, ellipse, diamond, RECT_ANCHORS, polar } from './geometry';
|
|
19
|
+
export type { ShapeDefinition, ShapeStyle } from './shapes';
|
|
20
|
+
export { BUILTIN_SHAPES, worldToLocal, localToWorld } from './shapes';
|
|
19
21
|
export type { ValueOf, AssertEqual } from './types';
|
|
20
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,8BAA8B,EAC9B,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,MAAM,CAAC;AACd,YAAY,EACV,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,0BAA0B,EAC1B,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,MAAM,EACN,MAAM,EACN,WAAW,EACX,YAAY,EACZ,MAAM,EACN,UAAU,EACV,WAAW,EACX,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EAChB,OAAO,EACP,EAAE,EACF,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,GACd,MAAM,MAAM,CAAC;AACd,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,sCAAsC,EACtC,WAAW,EACX,gBAAgB,GACjB,MAAM,MAAM,CAAC;AAGd,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW;AACX,oDAAoD;AACpD,eAAe,EACf,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,SAAS;AACT,6BAA6B;AAC7B,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,MAAM,EACN,KAAK,GACN,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG5E,YAAY,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,EACN,eAAe,EACf,QAAQ,EACR,UAAU,GACX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAIhE,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,MAAM,EACN,OAAO,EACP,OAAO,EACP,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxF,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/ir/node.cjs
CHANGED
|
@@ -32,12 +32,18 @@ var NodeLabelSchema = zod.z.object({
|
|
|
32
32
|
distance: zod.z.number().nonnegative().optional().describe("Gap between the node border and the label center, in user units. Default 12."),
|
|
33
33
|
textColor: zod.z.string().optional().describe("Label text color; falls back to currentColor."),
|
|
34
34
|
opacity: zod.z.number().min(0).max(1).optional().describe("Label-only opacity 0..1; multiplied with the node opacity if both are set."),
|
|
35
|
-
font: require_font.FontSchema.optional().describe("Label font overrides; missing fields inherit from the parent node font, then renderer defaults.")
|
|
35
|
+
font: require_font.FontSchema.optional().describe("Label font overrides; missing fields inherit from the parent node font, then renderer defaults."),
|
|
36
|
+
rotate: zod.z.union([zod.z.enum([
|
|
37
|
+
"none",
|
|
38
|
+
"radial",
|
|
39
|
+
"tangent"
|
|
40
|
+
]), zod.z.number()]).optional().describe("Rotate the label text around its own center. `none` (default) = horizontal; `radial` = along the node-center -> label-center direction; `tangent` = radial + 90 deg; a number = explicit degrees (screen y-down: 0 = +x, 90 = +y). Only changes text orientation, not placement."),
|
|
41
|
+
keepUpright: zod.z.boolean().optional().describe("When true, flips the rotated label 180 deg if it would otherwise read upside-down (more than 90 deg from upright). Default false (strict geometric angle).")
|
|
36
42
|
}).describe("Extra text attached around a node border. Multiple labels supported via array form on `Node.label`.");
|
|
37
43
|
var NodeSchema = zod.z.object({
|
|
38
44
|
type: zod.z.literal("node").describe("Discriminator marking this child as a node"),
|
|
39
45
|
id: zod.z.string().min(1).optional().describe("Optional unique id; required if any path needs to reference this node by string"),
|
|
40
|
-
shape: zod.z.
|
|
46
|
+
shape: zod.z.string().min(1).optional().describe("Node visual shape name; built-in `rectangle` / `circle` / `ellipse` / `diamond`, or an extension shape registered via `CompileOptions.shapes`. Any non-empty string passes schema validation; unregistered names are rejected at compile time. Defaults to `rectangle`. The boundary fully contains text + padding (circumscribed for circle / ellipse / diamond)."),
|
|
41
47
|
position: zod.z.union([
|
|
42
48
|
require_position.PositionSchema,
|
|
43
49
|
require_polar_position.PolarPositionSchema,
|
|
@@ -72,7 +78,8 @@ var NodeSchema = zod.z.object({
|
|
|
72
78
|
padding: zod.z.number().nonnegative().optional().describe("Symmetric inner padding (alias for `innerXSep` + `innerYSep`); axis-specific fields take precedence."),
|
|
73
79
|
margin: zod.z.number().nonnegative().optional().describe("Symmetric outer margin (alias for `outerSep`); axis-specific field takes precedence."),
|
|
74
80
|
font: require_font.FontSchema.optional().describe("Font spec for the inner text label (family / size / weight / style); all fields optional, all fall back to renderer defaults."),
|
|
75
|
-
label: zod.z.union([NodeLabelSchema, zod.z.array(NodeLabelSchema)]).optional().describe("Extra label(s) attached around the node border (TikZ `[label=above:foo]`); single object or array form. Compiled into one TextPrim per label, positioned by `position` direction / angle and `distance`.")
|
|
81
|
+
label: zod.z.union([NodeLabelSchema, zod.z.array(NodeLabelSchema)]).optional().describe("Extra label(s) attached around the node border (TikZ `[label=above:foo]`); single object or array form. Compiled into one TextPrim per label, positioned by `position` direction / angle and `distance`."),
|
|
82
|
+
zIndex: zod.z.number().int().finite().optional().describe("Explicit stacking order among sibling IR children. Higher draws on top. Omitted = 0 = source order. Sorting is stable: same zIndex keeps source order. Scoped per group (a node inside a scope only restacks within that scope).")
|
|
76
83
|
}).describe("Node primitive: a positioned, optionally textual shape (rectangle / circle / ellipse / diamond)");
|
|
77
84
|
//#endregion
|
|
78
85
|
exports.NODE_SHAPES = NODE_SHAPES;
|