@cardenelabs/cdl 0.30.1 → 0.30.3
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 +59 -1
- package/dist/index.cjs +292 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +292 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +291 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +291 -0
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/layout/collisions.ts +345 -0
- package/src/layout/edges.ts +108 -0
- package/src/layout.ts +14 -0
package/dist/react.cjs
CHANGED
|
@@ -2015,6 +2015,234 @@ function resolveEdgeLabelOverlapsWithChainAndPropagate(edges, obstacles, minClea
|
|
|
2015
2015
|
edgePathShifts: edgePathShiftMap
|
|
2016
2016
|
};
|
|
2017
2017
|
}
|
|
2018
|
+
function resolveLabelClearanceAfterPathPasses(edges, obstacles, maxIter = 8) {
|
|
2019
|
+
if (edges.length === 0) return edges;
|
|
2020
|
+
const labeledIds = new Set(
|
|
2021
|
+
edges.filter((e) => e.label?.trim() || e.sub?.trim()).map((e) => e.id)
|
|
2022
|
+
);
|
|
2023
|
+
if (labeledIds.size === 0) return edges;
|
|
2024
|
+
const \u7BB1\u305F\u3061 = obstacles.filter((o) => o.kind === "node" || o.kind === "lane-label");
|
|
2025
|
+
const edgeById = /* @__PURE__ */ new Map();
|
|
2026
|
+
for (const e of edges) edgeById.set(e.id, e);
|
|
2027
|
+
const \u533A\u9593cache = /* @__PURE__ */ new Map();
|
|
2028
|
+
const \u533A\u9593 = (id, d) => {
|
|
2029
|
+
const hit = \u533A\u9593cache.get(id);
|
|
2030
|
+
if (hit) return hit;
|
|
2031
|
+
const segs = flattenPathSegments(extractPathSegments(d));
|
|
2032
|
+
\u533A\u9593cache.set(id, segs);
|
|
2033
|
+
return segs;
|
|
2034
|
+
};
|
|
2035
|
+
const \u5916\u63A5cache = /* @__PURE__ */ new Map();
|
|
2036
|
+
const \u5916\u63A5 = (id, d) => {
|
|
2037
|
+
const hit = \u5916\u63A5cache.get(id);
|
|
2038
|
+
if (hit !== void 0) return hit;
|
|
2039
|
+
const segs = \u533A\u9593(id, d);
|
|
2040
|
+
if (segs.length === 0) {
|
|
2041
|
+
\u5916\u63A5cache.set(id, null);
|
|
2042
|
+
return null;
|
|
2043
|
+
}
|
|
2044
|
+
let x1 = Infinity, y1 = Infinity, x2 = -Infinity, y2 = -Infinity;
|
|
2045
|
+
for (const g of segs) {
|
|
2046
|
+
x1 = Math.min(x1, g.x1, g.x2);
|
|
2047
|
+
y1 = Math.min(y1, g.y1, g.y2);
|
|
2048
|
+
x2 = Math.max(x2, g.x1, g.x2);
|
|
2049
|
+
y2 = Math.max(y2, g.y1, g.y2);
|
|
2050
|
+
}
|
|
2051
|
+
const box = { x: x1, y: y1, w: x2 - x1, h: y2 - y1 };
|
|
2052
|
+
\u5916\u63A5cache.set(id, box);
|
|
2053
|
+
return box;
|
|
2054
|
+
};
|
|
2055
|
+
const \u9060\u3044 = (box, edgeId, d, \u4F59\u88D5) => {
|
|
2056
|
+
const b = \u5916\u63A5(edgeId, d);
|
|
2057
|
+
if (!b) return true;
|
|
2058
|
+
const dx = Math.max(0, Math.max(box.x - (b.x + b.w), b.x - (box.x + box.w)));
|
|
2059
|
+
const dy = Math.max(0, Math.max(box.y - (b.y + b.h), b.y - (box.y + box.h)));
|
|
2060
|
+
return Math.hypot(dx, dy) >= \u4F59\u88D5;
|
|
2061
|
+
};
|
|
2062
|
+
const \u6700\u5927\u79FB\u52D5 = CHAIN_SHIFT_MAX_ACCUMULATED * 2;
|
|
2063
|
+
const shiftMap = /* @__PURE__ */ new Map();
|
|
2064
|
+
const getShift = (id) => shiftMap.get(id) ?? { dx: 0, dy: 0 };
|
|
2065
|
+
const labelBBoxes = () => {
|
|
2066
|
+
const out = [];
|
|
2067
|
+
for (const e of edges) {
|
|
2068
|
+
if (!labeledIds.has(e.id)) continue;
|
|
2069
|
+
const base = computeLabelBBoxWorld(e);
|
|
2070
|
+
const s = getShift(e.id);
|
|
2071
|
+
out.push({ kind: "edge-label", id: e.id, x: base.x + s.dx, y: base.y + s.dy, w: base.w, h: base.h });
|
|
2072
|
+
}
|
|
2073
|
+
return out;
|
|
2074
|
+
};
|
|
2075
|
+
const \u96E2\u308C\u91CF = (a, b) => ({
|
|
2076
|
+
x: Math.max(a.x - (b.x + b.w), b.x - (a.x + a.w)),
|
|
2077
|
+
y: Math.max(a.y - (b.y + b.h), b.y - (a.y + a.h))
|
|
2078
|
+
});
|
|
2079
|
+
const \u52D5\u304B\u3057\u305F\u7BB1 = (box, axis, sign, amount) => ({
|
|
2080
|
+
...box,
|
|
2081
|
+
x: box.x + (axis === "x" ? sign * amount : 0),
|
|
2082
|
+
y: box.y + (axis === "y" ? sign * amount : 0)
|
|
2083
|
+
});
|
|
2084
|
+
for (let iter = 0; iter < maxIter; iter += 1) {
|
|
2085
|
+
const labels = labelBBoxes();
|
|
2086
|
+
const \u672D\u306E\u8981\u6C42 = requiredNearClearance("edge-label", "edge-label");
|
|
2087
|
+
let \u52D5\u3044\u305F = false;
|
|
2088
|
+
const \u4ECA\u56DE\u52D5\u304B\u3057\u305F = /* @__PURE__ */ new Set();
|
|
2089
|
+
const \u5B89\u5168\u304B = (label, \u884C\u304D\u5148) => {
|
|
2090
|
+
for (const obs of \u7BB1\u305F\u3061) {
|
|
2091
|
+
const \u524D = computeGap(label, obs);
|
|
2092
|
+
const \u5F8C = computeGap(\u884C\u304D\u5148, obs);
|
|
2093
|
+
if (\u5F8C < Math.min(\u524D, requiredNearClearance("edge-label", obs.kind))) return false;
|
|
2094
|
+
}
|
|
2095
|
+
for (const \u4ED6 of labels) {
|
|
2096
|
+
if (\u4ED6.id === label.id) continue;
|
|
2097
|
+
const \u524D = computeGap(label, \u4ED6);
|
|
2098
|
+
const \u5F8C = computeGap(\u884C\u304D\u5148, \u4ED6);
|
|
2099
|
+
if (\u5F8C < Math.min(\u524D, \u672D\u306E\u8981\u6C42)) return false;
|
|
2100
|
+
}
|
|
2101
|
+
const \u81EA\u5206 = edgeById.get(label.id);
|
|
2102
|
+
const \u81EA\u5206\u306E\u533A\u9593 = \u81EA\u5206 ? \u533A\u9593(\u81EA\u5206.id, \u81EA\u5206.d) : [];
|
|
2103
|
+
if (\u81EA\u5206\u306E\u533A\u9593.length > 0) {
|
|
2104
|
+
const \u524D = measurePathLabelGapSegs(\u81EA\u5206\u306E\u533A\u9593, label);
|
|
2105
|
+
const \u5F8C = measurePathLabelGapSegs(\u81EA\u5206\u306E\u533A\u9593, \u884C\u304D\u5148);
|
|
2106
|
+
if (\u5F8C > Math.max(\u524D, DIST_LABEL_PATH_MAX)) return false;
|
|
2107
|
+
}
|
|
2108
|
+
for (const \u76F8\u624B of edges) {
|
|
2109
|
+
if (\u76F8\u624B.id === label.id) continue;
|
|
2110
|
+
if (\u9060\u3044(label, \u76F8\u624B.id, \u76F8\u624B.d, LABEL_TO_PATH_CLEARANCE) && \u9060\u3044(\u884C\u304D\u5148, \u76F8\u624B.id, \u76F8\u624B.d, LABEL_TO_PATH_CLEARANCE)) continue;
|
|
2111
|
+
const segs = segmentsExcludingOwnPath(\u533A\u9593(\u76F8\u624B.id, \u76F8\u624B.d), \u81EA\u5206\u306E\u533A\u9593);
|
|
2112
|
+
if (segs.length === 0) continue;
|
|
2113
|
+
const \u524D = measurePathLabelGapSegs(segs, label);
|
|
2114
|
+
const \u5F8C = measurePathLabelGapSegs(segs, \u884C\u304D\u5148);
|
|
2115
|
+
if (\u5F8C < Math.min(\u524D, LABEL_TO_PATH_CLEARANCE)) return false;
|
|
2116
|
+
}
|
|
2117
|
+
return true;
|
|
2118
|
+
};
|
|
2119
|
+
const \u9003\u304C\u3059 = (label, \u5019\u88DC) => {
|
|
2120
|
+
for (const c of \u5019\u88DC.slice().sort((a, b) => a.amount - b.amount)) {
|
|
2121
|
+
if (c.amount <= 0) continue;
|
|
2122
|
+
const \u884C\u304D\u5148 = \u52D5\u304B\u3057\u305F\u7BB1(label, c.axis, c.sign, c.amount);
|
|
2123
|
+
if (!\u5B89\u5168\u304B(label, \u884C\u304D\u5148)) continue;
|
|
2124
|
+
const cur = getShift(label.id);
|
|
2125
|
+
const dx = c.axis === "x" ? cur.dx + c.sign * c.amount : cur.dx;
|
|
2126
|
+
const dy = c.axis === "y" ? cur.dy + c.sign * c.amount : cur.dy;
|
|
2127
|
+
if (Math.hypot(dx, dy) > \u6700\u5927\u79FB\u52D5) continue;
|
|
2128
|
+
shiftMap.set(label.id, { dx, dy });
|
|
2129
|
+
\u4ECA\u56DE\u52D5\u304B\u3057\u305F.add(label.id);
|
|
2130
|
+
return true;
|
|
2131
|
+
}
|
|
2132
|
+
return false;
|
|
2133
|
+
};
|
|
2134
|
+
const \u77E9\u5F62\u306E\u5019\u88DC = (label, static\u7BB1, required) => {
|
|
2135
|
+
const sep = \u96E2\u308C\u91CF(label, static\u7BB1);
|
|
2136
|
+
const \u5411\u304D = (axis) => {
|
|
2137
|
+
const a = axis === "x" ? label.x + label.w / 2 : label.y + label.h / 2;
|
|
2138
|
+
const b = axis === "x" ? static\u7BB1.x + static\u7BB1.w / 2 : static\u7BB1.y + static\u7BB1.h / 2;
|
|
2139
|
+
return a >= b ? 1 : -1;
|
|
2140
|
+
};
|
|
2141
|
+
return [
|
|
2142
|
+
{ axis: "x", sign: \u5411\u304D("x"), amount: required - sep.x + NEAR_MISS_MARGIN },
|
|
2143
|
+
{ axis: "y", sign: \u5411\u304D("y"), amount: required - sep.y + NEAR_MISS_MARGIN }
|
|
2144
|
+
];
|
|
2145
|
+
};
|
|
2146
|
+
for (const label of labels) {
|
|
2147
|
+
if (\u4ECA\u56DE\u52D5\u304B\u3057\u305F.has(label.id)) continue;
|
|
2148
|
+
for (const obs of \u7BB1\u305F\u3061) {
|
|
2149
|
+
const required = requiredNearClearance(label.kind, obs.kind);
|
|
2150
|
+
if (required <= 0) continue;
|
|
2151
|
+
if (computeGap(label, obs) >= required) continue;
|
|
2152
|
+
if (\u9003\u304C\u3059(label, \u77E9\u5F62\u306E\u5019\u88DC(label, obs, required))) {
|
|
2153
|
+
\u52D5\u3044\u305F = true;
|
|
2154
|
+
break;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
const \u672D\u9806 = /* @__PURE__ */ new Map();
|
|
2159
|
+
edges.forEach((e, i) => \u672D\u9806.set(e.id, i));
|
|
2160
|
+
for (let i = 0; i < labels.length; i += 1) {
|
|
2161
|
+
for (let j = i + 1; j < labels.length; j += 1) {
|
|
2162
|
+
const a = labels[i];
|
|
2163
|
+
const b = labels[j];
|
|
2164
|
+
if (computeGap(a, b) >= \u672D\u306E\u8981\u6C42) continue;
|
|
2165
|
+
const aIsLater = \u672D\u9806.get(a.id) > \u672D\u9806.get(b.id);
|
|
2166
|
+
const moveBox = aIsLater ? a : b;
|
|
2167
|
+
const staticBox = aIsLater ? b : a;
|
|
2168
|
+
if (\u4ECA\u56DE\u52D5\u304B\u3057\u305F.has(moveBox.id)) continue;
|
|
2169
|
+
if (\u9003\u304C\u3059(moveBox, \u77E9\u5F62\u306E\u5019\u88DC(moveBox, staticBox, \u672D\u306E\u8981\u6C42))) \u52D5\u3044\u305F = true;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
for (const label of labels) {
|
|
2173
|
+
if (\u4ECA\u56DE\u52D5\u304B\u3057\u305F.has(label.id)) continue;
|
|
2174
|
+
const \u81EA\u5206 = edgeById.get(label.id);
|
|
2175
|
+
if (!\u81EA\u5206) continue;
|
|
2176
|
+
const \u81EA\u5206\u306E\u533A\u9593 = \u533A\u9593(\u81EA\u5206.id, \u81EA\u5206.d);
|
|
2177
|
+
for (const \u4ED6 of edges) {
|
|
2178
|
+
if (\u4ED6.id === label.id) continue;
|
|
2179
|
+
if (\u81EA\u5206.from === \u4ED6.from && \u81EA\u5206.to === \u4ED6.to) continue;
|
|
2180
|
+
if (\u9060\u3044(label, \u4ED6.id, \u4ED6.d, LABEL_TO_PATH_CLEARANCE)) continue;
|
|
2181
|
+
const segs = segmentsExcludingOwnPath(\u533A\u9593(\u4ED6.id, \u4ED6.d), \u81EA\u5206\u306E\u533A\u9593);
|
|
2182
|
+
if (segs.length === 0) continue;
|
|
2183
|
+
const gap = measurePathLabelGapSegs(segs, label);
|
|
2184
|
+
if (gap >= LABEL_TO_PATH_CLEARANCE) continue;
|
|
2185
|
+
const \u82AF = { x: label.x + label.w / 2, y: label.y + label.h / 2 };
|
|
2186
|
+
let \u8FD1\u3044\u70B9 = null;
|
|
2187
|
+
let \u6700\u77ED = Infinity;
|
|
2188
|
+
for (const seg of segs) {
|
|
2189
|
+
for (const \u70B9 of [
|
|
2190
|
+
{ x: seg.x1, y: seg.y1 },
|
|
2191
|
+
{ x: seg.x2, y: seg.y2 },
|
|
2192
|
+
{ x: (seg.x1 + seg.x2) / 2, y: (seg.y1 + seg.y2) / 2 }
|
|
2193
|
+
]) {
|
|
2194
|
+
const d = Math.hypot(\u70B9.x - \u82AF.x, \u70B9.y - \u82AF.y);
|
|
2195
|
+
if (d < \u6700\u77ED) {
|
|
2196
|
+
\u6700\u77ED = d;
|
|
2197
|
+
\u8FD1\u3044\u70B9 = \u70B9;
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
if (!\u8FD1\u3044\u70B9) continue;
|
|
2202
|
+
const \u5FC5\u8981\u91CF = (axis, sign) => {
|
|
2203
|
+
const \u6E80\u305F\u3059 = (\u91CF) => measurePathLabelGapSegs(segs, \u52D5\u304B\u3057\u305F\u7BB1(label, axis, sign, \u91CF)) >= LABEL_TO_PATH_CLEARANCE;
|
|
2204
|
+
let lo = 0;
|
|
2205
|
+
let hi = Math.max(4, LABEL_TO_PATH_CLEARANCE - gap);
|
|
2206
|
+
while (!\u6E80\u305F\u3059(hi)) {
|
|
2207
|
+
if (hi >= \u6700\u5927\u79FB\u52D5) return null;
|
|
2208
|
+
lo = hi;
|
|
2209
|
+
hi = Math.min(hi * 2, \u6700\u5927\u79FB\u52D5);
|
|
2210
|
+
}
|
|
2211
|
+
for (let k = 0; k < 12; k += 1) {
|
|
2212
|
+
const mid = (lo + hi) / 2;
|
|
2213
|
+
if (\u6E80\u305F\u3059(mid)) hi = mid;
|
|
2214
|
+
else lo = mid;
|
|
2215
|
+
}
|
|
2216
|
+
return hi + NEAR_MISS_MARGIN;
|
|
2217
|
+
};
|
|
2218
|
+
const dx = \u82AF.x - \u8FD1\u3044\u70B9.x;
|
|
2219
|
+
const dy = \u82AF.y - \u8FD1\u3044\u70B9.y;
|
|
2220
|
+
const \u5019\u88DC = [];
|
|
2221
|
+
for (const c of [
|
|
2222
|
+
{ axis: "x", sign: dx >= 0 ? 1 : -1 },
|
|
2223
|
+
{ axis: "y", sign: dy >= 0 ? 1 : -1 },
|
|
2224
|
+
// 近い点から離れる向きが塞がれていることがある。 反対向きも候補に入れる。
|
|
2225
|
+
{ axis: "x", sign: dx >= 0 ? -1 : 1 },
|
|
2226
|
+
{ axis: "y", sign: dy >= 0 ? -1 : 1 }
|
|
2227
|
+
]) {
|
|
2228
|
+
const \u91CF = \u5FC5\u8981\u91CF(c.axis, c.sign);
|
|
2229
|
+
if (\u91CF !== null) \u5019\u88DC.push({ ...c, amount: \u91CF });
|
|
2230
|
+
}
|
|
2231
|
+
if (\u9003\u304C\u3059(label, \u5019\u88DC)) {
|
|
2232
|
+
\u52D5\u3044\u305F = true;
|
|
2233
|
+
break;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
if (!\u52D5\u3044\u305F) break;
|
|
2238
|
+
}
|
|
2239
|
+
if (shiftMap.size === 0) return edges;
|
|
2240
|
+
return edges.map((e) => {
|
|
2241
|
+
const s = shiftMap.get(e.id);
|
|
2242
|
+
if (!s || s.dx === 0 && s.dy === 0) return e;
|
|
2243
|
+
return { ...e, labelX: e.labelX + s.dx, labelY: e.labelY + s.dy };
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2018
2246
|
function applyEdgeLabelAndPathShifts(edges, labelShiftMap, edgePathShiftMap) {
|
|
2019
2247
|
if (labelShiftMap.size === 0 && edgePathShiftMap.size === 0) return edges;
|
|
2020
2248
|
return edges.map((e) => {
|
|
@@ -8600,11 +8828,66 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
|
|
|
8600
8828
|
parts.push(`L ${s.x2} ${s.y2}`);
|
|
8601
8829
|
}
|
|
8602
8830
|
const \u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C = Math.abs(\u6298\u308C1.x - last.x1) <= 0.5 && Math.abs(\u6298\u308C1.y - last.y1) <= 0.5;
|
|
8831
|
+
if (\u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C) {
|
|
8832
|
+
const \u6298\u308A\u8FD4\u3055\u306A\u3044 = \u76F4\u524D\u306E\u6298\u308C\u3054\u3068\u305A\u3089\u3059(segs, \u6A2A, d, nodes, e);
|
|
8833
|
+
if (\u6298\u308A\u8FD4\u3055\u306A\u3044) return \u6298\u308A\u8FD4\u3055\u306A\u3044;
|
|
8834
|
+
}
|
|
8603
8835
|
if (!\u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C) parts.push(`L ${round1(\u6298\u308C1.x)} ${round1(\u6298\u308C1.y)}`);
|
|
8604
8836
|
parts.push(`L ${round1(\u6298\u308C2.x)} ${round1(\u6298\u308C2.y)}`);
|
|
8605
8837
|
parts.push(`L ${round1(\u7D42\u70B9.x)} ${round1(\u7D42\u70B9.y)}`);
|
|
8606
8838
|
return parts.join(" ");
|
|
8607
8839
|
}
|
|
8840
|
+
function \u76F4\u524D\u306E\u6298\u308C\u3054\u3068\u305A\u3089\u3059(segs, \u6A2A, d, nodes, e) {
|
|
8841
|
+
const \u5E73\u884C\u304B = (s) => \u6A2A ? Math.abs(s.x2 - s.x1) < 0.5 && Math.abs(s.y2 - s.y1) > 0.5 : Math.abs(s.y2 - s.y1) < 0.5 && Math.abs(s.x2 - s.x1) > 0.5;
|
|
8842
|
+
let \u5438\u53CE = -1;
|
|
8843
|
+
for (let i = segs.length - 2; i >= 0; i -= 1) {
|
|
8844
|
+
if (\u5E73\u884C\u304B(segs[i])) {
|
|
8845
|
+
\u5438\u53CE = i;
|
|
8846
|
+
break;
|
|
8847
|
+
}
|
|
8848
|
+
}
|
|
8849
|
+
if (\u5438\u53CE < 0) return null;
|
|
8850
|
+
const \u5143\u306E\u9577\u3055 = \u6A2A ? Math.abs(segs[\u5438\u53CE].y2 - segs[\u5438\u53CE].y1) : Math.abs(segs[\u5438\u53CE].x2 - segs[\u5438\u53CE].x1);
|
|
8851
|
+
const \u5411\u304D = \u6A2A ? Math.sign(segs[\u5438\u53CE].y2 - segs[\u5438\u53CE].y1) : Math.sign(segs[\u5438\u53CE].x2 - segs[\u5438\u53CE].x1);
|
|
8852
|
+
const \u5F8C\u306E\u9577\u3055 = \u5143\u306E\u9577\u3055 + \u5411\u304D * d;
|
|
8853
|
+
if (\u5F8C\u306E\u9577\u3055 < ENDPOINT_FAN_RUNUP) return null;
|
|
8854
|
+
const \u305A\u3089\u3059 = (p) => \u6A2A ? { ...p, y: p.y + d } : { ...p, x: p.x + d };
|
|
8855
|
+
const \u65B0segs = segs.map((s, i) => {
|
|
8856
|
+
if (i <= \u5438\u53CE) return s;
|
|
8857
|
+
return {
|
|
8858
|
+
...s,
|
|
8859
|
+
x1: \u305A\u3089\u3059({ x: s.x1, y: s.y1 }).x,
|
|
8860
|
+
y1: \u305A\u3089\u3059({ x: s.x1, y: s.y1 }).y,
|
|
8861
|
+
x2: \u305A\u3089\u3059({ x: s.x2, y: s.y2 }).x,
|
|
8862
|
+
y2: \u305A\u3089\u3059({ x: s.x2, y: s.y2 }).y,
|
|
8863
|
+
...s.ctrl ? { ctrl: s.ctrl.map((c) => \u305A\u3089\u3059(c)) } : {}
|
|
8864
|
+
};
|
|
8865
|
+
});
|
|
8866
|
+
\u65B0segs[\u5438\u53CE] = {
|
|
8867
|
+
...segs[\u5438\u53CE],
|
|
8868
|
+
x2: \u6A2A ? segs[\u5438\u53CE].x2 : segs[\u5438\u53CE].x2 + d,
|
|
8869
|
+
y2: \u6A2A ? segs[\u5438\u53CE].y2 + d : segs[\u5438\u53CE].y2
|
|
8870
|
+
};
|
|
8871
|
+
if (nodes.some(
|
|
8872
|
+
(n) => n.id !== e.from && n.id !== e.to && segmentsCrossRect(
|
|
8873
|
+
\u65B0segs.slice(\u5438\u53CE).map((s) => ({ x1: s.x1, y1: s.y1, x2: s.x2, y2: s.y2 })),
|
|
8874
|
+
nodeRect(n)
|
|
8875
|
+
)
|
|
8876
|
+
)) {
|
|
8877
|
+
return null;
|
|
8878
|
+
}
|
|
8879
|
+
const head = \u65B0segs[0];
|
|
8880
|
+
const parts = [`M ${round1(head.x1)} ${round1(head.y1)}`];
|
|
8881
|
+
for (const s of \u65B0segs) {
|
|
8882
|
+
if (s.cmd === "Q") {
|
|
8883
|
+
const c = s.ctrl?.[0];
|
|
8884
|
+
parts.push(c ? `Q ${round1(c.x)} ${round1(c.y)}, ${round1(s.x2)} ${round1(s.y2)}` : `L ${round1(s.x2)} ${round1(s.y2)}`);
|
|
8885
|
+
continue;
|
|
8886
|
+
}
|
|
8887
|
+
parts.push(`L ${round1(s.x2)} ${round1(s.y2)}`);
|
|
8888
|
+
}
|
|
8889
|
+
return parts.join(" ");
|
|
8890
|
+
}
|
|
8608
8891
|
|
|
8609
8892
|
// src/layout/lanes.ts
|
|
8610
8893
|
var LANE_POSITION_EPSILON = 1e-9;
|
|
@@ -9089,6 +9372,14 @@ function layout(diag) {
|
|
|
9089
9372
|
hopEdgeCrossings(edges);
|
|
9090
9373
|
repositionParallelLabels(edges, nodesFinal);
|
|
9091
9374
|
slideLabelsAlongOwnPath(edges, nodesFinal);
|
|
9375
|
+
if (!isChainEdgeLabelDisabled()) {
|
|
9376
|
+
edges = resolveLabelClearanceAfterPathPasses(
|
|
9377
|
+
edges,
|
|
9378
|
+
collectBBoxes(containedLanesFinal, nodesFinal, []).filter(
|
|
9379
|
+
(b) => b.kind === "node" || b.kind === "lane-label"
|
|
9380
|
+
)
|
|
9381
|
+
);
|
|
9382
|
+
}
|
|
9092
9383
|
const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges);
|
|
9093
9384
|
const collisions = detectCollisions(bboxes, edges);
|
|
9094
9385
|
const nearCollisions = detectNearCollisions(bboxes, edges);
|