@cardenelabs/cdl 0.40.10 → 0.40.12

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 CHANGED
@@ -5,6 +5,61 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.40.12] - 2026-09-10
9
+
10
+ ### Fixed
11
+
12
+ - **表の列に書いた型の名前を、データと読み違えて注意を出さなくなった** (#771)
13
+
14
+ 行の検査 `row-content-typing` は `名前: 値` の名前から値の型を推し量る。 ER 図とクラス図は
15
+ 値の位置に **型の名前** を書くので、そのままでは `total: numeric` が「数字を期待したのに
16
+ `numeric`」 と読まれていた。
17
+
18
+ 逃げ道は型名を並べた手書きの一覧で、`BIGINT` / `INT` / `FLOAT` / `VARCHAR` は載っている
19
+ 一方 `numeric` が抜けていた。 同じ形で `decimal` / `jsonb` / `interval` も抜けている。
20
+ **書き手が思い付いた名前が上限になる** 形で、方言ごとに増える型名を追えない。
21
+
22
+ 行が列の宣言かどうかを、値の語ではなく **行頭の印** (`rowMarks`) で決めるようにした。
23
+ 印は `er` / `classDiagram` が `columns` / `attributes` を受け取った時だけ付くので、
24
+ 印がある行は engine 自身が「値の位置に型の名前が来る」 と知っている。
25
+
26
+ 外すのは **行の単位** にした。 箱の単位で外すと、印を持つ箱に混ざった印なしの行の実データ
27
+ まで見なくなる。
28
+
29
+ 手書きの一覧は残す。 `rows` を直接書いた古い形は印を持たないので、消すと丸ごと注意に
30
+ 落ちる。 一方で **足しもしない** = 足すと同じ穴が次の型名で戻る。
31
+
32
+ ## [0.40.11] - 2026-09-09
33
+
34
+ ### Fixed
35
+
36
+ - **棒 / 弧 / 半円 が受け取った前の時点の値を描くようにした** (#767)
37
+
38
+ `previous` を読むのは円 / 内訳の帯 / 2 時点の線 / 数値ひとつの図の 4 種だけで、残る
39
+ 3 種は **受け取っておきながら 1 度も読んでいなかった**。 数値ひとつの図で同じ抜けを
40
+ 直したのが `#763` で、そちらは画面に出る文字の数の記録が落ちて初めて見つかっている。
41
+
42
+ 下流の見本帳が 49 組を描き比べて残りを洗い出した。
43
+
44
+ | 種別 | 置き方 | 役割名 |
45
+ |---|---|---|
46
+ | 棒 | 棒の上に、前の高さを指す印を 1 本引く | `chart-bar-previous` |
47
+ | 弧 | 弧の帯を横切る印を、前の割合の角度に置く | `chart-radial-previous` |
48
+ | 半円 | 内側に前の内訳の輪を 1 本足す | `chart-gauge-previous` |
49
+
50
+ **薄い色で後ろに重ねる形は採らない**。 前が今より小さい件で今の形に完全に隠れ、1 px も
51
+ 見えなくなる。 棒と弧は 1 件が 1 本なので印を引き、半円は件を積んで合計を出す図
52
+ (半分の円グラフ) なので円グラフ (`#679`) と同じく内側の輪にする。
53
+
54
+ 棒は縦軸の天井を前の時点まで含めて決めるようにした。 含めないと、前が今より大きい件で
55
+ 印が枠の外へ出る。
56
+
57
+ 書かない図では役割を 1 つも出さず、半円の輪の太さも変わらない。
58
+
59
+ 対象外が 4 つある。 折れ線の `previous` (横軸そのものが時の流れで、点ごとの前の時点は
60
+ 線の中に既にある)、100 個の印の `previous` (印が 200 個になり 100 個で読む前提が崩れる)、
61
+ 折れ線の `tone` (線は 1 本 1 色)、棒の `tone` (`#747` が 1 色 + 濃さと決めた形)。
62
+
8
63
  ## [0.40.10] - 2026-09-08
9
64
 
10
65
  ### Fixed
@@ -2032,7 +2087,9 @@ Initial OSS release.
2032
2087
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
2033
2088
  行き止まりになる。
2034
2089
 
2035
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.40.10...HEAD
2090
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.40.12...HEAD
2091
+ [0.40.12]: https://github.com/cardene777/cdl/compare/v0.40.11...v0.40.12
2092
+ [0.40.11]: https://github.com/cardene777/cdl/compare/v0.40.10...v0.40.11
2036
2093
  [0.40.10]: https://github.com/cardene777/cdl/compare/v0.40.9...v0.40.10
2037
2094
  [0.40.9]: https://github.com/cardene777/cdl/compare/v0.40.8...v0.40.9
2038
2095
  [0.40.8]: https://github.com/cardene777/cdl/compare/v0.40.7...v0.40.8
package/dist/index.cjs CHANGED
@@ -17214,7 +17214,9 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes) {
17214
17214
  const SCHEMA_KEYWORDS = /^(string|number|boolean|text|enum|timestamp|date|datetime|json|blob|PK|FK|UUID|BIGINT|INT|FLOAT|VARCHAR|TEXT|DATETIME)$|^enum\(|^varchar\(/i;
17215
17215
  for (const n of diag.nodes) {
17216
17216
  if (!n.rows) continue;
17217
- for (const row of n.rows) {
17217
+ for (let i = 0; i < n.rows.length; i++) {
17218
+ const row = n.rows[i];
17219
+ if (n.rowMarks?.[i] != null) continue;
17218
17220
  const m = row.match(/^([^:]+):\s*(.+)$/);
17219
17221
  if (!m) continue;
17220
17222
  const [, key, value] = m;
@@ -24961,18 +24963,35 @@ function ChartGaugeNode({
24961
24963
  const \u5185\u534A\u5F84 = radius * 0.62;
24962
24964
  const cx = node.w / 2;
24963
24965
  const cy = PAD_TOP2 + radius;
24966
+ const \u524D\u3042\u308A = \u51FA\u3059\u4EF6\u305F\u3061.some((d) => d.previous !== void 0);
24967
+ const \u524D\u306E\u5024 = \u51FA\u3059\u4EF6\u305F\u3061.map((d) => Math.max(0, d.previous ?? 0));
24968
+ const \u524D\u306E\u5408\u8A08 = \u524D\u306E\u5024.reduce((acc, v) => acc + v, 0);
24969
+ const \u5E2F = radius - \u5185\u534A\u5F84;
24970
+ const \u4ECA\u306E\u5185\u534A\u5F84 = \u524D\u3042\u308A ? \u5185\u534A\u5F84 + \u5E2F * 0.42 : \u5185\u534A\u5F84;
24971
+ const \u524D\u306E\u5185\u534A\u5F84 = \u5185\u534A\u5F84;
24972
+ const \u524D\u306E\u5916\u534A\u5F84 = \u5185\u534A\u5F84 + \u5E2F * 0.32;
24973
+ const \u6247\u306E\u9053 = (a0, a1, \u5185, \u5916) => {
24974
+ const \u59161 = \u6975(cx, cy, \u5916, a0);
24975
+ const \u59162 = \u6975(cx, cy, \u5916, a1);
24976
+ const \u51852 = \u6975(cx, cy, \u5185, a1);
24977
+ const \u51851 = \u6975(cx, cy, \u5185, a0);
24978
+ return `M ${\u59161.x} ${\u59161.y} A ${\u5916} ${\u5916} 0 0 1 ${\u59162.x} ${\u59162.y} L ${\u51852.x} ${\u51852.y} A ${\u5185} ${\u5185} 0 0 0 ${\u51851.x} ${\u51851.y} Z`;
24979
+ };
24964
24980
  let cumFrac = 0;
24965
24981
  const slices = \u51FA\u3059\u4EF6\u305F\u3061.map((d) => {
24966
24982
  const frac = d.value / total;
24967
24983
  const a0 = Math.PI + cumFrac * Math.PI;
24968
24984
  const a1 = a0 + frac * Math.PI;
24969
24985
  cumFrac += frac;
24970
- const \u59161 = \u6975(cx, cy, radius, a0);
24971
- const \u59162 = \u6975(cx, cy, radius, a1);
24972
- const \u51852 = \u6975(cx, cy, \u5185\u534A\u5F84, a1);
24973
- const \u51851 = \u6975(cx, cy, \u5185\u534A\u5F84, a0);
24974
- const path = `M ${\u59161.x} ${\u59161.y} A ${radius} ${radius} 0 0 1 ${\u59162.x} ${\u59162.y} L ${\u51852.x} ${\u51852.y} A ${\u5185\u534A\u5F84} ${\u5185\u534A\u5F84} 0 0 0 ${\u51851.x} ${\u51851.y} Z`;
24975
- return { d, frac, path };
24986
+ return { d, frac, path: \u6247\u306E\u9053(a0, a1, \u4ECA\u306E\u5185\u534A\u5F84, radius) };
24987
+ });
24988
+ let \u524D\u306Ecum = 0;
24989
+ const \u524D\u306E\u6247\u305F\u3061 = \u51FA\u3059\u4EF6\u305F\u3061.map((d, idx) => {
24990
+ const frac = \u524D\u306E\u5408\u8A08 > 0 ? (\u524D\u306E\u5024[idx] ?? 0) / \u524D\u306E\u5408\u8A08 : 0;
24991
+ const a0 = Math.PI + \u524D\u306Ecum * Math.PI;
24992
+ const a1 = a0 + frac * Math.PI;
24993
+ \u524D\u306Ecum += frac;
24994
+ return { d, frac, path: \u6247\u306E\u9053(a0, a1, \u524D\u306E\u5185\u534A\u5F84, \u524D\u306E\u5916\u534A\u5F84) };
24976
24995
  });
24977
24996
  const \u5408\u8A08\u306E\u6587\u5B57 = \u5B9F\u5024\u8868\u8A18(Math.round(total));
24978
24997
  const \u5358\u4F4D\u5E45 = Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100), 1) / 100;
@@ -25001,6 +25020,20 @@ function ChartGaugeNode({
25001
25020
  },
25002
25021
  `arc-${idx}`
25003
25022
  ));
25023
+ const \u524D\u306E\u5F27\u305F\u3061 = \u524D\u3042\u308A ? \u524D\u306E\u6247\u305F\u3061.map((s, idx) => /* @__PURE__ */ jsxRuntime.jsx(
25024
+ "path",
25025
+ {
25026
+ "data-cdl-role": "chart-gauge-previous",
25027
+ "data-cdl-unresolved": s.d.unresolved ? "true" : void 0,
25028
+ d: s.path,
25029
+ fill: arcColor(s.d.tone, idx),
25030
+ fillOpacity: 0.45,
25031
+ stroke: "var(--cdl-node-fill, #ffffff)",
25032
+ strokeWidth: 1.5,
25033
+ strokeLinejoin: "round"
25034
+ },
25035
+ `prev-arc-${idx}`
25036
+ )) : null;
25004
25037
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
25005
25038
  /* @__PURE__ */ jsxRuntime.jsx(
25006
25039
  "rect",
@@ -25017,7 +25050,13 @@ function ChartGaugeNode({
25017
25050
  }
25018
25051
  ),
25019
25052
  drawing && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: \u5207\u308A\u629C\u304Did, children: \u6247\u5F62\u306E\u5207\u308A\u629C\u304D(cx, cy, radius + 2, \u4F38\u3073, Math.PI, Math.PI) }) }),
25020
- drawing ? /* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: `url(#${\u5207\u308A\u629C\u304Did})`, children: \u5F27\u305F\u3061 }) : \u5F27\u305F\u3061,
25053
+ drawing ? /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: `url(#${\u5207\u308A\u629C\u304Did})`, children: [
25054
+ \u524D\u306E\u5F27\u305F\u3061,
25055
+ \u5F27\u305F\u3061
25056
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
25057
+ \u524D\u306E\u5F27\u305F\u3061,
25058
+ \u5F27\u305F\u3061
25059
+ ] }),
25021
25060
  /* @__PURE__ */ jsxRuntime.jsx(
25022
25061
  "text",
25023
25062
  {
@@ -25126,9 +25165,11 @@ function ChartRadialNode({
25126
25165
  const rings = data.map((d, idx) => {
25127
25166
  const frac = d.value / total;
25128
25167
  const \u4E2D\u5FC3\u534A\u5F84 = \u5916\u534A\u5F84 - \u5E2F1\u672C * idx - \u5E2F1\u672C / 2;
25168
+ const \u524D\u306E\u5272\u5408 = d.previous === void 0 ? null : Math.max(0, d.previous) / total;
25129
25169
  return {
25130
25170
  d,
25131
25171
  frac,
25172
+ \u524D\u306E\u5272\u5408,
25132
25173
  \u4E2D\u5FC3\u534A\u5F84,
25133
25174
  // 軌道は全周。 1 周ちょうどは弧で表せないので、 わずかに欠かして描く
25134
25175
  \u8ECC\u9053: \u5F27\u306E\u90532(\u5F27\u306Ecx, cy, \u4E2D\u5FC3\u534A\u5F84, \u5E2F\u306E\u5E45, 0.9999),
@@ -25177,6 +25218,20 @@ function ChartRadialNode({
25177
25218
  )),
25178
25219
  drawing && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: \u5207\u308A\u629C\u304Did, children: \u6247\u5F62\u306E\u5207\u308A\u629C\u304D(\u5F27\u306Ecx, cy, \u5916\u534A\u5F84 + \u5E2F\u306E\u5E45, \u958B\u304D) }) }),
25179
25220
  drawing ? /* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: `url(#${\u5207\u308A\u629C\u304Did})`, children: \u53D6\u308A\u5206\u305F\u3061 }) : \u53D6\u308A\u5206\u305F\u3061,
25221
+ rings.map(
25222
+ (r, idx) => r.\u524D\u306E\u5272\u5408 === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
25223
+ "line",
25224
+ {
25225
+ "data-cdl-role": "chart-radial-previous",
25226
+ "data-cdl-unresolved": r.d.unresolved ? "true" : void 0,
25227
+ ...\u5E2F\u3092\u6A2A\u5207\u308B\u5370(\u5F27\u306Ecx, cy, r.\u4E2D\u5FC3\u534A\u5F84, \u5E2F\u306E\u5E45, Math.min(r.\u524D\u306E\u5272\u5408, 0.9999)),
25228
+ stroke: "var(--cdl-text-mute, #8a8678)",
25229
+ strokeWidth: 2,
25230
+ strokeLinecap: "round"
25231
+ },
25232
+ `prev-${idx}`
25233
+ )
25234
+ ),
25180
25235
  data.map((d, idx) => {
25181
25236
  const y = \u4E00\u89A7\u306E\u59CB\u307E\u308A + \u884C\u306E\u9AD8\u3055 * idx;
25182
25237
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-role": "chart-radial-item", children: [
@@ -25216,6 +25271,18 @@ function \u5F27\u306E\u90532(cx, cy, \u4E2D\u5FC3\u534A\u5F84, \u5E45, \u5272\u5
25216
25271
  const p = (r, a) => `${cx + r * Math.cos(a)} ${cy + r * Math.sin(a)}`;
25217
25272
  return `M ${p(\u5916, a0)} A ${\u5916} ${\u5916} 0 ${large} 1 ${p(\u5916, a1)} L ${p(\u5185, a1)} A ${\u5185} ${\u5185} 0 ${large} 0 ${p(\u5185, a0)} Z`;
25218
25273
  }
25274
+ function \u5E2F\u3092\u6A2A\u5207\u308B\u5370(cx, cy, \u4E2D\u5FC3\u534A\u5F84, \u5E45, \u5272\u5408) {
25275
+ const \u306F\u307F\u51FA\u3057 = Math.min(\u5E45 * 0.3, 5);
25276
+ const \u5916 = \u4E2D\u5FC3\u534A\u5F84 + \u5E45 / 2 + \u306F\u307F\u51FA\u3057;
25277
+ const \u5185 = Math.max(0.5, \u4E2D\u5FC3\u534A\u5F84 - \u5E45 / 2 - \u306F\u307F\u51FA\u3057);
25278
+ const a = -Math.PI / 2 + \u5272\u5408 * Math.PI * 2;
25279
+ return {
25280
+ x1: cx + \u5185 * Math.cos(a),
25281
+ y1: cy + \u5185 * Math.sin(a),
25282
+ x2: cx + \u5916 * Math.cos(a),
25283
+ y2: cy + \u5916 * Math.sin(a)
25284
+ };
25285
+ }
25219
25286
  function arcColor2(tone, idx) {
25220
25287
  if (tone) return TONE[tone];
25221
25288
  return chartSeriesColor(idx);
@@ -25966,8 +26033,9 @@ function ChartBarNode({
25966
26033
  const canvasW = node.w - PAD_LEFT2 - PAD_RIGHT2;
25967
26034
  const canvasH = node.h - PAD_TOP2 - PAD_BOTTOM2;
25968
26035
  const vMax = data.length > 0 ? Math.max(...data.map((d) => d.value)) : 1;
26036
+ const \u8EF8\u306E\u3082\u3068 = data.length > 0 ? Math.max(vMax, ...data.map((d) => d.previous ?? 0)) : vMax;
25969
26037
  const \u76EE\u76DB\u308A\u306E\u76EE\u5B892 = 4;
25970
- const \u5929\u4E95\u306E\u3082\u3068 = vMax > 0 ? vMax : 1;
26038
+ const \u5929\u4E95\u306E\u3082\u3068 = \u8EF8\u306E\u3082\u3068 > 0 ? \u8EF8\u306E\u3082\u3068 : 1;
25971
26039
  const \u523B\u307F = \u76EE\u76DB\u308A\u306E\u523B\u307F(\u5929\u4E95\u306E\u3082\u3068, \u76EE\u76DB\u308A\u306E\u76EE\u5B892);
25972
26040
  const \u523B\u307F\u306E\u6841 = \u5C0F\u6570\u306E\u6841(\u523B\u307F);
25973
26041
  const \u5929\u4E95 = \u6841\u3067\u4E38\u3081\u308B(Math.ceil(\u5929\u4E95\u306E\u3082\u3068 / \u523B\u307F - 1e-9) * \u523B\u307F, \u523B\u307F\u306E\u6841);
@@ -26060,8 +26128,24 @@ function ChartBarNode({
26060
26128
  fillOpacity: \u6FC3\u3055(d.value)
26061
26129
  }
26062
26130
  );
26131
+ const \u5370\u306E\u306F\u307F\u51FA\u3057 = Math.min(barW * 0.18, 8);
26132
+ const \u524D\u306E\u5370 = d.previous === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(
26133
+ "line",
26134
+ {
26135
+ "data-cdl-role": "chart-bar-previous",
26136
+ "data-cdl-unresolved": d.unresolved ? "true" : void 0,
26137
+ x1: bx - \u5370\u306E\u306F\u307F\u51FA\u3057,
26138
+ y1: yAt(Math.max(0, d.previous)),
26139
+ x2: bx + barW + \u5370\u306E\u306F\u307F\u51FA\u3057,
26140
+ y2: yAt(Math.max(0, d.previous)),
26141
+ stroke: "var(--cdl-text-mute, #8a8678)",
26142
+ strokeWidth: 1.5,
26143
+ strokeDasharray: "5 3"
26144
+ }
26145
+ );
26063
26146
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
26064
26147
  drawing ? /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(0 ${\u6A2A\u8EF8\u306Ey}) scale(1 ${\u4F38\u3073}) translate(0 ${-\u6A2A\u8EF8\u306Ey})`, children: \u68D2 }) : \u68D2,
26148
+ \u524D\u306E\u5370,
26065
26149
  /* @__PURE__ */ jsxRuntime.jsx(
26066
26150
  "text",
26067
26151
  {