@cardenelabs/cdl 0.113.0 → 0.114.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 +40 -1
- package/dist/index.cjs +43 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -28
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +43 -28
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +43 -28
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/kinds/mind-map.tsx +113 -63
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,44 @@ CDL (Chainome Diagram Language) の主要変更履歴。
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.114.0] - 2026-09-30
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **左右で段数が違う放射の図が札の横を半分しか使わなかった** (#966)
|
|
13
|
+
|
|
14
|
+
枝を中心からどれだけ離すかが図で 1 つの値だった。
|
|
15
|
+
子を持つ枝は子の世代のぶんを内側に空ける必要があるので、その都合が子を持たない枝にも効く。
|
|
16
|
+
左が入れ子で右が葉 1 枚の図では右の枝も中心から 149 に留まり、
|
|
17
|
+
右には空ける相手が居ないのにその 171 を誰も使わない。
|
|
18
|
+
|
|
19
|
+
離す量を **枝ごとに** 出すようにした。
|
|
20
|
+
子を持つ枝は子を収める位置まで、末端の枝は名前が描画域の端に届く位置まで外へ出る。
|
|
21
|
+
|
|
22
|
+
| 枝 | 直す前 | 直した後 |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| 子を 1 段持つ枝 | 149 | 149 (変わらない) |
|
|
25
|
+
| 同じ側の末端の枝 | 149 | 296 |
|
|
26
|
+
| 反対側の末端の枝 | 149 | 338 |
|
|
27
|
+
|
|
28
|
+
あわせて末端の上限から「箱ごと描画域に収める」 という条件を外した。
|
|
29
|
+
末端は枠を持たない (#907) ので、収めるのは名前で箱ではない。
|
|
30
|
+
箱まで収めると、名前より 41 広い箱の都合で名前が描画域の内側で終わっていた。
|
|
31
|
+
|
|
32
|
+
名前を描く幅の見積りを、切る側 (`箱に積む` / `幅に収める`) と同じ `textWidth` に揃えた。
|
|
33
|
+
別の見積りで置き場所を決めていたため、ちょうど収まる位置に置いた名前が描く側で切られていた
|
|
34
|
+
(実測 = `Features` が `Featur…` になった)。
|
|
35
|
+
|
|
36
|
+
枝の離れは整数に落とす。
|
|
37
|
+
端数を持ったまま置くと枝の長さが座標の差から出るぶん丸め誤差が乗る
|
|
38
|
+
(実測 = 24 であるべき枝が 23.99999999999997 になった)。
|
|
39
|
+
|
|
40
|
+
中心の箱を横中央へ寄せる処理 (#913) は、両側が端まで届くようになったため
|
|
41
|
+
この形の図では働かなくなる。 片側にしか枝が無い図では引き続き働く。
|
|
42
|
+
|
|
43
|
+
見本帳 (`cardene777/dragon`) の 3 図を実際の画面で測ると、札の横を使う割合が
|
|
44
|
+
85% から 88%、52% から 88%、79% から 87% になった。
|
|
45
|
+
|
|
8
46
|
## [0.113.0] - 2026-09-30
|
|
9
47
|
|
|
10
48
|
### Fixed
|
|
@@ -4512,7 +4550,8 @@ Initial OSS release.
|
|
|
4512
4550
|
使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
|
|
4513
4551
|
行き止まりになる。
|
|
4514
4552
|
|
|
4515
|
-
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.
|
|
4553
|
+
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.114.0...HEAD
|
|
4554
|
+
[0.114.0]: https://github.com/cardene777/cdl/compare/v0.113.0...v0.114.0
|
|
4516
4555
|
[0.113.0]: https://github.com/cardene777/cdl/compare/v0.112.0...v0.113.0
|
|
4517
4556
|
[0.112.0]: https://github.com/cardene777/cdl/compare/v0.111.0...v0.112.0
|
|
4518
4557
|
[0.111.0]: https://github.com/cardene777/cdl/compare/v0.110.0...v0.111.0
|
package/dist/index.cjs
CHANGED
|
@@ -16141,7 +16141,7 @@ function \u63CF\u304F\u6A2A\u306E\u7AEF(n) {
|
|
|
16141
16141
|
if (n.isRoot || !n.isLeaf) return [n.x - n.w / 2, n.x + n.w / 2];
|
|
16142
16142
|
const \u8D77\u70B9 = n.x + (n.side === "right" ? -n.w / 2 : n.w / 2);
|
|
16143
16143
|
const \u540D\u524D = \u653E\u5C04\u306E\u884C(n)[0];
|
|
16144
|
-
const \u5E45 =
|
|
16144
|
+
const \u5E45 = textWidth(\u540D\u524D.text, \u540D\u524D.fontSize);
|
|
16145
16145
|
return n.side === "right" ? [\u8D77\u70B9, \u8D77\u70B9 + \u5E45] : [\u8D77\u70B9 - \u5E45, \u8D77\u70B9];
|
|
16146
16146
|
}
|
|
16147
16147
|
function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
|
|
@@ -16214,38 +16214,52 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
|
|
|
16214
16214
|
if (kids.length === 0) return 1;
|
|
16215
16215
|
return kids.reduce((sum, k) => sum + leafCountOf(k.id, seen), 0);
|
|
16216
16216
|
};
|
|
16217
|
-
const
|
|
16217
|
+
const leftBranches = firstLevel.slice(0, leftCount);
|
|
16218
|
+
const rightBranches = firstLevel.slice(leftCount);
|
|
16218
16219
|
const minLayer1XOffset = rootW / 2 + branchW / 2 + MIND_BOX_GAP;
|
|
16219
16220
|
const preferredSubDx = subBranchW + 20;
|
|
16220
|
-
const reserve = maxSubDepth > 0 ? branchW / 2 + maxSubDepth * preferredSubDx : 0;
|
|
16221
|
-
const maxLayer1XOffset = Math.max(minLayer1XOffset, canvasW / 2 - reserve);
|
|
16222
|
-
const \u8449\u306E\u540D\u524D\u306E\u6700\u5927\u5E45 = Math.max(
|
|
16223
|
-
0,
|
|
16224
|
-
...firstLevel.filter((br) => (childrenOf.get(br.id) ?? []).length === 0).map((br) => {
|
|
16225
|
-
const \u540D\u524D = \u653E\u5C04\u306E\u884C({ title: br.title, isRoot: false })[0];
|
|
16226
|
-
return measureTextWidth(\u540D\u524D.text, { fontSize: \u540D\u524D.fontSize});
|
|
16227
|
-
})
|
|
16228
|
-
);
|
|
16229
|
-
const \u540D\u524D\u3067\u6C7A\u307E\u308B\u4E0A\u9650 = canvasW / 2 + branchW / 2 - \u8449\u306E\u540D\u524D\u306E\u6700\u5927\u5E45;
|
|
16230
|
-
const layer1XOffset = Math.max(minLayer1XOffset, Math.min(\u540D\u524D\u3067\u6C7A\u307E\u308B\u4E0A\u9650, maxLayer1XOffset));
|
|
16231
|
-
const room = canvasW / 2 - layer1XOffset;
|
|
16232
16221
|
const MIN_SUB_W = 56;
|
|
16233
16222
|
const PREFERRED_GAP = MIND_BOX_GAP;
|
|
16234
|
-
const
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
const
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16223
|
+
const \u679D\u306E\u540D\u524D\u306E\u5E45 = (title) => {
|
|
16224
|
+
const \u540D\u524D = \u653E\u5C04\u306E\u884C({ title, isRoot: false })[0];
|
|
16225
|
+
return textWidth(\u540D\u524D.text, \u540D\u524D.fontSize);
|
|
16226
|
+
};
|
|
16227
|
+
const \u679D\u306E\u6A2A\u3092\u6C7A\u3081\u308B = (br) => {
|
|
16228
|
+
const maxSubDepth = subDepthOf(br.id, /* @__PURE__ */ new Set());
|
|
16229
|
+
const \u4E0A\u9650 = maxSubDepth > 0 ? canvasW / 2 - (branchW / 2 + maxSubDepth * preferredSubDx) : canvasW / 2 + branchW / 2 - \u679D\u306E\u540D\u524D\u306E\u5E45(br.title);
|
|
16230
|
+
const layer1XOffset = Math.floor(Math.max(minLayer1XOffset, \u4E0A\u9650));
|
|
16231
|
+
const room = canvasW / 2 - layer1XOffset;
|
|
16232
|
+
const gapRoom = maxSubDepth > 0 ? (room - branchW / 2 - maxSubDepth * MIN_SUB_W) / maxSubDepth : 0;
|
|
16233
|
+
const gap = Math.floor(Math.max(8, Math.min(PREFERRED_GAP, gapRoom)));
|
|
16234
|
+
const effSubW = maxSubDepth > 0 ? Math.floor(
|
|
16235
|
+
Math.max(1, Math.min(subBranchW, (room - branchW / 2 - maxSubDepth * gap) / maxSubDepth))
|
|
16236
|
+
) : subBranchW;
|
|
16237
|
+
const step1 = (branchW + effSubW) / 2 + gap;
|
|
16238
|
+
const stepN = effSubW + gap;
|
|
16239
|
+
return {
|
|
16240
|
+
layer1XOffset,
|
|
16241
|
+
effSubW,
|
|
16242
|
+
subOffset: (subDepth) => subDepth <= 0 ? 0 : step1 + (subDepth - 1) * stepN
|
|
16243
|
+
};
|
|
16244
|
+
};
|
|
16245
|
+
const \u6A2A\u306E\u5272\u4ED8\u8868 = new Map(
|
|
16246
|
+
firstLevel.map((br) => [br.id, \u679D\u306E\u6A2A\u3092\u6C7A\u3081\u308B(br)])
|
|
16247
|
+
);
|
|
16248
|
+
const \u4E00\u756A\u5185\u5074\u306E\u96E2\u308C = Math.min(
|
|
16249
|
+
...firstLevel.length > 0 ? firstLevel.map((br) => \u6A2A\u306E\u5272\u4ED8\u8868.get(br.id).layer1XOffset) : [minLayer1XOffset]
|
|
16250
|
+
);
|
|
16242
16251
|
const leavesOfSide = (brs) => Math.max(
|
|
16243
16252
|
1,
|
|
16244
16253
|
brs.reduce((sum, br) => sum + leafCountOf(br.id, /* @__PURE__ */ new Set()), 0)
|
|
16245
16254
|
);
|
|
16246
16255
|
const sideLaneCount = Math.max(leavesOfSide(leftBranches), leavesOfSide(rightBranches));
|
|
16247
16256
|
const laneBandH = Math.max(0, canvasH - BRANCH_BOX_H_MAX);
|
|
16248
|
-
const rowGap = sideLaneCount > 1 ? Math.min(
|
|
16257
|
+
const rowGap = sideLaneCount > 1 ? Math.min(
|
|
16258
|
+
laneBandH / (sideLaneCount - 1),
|
|
16259
|
+
// 帯は図で 1 つなので、**一番内側の枝** から上限を取る (#966)。
|
|
16260
|
+
// 外へ出た枝に合わせると、内側に残った枝の傾きが 45 度を超える
|
|
16261
|
+
\u7E26\u306E\u9593\u9694\u306E\u4E0A\u9650(\u4E00\u756A\u5185\u5074\u306E\u96E2\u308C)
|
|
16262
|
+
) : subBranchH + 14;
|
|
16249
16263
|
const effSubH = Math.min(SUB_BOX_H_MAX, rowGap * 0.7);
|
|
16250
16264
|
const effBranchH = Math.min(BRANCH_BOX_H_MAX, rowGap * 0.7);
|
|
16251
16265
|
const \u7AEF\u306E\u4F59\u308A = Math.max(effSubH, effBranchH) / 2;
|
|
@@ -16261,11 +16275,11 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
|
|
|
16261
16275
|
const half = nodeHalfW.get(mindData.rootId) ?? rootW / 2;
|
|
16262
16276
|
return \u4E2D\u5FC3\u306Ex + (isLeft ? -half : half);
|
|
16263
16277
|
};
|
|
16264
|
-
const placeSubtree = (node, subDepth, isLeft, tone, placed, laneRef) => {
|
|
16278
|
+
const placeSubtree = (node, subDepth, isLeft, tone, placed, laneRef, \u6A2A) => {
|
|
16265
16279
|
placed.add(node.id);
|
|
16266
16280
|
const dirX = isLeft ? -1 : 1;
|
|
16267
|
-
const x = cx + dirX * (layer1XOffset + subOffset(subDepth));
|
|
16268
|
-
const w = subDepth === 0 ? branchW : effSubW;
|
|
16281
|
+
const x = cx + dirX * (\u6A2A.layer1XOffset + \u6A2A.subOffset(subDepth));
|
|
16282
|
+
const w = subDepth === 0 ? branchW : \u6A2A.effSubW;
|
|
16269
16283
|
const h = subDepth === 0 ? effBranchH : effSubH;
|
|
16270
16284
|
const myTone = node.tone ?? tone;
|
|
16271
16285
|
const kids = (childrenOf.get(node.id) ?? []).filter((k) => !placed.has(k.id));
|
|
@@ -16281,7 +16295,8 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
|
|
|
16281
16295
|
isLeft,
|
|
16282
16296
|
myTone ?? MIND_TONES[i % MIND_TONES.length],
|
|
16283
16297
|
placed,
|
|
16284
|
-
laneRef
|
|
16298
|
+
laneRef,
|
|
16299
|
+
\u6A2A
|
|
16285
16300
|
)
|
|
16286
16301
|
);
|
|
16287
16302
|
y = (ys[0] + ys[ys.length - 1]) / 2;
|
|
@@ -16314,7 +16329,7 @@ function computeMindMapLayout(mindData, cx, cy, canvasW, canvasH) {
|
|
|
16314
16329
|
const placed = /* @__PURE__ */ new Set();
|
|
16315
16330
|
brs.forEach((br, i) => {
|
|
16316
16331
|
const tone = br.tone ?? MIND_TONES[(toneBase + i) % MIND_TONES.length];
|
|
16317
|
-
placeSubtree(br, 0, isLeft, tone, placed, laneRef);
|
|
16332
|
+
placeSubtree(br, 0, isLeft, tone, placed, laneRef, \u6A2A\u306E\u5272\u4ED8\u8868.get(br.id) ?? \u679D\u306E\u6A2A\u3092\u6C7A\u3081\u308B(br));
|
|
16318
16333
|
});
|
|
16319
16334
|
};
|
|
16320
16335
|
placeSide(leftBranches, true, 0);
|