@cardenelabs/cdl 0.47.0 → 0.49.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 +57 -1
- package/dist/index.cjs +230 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +230 -105
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +219 -101
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +219 -101
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/layout/collisions.ts +293 -139
- package/src/layout/edges.ts +95 -23
- package/src/layout-with-validation.ts +4 -2
- package/src/visual-validate.ts +62 -6
package/src/visual-validate.ts
CHANGED
|
@@ -88,6 +88,7 @@ import {
|
|
|
88
88
|
flattenPathSegments,
|
|
89
89
|
measurePathLabelGapSegs,
|
|
90
90
|
segmentsCrossRect,
|
|
91
|
+
札が動けない理由,
|
|
91
92
|
} from "./layout/collisions";
|
|
92
93
|
import { measureTextWidth } from "./layout/text-width";
|
|
93
94
|
import { droppedLineIsHidden, labelPlan } from "./kinds/shape-region";
|
|
@@ -276,6 +277,14 @@ export interface Violation {
|
|
|
276
277
|
diagramId: string;
|
|
277
278
|
detail: string;
|
|
278
279
|
severity: "error" | "warn";
|
|
280
|
+
/**
|
|
281
|
+
* engine がなぜ直せなかったか (#810)。 分かる時だけ付く。
|
|
282
|
+
*
|
|
283
|
+
* `detail` とは別の欄に置く = `detail` は「どの 2 つが何 px か」 を固定の形で持ち、
|
|
284
|
+
* 消費側がそこから id を読み取っている。 理由を `detail` に足すと、 理由の中の id まで
|
|
285
|
+
* 違反の対象として拾われる。
|
|
286
|
+
*/
|
|
287
|
+
reason?: string;
|
|
279
288
|
}
|
|
280
289
|
|
|
281
290
|
export type VisualAxis =
|
|
@@ -1447,12 +1456,23 @@ export function visualValidateLaid(
|
|
|
1447
1456
|
const counts = emptyCounts();
|
|
1448
1457
|
const profile = opts?.profile ?? "production";
|
|
1449
1458
|
const skipped = SKIPPED_AXES[profile];
|
|
1450
|
-
const push = (
|
|
1459
|
+
const push = (
|
|
1460
|
+
axis: VisualAxis,
|
|
1461
|
+
detail: string,
|
|
1462
|
+
severity: "error" | "warn" = "error",
|
|
1463
|
+
reason?: string,
|
|
1464
|
+
) => {
|
|
1451
1465
|
// 用途に合わない軸は数えない。
|
|
1452
1466
|
if (skipped.has(axis)) return;
|
|
1453
1467
|
// `diag` は壊れた形でも渡りうる (`#393`)。 報告そのものが例外になると、 壊れている
|
|
1454
1468
|
// ことを伝える手段が無くなる。
|
|
1455
|
-
violations.push({
|
|
1469
|
+
violations.push({
|
|
1470
|
+
axis,
|
|
1471
|
+
diagramId: safeDiagramId(diag),
|
|
1472
|
+
detail,
|
|
1473
|
+
severity,
|
|
1474
|
+
...(reason !== undefined ? { reason } : {}),
|
|
1475
|
+
});
|
|
1456
1476
|
counts[axis]++;
|
|
1457
1477
|
};
|
|
1458
1478
|
|
|
@@ -1479,10 +1499,21 @@ export function visualValidate(diag: CdlDiagram, opts?: ValidateOptions): Visual
|
|
|
1479
1499
|
const counts = emptyCounts();
|
|
1480
1500
|
const profile = opts?.profile ?? "production";
|
|
1481
1501
|
const skipped = SKIPPED_AXES[profile];
|
|
1482
|
-
const push = (
|
|
1502
|
+
const push = (
|
|
1503
|
+
axis: VisualAxis,
|
|
1504
|
+
detail: string,
|
|
1505
|
+
severity: "error" | "warn" = "error",
|
|
1506
|
+
reason?: string,
|
|
1507
|
+
) => {
|
|
1483
1508
|
// 用途に合わない軸は数えない。 見なかった軸は report の `skippedAxes` に載せる。
|
|
1484
1509
|
if (skipped.has(axis)) return;
|
|
1485
|
-
violations.push({
|
|
1510
|
+
violations.push({
|
|
1511
|
+
axis,
|
|
1512
|
+
diagramId: safeDiagramId(diag),
|
|
1513
|
+
detail,
|
|
1514
|
+
severity,
|
|
1515
|
+
...(reason !== undefined ? { reason } : {}),
|
|
1516
|
+
});
|
|
1486
1517
|
counts[axis]++;
|
|
1487
1518
|
};
|
|
1488
1519
|
|
|
@@ -1852,7 +1883,7 @@ function visualValidateInner(
|
|
|
1852
1883
|
diag: CdlDiagram,
|
|
1853
1884
|
violations: Violation[],
|
|
1854
1885
|
counts: Record<VisualAxis, number>,
|
|
1855
|
-
push: (axis: VisualAxis, detail: string, severity?: "error" | "warn") => void,
|
|
1886
|
+
push: (axis: VisualAxis, detail: string, severity?: "error" | "warn", reason?: string) => void,
|
|
1856
1887
|
profile: ValidationProfile,
|
|
1857
1888
|
skippedAxes: VisualAxis[],
|
|
1858
1889
|
/** 軸 23 が基準にする器。 入口で確かめ済 (`器を確かめる`)。 高さ `undefined` は上限なし。 */
|
|
@@ -1909,7 +1940,7 @@ function runAxes(
|
|
|
1909
1940
|
diag: CdlDiagram,
|
|
1910
1941
|
violations: Violation[],
|
|
1911
1942
|
counts: Record<VisualAxis, number>,
|
|
1912
|
-
push: (axis: VisualAxis, detail: string, severity?: "error" | "warn") => void,
|
|
1943
|
+
push: (axis: VisualAxis, detail: string, severity?: "error" | "warn", reason?: string) => void,
|
|
1913
1944
|
profile: ValidationProfile,
|
|
1914
1945
|
skippedAxes: VisualAxis[],
|
|
1915
1946
|
/** 軸 23 が基準にする器。 入口で確かめ済 (`器を確かめる`)。 高さ `undefined` は上限なし。 */
|
|
@@ -2046,10 +2077,35 @@ function runAxes(
|
|
|
2046
2077
|
// Axis 6: clearance (near collision 0 件、 CLEARANCE_POLICY 違反)
|
|
2047
2078
|
// ───────────────────────────────────────────────────────────
|
|
2048
2079
|
const nears = detectNearCollisions(bboxes, laid.edges);
|
|
2080
|
+
/*
|
|
2081
|
+
* 札が絡む違反には、 engine がなぜ動かせなかったかを添える (#810)。
|
|
2082
|
+
*
|
|
2083
|
+
* 動かす側は逃がし pass と同じ = 札どうしなら後に書いた方 (`resolveLabelClearanceAfterPathPasses`
|
|
2084
|
+
* が後の方を動かす)、 札と別の物なら札。 札の絡まない違反 (箱どうし等) には添えない。
|
|
2085
|
+
*/
|
|
2086
|
+
const 札の障害物 = bboxes.filter((b) => b.kind === "node" || b.kind === "lane-label");
|
|
2087
|
+
const 辺の順 = new Map(laid.edges.map((e, i) => [e.id, i] as const));
|
|
2049
2088
|
for (const n of nears) {
|
|
2089
|
+
const aは札 = n.a.kind === "edge-label";
|
|
2090
|
+
const bは札 = n.b.kind === "edge-label";
|
|
2091
|
+
const 動かす =
|
|
2092
|
+
aは札 && bは札
|
|
2093
|
+
? (辺の順.get(n.a.id) ?? 0) > (辺の順.get(n.b.id) ?? 0)
|
|
2094
|
+
? n.a
|
|
2095
|
+
: n.b
|
|
2096
|
+
: aは札
|
|
2097
|
+
? n.a
|
|
2098
|
+
: bは札
|
|
2099
|
+
? n.b
|
|
2100
|
+
: null;
|
|
2101
|
+
const 相手 = 動かす === n.a ? n.b : n.a;
|
|
2102
|
+
const reason =
|
|
2103
|
+
動かす !== null ? (札が動けない理由(動かす.id, 相手, laid.edges, 札の障害物) ?? undefined) : undefined;
|
|
2050
2104
|
push(
|
|
2051
2105
|
"clearance",
|
|
2052
2106
|
`${n.a.kind}:${n.a.id} ↔ ${n.b.kind}:${n.b.id} gap=${n.gap.toFixed(1)}px (need ${n.required}px)`,
|
|
2107
|
+
"error",
|
|
2108
|
+
reason,
|
|
2053
2109
|
);
|
|
2054
2110
|
}
|
|
2055
2111
|
|