@cardenelabs/cdl 0.72.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -1
- package/dist/index.cjs +43 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -22
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +43 -22
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +43 -22
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/kinds/shape-blockchain.tsx +49 -8
- package/src/kinds/shape-region.tsx +20 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/cdl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.73.0",
|
|
4
4
|
"description": "CDL (Chainome Diagram Language). Mermaid-like declarative DSL that compiles to animated SVG diagrams. Built for blockchain / Solidity flows, generic enough for sequence / flow / state / ER / topology diagrams.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "cardene777",
|
|
@@ -29,6 +29,35 @@ const SMART_CONTRACT_H = 220;
|
|
|
29
29
|
|
|
30
30
|
const BLOCK_W = 240;
|
|
31
31
|
const BLOCK_H = 220;
|
|
32
|
+
/** `shape-blockchain-block` の字の指定 (#871 で打ち消しの計算に使うため定数へ出した) */
|
|
33
|
+
const 見出しの字 = 13;
|
|
34
|
+
const 名の字 = 10.5;
|
|
35
|
+
const 値の字 = 11;
|
|
36
|
+
/** 5 行を並べる間隔と、見出しが乗る帯の高さ。 打ち消しの上限をここから出す (#871) */
|
|
37
|
+
const 行の間隔 = 22;
|
|
38
|
+
const 見出しの帯 = 32;
|
|
39
|
+
/** 打ち消した字が帯のどこまでを占めてよいか。 超えると上下の行や帯の縁に触れる */
|
|
40
|
+
const 帯に対する上限 = 0.8;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 縮んだ分を字の指定で打ち消す倍率 (#871)。
|
|
44
|
+
*
|
|
45
|
+
* この絵は 240 x 220 で組んでから、箱に収まる倍率で丸ごと縮む。 字も一緒に縮むので、
|
|
46
|
+
* 指定 10.5 が `k = 0.719` の図で 7.55 になり、画面で読める下限 (8px) を割っていた。
|
|
47
|
+
*
|
|
48
|
+
* **上限は絵の中の帯から出す** = 固定値にすると、絵の寸法を変えた日に効き方だけが変わる。
|
|
49
|
+
* 5 行は 22 ずつ空けて並べ、見出しは高さ 32 の帯に乗る。
|
|
50
|
+
*
|
|
51
|
+
* 1 を下回らない = 縮んでいない図 (`k = 1`) で字を小さくしない。
|
|
52
|
+
*/
|
|
53
|
+
function 打ち消しの倍率(k: number): number {
|
|
54
|
+
const 戻し = Number.isFinite(k) && k > 0 ? 1 / k : 1;
|
|
55
|
+
const 上限 = Math.min(
|
|
56
|
+
(行の間隔 * 帯に対する上限) / 値の字,
|
|
57
|
+
(見出しの帯 * 帯に対する上限) / 見出しの字,
|
|
58
|
+
);
|
|
59
|
+
return Math.max(1, Math.min(戻し, 上限));
|
|
60
|
+
}
|
|
32
61
|
const BLOCK_SHADOW = 6;
|
|
33
62
|
|
|
34
63
|
const NFT_W = 220;
|
|
@@ -321,27 +350,38 @@ export function ShapeBlockchainBlockNode({ node, active, lang }: ShapeProps): JS
|
|
|
321
350
|
|
|
322
351
|
// 見出しは右上の丸 (半径 5.5、 中心が bw - 16) に掛からないところまで
|
|
323
352
|
const 見出しの幅 = bw - 14 - 30;
|
|
324
|
-
|
|
353
|
+
/*
|
|
354
|
+
* 絵を **倍率を受け取ってから** 組む (#871)。 縮んだ分を字の指定で打ち消す。
|
|
355
|
+
*
|
|
356
|
+
* **幅の予算も打ち消した後の大きさで計算する** = 字だけ大きくして切る位置を元の大きさの
|
|
357
|
+
* まま置くと、切った字が枠から出る。
|
|
358
|
+
*/
|
|
359
|
+
const art = (倍率: number): JSX.Element => {
|
|
360
|
+
const 倍 = 打ち消しの倍率(倍率);
|
|
361
|
+
const 題の大きさ = 見出しの字 * 倍;
|
|
362
|
+
const 名の大きさ = 名の字 * 倍;
|
|
363
|
+
const 値の大きさ = 値の字 * 倍;
|
|
364
|
+
return (
|
|
325
365
|
<g>
|
|
326
366
|
{/* 3D shadow */}
|
|
327
367
|
<rect x={x + 6} y={y + 6} width={bw} height={bh} rx={8} fill={frame.stroke} opacity={0.2} stroke="none" />
|
|
328
368
|
<rect data-cdl-role="node-body" x={x} y={y} width={bw} height={bh} rx={8} {...frame} />
|
|
329
369
|
{/* header bar */}
|
|
330
370
|
<path d={`M ${x} ${y + 32} L ${x} ${y + 8} Q ${x} ${y}, ${x + 8} ${y} L ${x + bw - 8} ${y} Q ${x + bw} ${y}, ${x + bw} ${y + 8} L ${x + bw} ${y + 32} Z`} fill="var(--cdl-tone-accent, #2d6a8f)" fillOpacity={0.9} stroke="none" />
|
|
331
|
-
<text data-cdl-role="blockchain-block-title" x={x + 14} y={y + 22} fontSize={
|
|
332
|
-
{幅で切る(見出し,
|
|
371
|
+
<text data-cdl-role="blockchain-block-title" x={x + 14} y={y + 22} fontSize={題の大きさ} fontWeight={700} fontFamily="ui-monospace, SFMono-Regular, Menlo, monospace" fill="#ffffff">
|
|
372
|
+
{幅で切る(見出し, 題の大きさ, 見出しの幅, 字の幅)}
|
|
333
373
|
</text>
|
|
334
374
|
<circle cx={x + bw - 16} cy={y + 16} r={5.5} fill="#7cd88f" stroke="#ffffff" strokeWidth={1.5} />
|
|
335
375
|
{/* fields */}
|
|
336
376
|
{fields.map((f, i) => (
|
|
337
377
|
<g key={i}>
|
|
338
|
-
<text x={x + 14} y={y + 54 + i *
|
|
378
|
+
<text x={x + 14} y={y + 54 + i * 行の間隔} fontSize={名の大きさ} fontFamily="ui-monospace, SFMono-Regular, Menlo, monospace" fill="var(--cdl-text-dim, #5a6270)">
|
|
339
379
|
{f.label}
|
|
340
380
|
</text>
|
|
341
|
-
<text data-cdl-role={`blockchain-block-${f.key}`} x={x + bw - 14} y={y + 54 + i *
|
|
342
|
-
{幅で切る(f.value,
|
|
381
|
+
<text data-cdl-role={`blockchain-block-${f.key}`} x={x + bw - 14} y={y + 54 + i * 行の間隔} fontSize={値の大きさ} fontFamily="ui-monospace, SFMono-Regular, Menlo, monospace" fontWeight={600} textAnchor="end" fill="var(--cdl-text, #1a1f2a)">
|
|
382
|
+
{幅で切る(f.value, 値の大きさ, bw - 28 - 字の幅(f.label, 名の大きさ) - 8, 字の幅)}
|
|
343
383
|
</text>
|
|
344
|
-
<line x1={x + 14} y1={y + 60 + i *
|
|
384
|
+
<line x1={x + 14} y1={y + 60 + i * 行の間隔} x2={x + bw - 14} y2={y + 60 + i * 行の間隔} stroke="var(--cdl-divider, #d4d4d8)" strokeWidth={0.5} opacity={0.5} />
|
|
345
385
|
</g>
|
|
346
386
|
))}
|
|
347
387
|
{/* chain link icon (bottom center) */}
|
|
@@ -351,7 +391,8 @@ export function ShapeBlockchainBlockNode({ node, active, lang }: ShapeProps): JS
|
|
|
351
391
|
<rect x={42} y={0} width={22} height={18} rx={3} fill="var(--cdl-tone-accent, #2d6a8f)" fillOpacity={0.5} stroke={frame.stroke} strokeWidth={1.5} />
|
|
352
392
|
</g>
|
|
353
393
|
</g>
|
|
354
|
-
|
|
394
|
+
);
|
|
395
|
+
};
|
|
355
396
|
return <g>{fitArt(r, blockchainBlockExtent(frame.strokeWidth), art)}</g>;
|
|
356
397
|
}
|
|
357
398
|
|
|
@@ -450,13 +450,27 @@ export type ArtExtent = { 上: number; 下: number; 左: number; 右: number };
|
|
|
450
450
|
export function fitArt(
|
|
451
451
|
region: { cx: number; cy: number; availW: number; availH: number },
|
|
452
452
|
extent: ArtExtent,
|
|
453
|
-
art: JSX.Element,
|
|
453
|
+
art: JSX.Element | ((倍率: number) => JSX.Element),
|
|
454
454
|
): JSX.Element {
|
|
455
|
+
/*
|
|
456
|
+
* 絵を **倍率を知った上で** 組めるようにする (#871)。
|
|
457
|
+
*
|
|
458
|
+
* 縮める時は絵を丸ごと `scale(k)` で包むため、中の文字も一緒に縮む。 指定 10.5 の字が
|
|
459
|
+
* `k = 0.719` の図で 7.55 になり、読める下限 (画面で 8px) を割っていた。
|
|
460
|
+
*
|
|
461
|
+
* **打ち消せるのは絵の側だけ**。 ここで文字の指定を機械的に `1/k` 倍すると、絵が自分で
|
|
462
|
+
* 計算している「その字が収まる幅」 が指定の大きさのまま残り、字だけが大きくなって
|
|
463
|
+
* 枠から出る (`shape-blockchain-block` は `幅で切る` に指定 11 を渡して切る位置を決めている)。
|
|
464
|
+
*
|
|
465
|
+
* そこで **倍率を絵に渡し、打ち消すかどうかを絵に決めさせる**。 関数を渡さない絵は
|
|
466
|
+
* 今までどおり縮むだけで、1 つも描き方が変わらない。
|
|
467
|
+
*/
|
|
468
|
+
const 組む = (k: number): JSX.Element => (typeof art === "function" ? art(k) : art);
|
|
455
469
|
const 縦 = extent.上 + extent.下;
|
|
456
470
|
const 横 = extent.左 + extent.右;
|
|
457
471
|
// 広がりが無限なら倍率が 0 になるので後段の `s` の防御でも止まる。 ここで先に落とすのは
|
|
458
472
|
// 契約 (有限で正の値だけを通す) を入口で 1 つに揃えるため
|
|
459
|
-
if (!Number.isFinite(縦) || !Number.isFinite(横) || 縦 <= 0 || 横 <= 0) return
|
|
473
|
+
if (!Number.isFinite(縦) || !Number.isFinite(横) || 縦 <= 0 || 横 <= 0) return 組む(1);
|
|
460
474
|
|
|
461
475
|
// **ここは後段の `s` の防御では代替できない**。 無限の軸は倍率の候補が `Infinity` になって
|
|
462
476
|
// `Math.min` から落ちるだけなので、 残りの候補 (上限 1 と反対の軸) で倍率が決まり、 通常の
|
|
@@ -467,11 +481,11 @@ export function fitArt(
|
|
|
467
481
|
region.availH <= 0 ||
|
|
468
482
|
region.availW <= 0
|
|
469
483
|
) {
|
|
470
|
-
return
|
|
484
|
+
return 組む(1);
|
|
471
485
|
}
|
|
472
486
|
|
|
473
487
|
const s = Math.min(1, region.availH / 縦, region.availW / 横);
|
|
474
|
-
if (!Number.isFinite(s) || s <= 0) return
|
|
488
|
+
if (!Number.isFinite(s) || s <= 0) return 組む(1);
|
|
475
489
|
|
|
476
490
|
// 絵の外接矩形の中心を領域の中心に合わせる。 上下 (左右) の広がりが違うので、 中心を
|
|
477
491
|
// そろえないと片側だけはみ出す
|
|
@@ -488,14 +502,14 @@ export function fitArt(
|
|
|
488
502
|
// 食い込む。 「収まるか」 を合計だけで見て位置を見ていなかった。
|
|
489
503
|
//
|
|
490
504
|
// 倍率が 1 で中心も合っている時だけ包まない = 対称な絵に余計な `<g>` を挟まない。
|
|
491
|
-
if (s >= 1 && dx === 0 && dy === 0) return
|
|
505
|
+
if (s >= 1 && dx === 0 && dy === 0) return 組む(1);
|
|
492
506
|
|
|
493
507
|
// **包む時は必ず `translate` と `scale` を両方書く**。 倍率 1 の時に `translate` だけを
|
|
494
508
|
// 書くと変換の形が 2 通りになり、 読む側が両方を扱う必要が出る (実測 = 検査の変換 parser が
|
|
495
509
|
// `translate(0 1)` を読めず 8 件落ちた)。 `scale(1)` は無害なので形を 1 つに保つ
|
|
496
510
|
return (
|
|
497
511
|
<g transform={`translate(${dx} ${dy}) scale(${s})`}>
|
|
498
|
-
{
|
|
512
|
+
{組む(s)}
|
|
499
513
|
</g>
|
|
500
514
|
);
|
|
501
515
|
}
|