sketchmark 0.2.0 → 0.2.2
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/animation/index.d.ts +2 -1
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/ast/types.d.ts +0 -4
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/index.cjs +351 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +351 -136
- package/dist/index.js.map +1 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/renderer/canvas/index.d.ts.map +1 -1
- package/dist/renderer/canvas/roughChartCanvas.d.ts.map +1 -1
- package/dist/renderer/svg/index.d.ts.map +1 -1
- package/dist/renderer/svg/roughChartSVG.d.ts.map +1 -1
- package/dist/sketchmark.iife.js +351 -136
- package/package.json +1 -1
package/dist/sketchmark.iife.js
CHANGED
|
@@ -262,10 +262,6 @@ var AIDiagram = (function (exports) {
|
|
|
262
262
|
s.color = p.color;
|
|
263
263
|
if (p.opacity)
|
|
264
264
|
s.opacity = parseFloat(p.opacity);
|
|
265
|
-
if (p.radius)
|
|
266
|
-
s.radius = parseFloat(p.radius);
|
|
267
|
-
if (p.shadow)
|
|
268
|
-
s.shadow = p.shadow === "true";
|
|
269
265
|
if (p["font-size"])
|
|
270
266
|
s.fontSize = parseFloat(p["font-size"]);
|
|
271
267
|
if (p["font-weight"])
|
|
@@ -282,8 +278,9 @@ var AIDiagram = (function (exports) {
|
|
|
282
278
|
s.letterSpacing = parseFloat(p["letter-spacing"]);
|
|
283
279
|
if (p.font)
|
|
284
280
|
s.font = p.font;
|
|
285
|
-
|
|
286
|
-
|
|
281
|
+
const dashVal = p["dash"] || p["stroke-dash"];
|
|
282
|
+
if (dashVal) {
|
|
283
|
+
const parts = dashVal
|
|
287
284
|
.split(",")
|
|
288
285
|
.map(Number)
|
|
289
286
|
.filter((n) => !isNaN(n));
|
|
@@ -1490,13 +1487,22 @@ var AIDiagram = (function (exports) {
|
|
|
1490
1487
|
n.h = n.h || 50;
|
|
1491
1488
|
break;
|
|
1492
1489
|
case "text": {
|
|
1493
|
-
// read fontSize from style if set, otherwise use default
|
|
1494
1490
|
const fontSize = Number(n.style?.fontSize ?? 13);
|
|
1495
1491
|
const charWidth = fontSize * 0.55;
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1492
|
+
const pad = Number(n.style?.padding ?? 8) * 2;
|
|
1493
|
+
if (n.width) {
|
|
1494
|
+
// User set width → word-wrap within it
|
|
1495
|
+
const approxLines = Math.ceil((n.label.length * charWidth) / (n.width - pad));
|
|
1496
|
+
n.w = n.width;
|
|
1497
|
+
n.h = n.height ?? Math.max(24, approxLines * fontSize * 1.5 + pad);
|
|
1498
|
+
}
|
|
1499
|
+
else {
|
|
1500
|
+
// Auto-size to content
|
|
1501
|
+
const lines = n.label.split("\\n");
|
|
1502
|
+
const longest = lines.reduce((a, b) => (a.length > b.length ? a : b), "");
|
|
1503
|
+
n.w = Math.max(MIN_W, Math.round(longest.length * charWidth + pad));
|
|
1504
|
+
n.h = n.height ?? Math.max(24, lines.length * fontSize * 1.5 + pad);
|
|
1505
|
+
}
|
|
1500
1506
|
break;
|
|
1501
1507
|
}
|
|
1502
1508
|
default:
|
|
@@ -1713,17 +1719,16 @@ var AIDiagram = (function (exports) {
|
|
|
1713
1719
|
if (layout === "row") {
|
|
1714
1720
|
const ws = kids.map((r) => iW(r, nm, gm, tm, ntm, cm, mdm));
|
|
1715
1721
|
const hs = kids.map((r) => iH(r, nm, gm, tm, ntm, cm, mdm));
|
|
1716
|
-
const maxH = Math.max(...hs);
|
|
1717
1722
|
const { start, gaps } = distribute(ws, contentW, gap, justify);
|
|
1718
1723
|
let x = contentX + start;
|
|
1719
1724
|
for (let i = 0; i < kids.length; i++) {
|
|
1720
1725
|
let y;
|
|
1721
1726
|
switch (align) {
|
|
1722
1727
|
case "center":
|
|
1723
|
-
y = contentY + (
|
|
1728
|
+
y = contentY + (contentH - hs[i]) / 2;
|
|
1724
1729
|
break;
|
|
1725
1730
|
case "end":
|
|
1726
|
-
y = contentY +
|
|
1731
|
+
y = contentY + contentH - hs[i];
|
|
1727
1732
|
break;
|
|
1728
1733
|
default:
|
|
1729
1734
|
y = contentY;
|
|
@@ -1744,17 +1749,16 @@ var AIDiagram = (function (exports) {
|
|
|
1744
1749
|
// column (default)
|
|
1745
1750
|
const ws = kids.map((r) => iW(r, nm, gm, tm, ntm, cm, mdm));
|
|
1746
1751
|
const hs = kids.map((r) => iH(r, nm, gm, tm, ntm, cm, mdm));
|
|
1747
|
-
const maxW = Math.max(...ws);
|
|
1748
1752
|
const { start, gaps } = distribute(hs, contentH, gap, justify);
|
|
1749
1753
|
let y = contentY + start;
|
|
1750
1754
|
for (let i = 0; i < kids.length; i++) {
|
|
1751
1755
|
let x;
|
|
1752
1756
|
switch (align) {
|
|
1753
1757
|
case "center":
|
|
1754
|
-
x = contentX + (
|
|
1758
|
+
x = contentX + (contentW - ws[i]) / 2;
|
|
1755
1759
|
break;
|
|
1756
1760
|
case "end":
|
|
1757
|
-
x = contentX +
|
|
1761
|
+
x = contentX + contentW - ws[i];
|
|
1758
1762
|
break;
|
|
1759
1763
|
default:
|
|
1760
1764
|
x = contentX;
|
|
@@ -2178,13 +2182,13 @@ var AIDiagram = (function (exports) {
|
|
|
2178
2182
|
g.setAttribute('class', cls);
|
|
2179
2183
|
return g;
|
|
2180
2184
|
}
|
|
2181
|
-
function mkT(txt, x, y, sz = 10, wt = 400, col = '#4a2e10', anchor = 'middle') {
|
|
2185
|
+
function mkT(txt, x, y, sz = 10, wt = 400, col = '#4a2e10', anchor = 'middle', font = 'system-ui, sans-serif') {
|
|
2182
2186
|
const t = se$1('text');
|
|
2183
2187
|
t.setAttribute('x', String(x));
|
|
2184
2188
|
t.setAttribute('y', String(y));
|
|
2185
2189
|
t.setAttribute('text-anchor', anchor);
|
|
2186
2190
|
t.setAttribute('dominant-baseline', 'middle');
|
|
2187
|
-
t.setAttribute('font-family',
|
|
2191
|
+
t.setAttribute('font-family', font);
|
|
2188
2192
|
t.setAttribute('font-size', String(sz));
|
|
2189
2193
|
t.setAttribute('font-weight', String(wt));
|
|
2190
2194
|
t.setAttribute('fill', col);
|
|
@@ -2200,7 +2204,7 @@ var AIDiagram = (function (exports) {
|
|
|
2200
2204
|
}
|
|
2201
2205
|
const BASE = { roughness: 1.2, bowing: 0.7 };
|
|
2202
2206
|
// ── Axes ───────────────────────────────────────────────────
|
|
2203
|
-
function drawAxes$1(rc, g, c, px, py, pw, ph, allY, labelCol) {
|
|
2207
|
+
function drawAxes$1(rc, g, c, px, py, pw, ph, allY, labelCol, font = 'system-ui, sans-serif') {
|
|
2204
2208
|
// Y axis
|
|
2205
2209
|
g.appendChild(rc.line(px, py, px, py + ph, {
|
|
2206
2210
|
roughness: 0.4, seed: hashStr$4(c.id + 'ya'), stroke: labelCol, strokeWidth: 1,
|
|
@@ -2219,7 +2223,7 @@ var AIDiagram = (function (exports) {
|
|
|
2219
2223
|
g.appendChild(rc.line(px - 3, ty, px, ty, {
|
|
2220
2224
|
roughness: 0.2, seed: hashStr$4(c.id + 'yt' + tick), stroke: labelCol, strokeWidth: 0.7,
|
|
2221
2225
|
}));
|
|
2222
|
-
g.appendChild(mkT(fmtNum$1(tick), px - 5, ty, 9, 400, labelCol, 'end'));
|
|
2226
|
+
g.appendChild(mkT(fmtNum$1(tick), px - 5, ty, 9, 400, labelCol, 'end', font));
|
|
2223
2227
|
}
|
|
2224
2228
|
}
|
|
2225
2229
|
function fmtNum$1(v) {
|
|
@@ -2228,7 +2232,7 @@ var AIDiagram = (function (exports) {
|
|
|
2228
2232
|
return String(v);
|
|
2229
2233
|
}
|
|
2230
2234
|
// ── Legend row ─────────────────────────────────────────────
|
|
2231
|
-
function legend(g, labels, colors, x, y, labelCol) {
|
|
2235
|
+
function legend(g, labels, colors, x, y, labelCol, font = 'system-ui, sans-serif') {
|
|
2232
2236
|
labels.forEach((lbl, i) => {
|
|
2233
2237
|
const dot = se$1('rect');
|
|
2234
2238
|
dot.setAttribute('x', String(x));
|
|
@@ -2238,7 +2242,7 @@ var AIDiagram = (function (exports) {
|
|
|
2238
2242
|
dot.setAttribute('fill', colors[i % colors.length]);
|
|
2239
2243
|
dot.setAttribute('rx', '1');
|
|
2240
2244
|
g.appendChild(dot);
|
|
2241
|
-
g.appendChild(mkT(lbl, x + 12, y + i * 14 + 4, 9, 400, labelCol, 'start'));
|
|
2245
|
+
g.appendChild(mkT(lbl, x + 12, y + i * 14 + 4, 9, 400, labelCol, 'start', font));
|
|
2242
2246
|
});
|
|
2243
2247
|
}
|
|
2244
2248
|
// ── Public entry ───────────────────────────────────────────
|
|
@@ -2249,6 +2253,11 @@ var AIDiagram = (function (exports) {
|
|
|
2249
2253
|
const bgFill = String(s.fill ?? palette.nodeFill);
|
|
2250
2254
|
const bgStroke = String(s.stroke ?? (isDark ? '#5a4a30' : '#c8b898'));
|
|
2251
2255
|
const lc = String(s.color ?? palette.titleText);
|
|
2256
|
+
const cFont = String(s.font ? `${s.font}, system-ui, sans-serif` : 'system-ui, sans-serif');
|
|
2257
|
+
const cFontSize = Number(s.fontSize ?? 12);
|
|
2258
|
+
const cFontWeight = s.fontWeight ?? 600;
|
|
2259
|
+
if (s.opacity != null)
|
|
2260
|
+
cg.setAttribute('opacity', String(s.opacity));
|
|
2252
2261
|
// Background box
|
|
2253
2262
|
cg.appendChild(rc.rectangle(c.x, c.y, c.w, c.h, {
|
|
2254
2263
|
...BASE, seed: hashStr$4(c.id),
|
|
@@ -2258,7 +2267,7 @@ var AIDiagram = (function (exports) {
|
|
|
2258
2267
|
}));
|
|
2259
2268
|
// Title
|
|
2260
2269
|
if (c.title) {
|
|
2261
|
-
cg.appendChild(mkT(c.title, c.x + c.w / 2, c.y + 14,
|
|
2270
|
+
cg.appendChild(mkT(c.title, c.x + c.w / 2, c.y + 14, cFontSize, cFontWeight, lc, 'middle', cFont));
|
|
2262
2271
|
}
|
|
2263
2272
|
const { px, py, pw, ph, cx, cy } = chartLayout(c);
|
|
2264
2273
|
// ── Pie / Donut ──────────────────────────────────────────
|
|
@@ -2284,7 +2293,7 @@ var AIDiagram = (function (exports) {
|
|
|
2284
2293
|
angle += sweep;
|
|
2285
2294
|
}
|
|
2286
2295
|
// Mini legend on left
|
|
2287
|
-
legend(cg, segments.map(s => `${s.label} ${Math.round(s.value / total * 100)}%`), segments.map(s => s.color), legendX, legendY, lc);
|
|
2296
|
+
legend(cg, segments.map(s => `${s.label} ${Math.round(s.value / total * 100)}%`), segments.map(s => s.color), legendX, legendY, lc, cFont);
|
|
2288
2297
|
return cg;
|
|
2289
2298
|
}
|
|
2290
2299
|
// ── Scatter ───────────────────────────────────────────────
|
|
@@ -2305,7 +2314,7 @@ var AIDiagram = (function (exports) {
|
|
|
2305
2314
|
strokeWidth: 1.2,
|
|
2306
2315
|
}));
|
|
2307
2316
|
});
|
|
2308
|
-
legend(cg, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + (c.title ? 28 : 12), lc);
|
|
2317
|
+
legend(cg, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + (c.title ? 28 : 12), lc, cFont);
|
|
2309
2318
|
return cg;
|
|
2310
2319
|
}
|
|
2311
2320
|
// ── Bar / Line / Area ─────────────────────────────────────
|
|
@@ -2314,10 +2323,10 @@ var AIDiagram = (function (exports) {
|
|
|
2314
2323
|
const toY = makeValueToY(allY, py, ph);
|
|
2315
2324
|
const baseline = toY(0);
|
|
2316
2325
|
const n = labels.length;
|
|
2317
|
-
drawAxes$1(rc, cg, c, px, py, pw, ph, allY, lc);
|
|
2326
|
+
drawAxes$1(rc, cg, c, px, py, pw, ph, allY, lc, cFont);
|
|
2318
2327
|
// X labels
|
|
2319
2328
|
labels.forEach((lbl, i) => {
|
|
2320
|
-
cg.appendChild(mkT(lbl, px + (i + 0.5) * (pw / n), py + ph + 14, 9, 400, lc));
|
|
2329
|
+
cg.appendChild(mkT(lbl, px + (i + 0.5) * (pw / n), py + ph + 14, 9, 400, lc, 'middle', cFont));
|
|
2321
2330
|
});
|
|
2322
2331
|
if (c.chartType === 'bar') {
|
|
2323
2332
|
const groupW = pw / n;
|
|
@@ -2388,7 +2397,7 @@ var AIDiagram = (function (exports) {
|
|
|
2388
2397
|
}
|
|
2389
2398
|
// Multi-series legend
|
|
2390
2399
|
if (series.length > 1) {
|
|
2391
|
-
legend(cg, series.map(s => s.name), series.map(s => s.color), px, py - 2, lc);
|
|
2400
|
+
legend(cg, series.map(s => s.name), series.map(s => s.color), px, py - 2, lc, cFont);
|
|
2392
2401
|
}
|
|
2393
2402
|
return cg;
|
|
2394
2403
|
}
|
|
@@ -4854,6 +4863,14 @@ var AIDiagram = (function (exports) {
|
|
|
4854
4863
|
return h;
|
|
4855
4864
|
}
|
|
4856
4865
|
const BASE_ROUGH = { roughness: 1.3, bowing: 0.7 };
|
|
4866
|
+
/** Darken a CSS hex colour by `amount` (0–1). Falls back to input for non-hex. */
|
|
4867
|
+
function darkenHex$1(hex, amount = 0.12) {
|
|
4868
|
+
const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);
|
|
4869
|
+
if (!m)
|
|
4870
|
+
return hex;
|
|
4871
|
+
const d = (v) => Math.max(0, Math.round(parseInt(v, 16) * (1 - amount)));
|
|
4872
|
+
return `#${d(m[1]).toString(16).padStart(2, "0")}${d(m[2]).toString(16).padStart(2, "0")}${d(m[3]).toString(16).padStart(2, "0")}`;
|
|
4873
|
+
}
|
|
4857
4874
|
// ── Small helper: load + resolve font from style or fall back ─────────────
|
|
4858
4875
|
function resolveStyleFont$1(style, fallback) {
|
|
4859
4876
|
const raw = String(style["font"] ?? "");
|
|
@@ -5024,6 +5041,7 @@ var AIDiagram = (function (exports) {
|
|
|
5024
5041
|
fillStyle: "solid",
|
|
5025
5042
|
stroke,
|
|
5026
5043
|
strokeWidth: Number(s.strokeWidth ?? 1.9),
|
|
5044
|
+
...(s.strokeDash ? { strokeLineDash: s.strokeDash } : {}),
|
|
5027
5045
|
};
|
|
5028
5046
|
const cx = n.x + n.w / 2, cy = n.y + n.h / 2;
|
|
5029
5047
|
const hw = n.w / 2 - 2;
|
|
@@ -5206,6 +5224,8 @@ var AIDiagram = (function (exports) {
|
|
|
5206
5224
|
continue;
|
|
5207
5225
|
const gs = g.style ?? {};
|
|
5208
5226
|
const gg = mkGroup(`group-${g.id}`, "gg");
|
|
5227
|
+
if (gs.opacity != null)
|
|
5228
|
+
gg.setAttribute("opacity", String(gs.opacity));
|
|
5209
5229
|
gg.appendChild(rc.rectangle(g.x, g.y, g.w, g.h, {
|
|
5210
5230
|
...BASE_ROUGH,
|
|
5211
5231
|
roughness: 1.7,
|
|
@@ -5218,14 +5238,26 @@ var AIDiagram = (function (exports) {
|
|
|
5218
5238
|
strokeLineDash: gs.strokeDash ?? palette.groupDash,
|
|
5219
5239
|
}));
|
|
5220
5240
|
// ── Group label typography ──────────────────────────
|
|
5221
|
-
// supports: font, font-size, letter-spacing
|
|
5222
|
-
// always left-anchored (single line)
|
|
5223
5241
|
const gLabelColor = gs.color ? String(gs.color) : palette.groupLabel;
|
|
5224
5242
|
const gFontSize = Number(gs.fontSize ?? 12);
|
|
5243
|
+
const gFontWeight = gs.fontWeight ?? 500;
|
|
5225
5244
|
const gFont = resolveStyleFont$1(gs, diagramFont);
|
|
5226
5245
|
const gLetterSpacing = gs.letterSpacing;
|
|
5246
|
+
const gPad = Number(gs.padding ?? 14);
|
|
5247
|
+
const gTextAlign = String(gs.textAlign ?? "left");
|
|
5248
|
+
const gAnchorMap = {
|
|
5249
|
+
left: "start",
|
|
5250
|
+
center: "middle",
|
|
5251
|
+
right: "end",
|
|
5252
|
+
};
|
|
5253
|
+
const gAnchor = gAnchorMap[gTextAlign] ?? "start";
|
|
5254
|
+
const gTextX = gTextAlign === "right"
|
|
5255
|
+
? g.x + g.w - gPad
|
|
5256
|
+
: gTextAlign === "center"
|
|
5257
|
+
? g.x + g.w / 2
|
|
5258
|
+
: g.x + gPad;
|
|
5227
5259
|
if (g.label) {
|
|
5228
|
-
gg.appendChild(mkText(g.label,
|
|
5260
|
+
gg.appendChild(mkText(g.label, gTextX, g.y + gPad, gFontSize, gFontWeight, gLabelColor, gAnchor, gFont, gLetterSpacing));
|
|
5229
5261
|
}
|
|
5230
5262
|
GL.appendChild(gg);
|
|
5231
5263
|
}
|
|
@@ -5246,6 +5278,8 @@ var AIDiagram = (function (exports) {
|
|
|
5246
5278
|
const [x1, y1] = getConnPoint$1(src, dstCX, dstCY);
|
|
5247
5279
|
const [x2, y2] = getConnPoint$1(dst, srcCX, srcCY);
|
|
5248
5280
|
const eg = mkGroup(`edge-${e.from}-${e.to}`, "eg");
|
|
5281
|
+
if (e.style?.opacity != null)
|
|
5282
|
+
eg.setAttribute("opacity", String(e.style.opacity));
|
|
5249
5283
|
const len = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) || 1;
|
|
5250
5284
|
const nx = (x2 - x1) / len, ny = (y2 - y1) / len;
|
|
5251
5285
|
const ecol = String(e.style?.stroke ?? palette.edgeStroke);
|
|
@@ -5286,7 +5320,9 @@ var AIDiagram = (function (exports) {
|
|
|
5286
5320
|
const eFontSize = Number(e.style?.fontSize ?? 11);
|
|
5287
5321
|
const eFont = resolveStyleFont$1(e.style ?? {}, diagramFont);
|
|
5288
5322
|
const eLetterSpacing = e.style?.letterSpacing;
|
|
5289
|
-
|
|
5323
|
+
const eFontWeight = e.style?.fontWeight ?? 400;
|
|
5324
|
+
const eLabelColor = String(e.style?.color ?? palette.edgeLabelText);
|
|
5325
|
+
eg.appendChild(mkText(e.label, mx, my, eFontSize, eFontWeight, eLabelColor, "middle", eFont, eLetterSpacing));
|
|
5290
5326
|
}
|
|
5291
5327
|
EL.appendChild(eg);
|
|
5292
5328
|
}
|
|
@@ -5295,6 +5331,8 @@ var AIDiagram = (function (exports) {
|
|
|
5295
5331
|
const NL = mkGroup("node-layer");
|
|
5296
5332
|
for (const n of sg.nodes) {
|
|
5297
5333
|
const ng = mkGroup(`node-${n.id}`, "ng");
|
|
5334
|
+
if (n.style?.opacity != null)
|
|
5335
|
+
ng.setAttribute("opacity", String(n.style.opacity));
|
|
5298
5336
|
renderShape$1(rc, n, palette).forEach((s) => ng.appendChild(s));
|
|
5299
5337
|
// ── Node / text typography ─────────────────────────
|
|
5300
5338
|
// supports: font, font-size, letter-spacing, text-align, line-height
|
|
@@ -5313,18 +5351,19 @@ var AIDiagram = (function (exports) {
|
|
|
5313
5351
|
// line-height is a multiplier (e.g. 1.4 = 140% of font-size)
|
|
5314
5352
|
const lineHeight = Number(n.style?.lineHeight ?? 1.3) * fontSize;
|
|
5315
5353
|
const letterSpacing = n.style?.letterSpacing;
|
|
5354
|
+
const pad = Number(n.style?.padding ?? 8);
|
|
5316
5355
|
// x shifts for left / right alignment
|
|
5317
5356
|
const textX = textAlign === "left"
|
|
5318
|
-
? n.x +
|
|
5357
|
+
? n.x + pad
|
|
5319
5358
|
: textAlign === "right"
|
|
5320
|
-
? n.x + n.w -
|
|
5359
|
+
? n.x + n.w - pad
|
|
5321
5360
|
: n.x + n.w / 2;
|
|
5322
5361
|
const lines = n.shape === 'text' && !n.label.includes('\n')
|
|
5323
|
-
? wrapText$1(n.label, n.w -
|
|
5362
|
+
? wrapText$1(n.label, n.w - pad * 2, fontSize)
|
|
5324
5363
|
: n.label.split('\n');
|
|
5325
5364
|
const verticalAlign = String(n.style?.verticalAlign ?? "middle");
|
|
5326
|
-
const nodeBodyTop = n.y +
|
|
5327
|
-
const nodeBodyBottom = n.y + n.h -
|
|
5365
|
+
const nodeBodyTop = n.y + pad;
|
|
5366
|
+
const nodeBodyBottom = n.y + n.h - pad;
|
|
5328
5367
|
const nodeBodyMid = n.y + n.h / 2;
|
|
5329
5368
|
const blockH = (lines.length - 1) * lineHeight;
|
|
5330
5369
|
const textCY = verticalAlign === "top"
|
|
@@ -5356,15 +5395,19 @@ var AIDiagram = (function (exports) {
|
|
|
5356
5395
|
const fill = String(gs.fill ?? palette.tableFill);
|
|
5357
5396
|
const strk = String(gs.stroke ?? palette.tableStroke);
|
|
5358
5397
|
const textCol = String(gs.color ?? palette.tableText);
|
|
5359
|
-
const hdrFill = palette.tableHeaderFill;
|
|
5398
|
+
const hdrFill = gs.fill ? darkenHex$1(fill, 0.08) : palette.tableHeaderFill;
|
|
5360
5399
|
const hdrText = String(gs.color ?? palette.tableHeaderText);
|
|
5361
5400
|
const divCol = palette.tableDivider;
|
|
5362
5401
|
const pad = t.labelH;
|
|
5402
|
+
const tStrokeWidth = Number(gs.strokeWidth ?? 1.5);
|
|
5403
|
+
const tFontWeight = gs.fontWeight ?? 500;
|
|
5363
5404
|
// ── Table-level font (applies to label + all cells) ─
|
|
5364
5405
|
// supports: font, font-size, letter-spacing
|
|
5365
5406
|
const tFontSize = Number(gs.fontSize ?? 12);
|
|
5366
5407
|
const tFont = resolveStyleFont$1(gs, diagramFont);
|
|
5367
5408
|
const tLetterSpacing = gs.letterSpacing;
|
|
5409
|
+
if (gs.opacity != null)
|
|
5410
|
+
tg.setAttribute("opacity", String(gs.opacity));
|
|
5368
5411
|
// outer border
|
|
5369
5412
|
tg.appendChild(rc.rectangle(t.x, t.y, t.w, t.h, {
|
|
5370
5413
|
...BASE_ROUGH,
|
|
@@ -5372,7 +5415,8 @@ var AIDiagram = (function (exports) {
|
|
|
5372
5415
|
fill,
|
|
5373
5416
|
fillStyle: "solid",
|
|
5374
5417
|
stroke: strk,
|
|
5375
|
-
strokeWidth:
|
|
5418
|
+
strokeWidth: tStrokeWidth,
|
|
5419
|
+
...(gs.strokeDash ? { strokeLineDash: gs.strokeDash } : {}),
|
|
5376
5420
|
}));
|
|
5377
5421
|
// label strip separator
|
|
5378
5422
|
tg.appendChild(rc.line(t.x, t.y + pad, t.x + t.w, t.y + pad, {
|
|
@@ -5381,8 +5425,8 @@ var AIDiagram = (function (exports) {
|
|
|
5381
5425
|
stroke: strk,
|
|
5382
5426
|
strokeWidth: 1,
|
|
5383
5427
|
}));
|
|
5384
|
-
// ── Table label: font, font-size, letter-spacing (always left) ──
|
|
5385
|
-
tg.appendChild(mkText(t.label, t.x + 10, t.y + pad / 2, tFontSize,
|
|
5428
|
+
// ── Table label: font, font-size, font-weight, letter-spacing (always left) ──
|
|
5429
|
+
tg.appendChild(mkText(t.label, t.x + 10, t.y + pad / 2, tFontSize, tFontWeight, textCol, "start", tFont, tLetterSpacing));
|
|
5386
5430
|
// rows
|
|
5387
5431
|
let rowY = t.y + pad;
|
|
5388
5432
|
for (const row of t.rows) {
|
|
@@ -5411,7 +5455,7 @@ var AIDiagram = (function (exports) {
|
|
|
5411
5455
|
right: "end",
|
|
5412
5456
|
};
|
|
5413
5457
|
const cellAnchor = cellAnchorMap[cellAlignProp] ?? "middle";
|
|
5414
|
-
const cellFw = row.kind === "header" ? 600 : 400;
|
|
5458
|
+
const cellFw = row.kind === "header" ? 600 : (gs.fontWeight ?? 400);
|
|
5415
5459
|
const cellColor = row.kind === "header" ? hdrText : textCol;
|
|
5416
5460
|
let cx = t.x;
|
|
5417
5461
|
row.cells.forEach((cell, i) => {
|
|
@@ -5450,27 +5494,31 @@ var AIDiagram = (function (exports) {
|
|
|
5450
5494
|
const gs = n.style ?? {};
|
|
5451
5495
|
const fill = String(gs.fill ?? palette.noteFill);
|
|
5452
5496
|
const strk = String(gs.stroke ?? palette.noteStroke);
|
|
5497
|
+
const nStrokeWidth = Number(gs.strokeWidth ?? 1.2);
|
|
5453
5498
|
const fold = 14;
|
|
5454
5499
|
const { x, y, w, h } = n;
|
|
5500
|
+
if (gs.opacity != null)
|
|
5501
|
+
ng.setAttribute("opacity", String(gs.opacity));
|
|
5455
5502
|
// ── Note typography ─────────────────────────────────
|
|
5456
|
-
// supports: font, font-size, letter-spacing, text-align, line-height
|
|
5457
5503
|
const nFontSize = Number(gs.fontSize ?? 12);
|
|
5504
|
+
const nFontWeight = gs.fontWeight ?? 400;
|
|
5458
5505
|
const nFont = resolveStyleFont$1(gs, diagramFont);
|
|
5459
5506
|
const nLetterSpacing = gs.letterSpacing;
|
|
5460
5507
|
const nLineHeight = Number(gs.lineHeight ?? 1.4) * nFontSize;
|
|
5461
5508
|
const nTextAlign = String(gs.textAlign ?? "left");
|
|
5509
|
+
const nPad = Number(gs.padding ?? 12);
|
|
5462
5510
|
const nAnchorMap = {
|
|
5463
5511
|
left: "start",
|
|
5464
5512
|
center: "middle",
|
|
5465
5513
|
right: "end",
|
|
5466
5514
|
};
|
|
5467
5515
|
const nAnchor = nAnchorMap[nTextAlign] ?? "start";
|
|
5468
|
-
// x position for the text block (pad from left, with alignment)
|
|
5469
5516
|
const nTextX = nTextAlign === "right"
|
|
5470
|
-
? x + w - fold -
|
|
5517
|
+
? x + w - fold - nPad
|
|
5471
5518
|
: nTextAlign === "center"
|
|
5472
5519
|
? x + (w - fold) / 2
|
|
5473
|
-
: x +
|
|
5520
|
+
: x + nPad;
|
|
5521
|
+
const nFoldPad = fold + nPad; // text starts below fold + user padding
|
|
5474
5522
|
ng.appendChild(rc.polygon([
|
|
5475
5523
|
[x, y],
|
|
5476
5524
|
[x + w - fold, y],
|
|
@@ -5483,7 +5531,8 @@ var AIDiagram = (function (exports) {
|
|
|
5483
5531
|
fill,
|
|
5484
5532
|
fillStyle: "solid",
|
|
5485
5533
|
stroke: strk,
|
|
5486
|
-
strokeWidth:
|
|
5534
|
+
strokeWidth: nStrokeWidth,
|
|
5535
|
+
...(gs.strokeDash ? { strokeLineDash: gs.strokeDash } : {}),
|
|
5487
5536
|
}));
|
|
5488
5537
|
ng.appendChild(rc.polygon([
|
|
5489
5538
|
[x + w - fold, y],
|
|
@@ -5495,11 +5544,11 @@ var AIDiagram = (function (exports) {
|
|
|
5495
5544
|
fill: palette.noteFold,
|
|
5496
5545
|
fillStyle: "solid",
|
|
5497
5546
|
stroke: strk,
|
|
5498
|
-
strokeWidth: 0.8,
|
|
5547
|
+
strokeWidth: Math.min(nStrokeWidth, 0.8),
|
|
5499
5548
|
}));
|
|
5500
5549
|
const nVerticalAlign = String(gs.verticalAlign ?? "top");
|
|
5501
|
-
const bodyTop = y +
|
|
5502
|
-
const bodyBottom = y + h -
|
|
5550
|
+
const bodyTop = y + nFoldPad;
|
|
5551
|
+
const bodyBottom = y + h - nPad;
|
|
5503
5552
|
const bodyMid = (bodyTop + bodyBottom) / 2;
|
|
5504
5553
|
const blockH = (n.lines.length - 1) * nLineHeight;
|
|
5505
5554
|
const blockCY = nVerticalAlign === "bottom"
|
|
@@ -5507,13 +5556,11 @@ var AIDiagram = (function (exports) {
|
|
|
5507
5556
|
: nVerticalAlign === "middle"
|
|
5508
5557
|
? bodyMid
|
|
5509
5558
|
: bodyTop + blockH / 2;
|
|
5510
|
-
// multiline: use mkMultilineText so line-height is respected
|
|
5511
5559
|
if (n.lines.length > 1) {
|
|
5512
|
-
|
|
5513
|
-
ng.appendChild(mkMultilineText(n.lines, nTextX, blockCY, nFontSize, 400, String(gs.color ?? palette.noteText), nAnchor, nLineHeight, nFont, nLetterSpacing));
|
|
5560
|
+
ng.appendChild(mkMultilineText(n.lines, nTextX, blockCY, nFontSize, nFontWeight, String(gs.color ?? palette.noteText), nAnchor, nLineHeight, nFont, nLetterSpacing));
|
|
5514
5561
|
}
|
|
5515
5562
|
else {
|
|
5516
|
-
ng.appendChild(mkText(n.lines[0] ?? "", nTextX, blockCY, nFontSize,
|
|
5563
|
+
ng.appendChild(mkText(n.lines[0] ?? "", nTextX, blockCY, nFontSize, nFontWeight, String(gs.color ?? palette.noteText), nAnchor, nFont, nLetterSpacing));
|
|
5517
5564
|
}
|
|
5518
5565
|
NoteL.appendChild(ng);
|
|
5519
5566
|
}
|
|
@@ -5522,13 +5569,27 @@ var AIDiagram = (function (exports) {
|
|
|
5522
5569
|
const MDL = mkGroup('markdown-layer');
|
|
5523
5570
|
for (const m of sg.markdowns) {
|
|
5524
5571
|
const mg = mkGroup(`markdown-${m.id}`, 'mdg');
|
|
5525
|
-
const
|
|
5526
|
-
const
|
|
5527
|
-
const
|
|
5572
|
+
const gs = m.style ?? {};
|
|
5573
|
+
const mFont = resolveStyleFont$1(gs, diagramFont);
|
|
5574
|
+
const baseColor = String(gs.color ?? palette.nodeText);
|
|
5575
|
+
const textAlign = String(gs.textAlign ?? 'left');
|
|
5528
5576
|
const anchor = textAlign === 'right' ? 'end'
|
|
5529
5577
|
: textAlign === 'center' ? 'middle'
|
|
5530
5578
|
: 'start';
|
|
5531
|
-
const PAD = Number(
|
|
5579
|
+
const PAD = Number(gs.padding ?? 16);
|
|
5580
|
+
const mLetterSpacing = gs.letterSpacing;
|
|
5581
|
+
if (gs.opacity != null)
|
|
5582
|
+
mg.setAttribute('opacity', String(gs.opacity));
|
|
5583
|
+
// Background + border
|
|
5584
|
+
if (gs.fill || gs.stroke) {
|
|
5585
|
+
mg.appendChild(rc.rectangle(m.x, m.y, m.w, m.h, {
|
|
5586
|
+
...BASE_ROUGH, seed: hashStr$3(m.id),
|
|
5587
|
+
fill: String(gs.fill ?? 'none'), fillStyle: 'solid',
|
|
5588
|
+
stroke: String(gs.stroke ?? 'none'),
|
|
5589
|
+
strokeWidth: Number(gs.strokeWidth ?? 1.2),
|
|
5590
|
+
...(gs.strokeDash ? { strokeLineDash: gs.strokeDash } : {}),
|
|
5591
|
+
}));
|
|
5592
|
+
}
|
|
5532
5593
|
const textX = textAlign === 'right' ? m.x + m.w - PAD
|
|
5533
5594
|
: textAlign === 'center' ? m.x + m.w / 2
|
|
5534
5595
|
: m.x + PAD;
|
|
@@ -5551,6 +5612,8 @@ var AIDiagram = (function (exports) {
|
|
|
5551
5612
|
t.setAttribute('fill', baseColor);
|
|
5552
5613
|
t.setAttribute('pointer-events', 'none');
|
|
5553
5614
|
t.setAttribute('user-select', 'none');
|
|
5615
|
+
if (mLetterSpacing != null)
|
|
5616
|
+
t.setAttribute('letter-spacing', String(mLetterSpacing));
|
|
5554
5617
|
for (const run of line.runs) {
|
|
5555
5618
|
const span = se('tspan');
|
|
5556
5619
|
span.textContent = run.text;
|
|
@@ -5640,7 +5703,7 @@ var AIDiagram = (function (exports) {
|
|
|
5640
5703
|
});
|
|
5641
5704
|
}
|
|
5642
5705
|
// ── Axes ───────────────────────────────────────────────────
|
|
5643
|
-
function drawAxes(rc, ctx, c, px, py, pw, ph, allY, labelCol, R) {
|
|
5706
|
+
function drawAxes(rc, ctx, c, px, py, pw, ph, allY, labelCol, R, font = 'system-ui, sans-serif') {
|
|
5644
5707
|
const toY = makeValueToY(allY, py, ph);
|
|
5645
5708
|
const baseline = toY(0);
|
|
5646
5709
|
// Y axis
|
|
@@ -5654,7 +5717,7 @@ var AIDiagram = (function (exports) {
|
|
|
5654
5717
|
continue;
|
|
5655
5718
|
rc.line(px - 3, ty, px, ty, { roughness: 0.2, seed: hashStr$2(c.id + 'yt' + tick), stroke: labelCol, strokeWidth: 0.7 });
|
|
5656
5719
|
ctx.save();
|
|
5657
|
-
ctx.font =
|
|
5720
|
+
ctx.font = `400 9px ${font}`;
|
|
5658
5721
|
ctx.fillStyle = labelCol;
|
|
5659
5722
|
ctx.textAlign = 'right';
|
|
5660
5723
|
ctx.textBaseline = 'middle';
|
|
@@ -5663,9 +5726,9 @@ var AIDiagram = (function (exports) {
|
|
|
5663
5726
|
}
|
|
5664
5727
|
}
|
|
5665
5728
|
// ── Legend ─────────────────────────────────────────────────
|
|
5666
|
-
function drawLegend(ctx, labels, colors, x, y, labelCol) {
|
|
5729
|
+
function drawLegend(ctx, labels, colors, x, y, labelCol, font = 'system-ui, sans-serif') {
|
|
5667
5730
|
ctx.save();
|
|
5668
|
-
ctx.font =
|
|
5731
|
+
ctx.font = `400 9px ${font}`;
|
|
5669
5732
|
ctx.textAlign = 'left';
|
|
5670
5733
|
ctx.textBaseline = 'middle';
|
|
5671
5734
|
labels.forEach((lbl, i) => {
|
|
@@ -5683,6 +5746,11 @@ var AIDiagram = (function (exports) {
|
|
|
5683
5746
|
const bgFill = String(s.fill ?? pal.nodeFill);
|
|
5684
5747
|
const bgStroke = String(s.stroke ?? (pal.nodeStroke === 'none' ? '#c8b898' : pal.nodeStroke));
|
|
5685
5748
|
const lc = String(s.color ?? pal.labelText);
|
|
5749
|
+
const cFont = String(s.font ? `${s.font}, system-ui, sans-serif` : 'system-ui, sans-serif');
|
|
5750
|
+
const cFontSize = Number(s.fontSize ?? 12);
|
|
5751
|
+
const cFontWeight = s.fontWeight ?? 600;
|
|
5752
|
+
if (s.opacity != null)
|
|
5753
|
+
ctx.globalAlpha = Number(s.opacity);
|
|
5686
5754
|
// Background
|
|
5687
5755
|
rc.rectangle(c.x, c.y, c.w, c.h, {
|
|
5688
5756
|
...R, seed: hashStr$2(c.id),
|
|
@@ -5695,7 +5763,7 @@ var AIDiagram = (function (exports) {
|
|
|
5695
5763
|
// Title
|
|
5696
5764
|
if (c.title) {
|
|
5697
5765
|
ctx.save();
|
|
5698
|
-
ctx.font =
|
|
5766
|
+
ctx.font = `${cFontWeight} ${cFontSize}px ${cFont}`;
|
|
5699
5767
|
ctx.fillStyle = lc;
|
|
5700
5768
|
ctx.textAlign = 'center';
|
|
5701
5769
|
ctx.textBaseline = 'middle';
|
|
@@ -5716,7 +5784,8 @@ var AIDiagram = (function (exports) {
|
|
|
5716
5784
|
drawPieArc(rc, ctx, cx, cy, r, ir, angle, angle + sweep, seg.color, hashStr$2(c.id + seg.label + i));
|
|
5717
5785
|
angle += sweep;
|
|
5718
5786
|
});
|
|
5719
|
-
drawLegend(ctx, segments.map(s => `${s.label} ${Math.round(s.value / total * 100)}%`), segments.map(s => s.color), legendX, legendY, lc);
|
|
5787
|
+
drawLegend(ctx, segments.map(s => `${s.label} ${Math.round(s.value / total * 100)}%`), segments.map(s => s.color), legendX, legendY, lc, cFont);
|
|
5788
|
+
ctx.globalAlpha = 1;
|
|
5720
5789
|
return;
|
|
5721
5790
|
}
|
|
5722
5791
|
// ── Scatter ───────────────────────────────────────────────
|
|
@@ -5736,7 +5805,8 @@ var AIDiagram = (function (exports) {
|
|
|
5736
5805
|
strokeWidth: 1.2,
|
|
5737
5806
|
});
|
|
5738
5807
|
});
|
|
5739
|
-
drawLegend(ctx, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + (c.title ? 28 : 12), lc);
|
|
5808
|
+
drawLegend(ctx, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + (c.title ? 28 : 12), lc, cFont);
|
|
5809
|
+
ctx.globalAlpha = 1;
|
|
5740
5810
|
return;
|
|
5741
5811
|
}
|
|
5742
5812
|
// ── Bar / Line / Area ─────────────────────────────────────
|
|
@@ -5745,10 +5815,10 @@ var AIDiagram = (function (exports) {
|
|
|
5745
5815
|
const toY = makeValueToY(allY, py, ph);
|
|
5746
5816
|
const baseline = toY(0);
|
|
5747
5817
|
const n = labels.length;
|
|
5748
|
-
drawAxes(rc, ctx, c, px, py, pw, ph, allY, lc, R);
|
|
5818
|
+
drawAxes(rc, ctx, c, px, py, pw, ph, allY, lc, R, cFont);
|
|
5749
5819
|
// X labels
|
|
5750
5820
|
ctx.save();
|
|
5751
|
-
ctx.font =
|
|
5821
|
+
ctx.font = `400 9px ${cFont}`;
|
|
5752
5822
|
ctx.fillStyle = lc;
|
|
5753
5823
|
ctx.textAlign = 'center';
|
|
5754
5824
|
ctx.textBaseline = 'top';
|
|
@@ -5825,8 +5895,9 @@ var AIDiagram = (function (exports) {
|
|
|
5825
5895
|
}
|
|
5826
5896
|
// Multi-series legend
|
|
5827
5897
|
if (series.length > 1) {
|
|
5828
|
-
drawLegend(ctx, series.map(s => s.name), series.map(s => s.color), px, py - 2, lc);
|
|
5898
|
+
drawLegend(ctx, series.map(s => s.name), series.map(s => s.color), px, py - 2, lc, cFont);
|
|
5829
5899
|
}
|
|
5900
|
+
ctx.globalAlpha = 1;
|
|
5830
5901
|
}
|
|
5831
5902
|
|
|
5832
5903
|
// ============================================================
|
|
@@ -5839,6 +5910,14 @@ var AIDiagram = (function (exports) {
|
|
|
5839
5910
|
h = ((h * 33) ^ s.charCodeAt(i)) & 0xffff;
|
|
5840
5911
|
return h;
|
|
5841
5912
|
}
|
|
5913
|
+
/** Darken a CSS hex colour by `amount` (0–1). Falls back to input for non-hex. */
|
|
5914
|
+
function darkenHex(hex, amount = 0.12) {
|
|
5915
|
+
const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);
|
|
5916
|
+
if (!m)
|
|
5917
|
+
return hex;
|
|
5918
|
+
const d = (v) => Math.max(0, Math.round(parseInt(v, 16) * (1 - amount)));
|
|
5919
|
+
return `#${d(m[1]).toString(16).padStart(2, "0")}${d(m[2]).toString(16).padStart(2, "0")}${d(m[3]).toString(16).padStart(2, "0")}`;
|
|
5920
|
+
}
|
|
5842
5921
|
// ── Small helper: load + resolve font from a style map ────────────────────
|
|
5843
5922
|
function resolveStyleFont(style, fallback) {
|
|
5844
5923
|
const raw = String(style['font'] ?? '');
|
|
@@ -5956,6 +6035,7 @@ var AIDiagram = (function (exports) {
|
|
|
5956
6035
|
...R, seed: hashStr$1(n.id),
|
|
5957
6036
|
fill, fillStyle: 'solid',
|
|
5958
6037
|
stroke, strokeWidth: Number(s.strokeWidth ?? 1.9),
|
|
6038
|
+
...(s.strokeDash ? { strokeLineDash: s.strokeDash } : {}),
|
|
5959
6039
|
};
|
|
5960
6040
|
const cx = n.x + n.w / 2, cy = n.y + n.h / 2;
|
|
5961
6041
|
const hw = n.w / 2 - 2;
|
|
@@ -6091,6 +6171,8 @@ var AIDiagram = (function (exports) {
|
|
|
6091
6171
|
if (!g.w)
|
|
6092
6172
|
continue;
|
|
6093
6173
|
const gs = g.style ?? {};
|
|
6174
|
+
if (gs.opacity != null)
|
|
6175
|
+
ctx.globalAlpha = Number(gs.opacity);
|
|
6094
6176
|
rc.rectangle(g.x, g.y, g.w, g.h, {
|
|
6095
6177
|
...R, roughness: 1.7, bowing: 0.4, seed: hashStr$1(g.id),
|
|
6096
6178
|
fill: String(gs.fill ?? palette.groupFill),
|
|
@@ -6099,16 +6181,21 @@ var AIDiagram = (function (exports) {
|
|
|
6099
6181
|
strokeWidth: Number(gs.strokeWidth ?? 1.2),
|
|
6100
6182
|
strokeLineDash: gs.strokeDash ?? palette.groupDash,
|
|
6101
6183
|
});
|
|
6102
|
-
// ── Group label ──────────────────────────────────────
|
|
6103
|
-
// Only render when label has content — empty label = no reserved space
|
|
6104
|
-
// supports: font, font-size, letter-spacing (always left-anchored)
|
|
6105
6184
|
if (g.label) {
|
|
6106
6185
|
const gFontSize = Number(gs.fontSize ?? 12);
|
|
6186
|
+
const gFontWeight = gs.fontWeight ?? 500;
|
|
6107
6187
|
const gFont = resolveStyleFont(gs, diagramFont);
|
|
6108
6188
|
const gLetterSpacing = gs.letterSpacing;
|
|
6109
6189
|
const gLabelColor = gs.color ? String(gs.color) : palette.groupLabel;
|
|
6110
|
-
|
|
6190
|
+
const gPad = Number(gs.padding ?? 14);
|
|
6191
|
+
const gTextAlign = String(gs.textAlign ?? 'left');
|
|
6192
|
+
const gTextX = gTextAlign === 'right' ? g.x + g.w - gPad
|
|
6193
|
+
: gTextAlign === 'center' ? g.x + g.w / 2
|
|
6194
|
+
: g.x + gPad;
|
|
6195
|
+
drawText(ctx, g.label, gTextX, g.y + gPad + 2, gFontSize, gFontWeight, gLabelColor, gTextAlign, gFont, gLetterSpacing);
|
|
6111
6196
|
}
|
|
6197
|
+
if (gs.opacity != null)
|
|
6198
|
+
ctx.globalAlpha = 1;
|
|
6112
6199
|
}
|
|
6113
6200
|
// ── Edges ─────────────────────────────────────────────────
|
|
6114
6201
|
for (const e of sg.edges) {
|
|
@@ -6120,6 +6207,8 @@ var AIDiagram = (function (exports) {
|
|
|
6120
6207
|
const srcCX = src.x + src.w / 2, srcCY = src.y + src.h / 2;
|
|
6121
6208
|
const [x1, y1] = getConnPoint(src, dstCX, dstCY);
|
|
6122
6209
|
const [x2, y2] = getConnPoint(dst, srcCX, srcCY);
|
|
6210
|
+
if (e.style?.opacity != null)
|
|
6211
|
+
ctx.globalAlpha = Number(e.style.opacity);
|
|
6123
6212
|
const ecol = String(e.style?.stroke ?? palette.edgeStroke);
|
|
6124
6213
|
const { arrowAt, dashed } = connMeta(e.connector);
|
|
6125
6214
|
const len = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) || 1;
|
|
@@ -6148,17 +6237,22 @@ var AIDiagram = (function (exports) {
|
|
|
6148
6237
|
const eFontSize = Number(e.style?.fontSize ?? 11);
|
|
6149
6238
|
const eFont = resolveStyleFont(e.style ?? {}, diagramFont);
|
|
6150
6239
|
const eLetterSpacing = e.style?.letterSpacing;
|
|
6240
|
+
const eFontWeight = e.style?.fontWeight ?? 400;
|
|
6241
|
+
const eLabelColor = String(e.style?.color ?? palette.edgeLabelText);
|
|
6151
6242
|
ctx.save();
|
|
6152
|
-
ctx.font =
|
|
6243
|
+
ctx.font = `${eFontWeight} ${eFontSize}px ${eFont}`;
|
|
6153
6244
|
const tw = ctx.measureText(e.label).width + 12;
|
|
6154
6245
|
ctx.restore();
|
|
6155
6246
|
ctx.fillStyle = palette.edgeLabelBg;
|
|
6156
6247
|
ctx.fillRect(mx - tw / 2, my - 8, tw, 15);
|
|
6157
|
-
drawText(ctx, e.label, mx, my + 3, eFontSize,
|
|
6248
|
+
drawText(ctx, e.label, mx, my + 3, eFontSize, eFontWeight, eLabelColor, 'center', eFont, eLetterSpacing);
|
|
6158
6249
|
}
|
|
6250
|
+
ctx.globalAlpha = 1;
|
|
6159
6251
|
}
|
|
6160
6252
|
// ── Nodes ─────────────────────────────────────────────────
|
|
6161
6253
|
for (const n of sg.nodes) {
|
|
6254
|
+
if (n.style?.opacity != null)
|
|
6255
|
+
ctx.globalAlpha = Number(n.style.opacity);
|
|
6162
6256
|
renderShape(rc, ctx, n, palette, R);
|
|
6163
6257
|
// ── Node / text typography ─────────────────────────
|
|
6164
6258
|
// supports: font, font-size, letter-spacing, text-align,
|
|
@@ -6172,18 +6266,19 @@ var AIDiagram = (function (exports) {
|
|
|
6172
6266
|
const lineHeight = Number(n.style?.lineHeight ?? 1.3) * fontSize;
|
|
6173
6267
|
const letterSpacing = n.style?.letterSpacing;
|
|
6174
6268
|
const vertAlign = String(n.style?.verticalAlign ?? 'middle');
|
|
6269
|
+
const pad = Number(n.style?.padding ?? 8);
|
|
6175
6270
|
// x shifts for left/right alignment
|
|
6176
|
-
const textX = textAlign === 'left' ? n.x +
|
|
6177
|
-
: textAlign === 'right' ? n.x + n.w -
|
|
6271
|
+
const textX = textAlign === 'left' ? n.x + pad
|
|
6272
|
+
: textAlign === 'right' ? n.x + n.w - pad
|
|
6178
6273
|
: n.x + n.w / 2;
|
|
6179
6274
|
// word-wrap for text shape; explicit \n for all others
|
|
6180
6275
|
const rawLines = n.label.split('\n');
|
|
6181
6276
|
const lines = n.shape === 'text' && rawLines.length === 1
|
|
6182
|
-
? wrapText(n.label, n.w -
|
|
6277
|
+
? wrapText(n.label, n.w - pad * 2, fontSize)
|
|
6183
6278
|
: rawLines;
|
|
6184
6279
|
// vertical-align: compute textCY from top/middle/bottom
|
|
6185
|
-
const nodeBodyTop = n.y +
|
|
6186
|
-
const nodeBodyBottom = n.y + n.h -
|
|
6280
|
+
const nodeBodyTop = n.y + pad;
|
|
6281
|
+
const nodeBodyBottom = n.y + n.h - pad;
|
|
6187
6282
|
const blockH = (lines.length - 1) * lineHeight;
|
|
6188
6283
|
const textCY = vertAlign === 'top' ? nodeBodyTop + blockH / 2
|
|
6189
6284
|
: vertAlign === 'bottom' ? nodeBodyBottom - blockH / 2
|
|
@@ -6194,6 +6289,8 @@ var AIDiagram = (function (exports) {
|
|
|
6194
6289
|
else {
|
|
6195
6290
|
drawText(ctx, lines[0] ?? '', textX, textCY, fontSize, fontWeight, textColor, textAlign, nodeFont, letterSpacing);
|
|
6196
6291
|
}
|
|
6292
|
+
if (n.style?.opacity != null)
|
|
6293
|
+
ctx.globalAlpha = 1;
|
|
6197
6294
|
}
|
|
6198
6295
|
// ── Tables ────────────────────────────────────────────────
|
|
6199
6296
|
for (const t of sg.tables) {
|
|
@@ -6203,25 +6300,28 @@ var AIDiagram = (function (exports) {
|
|
|
6203
6300
|
const textCol = String(gs.color ?? palette.tableText);
|
|
6204
6301
|
const pad = t.labelH;
|
|
6205
6302
|
// ── Table-level font ────────────────────────────────
|
|
6206
|
-
// supports: font, font-size, letter-spacing
|
|
6207
|
-
// cells also support text-align
|
|
6208
6303
|
const tFontSize = Number(gs.fontSize ?? 12);
|
|
6209
6304
|
const tFont = resolveStyleFont(gs, diagramFont);
|
|
6210
6305
|
const tLetterSpacing = gs.letterSpacing;
|
|
6306
|
+
const tStrokeWidth = Number(gs.strokeWidth ?? 1.5);
|
|
6307
|
+
const tFontWeight = gs.fontWeight ?? 500;
|
|
6308
|
+
if (gs.opacity != null)
|
|
6309
|
+
ctx.globalAlpha = Number(gs.opacity);
|
|
6211
6310
|
rc.rectangle(t.x, t.y, t.w, t.h, {
|
|
6212
6311
|
...R, seed: hashStr$1(t.id),
|
|
6213
|
-
fill, fillStyle: 'solid', stroke: strk, strokeWidth:
|
|
6312
|
+
fill, fillStyle: 'solid', stroke: strk, strokeWidth: tStrokeWidth,
|
|
6313
|
+
...(gs.strokeDash ? { strokeLineDash: gs.strokeDash } : {}),
|
|
6214
6314
|
});
|
|
6215
6315
|
rc.line(t.x, t.y + pad, t.x + t.w, t.y + pad, {
|
|
6216
6316
|
roughness: 0.6, seed: hashStr$1(t.id + 'l'), stroke: strk, strokeWidth: 1,
|
|
6217
6317
|
});
|
|
6218
6318
|
// ── Table label: always left-anchored ───────────────
|
|
6219
|
-
drawText(ctx, t.label, t.x + 10, t.y + pad / 2, tFontSize,
|
|
6319
|
+
drawText(ctx, t.label, t.x + 10, t.y + pad / 2, tFontSize, tFontWeight, textCol, 'left', tFont, tLetterSpacing);
|
|
6220
6320
|
let rowY = t.y + pad;
|
|
6221
6321
|
for (const row of t.rows) {
|
|
6222
6322
|
const rh = row.kind === 'header' ? t.headerH : t.rowH;
|
|
6223
6323
|
if (row.kind === 'header') {
|
|
6224
|
-
ctx.fillStyle = palette.tableHeaderFill;
|
|
6324
|
+
ctx.fillStyle = gs.fill ? darkenHex(fill, 0.08) : palette.tableHeaderFill;
|
|
6225
6325
|
ctx.fillRect(t.x + 1, rowY + 1, t.w - 2, rh - 1);
|
|
6226
6326
|
}
|
|
6227
6327
|
rc.line(t.x, rowY + rh, t.x + t.w, rowY + rh, {
|
|
@@ -6234,7 +6334,7 @@ var AIDiagram = (function (exports) {
|
|
|
6234
6334
|
const cellAlignProp = (row.kind === 'header'
|
|
6235
6335
|
? 'center'
|
|
6236
6336
|
: String(gs.textAlign ?? 'center'));
|
|
6237
|
-
const cellFw = row.kind === 'header' ? 600 : 400;
|
|
6337
|
+
const cellFw = row.kind === 'header' ? 600 : (gs.fontWeight ?? 400);
|
|
6238
6338
|
const cellColor = row.kind === 'header'
|
|
6239
6339
|
? String(gs.color ?? palette.tableHeaderText)
|
|
6240
6340
|
: textCol;
|
|
@@ -6255,63 +6355,87 @@ var AIDiagram = (function (exports) {
|
|
|
6255
6355
|
});
|
|
6256
6356
|
rowY += rh;
|
|
6257
6357
|
}
|
|
6358
|
+
ctx.globalAlpha = 1;
|
|
6258
6359
|
}
|
|
6259
6360
|
// ── Notes ─────────────────────────────────────────────────
|
|
6260
6361
|
for (const n of sg.notes) {
|
|
6261
6362
|
const gs = n.style ?? {};
|
|
6262
6363
|
const fill = String(gs.fill ?? palette.noteFill);
|
|
6263
6364
|
const strk = String(gs.stroke ?? palette.noteStroke);
|
|
6365
|
+
const nStrokeWidth = Number(gs.strokeWidth ?? 1.2);
|
|
6264
6366
|
const fold = 14;
|
|
6265
6367
|
const { x, y, w, h } = n;
|
|
6368
|
+
if (gs.opacity != null)
|
|
6369
|
+
ctx.globalAlpha = Number(gs.opacity);
|
|
6266
6370
|
rc.polygon([
|
|
6267
6371
|
[x, y],
|
|
6268
6372
|
[x + w - fold, y],
|
|
6269
6373
|
[x + w, y + fold],
|
|
6270
6374
|
[x + w, y + h],
|
|
6271
6375
|
[x, y + h],
|
|
6272
|
-
], { ...R, seed: hashStr$1(n.id), fill, fillStyle: 'solid', stroke: strk,
|
|
6376
|
+
], { ...R, seed: hashStr$1(n.id), fill, fillStyle: 'solid', stroke: strk,
|
|
6377
|
+
strokeWidth: nStrokeWidth,
|
|
6378
|
+
...(gs.strokeDash ? { strokeLineDash: gs.strokeDash } : {}),
|
|
6379
|
+
});
|
|
6273
6380
|
rc.polygon([
|
|
6274
6381
|
[x + w - fold, y],
|
|
6275
6382
|
[x + w, y + fold],
|
|
6276
6383
|
[x + w - fold, y + fold],
|
|
6277
6384
|
], { roughness: 0.4, seed: hashStr$1(n.id + 'f'),
|
|
6278
|
-
fill: palette.noteFold, fillStyle: 'solid', stroke: strk,
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
// vertical-align, line-height
|
|
6385
|
+
fill: palette.noteFold, fillStyle: 'solid', stroke: strk,
|
|
6386
|
+
strokeWidth: Math.min(nStrokeWidth, 0.8),
|
|
6387
|
+
});
|
|
6282
6388
|
const nFontSize = Number(gs.fontSize ?? 12);
|
|
6389
|
+
const nFontWeight = gs.fontWeight ?? 400;
|
|
6283
6390
|
const nFont = resolveStyleFont(gs, diagramFont);
|
|
6284
6391
|
const nLetterSpacing = gs.letterSpacing;
|
|
6285
6392
|
const nLineHeight = Number(gs.lineHeight ?? 1.4) * nFontSize;
|
|
6286
6393
|
const nTextAlign = String(gs.textAlign ?? 'left');
|
|
6287
6394
|
const nVertAlign = String(gs.verticalAlign ?? 'top');
|
|
6288
6395
|
const nColor = String(gs.color ?? palette.noteText);
|
|
6289
|
-
const
|
|
6396
|
+
const nPad = Number(gs.padding ?? 12);
|
|
6397
|
+
const nTextX = nTextAlign === 'right' ? x + w - fold - nPad
|
|
6290
6398
|
: nTextAlign === 'center' ? x + (w - fold) / 2
|
|
6291
|
-
: x +
|
|
6292
|
-
|
|
6293
|
-
const bodyTop = y +
|
|
6294
|
-
const bodyBottom = y + h -
|
|
6399
|
+
: x + nPad;
|
|
6400
|
+
const nFoldPad = fold + nPad;
|
|
6401
|
+
const bodyTop = y + nFoldPad;
|
|
6402
|
+
const bodyBottom = y + h - nPad;
|
|
6295
6403
|
const blockH = (n.lines.length - 1) * nLineHeight;
|
|
6296
6404
|
const blockCY = nVertAlign === 'bottom' ? bodyBottom - blockH / 2
|
|
6297
6405
|
: nVertAlign === 'middle' ? (bodyTop + bodyBottom) / 2
|
|
6298
|
-
: bodyTop + blockH / 2;
|
|
6406
|
+
: bodyTop + blockH / 2;
|
|
6299
6407
|
if (n.lines.length > 1) {
|
|
6300
|
-
drawMultilineText(ctx, n.lines, nTextX, blockCY, nFontSize,
|
|
6408
|
+
drawMultilineText(ctx, n.lines, nTextX, blockCY, nFontSize, nFontWeight, nColor, nTextAlign, nLineHeight, nFont, nLetterSpacing);
|
|
6301
6409
|
}
|
|
6302
6410
|
else {
|
|
6303
|
-
drawText(ctx, n.lines[0] ?? '', nTextX, blockCY, nFontSize,
|
|
6411
|
+
drawText(ctx, n.lines[0] ?? '', nTextX, blockCY, nFontSize, nFontWeight, nColor, nTextAlign, nFont, nLetterSpacing);
|
|
6304
6412
|
}
|
|
6413
|
+
if (gs.opacity != null)
|
|
6414
|
+
ctx.globalAlpha = 1;
|
|
6305
6415
|
}
|
|
6306
6416
|
// ── Markdown blocks ────────────────────────────────────────
|
|
6307
6417
|
// Renders prose with Markdown headings and bold/italic inline spans.
|
|
6308
6418
|
// Canvas has no native bold-within-a-run, so each run is drawn
|
|
6309
6419
|
// individually with its own ctx.font setting.
|
|
6310
6420
|
for (const m of (sg.markdowns ?? [])) {
|
|
6311
|
-
const
|
|
6312
|
-
const
|
|
6313
|
-
const
|
|
6314
|
-
const
|
|
6421
|
+
const gs = m.style ?? {};
|
|
6422
|
+
const mFont = resolveStyleFont(gs, diagramFont);
|
|
6423
|
+
const baseColor = String(gs.color ?? palette.nodeText);
|
|
6424
|
+
const textAlign = String(gs.textAlign ?? 'left');
|
|
6425
|
+
const PAD = Number(gs.padding ?? 16);
|
|
6426
|
+
const mLetterSpacing = gs.letterSpacing;
|
|
6427
|
+
if (gs.opacity != null)
|
|
6428
|
+
ctx.globalAlpha = Number(gs.opacity);
|
|
6429
|
+
// Background + border
|
|
6430
|
+
if (gs.fill || gs.stroke) {
|
|
6431
|
+
rc.rectangle(m.x, m.y, m.w, m.h, {
|
|
6432
|
+
...R, seed: hashStr$1(m.id),
|
|
6433
|
+
fill: String(gs.fill ?? 'none'), fillStyle: 'solid',
|
|
6434
|
+
stroke: String(gs.stroke ?? 'none'),
|
|
6435
|
+
strokeWidth: Number(gs.strokeWidth ?? 1.2),
|
|
6436
|
+
...(gs.strokeDash ? { strokeLineDash: gs.strokeDash } : {}),
|
|
6437
|
+
});
|
|
6438
|
+
}
|
|
6315
6439
|
const anchorX = textAlign === 'right' ? m.x + m.w - PAD
|
|
6316
6440
|
: textAlign === 'center' ? m.x + m.w / 2
|
|
6317
6441
|
: m.x + PAD;
|
|
@@ -6329,14 +6453,29 @@ var AIDiagram = (function (exports) {
|
|
|
6329
6453
|
ctx.save();
|
|
6330
6454
|
ctx.textBaseline = 'middle';
|
|
6331
6455
|
ctx.fillStyle = baseColor;
|
|
6456
|
+
const ls = mLetterSpacing ?? 0;
|
|
6457
|
+
// measure run width including letter-spacing
|
|
6458
|
+
const runW = (run) => {
|
|
6459
|
+
return ctx.measureText(run.text).width + ls * run.text.length;
|
|
6460
|
+
};
|
|
6461
|
+
const drawRun = (run, rx) => {
|
|
6462
|
+
if (ls) {
|
|
6463
|
+
for (const ch of run.text) {
|
|
6464
|
+
ctx.fillText(ch, rx, lineY);
|
|
6465
|
+
rx += ctx.measureText(ch).width + ls;
|
|
6466
|
+
}
|
|
6467
|
+
}
|
|
6468
|
+
else {
|
|
6469
|
+
ctx.fillText(run.text, rx, lineY);
|
|
6470
|
+
}
|
|
6471
|
+
};
|
|
6332
6472
|
if (textAlign === 'center' || textAlign === 'right') {
|
|
6333
|
-
// Measure full line width first
|
|
6334
6473
|
let totalW = 0;
|
|
6335
6474
|
for (const run of line.runs) {
|
|
6336
6475
|
const runStyle = run.italic ? 'italic ' : '';
|
|
6337
6476
|
const runWeight = run.bold ? 700 : fontWeight;
|
|
6338
6477
|
ctx.font = `${runStyle}${runWeight} ${fontSize}px ${mFont}`;
|
|
6339
|
-
totalW +=
|
|
6478
|
+
totalW += runW(run);
|
|
6340
6479
|
}
|
|
6341
6480
|
let runX = textAlign === 'center' ? anchorX - totalW / 2 : anchorX - totalW;
|
|
6342
6481
|
ctx.textAlign = 'left';
|
|
@@ -6344,25 +6483,25 @@ var AIDiagram = (function (exports) {
|
|
|
6344
6483
|
const runStyle = run.italic ? 'italic ' : '';
|
|
6345
6484
|
const runWeight = run.bold ? 700 : fontWeight;
|
|
6346
6485
|
ctx.font = `${runStyle}${runWeight} ${fontSize}px ${mFont}`;
|
|
6347
|
-
|
|
6348
|
-
runX +=
|
|
6486
|
+
drawRun(run, runX);
|
|
6487
|
+
runX += runW(run);
|
|
6349
6488
|
}
|
|
6350
6489
|
}
|
|
6351
6490
|
else {
|
|
6352
|
-
// left-aligned — draw runs left to right from anchorX
|
|
6353
6491
|
let runX = anchorX;
|
|
6354
6492
|
ctx.textAlign = 'left';
|
|
6355
6493
|
for (const run of line.runs) {
|
|
6356
6494
|
const runStyle = run.italic ? 'italic ' : '';
|
|
6357
6495
|
const runWeight = run.bold ? 700 : fontWeight;
|
|
6358
6496
|
ctx.font = `${runStyle}${runWeight} ${fontSize}px ${mFont}`;
|
|
6359
|
-
|
|
6360
|
-
runX +=
|
|
6497
|
+
drawRun(run, runX);
|
|
6498
|
+
runX += runW(run);
|
|
6361
6499
|
}
|
|
6362
6500
|
}
|
|
6363
6501
|
ctx.restore();
|
|
6364
6502
|
y += LINE_SPACING[line.kind];
|
|
6365
6503
|
}
|
|
6504
|
+
ctx.globalAlpha = 1;
|
|
6366
6505
|
}
|
|
6367
6506
|
// ── Charts ────────────────────────────────────────────────
|
|
6368
6507
|
for (const c of sg.charts) {
|
|
@@ -6400,6 +6539,7 @@ var AIDiagram = (function (exports) {
|
|
|
6400
6539
|
const getTableEl = (svg, id) => getEl(svg, `table-${id}`);
|
|
6401
6540
|
const getNoteEl = (svg, id) => getEl(svg, `note-${id}`);
|
|
6402
6541
|
const getChartEl = (svg, id) => getEl(svg, `chart-${id}`);
|
|
6542
|
+
const getMarkdownEl = (svg, id) => getEl(svg, `markdown-${id}`);
|
|
6403
6543
|
function resolveEl(svg, target) {
|
|
6404
6544
|
// check edge first — target contains connector like "a-->b"
|
|
6405
6545
|
const edge = parseEdgeTarget(target);
|
|
@@ -6411,6 +6551,7 @@ var AIDiagram = (function (exports) {
|
|
|
6411
6551
|
getTableEl(svg, target) ??
|
|
6412
6552
|
getNoteEl(svg, target) ??
|
|
6413
6553
|
getChartEl(svg, target) ??
|
|
6554
|
+
getMarkdownEl(svg, target) ??
|
|
6414
6555
|
null);
|
|
6415
6556
|
}
|
|
6416
6557
|
function pathLength(p) {
|
|
@@ -6421,6 +6562,15 @@ var AIDiagram = (function (exports) {
|
|
|
6421
6562
|
return 200;
|
|
6422
6563
|
}
|
|
6423
6564
|
}
|
|
6565
|
+
function clearDashOverridesAfter(el, delayMs) {
|
|
6566
|
+
setTimeout(() => {
|
|
6567
|
+
el.querySelectorAll('path').forEach(p => {
|
|
6568
|
+
p.style.strokeDasharray = '';
|
|
6569
|
+
p.style.strokeDashoffset = '';
|
|
6570
|
+
p.style.transition = '';
|
|
6571
|
+
});
|
|
6572
|
+
}, delayMs);
|
|
6573
|
+
}
|
|
6424
6574
|
// ── Arrow connector parser ────────────────────────────────
|
|
6425
6575
|
const ARROW_CONNECTORS = ["<-->", "<->", "-->", "<--", "->", "<-", "---", "--"];
|
|
6426
6576
|
function parseEdgeTarget(target) {
|
|
@@ -6528,32 +6678,39 @@ var AIDiagram = (function (exports) {
|
|
|
6528
6678
|
});
|
|
6529
6679
|
}
|
|
6530
6680
|
function animateEdgeDraw(el, conn) {
|
|
6531
|
-
const paths = Array.from(el.querySelectorAll(
|
|
6681
|
+
const paths = Array.from(el.querySelectorAll('path'));
|
|
6532
6682
|
if (!paths.length)
|
|
6533
6683
|
return;
|
|
6534
6684
|
const linePath = paths[0];
|
|
6535
6685
|
const headPaths = paths.slice(1);
|
|
6536
6686
|
const STROKE_DUR = 360;
|
|
6537
6687
|
const len = pathLength(linePath);
|
|
6538
|
-
const reversed = conn.startsWith(
|
|
6688
|
+
const reversed = conn.startsWith('<') && !conn.includes('>');
|
|
6539
6689
|
linePath.style.strokeDasharray = `${len}`;
|
|
6540
6690
|
linePath.style.strokeDashoffset = reversed ? `${-len}` : `${len}`;
|
|
6541
|
-
linePath.style.transition =
|
|
6542
|
-
headPaths.forEach(
|
|
6543
|
-
p.style.opacity =
|
|
6544
|
-
p.style.transition =
|
|
6691
|
+
linePath.style.transition = 'none';
|
|
6692
|
+
headPaths.forEach(p => {
|
|
6693
|
+
p.style.opacity = '0';
|
|
6694
|
+
p.style.transition = 'none';
|
|
6545
6695
|
});
|
|
6546
|
-
el.classList.remove(
|
|
6547
|
-
el.classList.add(
|
|
6548
|
-
el.style.opacity =
|
|
6696
|
+
el.classList.remove('draw-hidden');
|
|
6697
|
+
el.classList.add('draw-reveal');
|
|
6698
|
+
el.style.opacity = '1';
|
|
6549
6699
|
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
6550
6700
|
linePath.style.transition = `stroke-dashoffset ${STROKE_DUR}ms cubic-bezier(.4,0,.2,1)`;
|
|
6551
|
-
linePath.style.strokeDashoffset =
|
|
6701
|
+
linePath.style.strokeDashoffset = '0';
|
|
6552
6702
|
setTimeout(() => {
|
|
6553
|
-
headPaths.forEach(
|
|
6554
|
-
p.style.transition =
|
|
6555
|
-
p.style.opacity =
|
|
6703
|
+
headPaths.forEach(p => {
|
|
6704
|
+
p.style.transition = 'opacity 120ms ease';
|
|
6705
|
+
p.style.opacity = '1';
|
|
6556
6706
|
});
|
|
6707
|
+
// ── ADD: clear inline dash overrides so SVG attribute
|
|
6708
|
+
// (stroke-dasharray="6,5" for dashed arrows) takes over again
|
|
6709
|
+
setTimeout(() => {
|
|
6710
|
+
linePath.style.strokeDasharray = '';
|
|
6711
|
+
linePath.style.strokeDashoffset = '';
|
|
6712
|
+
linePath.style.transition = '';
|
|
6713
|
+
}, 160);
|
|
6557
6714
|
}, STROKE_DUR - 40);
|
|
6558
6715
|
}));
|
|
6559
6716
|
}
|
|
@@ -6577,6 +6734,7 @@ var AIDiagram = (function (exports) {
|
|
|
6577
6734
|
this.drawTargetTables = new Set();
|
|
6578
6735
|
this.drawTargetNotes = new Set();
|
|
6579
6736
|
this.drawTargetCharts = new Set();
|
|
6737
|
+
this.drawTargetMarkdowns = new Set();
|
|
6580
6738
|
for (const s of steps) {
|
|
6581
6739
|
if (s.action !== "draw" || parseEdgeTarget(s.target))
|
|
6582
6740
|
continue;
|
|
@@ -6597,6 +6755,10 @@ var AIDiagram = (function (exports) {
|
|
|
6597
6755
|
this.drawTargetCharts.add(`chart-${s.target}`);
|
|
6598
6756
|
this.drawTargetNodes.delete(`node-${s.target}`);
|
|
6599
6757
|
}
|
|
6758
|
+
if (svg.querySelector(`#markdown-${s.target}`)) {
|
|
6759
|
+
this.drawTargetMarkdowns.add(`markdown-${s.target}`);
|
|
6760
|
+
this.drawTargetNodes.delete(`node-${s.target}`);
|
|
6761
|
+
}
|
|
6600
6762
|
}
|
|
6601
6763
|
this._clearAll();
|
|
6602
6764
|
}
|
|
@@ -6768,7 +6930,24 @@ var AIDiagram = (function (exports) {
|
|
|
6768
6930
|
});
|
|
6769
6931
|
}
|
|
6770
6932
|
});
|
|
6771
|
-
|
|
6933
|
+
// Markdown
|
|
6934
|
+
this.svg.querySelectorAll(".mdg").forEach((el) => {
|
|
6935
|
+
clearDrawStyles(el);
|
|
6936
|
+
el.style.transition = "none";
|
|
6937
|
+
el.style.opacity = "";
|
|
6938
|
+
if (this.drawTargetMarkdowns.has(el.id)) {
|
|
6939
|
+
el.classList.add("gg-hidden");
|
|
6940
|
+
}
|
|
6941
|
+
else {
|
|
6942
|
+
el.classList.remove("gg-hidden");
|
|
6943
|
+
requestAnimationFrame(() => {
|
|
6944
|
+
el.style.transition = "";
|
|
6945
|
+
});
|
|
6946
|
+
}
|
|
6947
|
+
});
|
|
6948
|
+
this.svg
|
|
6949
|
+
.querySelectorAll(".tg, .ntg, .cg, .mdg")
|
|
6950
|
+
.forEach((el) => {
|
|
6772
6951
|
el.style.transform = "";
|
|
6773
6952
|
el.style.transition = "";
|
|
6774
6953
|
el.style.opacity = "";
|
|
@@ -6946,6 +7125,9 @@ var AIDiagram = (function (exports) {
|
|
|
6946
7125
|
if (!firstPath?.style.strokeDasharray)
|
|
6947
7126
|
prepareForDraw(groupEl);
|
|
6948
7127
|
animateShapeDraw(groupEl, 550, 40);
|
|
7128
|
+
const pathCount = groupEl.querySelectorAll('path').length;
|
|
7129
|
+
const totalMs = pathCount * 40 + 550 + 120; // stagger + duration + buffer
|
|
7130
|
+
clearDashOverridesAfter(groupEl, totalMs);
|
|
6949
7131
|
}
|
|
6950
7132
|
return;
|
|
6951
7133
|
}
|
|
@@ -6966,6 +7148,8 @@ var AIDiagram = (function (exports) {
|
|
|
6966
7148
|
tableEl.classList.remove("gg-hidden");
|
|
6967
7149
|
prepareForDraw(tableEl);
|
|
6968
7150
|
animateShapeDraw(tableEl, 500, 40);
|
|
7151
|
+
const tablePathCount = tableEl.querySelectorAll('path').length;
|
|
7152
|
+
clearDashOverridesAfter(tableEl, tablePathCount * 40 + 500 + 120);
|
|
6969
7153
|
}
|
|
6970
7154
|
return;
|
|
6971
7155
|
}
|
|
@@ -6986,6 +7170,8 @@ var AIDiagram = (function (exports) {
|
|
|
6986
7170
|
noteEl.classList.remove("gg-hidden");
|
|
6987
7171
|
prepareForDraw(noteEl);
|
|
6988
7172
|
animateShapeDraw(noteEl, 420, 55);
|
|
7173
|
+
const notePathCount = noteEl.querySelectorAll('path').length;
|
|
7174
|
+
clearDashOverridesAfter(noteEl, notePathCount * 55 + 420 + 120);
|
|
6989
7175
|
}
|
|
6990
7176
|
return;
|
|
6991
7177
|
}
|
|
@@ -7013,6 +7199,28 @@ var AIDiagram = (function (exports) {
|
|
|
7013
7199
|
}
|
|
7014
7200
|
return;
|
|
7015
7201
|
}
|
|
7202
|
+
// ── Markdown ──────────────────────────────────────────
|
|
7203
|
+
const markdownEl = getMarkdownEl(this.svg, target);
|
|
7204
|
+
if (markdownEl) {
|
|
7205
|
+
if (silent) {
|
|
7206
|
+
markdownEl.style.transition = "none";
|
|
7207
|
+
markdownEl.style.opacity = "";
|
|
7208
|
+
markdownEl.classList.remove("gg-hidden");
|
|
7209
|
+
markdownEl.style.opacity = "1";
|
|
7210
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
7211
|
+
markdownEl.style.transition = "";
|
|
7212
|
+
}));
|
|
7213
|
+
}
|
|
7214
|
+
else {
|
|
7215
|
+
markdownEl.style.opacity = "0";
|
|
7216
|
+
markdownEl.classList.remove("gg-hidden");
|
|
7217
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
7218
|
+
markdownEl.style.transition = "opacity 500ms ease";
|
|
7219
|
+
markdownEl.style.opacity = "1";
|
|
7220
|
+
}));
|
|
7221
|
+
}
|
|
7222
|
+
return;
|
|
7223
|
+
}
|
|
7016
7224
|
// ── Node draw ──────────────────────────────────────
|
|
7017
7225
|
const nodeEl = getNodeEl(this.svg, target);
|
|
7018
7226
|
if (!nodeEl)
|
|
@@ -7026,14 +7234,16 @@ var AIDiagram = (function (exports) {
|
|
|
7026
7234
|
if (!firstPath?.style.strokeDasharray)
|
|
7027
7235
|
prepareForDraw(nodeEl);
|
|
7028
7236
|
animateShapeDraw(nodeEl, 420, 55);
|
|
7237
|
+
const nodePathCount = nodeEl.querySelectorAll('path').length;
|
|
7238
|
+
clearDashOverridesAfter(nodeEl, nodePathCount * 55 + 420 + 120);
|
|
7029
7239
|
}
|
|
7030
7240
|
}
|
|
7031
7241
|
// ── erase ─────────────────────────────────────────────────
|
|
7032
7242
|
_doErase(target) {
|
|
7033
7243
|
const el = resolveEl(this.svg, target); // handles edges too now
|
|
7034
7244
|
if (el) {
|
|
7035
|
-
el.style.transition =
|
|
7036
|
-
el.style.opacity =
|
|
7245
|
+
el.style.transition = "opacity 0.4s";
|
|
7246
|
+
el.style.opacity = "0";
|
|
7037
7247
|
}
|
|
7038
7248
|
}
|
|
7039
7249
|
// ── show / hide ───────────────────────────────────────────
|
|
@@ -7061,10 +7271,10 @@ var AIDiagram = (function (exports) {
|
|
|
7061
7271
|
return;
|
|
7062
7272
|
// edge — color stroke
|
|
7063
7273
|
if (parseEdgeTarget(target)) {
|
|
7064
|
-
el.querySelectorAll(
|
|
7274
|
+
el.querySelectorAll("path, line, polyline").forEach((p) => {
|
|
7065
7275
|
p.style.stroke = color;
|
|
7066
7276
|
});
|
|
7067
|
-
el.querySelectorAll(
|
|
7277
|
+
el.querySelectorAll("polygon").forEach((p) => {
|
|
7068
7278
|
p.style.fill = color;
|
|
7069
7279
|
p.style.stroke = color;
|
|
7070
7280
|
});
|
|
@@ -7072,22 +7282,24 @@ var AIDiagram = (function (exports) {
|
|
|
7072
7282
|
}
|
|
7073
7283
|
// everything else — color fill
|
|
7074
7284
|
let hit = false;
|
|
7075
|
-
el.querySelectorAll(
|
|
7076
|
-
const attrFill = c.getAttribute(
|
|
7077
|
-
if (attrFill ===
|
|
7285
|
+
el.querySelectorAll("path, rect, ellipse, polygon").forEach((c) => {
|
|
7286
|
+
const attrFill = c.getAttribute("fill");
|
|
7287
|
+
if (attrFill === "none")
|
|
7078
7288
|
return;
|
|
7079
|
-
if (attrFill === null && c.tagName ===
|
|
7289
|
+
if (attrFill === null && c.tagName === "path")
|
|
7080
7290
|
return;
|
|
7081
7291
|
c.style.fill = color;
|
|
7082
7292
|
hit = true;
|
|
7083
7293
|
});
|
|
7084
7294
|
if (!hit) {
|
|
7085
|
-
el.querySelectorAll(
|
|
7295
|
+
el.querySelectorAll("text").forEach((t) => {
|
|
7296
|
+
t.style.fill = color;
|
|
7297
|
+
});
|
|
7086
7298
|
}
|
|
7087
7299
|
}
|
|
7088
7300
|
}
|
|
7089
7301
|
const ANIMATION_CSS = `
|
|
7090
|
-
.ng, .gg, .tg, .ntg, .cg, .eg {
|
|
7302
|
+
.ng, .gg, .tg, .ntg, .cg, .eg, .mdg {
|
|
7091
7303
|
transform-box: fill-box;
|
|
7092
7304
|
transform-origin: center;
|
|
7093
7305
|
transition: filter 0.3s, opacity 0.35s;
|
|
@@ -7098,9 +7310,10 @@ var AIDiagram = (function (exports) {
|
|
|
7098
7310
|
.tg.hl path, .tg.hl rect,
|
|
7099
7311
|
.ntg.hl path, .ntg.hl polygon,
|
|
7100
7312
|
.cg.hl path, .cg.hl rect,
|
|
7313
|
+
.mdg.hl text,
|
|
7101
7314
|
.eg.hl path, .eg.hl line, .eg.hl polygon { stroke-width: 2.8 !important; }
|
|
7102
7315
|
|
|
7103
|
-
.ng.hl, .tg.hl, .ntg.hl, .cg.hl, .eg.hl {
|
|
7316
|
+
.ng.hl, .tg.hl, .ntg.hl, .cg.hl, .mdg.hl, .eg.hl {
|
|
7104
7317
|
animation: ng-pulse 1.4s ease-in-out infinite;
|
|
7105
7318
|
}
|
|
7106
7319
|
@keyframes ng-pulse {
|
|
@@ -7109,7 +7322,8 @@ var AIDiagram = (function (exports) {
|
|
|
7109
7322
|
}
|
|
7110
7323
|
|
|
7111
7324
|
/* fade */
|
|
7112
|
-
.ng.faded, .gg.faded, .tg.faded, .ntg.faded,
|
|
7325
|
+
.ng.faded, .gg.faded, .tg.faded, .ntg.faded,
|
|
7326
|
+
.cg.faded, .eg.faded, .mdg.faded { opacity: 0.22; }
|
|
7113
7327
|
|
|
7114
7328
|
.ng.hidden { opacity: 0; pointer-events: none; }
|
|
7115
7329
|
.eg.draw-hidden { opacity: 0; }
|
|
@@ -7118,6 +7332,7 @@ var AIDiagram = (function (exports) {
|
|
|
7118
7332
|
.tg.gg-hidden { opacity: 0; }
|
|
7119
7333
|
.ntg.gg-hidden { opacity: 0; }
|
|
7120
7334
|
.cg.gg-hidden { opacity: 0; }
|
|
7335
|
+
.mdg.gg-hidden { opacity: 0; }
|
|
7121
7336
|
`;
|
|
7122
7337
|
|
|
7123
7338
|
// ============================================================
|