@cardenelabs/cdl 0.40.0 → 0.40.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/CHANGELOG.md CHANGED
@@ -5,6 +5,48 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.40.2] - 2026-09-07
9
+
10
+ ### Fixed
11
+
12
+ - **円グラフで小さい取り分が続くと名札が重なるのを直した** (#727)
13
+
14
+ 名札 (割合と名前) は扇の中央角の向きに置いていたので、**角度が近い扇が続くと同じ場所に
15
+ 印字されて読めなかった**。 実測で 0.3% の小片 2 個が完全に重なり、割合の字 (級 19 の
16
+ 太字) が真っ黒な塊になっていた。 小片を 5 個にすると重なりは 20 組に増える。
17
+ 件数 12 の図でも上部の `5.4%` と `5.9%` がぶつかっていた。
18
+
19
+ **縦は重なりをほどく**。 傾き図で入れたのと同じ形 (#723) で、重なった連なりを元の位置の
20
+ 平均を中心にして等間隔に置き直す。 ほどきの計算は `kinds/label-stack.ts` に移して
21
+ 傾き図と共用する。
22
+
23
+ **横は左右の列に揃える**。 角度から決めたままだと、縦をずらした名札が円の上へ乗る。
24
+ 引き出し線の肘も列の手前に置くので、線が円を横切らない。
25
+
26
+ 扇と縁の点は動かさない = どの扇の名札かは引き出し線と縁の色の点が示す。
27
+
28
+ 段の `draw` の途中でも名札は動かない。 まだ開いていない扇も数に入れてほどくため。
29
+
30
+ ## [0.40.1] - 2026-09-07
31
+
32
+ ### Fixed
33
+
34
+ - **傾き図で同じ値の系列の名札が重なって読めなくなるのを直した** (#723)
35
+
36
+ `chart-slope` は名札 (値と名前) を点と同じ縦の位置に置いていたので、値が同じ / 近い
37
+ 系列が 2 件以上あると同じ場所に印字されていた。 実測で 59 と 59 の 2 件が完全に重なり、
38
+ 値は太字が二重に乗った染み、名前は 2 つの語が重なった判読不能な塊になっていた。
39
+ 完全一致でなくても起きる = 59 と 60 の差は 3.55 しかなく、字の高さ 14 に対して足りない。
40
+
41
+ **動かすのは名札だけ**。 点と線は真の位置に残す = 位置をずらすと、書いていない差を
42
+ 絵が主張することになる (同順位を段でずらさない判断と同じ理由、#707)。 同じ値の点は
43
+ 重なったままで、どの名札がどの系列かは名前の色が担う (#698)。
44
+
45
+ 重なった連なりは **元の位置の平均を中心にして** 間隔ぶんずつ均等に置き直す。
46
+ 上から順に押し下げるだけだと塊が片側へ寄り、点との対応が遠くなる。
47
+
48
+ 枠に入り切らない件数の図では、どれか 1 つを枠の外へ出さず全部を等間隔に詰める。
49
+
8
50
  ## [0.40.0] - 2026-09-07
9
51
 
10
52
  ### Added
@@ -1781,7 +1823,9 @@ Initial OSS release.
1781
1823
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
1782
1824
  行き止まりになる。
1783
1825
 
1784
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.40.0...HEAD
1826
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.40.2...HEAD
1827
+ [0.40.2]: https://github.com/cardene777/cdl/compare/v0.40.1...v0.40.2
1828
+ [0.40.1]: https://github.com/cardene777/cdl/compare/v0.40.0...v0.40.1
1785
1829
  [0.40.0]: https://github.com/cardene777/cdl/compare/v0.39.0...v0.40.0
1786
1830
  [0.39.0]: https://github.com/cardene777/cdl/compare/v0.38.0...v0.39.0
1787
1831
  [0.38.0]: https://github.com/cardene777/cdl/compare/v0.37.0...v0.38.0
package/dist/index.cjs CHANGED
@@ -24358,6 +24358,38 @@ function interpolateColor(template, stateValues, fallback) {
24358
24358
  if (!template) return fallback;
24359
24359
  return interpolate(template, stateValues);
24360
24360
  }
24361
+
24362
+ // src/kinds/label-stack.ts
24363
+ function \u540D\u672D\u306E\u6BB5\u3092\u307B\u3069\u304F(\u771F\u306Ey, \u9593\u9694, \u4E0A\u9650, \u4E0B\u9650) {
24364
+ const \u4EF6\u6570 = \u771F\u306Ey.length;
24365
+ if (\u4EF6\u6570 === 0) return [];
24366
+ const \u4E26\u3073 = \u771F\u306Ey.map((y, i) => ({ y, i })).sort((a, b) => a.y - b.y || a.i - b.i);
24367
+ const \u7D50\u679C = new Array(\u4EF6\u6570);
24368
+ if (\u9593\u9694 * (\u4EF6\u6570 - 1) > \u4E0B\u9650 - \u4E0A\u9650) {
24369
+ \u4E26\u3073.forEach((e, k) => {
24370
+ \u7D50\u679C[e.i] = \u4EF6\u6570 > 1 ? \u4E0A\u9650 + (\u4E0B\u9650 - \u4E0A\u9650) / (\u4EF6\u6570 - 1) * k : (\u4E0A\u9650 + \u4E0B\u9650) / 2;
24371
+ });
24372
+ return \u7D50\u679C;
24373
+ }
24374
+ const \u584A\u305F\u3061 = [];
24375
+ \u4E26\u3073.forEach((e, k) => {
24376
+ \u584A\u305F\u3061.push({ \u5408\u8A08: e.y - \u9593\u9694 * k, \u4EF6\u6570: 1 });
24377
+ while (\u584A\u305F\u3061.length >= 2) {
24378
+ const \u5F8C = \u584A\u305F\u3061[\u584A\u305F\u3061.length - 1];
24379
+ const \u524D = \u584A\u305F\u3061[\u584A\u305F\u3061.length - 2];
24380
+ if (\u524D.\u5408\u8A08 / \u524D.\u4EF6\u6570 <= \u5F8C.\u5408\u8A08 / \u5F8C.\u4EF6\u6570) break;
24381
+ \u584A\u305F\u3061.splice(\u584A\u305F\u3061.length - 2, 2, { \u5408\u8A08: \u524D.\u5408\u8A08 + \u5F8C.\u5408\u8A08, \u4EF6\u6570: \u524D.\u4EF6\u6570 + \u5F8C.\u4EF6\u6570 });
24382
+ }
24383
+ });
24384
+ const \u307B\u3069\u3044\u305F = [];
24385
+ \u584A\u305F\u3061.forEach((\u584A) => {
24386
+ const \u5E73\u5747 = \u584A.\u5408\u8A08 / \u584A.\u4EF6\u6570;
24387
+ for (let j = 0; j < \u584A.\u4EF6\u6570; j++) \u307B\u3069\u3044\u305F.push(\u5E73\u5747 + \u9593\u9694 * \u307B\u3069\u3044\u305F.length);
24388
+ });
24389
+ const \u305A\u308C = Math.max(0, \u4E0A\u9650 - \u307B\u3069\u3044\u305F[0]) - Math.max(0, \u307B\u3069\u3044\u305F[\u4EF6\u6570 - 1] - \u4E0B\u9650);
24390
+ \u4E26\u3073.forEach((e, k) => \u7D50\u679C[e.i] = \u307B\u3069\u3044\u305F[k] + \u305A\u308C);
24391
+ return \u7D50\u679C;
24392
+ }
24361
24393
  function \u6247\u5F62\u306E\u5207\u308A\u629C\u304D(cx, cy, r, \u958B\u304D, \u8D77\u70B9 = -Math.PI / 2, \u5168\u5468 = Math.PI * 2) {
24362
24394
  if (\u958B\u304D <= 0) return null;
24363
24395
  if (\u958B\u304D >= 1 && \u5168\u5468 >= Math.PI * 2) return /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r });
@@ -24438,6 +24470,26 @@ function ChartPieNode({
24438
24470
  const \u5207\u308A\u629C\u304Did = `cdl-pie-draw-${instanceId}`;
24439
24471
  const \u5F71id = `cdl-pie-shadow-${instanceId}`;
24440
24472
  const \u958B\u304D\u59CB\u3081\u305F = (startFrac) => !drawing || \u958B\u304D > startFrac;
24473
+ const \u540D\u672D\u306E\u884C = \u5272\u5408\u306E\u7D1A + \u540D\u524D\u306E\u7D1A + 3;
24474
+ const \u540D\u672D\u306E\u5074 = slices.map((s) => Math.cos(s.\u4E2D\u592E\u89D2) >= 0);
24475
+ const \u540D\u672D\u306E\u771F\u306Ey = slices.map((s) => cy + (radius + \u5F15\u304D\u51FA\u3057) * Math.sin(s.\u4E2D\u592E\u89D2));
24476
+ const \u540D\u672D\u306Ey = (() => {
24477
+ const \u51FA\u3059 = [...\u540D\u672D\u306E\u771F\u306Ey];
24478
+ for (const \u5074 of [true, false]) {
24479
+ const \u756A\u53F7 = \u540D\u672D\u306E\u5074.flatMap((\u53F3, i) => \u53F3 === \u5074 ? [i] : []);
24480
+ if (\u756A\u53F7.length === 0) continue;
24481
+ const \u76F4\u3057\u305F = \u540D\u672D\u306E\u6BB5\u3092\u307B\u3069\u304F(
24482
+ \u756A\u53F7.map((i) => \u540D\u672D\u306E\u771F\u306Ey[i]),
24483
+ \u540D\u672D\u306E\u884C,
24484
+ PAD_TOP2 + \u540D\u672D\u306E\u7E26\u306E\u5F35\u308A\u51FA\u3057,
24485
+ node.h - PAD_BOTTOM2 - \u540D\u672D\u306E\u7E26\u306E\u5F35\u308A\u51FA\u3057
24486
+ );
24487
+ \u756A\u53F7.forEach((i, k) => \u51FA\u3059[i] = \u76F4\u3057\u305F[k]);
24488
+ }
24489
+ return \u51FA\u3059;
24490
+ })();
24491
+ const \u8098\u306Ex = (\u53F3) => cx + (\u53F3 ? 1 : -1) * (radius + \u5F15\u304D\u51FA\u3057);
24492
+ const \u5B57\u306Ex = (\u53F3) => \u8098\u306Ex(\u53F3) + (\u53F3 ? \u5B57\u307E\u3067\u306E\u9593 : -\u5B57\u307E\u3067\u306E\u9593);
24441
24493
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
24442
24494
  /* @__PURE__ */ jsxRuntime.jsx(
24443
24495
  "rect",
@@ -24510,12 +24562,12 @@ function ChartPieNode({
24510
24562
  ),
24511
24563
  slices.map((s, idx) => {
24512
24564
  if (!\u958B\u304D\u59CB\u3081\u305F(s.startFrac)) return null;
24513
- const \u53F3 = Math.cos(s.\u4E2D\u592E\u89D2) >= 0;
24565
+ const \u53F3 = \u540D\u672D\u306E\u5074[idx];
24514
24566
  const \u7E01x = cx + radius * Math.cos(s.\u4E2D\u592E\u89D2);
24515
24567
  const \u7E01y = cy + radius * Math.sin(s.\u4E2D\u592E\u89D2);
24516
- const \u6298\u308Cx = cx + (radius + \u5F15\u304D\u51FA\u3057) * Math.cos(s.\u4E2D\u592E\u89D2);
24517
- const \u6298\u308Cy = cy + (radius + \u5F15\u304D\u51FA\u3057) * Math.sin(s.\u4E2D\u592E\u89D2);
24518
- const \u5B57x = \u6298\u308Cx + (\u53F3 ? \u5B57\u307E\u3067\u306E\u9593 : -\u5B57\u307E\u3067\u306E\u9593);
24568
+ const \u6298\u308Cx = \u8098\u306Ex(\u53F3);
24569
+ const \u6298\u308Cy = \u540D\u672D\u306Ey[idx];
24570
+ const \u5B57x = \u5B57\u306Ex(\u53F3);
24519
24571
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
24520
24572
  /* @__PURE__ */ jsxRuntime.jsx(
24521
24573
  "path",
@@ -25593,6 +25645,15 @@ function ChartSlopeNode({
25593
25645
  const \u53F3\u8EF8x = \u524D\u3042\u308A ? Math.min(node.w - PAD, Math.max(node.w - PAD - \u53F3\u306E\u4F59\u767D, node.w / 2 + \u7DDA\u306E\u6700\u5C0F\u5E45 / 2)) : \u5DE6\u8EF8x;
25594
25646
  const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
25595
25647
  const \u53F3\u3092\u51FA\u3059 = !drawing || \u4F38\u3073 >= 1;
25648
+ const \u5DE6\u306E\u70B9y = \u7CFB\u5217\u305F\u3061.map(
25649
+ (s, i) => \u5F62 === "rank" ? \u6BB5\u306Ey\u3092\u53D6\u308B(\u524D\u306E\u9806\u4F4D[i]) : y\u3092\u53D6\u308B(s.\u524D)
25650
+ );
25651
+ const \u53F3\u306E\u70B9y = \u7CFB\u5217\u305F\u3061.map(
25652
+ (s, i) => \u5F62 === "rank" ? \u6BB5\u306Ey\u3092\u53D6\u308B(\u4ECA\u306E\u9806\u4F4D[i]) : y\u3092\u53D6\u308B(s.\u4ECA)
25653
+ );
25654
+ const \u540D\u672D\u306E\u884C = Math.max(\u5024\u306E\u7D1A, \u540D\u524D\u306E\u7D1A) + 4;
25655
+ const \u5DE6\u306E\u540D\u672Dy = \u524D\u3042\u308A ? \u540D\u672D\u306E\u6BB5\u3092\u307B\u3069\u304F(\u5DE6\u306E\u70B9y, \u540D\u672D\u306E\u884C, \u4E0A\u7AEF, \u4E0B\u7AEF) : \u5DE6\u306E\u70B9y;
25656
+ const \u53F3\u306E\u540D\u672Dy = \u540D\u672D\u306E\u6BB5\u3092\u307B\u3069\u304F(\u53F3\u306E\u70B9y, \u540D\u672D\u306E\u884C, \u4E0A\u7AEF, \u4E0B\u7AEF);
25596
25657
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
25597
25658
  /* @__PURE__ */ jsxRuntime.jsx(
25598
25659
  "rect",
@@ -25650,8 +25711,10 @@ function ChartSlopeNode({
25650
25711
  )
25651
25712
  ] }),
25652
25713
  \u7CFB\u5217\u305F\u3061.map((s, i) => {
25653
- const \u5DE6y = \u5F62 === "rank" ? \u6BB5\u306Ey\u3092\u53D6\u308B(\u524D\u306E\u9806\u4F4D[i]) : y\u3092\u53D6\u308B(s.\u524D);
25654
- const \u53F3y = \u5F62 === "rank" ? \u6BB5\u306Ey\u3092\u53D6\u308B(\u4ECA\u306E\u9806\u4F4D[i]) : y\u3092\u53D6\u308B(s.\u4ECA);
25714
+ const \u5DE6y = \u5DE6\u306E\u70B9y[i];
25715
+ const \u53F3y = \u53F3\u306E\u70B9y[i];
25716
+ const \u5DE6\u672Dy = \u5DE6\u306E\u540D\u672Dy[i];
25717
+ const \u53F3\u672Dy = \u53F3\u306E\u540D\u672Dy[i];
25655
25718
  const \u672A\u89E3\u6C7A = s.\u672A\u89E3\u6C7A ? "true" : void 0;
25656
25719
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
25657
25720
  \u524D\u3042\u308A && /* @__PURE__ */ jsxRuntime.jsx(
@@ -25695,7 +25758,7 @@ function ChartSlopeNode({
25695
25758
  {
25696
25759
  "data-cdl-role": "chart-slope-value",
25697
25760
  x: \u5DE6\u8EF8x - \u8EF8\u304B\u3089\u5024\u307E\u3067,
25698
- y: \u5DE6y + 5,
25761
+ y: \u5DE6\u672Dy + 5,
25699
25762
  textAnchor: "end",
25700
25763
  fontSize: \u5024\u306E\u7D1A,
25701
25764
  fontWeight: 600,
@@ -25708,7 +25771,7 @@ function ChartSlopeNode({
25708
25771
  {
25709
25772
  "data-cdl-role": "chart-slope-name",
25710
25773
  x: \u5DE6\u8EF8x - \u8EF8\u304B\u3089\u5024\u307E\u3067 - \u5DE6\u5024\u5E45 - \u5024\u304B\u3089\u540D\u524D\u307E\u3067,
25711
- y: \u5DE6y + 5,
25774
+ y: \u5DE6\u672Dy + 5,
25712
25775
  textAnchor: "end",
25713
25776
  fontSize: \u540D\u524D\u306E\u7D1A,
25714
25777
  fill: s.\u8272,
@@ -25720,7 +25783,7 @@ function ChartSlopeNode({
25720
25783
  {
25721
25784
  "data-cdl-role": "chart-slope-name",
25722
25785
  x: \u5DE6\u8EF8x - \u8EF8\u304B\u3089\u5024\u307E\u3067,
25723
- y: \u53F3y + 5,
25786
+ y: \u53F3\u672Dy + 5,
25724
25787
  textAnchor: "end",
25725
25788
  fontSize: \u540D\u524D\u306E\u7D1A,
25726
25789
  fill: s.\u8272,
@@ -25733,7 +25796,7 @@ function ChartSlopeNode({
25733
25796
  {
25734
25797
  "data-cdl-role": \u5F62 === "delta" ? "chart-slope-delta" : "chart-slope-value",
25735
25798
  x: \u53F3\u8EF8x + \u8EF8\u304B\u3089\u5024\u307E\u3067,
25736
- y: \u53F3y + 5,
25799
+ y: \u53F3\u672Dy + 5,
25737
25800
  fontSize: \u5024\u306E\u7D1A,
25738
25801
  fontWeight: 600,
25739
25802
  fill: "var(--cdl-text, #1a1f2a)",
@@ -25745,7 +25808,7 @@ function ChartSlopeNode({
25745
25808
  {
25746
25809
  "data-cdl-role": "chart-slope-name",
25747
25810
  x: \u53F3\u8EF8x + \u8EF8\u304B\u3089\u5024\u307E\u3067 + \u53F3\u5024\u5E45 + \u5024\u304B\u3089\u540D\u524D\u307E\u3067,
25748
- y: \u53F3y + 5,
25811
+ y: \u53F3\u672Dy + 5,
25749
25812
  fontSize: \u540D\u524D\u306E\u7D1A,
25750
25813
  fill: s.\u8272,
25751
25814
  children: s.\u540D\u524D