@crazyhappyone/auto-graph 0.1.1 → 0.1.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/README.md +6 -1
- package/README.zh-CN.md +6 -1
- package/dist/cli/index.cjs +293 -21
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +293 -21
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +293 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +293 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2071,7 +2071,7 @@ function point(value) {
|
|
|
2071
2071
|
return { x: value.x, y: value.y };
|
|
2072
2072
|
}
|
|
2073
2073
|
var directionSchema = zod.z.enum(["TB", "LR", "BT", "RL"]);
|
|
2074
|
-
var routeKindSchema = zod.z.enum(["orthogonal", "straight"]);
|
|
2074
|
+
var routeKindSchema = zod.z.enum(["orthogonal", "straight", "obstacle-avoiding"]);
|
|
2075
2075
|
var outputFormatSchema = zod.z.enum(["svg", "excalidraw"]);
|
|
2076
2076
|
var edgeStrokeStyleSchema = zod.z.enum(["solid", "dashed"]);
|
|
2077
2077
|
var edgeArrowheadSchema = zod.z.enum(["triangle", "hollowTriangle"]);
|
|
@@ -3862,6 +3862,7 @@ function routeEdge(input) {
|
|
|
3862
3862
|
const diagnostics = [];
|
|
3863
3863
|
const softObstacles = input.obstacles ?? [];
|
|
3864
3864
|
const hardObstacles = input.hardObstacles ?? [];
|
|
3865
|
+
const maxAttempts = input.maxRoutingAttempts ?? 5;
|
|
3865
3866
|
const defaultAnchors = defaultAnchorsForGeometry(
|
|
3866
3867
|
input.source.box,
|
|
3867
3868
|
input.target.box,
|
|
@@ -3957,6 +3958,51 @@ function routeEdge(input) {
|
|
|
3957
3958
|
)
|
|
3958
3959
|
);
|
|
3959
3960
|
if (hardClearCandidate !== void 0) {
|
|
3961
|
+
let bestPoints2 = hardClearCandidate.points;
|
|
3962
|
+
if (input.kind === "obstacle-avoiding") {
|
|
3963
|
+
const allObstacles = [...softObstacles, ...hardObstacles];
|
|
3964
|
+
for (const candidate of candidateRoutes) {
|
|
3965
|
+
if (routeCrossesBoxes(candidate.points, hardObstacles) || routeIntersectsEndpointInteriors(
|
|
3966
|
+
candidate.points,
|
|
3967
|
+
candidate.endpointObstacles
|
|
3968
|
+
)) {
|
|
3969
|
+
continue;
|
|
3970
|
+
}
|
|
3971
|
+
const rerouted2 = greedyRerouteAroundObstacles(
|
|
3972
|
+
candidate.points,
|
|
3973
|
+
allObstacles,
|
|
3974
|
+
maxAttempts
|
|
3975
|
+
);
|
|
3976
|
+
if (!routeCrossesBoxes(rerouted2, allObstacles) && !routeIntersectsEndpointInteriors(
|
|
3977
|
+
rerouted2,
|
|
3978
|
+
candidate.endpointObstacles
|
|
3979
|
+
)) {
|
|
3980
|
+
return {
|
|
3981
|
+
points: finalizeRoute(
|
|
3982
|
+
rerouted2,
|
|
3983
|
+
softObstacles,
|
|
3984
|
+
hardObstacles,
|
|
3985
|
+
diagnostics
|
|
3986
|
+
),
|
|
3987
|
+
diagnostics
|
|
3988
|
+
};
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
const rerouted = greedyRerouteAroundObstacles(
|
|
3992
|
+
bestPoints2,
|
|
3993
|
+
allObstacles,
|
|
3994
|
+
Math.min(maxAttempts, 3)
|
|
3995
|
+
);
|
|
3996
|
+
const reroutedAvoidsEndpointInteriors = !routeIntersectsEndpointInteriors(
|
|
3997
|
+
rerouted,
|
|
3998
|
+
hardClearCandidate.endpointObstacles
|
|
3999
|
+
);
|
|
4000
|
+
if (reroutedAvoidsEndpointInteriors) {
|
|
4001
|
+
if (routeCrossesBoxes(rerouted, hardObstacles) && !routeCrossesBoxes(bestPoints2, hardObstacles)) ; else {
|
|
4002
|
+
bestPoints2 = rerouted;
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
3960
4006
|
diagnostics.push({
|
|
3961
4007
|
severity: "warning",
|
|
3962
4008
|
code: "routing.obstacle.unavoidable",
|
|
@@ -3964,7 +4010,7 @@ function routeEdge(input) {
|
|
|
3964
4010
|
});
|
|
3965
4011
|
return {
|
|
3966
4012
|
points: finalizeRoute(
|
|
3967
|
-
|
|
4013
|
+
bestPoints2,
|
|
3968
4014
|
softObstacles,
|
|
3969
4015
|
hardObstacles,
|
|
3970
4016
|
diagnostics
|
|
@@ -3973,6 +4019,33 @@ function routeEdge(input) {
|
|
|
3973
4019
|
};
|
|
3974
4020
|
}
|
|
3975
4021
|
if (hardObstacles.length > 0) {
|
|
4022
|
+
let bestPoints2 = candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors);
|
|
4023
|
+
if (input.kind === "obstacle-avoiding") {
|
|
4024
|
+
const allObstacles = [...softObstacles, ...hardObstacles];
|
|
4025
|
+
for (const candidate of candidateRoutes) {
|
|
4026
|
+
const rerouted = greedyRerouteAroundObstacles(
|
|
4027
|
+
candidate.points,
|
|
4028
|
+
allObstacles,
|
|
4029
|
+
maxAttempts
|
|
4030
|
+
);
|
|
4031
|
+
if (!routeCrossesBoxes(rerouted, allObstacles)) {
|
|
4032
|
+
return {
|
|
4033
|
+
points: finalizeRoute(
|
|
4034
|
+
rerouted,
|
|
4035
|
+
softObstacles,
|
|
4036
|
+
hardObstacles,
|
|
4037
|
+
diagnostics
|
|
4038
|
+
),
|
|
4039
|
+
diagnostics
|
|
4040
|
+
};
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
bestPoints2 = greedyRerouteAroundObstacles(
|
|
4044
|
+
candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors),
|
|
4045
|
+
allObstacles,
|
|
4046
|
+
maxAttempts
|
|
4047
|
+
);
|
|
4048
|
+
}
|
|
3976
4049
|
diagnostics.push({
|
|
3977
4050
|
severity: "error",
|
|
3978
4051
|
code: "routing.evidence.crossing_forbidden",
|
|
@@ -3980,7 +4053,7 @@ function routeEdge(input) {
|
|
|
3980
4053
|
});
|
|
3981
4054
|
return {
|
|
3982
4055
|
points: finalizeRoute(
|
|
3983
|
-
|
|
4056
|
+
bestPoints2,
|
|
3984
4057
|
softObstacles,
|
|
3985
4058
|
hardObstacles,
|
|
3986
4059
|
diagnostics
|
|
@@ -3988,6 +4061,33 @@ function routeEdge(input) {
|
|
|
3988
4061
|
diagnostics
|
|
3989
4062
|
};
|
|
3990
4063
|
}
|
|
4064
|
+
let bestPoints = candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors);
|
|
4065
|
+
if (input.kind === "obstacle-avoiding") {
|
|
4066
|
+
const allObstacles = [...softObstacles, ...hardObstacles];
|
|
4067
|
+
for (const candidate of candidateRoutes) {
|
|
4068
|
+
const rerouted = greedyRerouteAroundObstacles(
|
|
4069
|
+
candidate.points,
|
|
4070
|
+
allObstacles,
|
|
4071
|
+
maxAttempts
|
|
4072
|
+
);
|
|
4073
|
+
if (!routeCrossesBoxes(rerouted, allObstacles)) {
|
|
4074
|
+
return {
|
|
4075
|
+
points: finalizeRoute(
|
|
4076
|
+
rerouted,
|
|
4077
|
+
softObstacles,
|
|
4078
|
+
hardObstacles,
|
|
4079
|
+
diagnostics
|
|
4080
|
+
),
|
|
4081
|
+
diagnostics
|
|
4082
|
+
};
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
bestPoints = greedyRerouteAroundObstacles(
|
|
4086
|
+
candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors),
|
|
4087
|
+
allObstacles,
|
|
4088
|
+
maxAttempts
|
|
4089
|
+
);
|
|
4090
|
+
}
|
|
3991
4091
|
diagnostics.push({
|
|
3992
4092
|
severity: "warning",
|
|
3993
4093
|
code: "routing.obstacle.unavoidable",
|
|
@@ -3995,7 +4095,7 @@ function routeEdge(input) {
|
|
|
3995
4095
|
});
|
|
3996
4096
|
return {
|
|
3997
4097
|
points: finalizeRoute(
|
|
3998
|
-
|
|
4098
|
+
bestPoints,
|
|
3999
4099
|
softObstacles,
|
|
4000
4100
|
hardObstacles,
|
|
4001
4101
|
diagnostics
|
|
@@ -4153,6 +4253,70 @@ function insetBox(box, margin) {
|
|
|
4153
4253
|
height: box.height - margin * 2
|
|
4154
4254
|
};
|
|
4155
4255
|
}
|
|
4256
|
+
function greedyRerouteAroundObstacles(points, obstacles, maxIterations) {
|
|
4257
|
+
let current = [...points];
|
|
4258
|
+
for (let iter = 0; iter < maxIterations; iter++) {
|
|
4259
|
+
const improved = pushRouteAwayFromObstacles(current, obstacles);
|
|
4260
|
+
if (improved === null) {
|
|
4261
|
+
break;
|
|
4262
|
+
}
|
|
4263
|
+
current = improved;
|
|
4264
|
+
if (!routeCrossesBoxes(current, obstacles)) {
|
|
4265
|
+
break;
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
return current;
|
|
4269
|
+
}
|
|
4270
|
+
function pushRouteAwayFromObstacles(points, obstacles) {
|
|
4271
|
+
const result = [];
|
|
4272
|
+
let improved = false;
|
|
4273
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
4274
|
+
const a = points[i];
|
|
4275
|
+
const b = points[i + 1];
|
|
4276
|
+
if (a === void 0 || b === void 0) {
|
|
4277
|
+
result.push(a ?? b ?? { x: 0, y: 0 });
|
|
4278
|
+
continue;
|
|
4279
|
+
}
|
|
4280
|
+
result.push(a);
|
|
4281
|
+
const intersectors = obstacles.filter(
|
|
4282
|
+
(obs) => segmentIntersectsBox(a, b, obs)
|
|
4283
|
+
);
|
|
4284
|
+
if (intersectors.length === 0) {
|
|
4285
|
+
continue;
|
|
4286
|
+
}
|
|
4287
|
+
const mx = (a.x + b.x) / 2;
|
|
4288
|
+
const my = (a.y + b.y) / 2;
|
|
4289
|
+
const isHorizontal = a.y === b.y;
|
|
4290
|
+
const margin = 12;
|
|
4291
|
+
let bestWaypoint = null;
|
|
4292
|
+
let bestDist = Infinity;
|
|
4293
|
+
for (const obs of intersectors) {
|
|
4294
|
+
const candidates = isHorizontal ? [
|
|
4295
|
+
{ x: mx, y: obs.y - margin },
|
|
4296
|
+
{ x: mx, y: obs.y + obs.height + margin }
|
|
4297
|
+
] : [
|
|
4298
|
+
{ x: obs.x - margin, y: my },
|
|
4299
|
+
{ x: obs.x + obs.width + margin, y: my }
|
|
4300
|
+
];
|
|
4301
|
+
for (const wp of candidates) {
|
|
4302
|
+
const dist = Math.hypot(wp.x - mx, wp.y - my);
|
|
4303
|
+
if (dist < bestDist) {
|
|
4304
|
+
bestDist = dist;
|
|
4305
|
+
bestWaypoint = wp;
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
if (bestWaypoint !== null) {
|
|
4310
|
+
result.push(bestWaypoint);
|
|
4311
|
+
improved = true;
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
const last = points[points.length - 1];
|
|
4315
|
+
if (last !== void 0) {
|
|
4316
|
+
result.push(last);
|
|
4317
|
+
}
|
|
4318
|
+
return improved ? result : null;
|
|
4319
|
+
}
|
|
4156
4320
|
function fallbackRoute(input, defaultAnchors) {
|
|
4157
4321
|
return [
|
|
4158
4322
|
getEdgePort(
|
|
@@ -4739,7 +4903,9 @@ function solveDiagram(diagram, options = {}) {
|
|
|
4739
4903
|
styledEdges,
|
|
4740
4904
|
nodeGeometryById,
|
|
4741
4905
|
coordinatedNodes,
|
|
4742
|
-
[...nodeGeometryById.values()].map(
|
|
4906
|
+
[...nodeGeometryById.values()].map(
|
|
4907
|
+
(geometry) => options.routingGutter === void 0 ? geometry.obstacleBox : expandBox(geometry.obstacleBox, options.routingGutter)
|
|
4908
|
+
),
|
|
4743
4909
|
[...softObstacles, ...titleBarObstacles],
|
|
4744
4910
|
routingTextObstacles,
|
|
4745
4911
|
hardObstacles,
|
|
@@ -4754,7 +4920,9 @@ function solveDiagram(diagram, options = {}) {
|
|
|
4754
4920
|
...baseTextAnnotations.map((annotation) => annotation.box),
|
|
4755
4921
|
...frameTextAnnotation.map((annotation) => annotation.box)
|
|
4756
4922
|
],
|
|
4757
|
-
options.textMeasurer
|
|
4923
|
+
options.textMeasurer,
|
|
4924
|
+
options.labelPlacement,
|
|
4925
|
+
options.labelOffset
|
|
4758
4926
|
);
|
|
4759
4927
|
const textAnnotations = [
|
|
4760
4928
|
...baseTextAnnotations,
|
|
@@ -6695,7 +6863,8 @@ function coordinateBaseTextAnnotations(input) {
|
|
|
6695
6863
|
}
|
|
6696
6864
|
return annotations;
|
|
6697
6865
|
}
|
|
6698
|
-
function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer) {
|
|
6866
|
+
function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer, labelPlacement, labelOffset3) {
|
|
6867
|
+
const labelBaseOffset = labelPlacement === "beside" ? labelOffset3 ?? 16 : 10;
|
|
6699
6868
|
const measurer = textMeasurer ?? createDefaultTextMeasurer();
|
|
6700
6869
|
const annotations = [];
|
|
6701
6870
|
const placedLabelBoxes = [];
|
|
@@ -6722,7 +6891,8 @@ function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer) {
|
|
|
6722
6891
|
layout2,
|
|
6723
6892
|
edges,
|
|
6724
6893
|
obstacleBoxes,
|
|
6725
|
-
placedLabelBoxes
|
|
6894
|
+
placedLabelBoxes,
|
|
6895
|
+
labelBaseOffset
|
|
6726
6896
|
);
|
|
6727
6897
|
placedLabelBoxes.push({
|
|
6728
6898
|
x: center.x - layout2.box.width / 2,
|
|
@@ -7006,8 +7176,8 @@ function fallbackLabelLayout(text) {
|
|
|
7006
7176
|
diagnostics: []
|
|
7007
7177
|
};
|
|
7008
7178
|
}
|
|
7009
|
-
function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes) {
|
|
7010
|
-
const placement = labelPlacementOnPolyline2(edge.points);
|
|
7179
|
+
function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes, baseOffset = 10) {
|
|
7180
|
+
const placement = labelPlacementOnPolyline2(edge.points, baseOffset);
|
|
7011
7181
|
if (placement === void 0) {
|
|
7012
7182
|
return { x: 0, y: 0 };
|
|
7013
7183
|
}
|
|
@@ -7062,9 +7232,7 @@ function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
|
7062
7232
|
{ x: placement.x, y: placement.y + offset }
|
|
7063
7233
|
);
|
|
7064
7234
|
}
|
|
7065
|
-
|
|
7066
|
-
}
|
|
7067
|
-
if (segment.start.x === segment.end.x) {
|
|
7235
|
+
} else if (segment.start.x === segment.end.x) {
|
|
7068
7236
|
const needed = layout2.box.width / 2 + EDGE_LABEL_CLEARANCE;
|
|
7069
7237
|
const maxSteps = Math.max(12, Math.ceil(needed / EDGE_LABEL_CLEARANCE));
|
|
7070
7238
|
for (let step = 1; step <= maxSteps; step += 1) {
|
|
@@ -7074,14 +7242,90 @@ function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
|
7074
7242
|
{ x: placement.x - offset, y: placement.y }
|
|
7075
7243
|
);
|
|
7076
7244
|
}
|
|
7077
|
-
|
|
7245
|
+
} else {
|
|
7246
|
+
const dx = segment.end.x - segment.start.x;
|
|
7247
|
+
const dy = segment.end.y - segment.start.y;
|
|
7248
|
+
const segLen = Math.hypot(dx, dy);
|
|
7249
|
+
if (segLen > 0) {
|
|
7250
|
+
const nx = -dy / segLen;
|
|
7251
|
+
const ny = dx / segLen;
|
|
7252
|
+
const needed = (Math.abs(nx) * layout2.box.width + Math.abs(ny) * layout2.box.height) / 2 + EDGE_LABEL_CLEARANCE;
|
|
7253
|
+
const maxSteps = Math.max(12, Math.ceil(needed / EDGE_LABEL_CLEARANCE));
|
|
7254
|
+
for (let step = 1; step <= maxSteps; step += 1) {
|
|
7255
|
+
const offset = EDGE_LABEL_CLEARANCE * step;
|
|
7256
|
+
candidates.push(
|
|
7257
|
+
{ x: placement.x + nx * offset, y: placement.y + ny * offset },
|
|
7258
|
+
{ x: placement.x - nx * offset, y: placement.y - ny * offset }
|
|
7259
|
+
);
|
|
7260
|
+
}
|
|
7261
|
+
}
|
|
7262
|
+
}
|
|
7263
|
+
const totalLen = points.reduce((sum, p, idx) => {
|
|
7264
|
+
if (idx === 0) return 0;
|
|
7265
|
+
const prev = points[idx - 1];
|
|
7266
|
+
return sum + Math.hypot((p?.x ?? 0) - (prev?.x ?? 0), (p?.y ?? 0) - (prev?.y ?? 0));
|
|
7267
|
+
}, 0);
|
|
7268
|
+
if (totalLen > 200) {
|
|
7269
|
+
for (const ratio of [0.25, 0.75]) {
|
|
7270
|
+
const qp = labelPlacementAtRatio(points, ratio, totalLen);
|
|
7271
|
+
if (qp !== void 0) {
|
|
7272
|
+
candidates.push(qp);
|
|
7273
|
+
const qTargetDist = totalLen * ratio;
|
|
7274
|
+
let qTravelled = 0;
|
|
7275
|
+
let seg;
|
|
7276
|
+
for (let si = 1; si < points.length; si++) {
|
|
7277
|
+
const sp = points[si - 1];
|
|
7278
|
+
const sc = points[si];
|
|
7279
|
+
if (sp === void 0 || sc === void 0) continue;
|
|
7280
|
+
const sl = Math.hypot(sc.x - sp.x, sc.y - sp.y);
|
|
7281
|
+
if (sl <= 0) continue;
|
|
7282
|
+
if (qTravelled + sl >= qTargetDist) {
|
|
7283
|
+
seg = { start: sp, end: sc, length: sl };
|
|
7284
|
+
break;
|
|
7285
|
+
}
|
|
7286
|
+
qTravelled += sl;
|
|
7287
|
+
}
|
|
7288
|
+
if (seg !== void 0) {
|
|
7289
|
+
const segLen = Math.hypot(
|
|
7290
|
+
seg.end.x - seg.start.x,
|
|
7291
|
+
seg.end.y - seg.start.y
|
|
7292
|
+
);
|
|
7293
|
+
const qpNeeded = seg.start.y === seg.end.y ? layout2.box.height / 2 + EDGE_LABEL_CLEARANCE : seg.start.x === seg.end.x ? layout2.box.width / 2 + EDGE_LABEL_CLEARANCE : (Math.abs(seg.start.y - seg.end.y) * layout2.box.width + Math.abs(seg.end.x - seg.start.x) * layout2.box.height) / (2 * segLen) + EDGE_LABEL_CLEARANCE;
|
|
7294
|
+
const qpMaxSteps = Math.max(
|
|
7295
|
+
12,
|
|
7296
|
+
Math.ceil(qpNeeded / EDGE_LABEL_CLEARANCE)
|
|
7297
|
+
);
|
|
7298
|
+
for (let step = 1; step <= qpMaxSteps; step += 1) {
|
|
7299
|
+
const offset = EDGE_LABEL_CLEARANCE * step;
|
|
7300
|
+
if (seg.start.y === seg.end.y) {
|
|
7301
|
+
candidates.push(
|
|
7302
|
+
{ x: qp.x, y: qp.y - offset },
|
|
7303
|
+
{ x: qp.x, y: qp.y + offset }
|
|
7304
|
+
);
|
|
7305
|
+
} else if (seg.start.x === seg.end.x) {
|
|
7306
|
+
candidates.push(
|
|
7307
|
+
{ x: qp.x - offset, y: qp.y },
|
|
7308
|
+
{ x: qp.x + offset, y: qp.y }
|
|
7309
|
+
);
|
|
7310
|
+
} else {
|
|
7311
|
+
const nx = -(seg.end.y - seg.start.y) / segLen;
|
|
7312
|
+
const ny = (seg.end.x - seg.start.x) / segLen;
|
|
7313
|
+
candidates.push(
|
|
7314
|
+
{ x: qp.x + nx * offset, y: qp.y + ny * offset },
|
|
7315
|
+
{ x: qp.x - nx * offset, y: qp.y - ny * offset }
|
|
7316
|
+
);
|
|
7317
|
+
}
|
|
7318
|
+
}
|
|
7319
|
+
}
|
|
7320
|
+
}
|
|
7321
|
+
}
|
|
7078
7322
|
}
|
|
7079
7323
|
return candidates;
|
|
7080
7324
|
}
|
|
7081
|
-
function labelPlacementOnPolyline2(points) {
|
|
7082
|
-
return labelSegmentOnPolyline(points)?.placement;
|
|
7325
|
+
function labelPlacementOnPolyline2(points, baseOffset = 10) {
|
|
7326
|
+
return labelSegmentOnPolyline(points, baseOffset)?.placement;
|
|
7083
7327
|
}
|
|
7084
|
-
function labelSegmentOnPolyline(points) {
|
|
7328
|
+
function labelSegmentOnPolyline(points, baseOffset = 10) {
|
|
7085
7329
|
const segments = nonZeroSegments2(points);
|
|
7086
7330
|
const totalLength = segments.reduce(
|
|
7087
7331
|
(sum, segment) => sum + segment.length,
|
|
@@ -7096,7 +7340,7 @@ function labelSegmentOnPolyline(points) {
|
|
|
7096
7340
|
const ratio = remaining / segment.length;
|
|
7097
7341
|
const x = segment.start.x + (segment.end.x - segment.start.x) * ratio;
|
|
7098
7342
|
const y = segment.start.y + (segment.end.y - segment.start.y) * ratio;
|
|
7099
|
-
const offset2 = labelOffset2(segment);
|
|
7343
|
+
const offset2 = labelOffset2(segment, baseOffset);
|
|
7100
7344
|
return {
|
|
7101
7345
|
start: segment.start,
|
|
7102
7346
|
end: segment.end,
|
|
@@ -7131,8 +7375,36 @@ function nonZeroSegments2(points) {
|
|
|
7131
7375
|
}
|
|
7132
7376
|
return segments;
|
|
7133
7377
|
}
|
|
7134
|
-
function
|
|
7135
|
-
|
|
7378
|
+
function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
7379
|
+
if (points.length < 2 || ratio < 0 || ratio > 1) {
|
|
7380
|
+
return void 0;
|
|
7381
|
+
}
|
|
7382
|
+
const targetDist = totalLength * ratio;
|
|
7383
|
+
let travelled = 0;
|
|
7384
|
+
for (let idx = 1; idx < points.length; idx++) {
|
|
7385
|
+
const prev = points[idx - 1];
|
|
7386
|
+
const curr = points[idx];
|
|
7387
|
+
if (prev === void 0 || curr === void 0) {
|
|
7388
|
+
continue;
|
|
7389
|
+
}
|
|
7390
|
+
const segLen = Math.hypot(curr.x - prev.x, curr.y - prev.y);
|
|
7391
|
+
if (segLen <= 0) {
|
|
7392
|
+
continue;
|
|
7393
|
+
}
|
|
7394
|
+
if (travelled + segLen >= targetDist) {
|
|
7395
|
+
const t = (targetDist - travelled) / segLen;
|
|
7396
|
+
const offset = labelOffset2({ start: prev, end: curr, length: segLen });
|
|
7397
|
+
return {
|
|
7398
|
+
x: prev.x + (curr.x - prev.x) * t + offset.x,
|
|
7399
|
+
y: prev.y + (curr.y - prev.y) * t + offset.y
|
|
7400
|
+
};
|
|
7401
|
+
}
|
|
7402
|
+
travelled += segLen;
|
|
7403
|
+
}
|
|
7404
|
+
return void 0;
|
|
7405
|
+
}
|
|
7406
|
+
function labelOffset2(segment, baseOffset = 10) {
|
|
7407
|
+
const offset = baseOffset;
|
|
7136
7408
|
const dx = segment.end.x - segment.start.x;
|
|
7137
7409
|
const dy = segment.end.y - segment.start.y;
|
|
7138
7410
|
return {
|
|
@@ -7245,7 +7517,7 @@ function renderDiagramDsl(source, options = {}) {
|
|
|
7245
7517
|
return { diagnostics };
|
|
7246
7518
|
}
|
|
7247
7519
|
const solved = solveDiagram(normalized.diagram, {
|
|
7248
|
-
routeKind: normalized.diagram.metadata?.routeKind === "straight" ? "straight" : "orthogonal",
|
|
7520
|
+
routeKind: normalized.diagram.metadata?.routeKind === "straight" ? "straight" : normalized.diagram.metadata?.routeKind === "obstacle-avoiding" ? "obstacle-avoiding" : "orthogonal",
|
|
7249
7521
|
...solvePortShiftingOption(normalized.diagram.metadata?.portShifting),
|
|
7250
7522
|
...options.textMeasurer === void 0 ? {} : { textMeasurer: options.textMeasurer }
|
|
7251
7523
|
});
|