@crazyhappyone/auto-graph 0.1.2 → 0.1.4
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 +164 -29
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +164 -29
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +164 -29
- 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 +164 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -99,6 +99,9 @@ function applyLayoutConstraints(input) {
|
|
|
99
99
|
const nodeById = new Map(input.nodes.map((node) => [node.id, node]));
|
|
100
100
|
applyFixedPositionLocks(input.nodes, boxes, locks, diagnostics);
|
|
101
101
|
applyExactPositions(input.constraints, boxes, locks, diagnostics, nodeById);
|
|
102
|
+
if (input.distributeContainedChildren) {
|
|
103
|
+
yieldFixedPositionLocks(input, boxes, locks);
|
|
104
|
+
}
|
|
102
105
|
applyContainment(input.constraints, boxes, locks, diagnostics, false);
|
|
103
106
|
applyRelative(input.constraints, boxes, locks, diagnostics);
|
|
104
107
|
applyAlign(input.constraints, boxes, locks, diagnostics);
|
|
@@ -112,6 +115,13 @@ function applyLayoutConstraints(input) {
|
|
|
112
115
|
);
|
|
113
116
|
applyContainment(input.constraints, boxes, locks, diagnostics, true);
|
|
114
117
|
applyDistributeContained(input, boxes, locks, diagnostics);
|
|
118
|
+
if (input.distributeContainedChildren) {
|
|
119
|
+
const diagBefore = diagnostics.length;
|
|
120
|
+
applyContainment(input.constraints, boxes, locks, diagnostics, true);
|
|
121
|
+
applyDistributeContained(input, boxes, locks, diagnostics);
|
|
122
|
+
dedupReplayDiagnostics(diagnostics, diagBefore);
|
|
123
|
+
}
|
|
124
|
+
removeResolvedConstraintDiagnostics(input.constraints, boxes, diagnostics);
|
|
115
125
|
reportOverlaps(boxes, diagnostics, containmentOverlapKeys(input.constraints));
|
|
116
126
|
reportIntraContainerOverflow(input, boxes, diagnostics);
|
|
117
127
|
return { boxes, locks, diagnostics };
|
|
@@ -157,6 +167,62 @@ function applyFixedPositionLocks(nodes, boxes, locks, diagnostics) {
|
|
|
157
167
|
locks.set(node.id, { nodeId: node.id, source: "fixed-position" });
|
|
158
168
|
}
|
|
159
169
|
}
|
|
170
|
+
function dedupReplayDiagnostics(diagnostics, keepUpTo) {
|
|
171
|
+
const seen = /* @__PURE__ */ new Set();
|
|
172
|
+
for (let i = 0; i < keepUpTo && i < diagnostics.length; i += 1) {
|
|
173
|
+
const d = diagnostics[i];
|
|
174
|
+
if (d === void 0) continue;
|
|
175
|
+
seen.add(diagnosticFingerprint(d));
|
|
176
|
+
}
|
|
177
|
+
for (let i = diagnostics.length - 1; i >= keepUpTo; i -= 1) {
|
|
178
|
+
const d = diagnostics[i];
|
|
179
|
+
if (d === void 0) continue;
|
|
180
|
+
const fp = diagnosticFingerprint(d);
|
|
181
|
+
if (seen.has(fp)) {
|
|
182
|
+
diagnostics.splice(i, 1);
|
|
183
|
+
} else {
|
|
184
|
+
seen.add(fp);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function diagnosticFingerprint(d) {
|
|
189
|
+
const nodeId = typeof d.detail?.nodeId === "string" ? d.detail.nodeId : "";
|
|
190
|
+
const containerId = typeof d.detail?.containerId === "string" ? d.detail.containerId : "";
|
|
191
|
+
return `${d.code}|${nodeId}|${containerId}`;
|
|
192
|
+
}
|
|
193
|
+
function yieldFixedPositionLocks(input, boxes, locks) {
|
|
194
|
+
for (const c of input.constraints) {
|
|
195
|
+
if (c.kind !== "containment") continue;
|
|
196
|
+
const container = boxes.get(c.containerId);
|
|
197
|
+
if (container === void 0) continue;
|
|
198
|
+
const content = contentBox(container, c.padding);
|
|
199
|
+
const mainAxis = input.direction === "LR" || input.direction === "RL" ? "width" : "height";
|
|
200
|
+
const crossAxis = mainAxis === "width" ? "height" : "width";
|
|
201
|
+
let eligible = 0;
|
|
202
|
+
for (const childId of c.childIds) {
|
|
203
|
+
const box = boxes.get(childId);
|
|
204
|
+
if (box === void 0) continue;
|
|
205
|
+
const lock = locks.get(childId);
|
|
206
|
+
if (lock?.source === "exact-position") continue;
|
|
207
|
+
const fits = box[mainAxis] <= content[mainAxis] && box[crossAxis] <= content[crossAxis];
|
|
208
|
+
if (fits) {
|
|
209
|
+
eligible += 1;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (eligible < 2) continue;
|
|
213
|
+
for (const childId of c.childIds) {
|
|
214
|
+
const lock = locks.get(childId);
|
|
215
|
+
if (lock?.source === "fixed-position") {
|
|
216
|
+
const box = boxes.get(childId);
|
|
217
|
+
if (box === void 0) continue;
|
|
218
|
+
const fits = box[mainAxis] <= content[mainAxis] && box[crossAxis] <= content[crossAxis];
|
|
219
|
+
if (fits) {
|
|
220
|
+
locks.delete(childId);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
160
226
|
function applyExactPositions(constraints, boxes, locks, diagnostics, nodeById) {
|
|
161
227
|
for (const constraint of constraints) {
|
|
162
228
|
if (constraint.kind !== "exact-position") {
|
|
@@ -229,7 +295,7 @@ function applyContainment(constraints, boxes, locks, diagnostics, reportOverflow
|
|
|
229
295
|
code: "constraints.locked-target-not-moved",
|
|
230
296
|
message: `Locked child ${childId} was not moved into containment.`,
|
|
231
297
|
path: ["constraints", constraint.id ?? constraint.containerId],
|
|
232
|
-
detail: { nodeId: childId }
|
|
298
|
+
detail: { nodeId: childId, containerId: constraint.containerId }
|
|
233
299
|
});
|
|
234
300
|
if (!isInside(child, content)) {
|
|
235
301
|
diagnostics.push({
|
|
@@ -381,6 +447,60 @@ function repairOverlaps(input, boxes, locks, diagnostics, siblingPairs) {
|
|
|
381
447
|
}
|
|
382
448
|
reportOverlaps(boxes, diagnostics, ignoredPairs);
|
|
383
449
|
}
|
|
450
|
+
function removeResolvedConstraintDiagnostics(constraints, boxes, diagnostics) {
|
|
451
|
+
for (let i = diagnostics.length - 1; i >= 0; i -= 1) {
|
|
452
|
+
const d = diagnostics[i];
|
|
453
|
+
if (d === void 0) continue;
|
|
454
|
+
if (d.code === "constraints.overlap.unresolved") {
|
|
455
|
+
const aId = d.detail?.firstId;
|
|
456
|
+
const bId = d.detail?.secondId;
|
|
457
|
+
if (typeof aId !== "string" || typeof bId !== "string") continue;
|
|
458
|
+
const a = boxes.get(aId);
|
|
459
|
+
const b = boxes.get(bId);
|
|
460
|
+
if (a !== void 0 && b !== void 0 && !intersectsAabb(a, b)) {
|
|
461
|
+
diagnostics.splice(i, 1);
|
|
462
|
+
}
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
if (d.code === "constraints.containment.impossible" || d.code === "constraints.locked-target-not-moved" && typeof d.message === "string" && d.message.includes("not moved into containment")) {
|
|
466
|
+
const nodeId = d.detail?.nodeId;
|
|
467
|
+
if (typeof nodeId !== "string") continue;
|
|
468
|
+
const child = boxes.get(nodeId);
|
|
469
|
+
if (child === void 0) continue;
|
|
470
|
+
const diagContainerId = typeof d.detail?.containerId === "string" ? d.detail.containerId : void 0;
|
|
471
|
+
let resolved = false;
|
|
472
|
+
for (const c of constraints) {
|
|
473
|
+
if (c.kind !== "containment") continue;
|
|
474
|
+
if (!c.childIds.includes(nodeId)) continue;
|
|
475
|
+
if (diagContainerId !== void 0 && c.containerId !== diagContainerId) {
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
const container = boxes.get(c.containerId);
|
|
479
|
+
if (container === void 0) continue;
|
|
480
|
+
const content = contentBox(container, c.padding);
|
|
481
|
+
if (isInside(child, content)) {
|
|
482
|
+
diagnostics.splice(i, 1);
|
|
483
|
+
resolved = true;
|
|
484
|
+
}
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
if (!resolved && diagContainerId !== void 0) {
|
|
488
|
+
for (const c of constraints) {
|
|
489
|
+
if (c.kind !== "containment") continue;
|
|
490
|
+
if (c.containerId !== diagContainerId) continue;
|
|
491
|
+
if (!c.childIds.includes(nodeId)) continue;
|
|
492
|
+
const container = boxes.get(c.containerId);
|
|
493
|
+
if (container === void 0) continue;
|
|
494
|
+
const content = contentBox(container, c.padding);
|
|
495
|
+
if (isInside(child, content)) {
|
|
496
|
+
diagnostics.splice(i, 1);
|
|
497
|
+
}
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
384
504
|
function reportOverlaps(boxes, diagnostics, ignoredPairs = /* @__PURE__ */ new Set()) {
|
|
385
505
|
const ids = [...boxes.keys()].sort();
|
|
386
506
|
const reported = new Set(
|
|
@@ -688,6 +808,12 @@ function applyDistributeContained(input, boxes, locks, diagnostics) {
|
|
|
688
808
|
continue;
|
|
689
809
|
}
|
|
690
810
|
if (locks.has(childId)) {
|
|
811
|
+
const lock = locks.get(childId);
|
|
812
|
+
if (lock?.source === "fixed-position") {
|
|
813
|
+
unlocked.push({ id: childId, box });
|
|
814
|
+
locks.delete(childId);
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
691
817
|
diagnostics.push({
|
|
692
818
|
severity: "warning",
|
|
693
819
|
code: "constraints.locked-target-not-moved",
|
|
@@ -746,6 +872,7 @@ function applyDistributeContained(input, boxes, locks, diagnostics) {
|
|
|
746
872
|
});
|
|
747
873
|
}
|
|
748
874
|
boxes.set(child.id, clamped);
|
|
875
|
+
locks.delete(child.id);
|
|
749
876
|
pos = clamped[axis] + clamped[mainSize] + minGap;
|
|
750
877
|
}
|
|
751
878
|
diagnostics.push({
|
|
@@ -3862,6 +3989,7 @@ function routeEdge(input) {
|
|
|
3862
3989
|
const diagnostics = [];
|
|
3863
3990
|
const softObstacles = input.obstacles ?? [];
|
|
3864
3991
|
const hardObstacles = input.hardObstacles ?? [];
|
|
3992
|
+
const maxAttempts = input.maxRoutingAttempts ?? 5;
|
|
3865
3993
|
const defaultAnchors = defaultAnchorsForGeometry(
|
|
3866
3994
|
input.source.box,
|
|
3867
3995
|
input.target.box,
|
|
@@ -3970,7 +4098,7 @@ function routeEdge(input) {
|
|
|
3970
4098
|
const rerouted2 = greedyRerouteAroundObstacles(
|
|
3971
4099
|
candidate.points,
|
|
3972
4100
|
allObstacles,
|
|
3973
|
-
|
|
4101
|
+
maxAttempts
|
|
3974
4102
|
);
|
|
3975
4103
|
if (!routeCrossesBoxes(rerouted2, allObstacles) && !routeIntersectsEndpointInteriors(
|
|
3976
4104
|
rerouted2,
|
|
@@ -3990,7 +4118,7 @@ function routeEdge(input) {
|
|
|
3990
4118
|
const rerouted = greedyRerouteAroundObstacles(
|
|
3991
4119
|
bestPoints2,
|
|
3992
4120
|
allObstacles,
|
|
3993
|
-
|
|
4121
|
+
maxAttempts
|
|
3994
4122
|
);
|
|
3995
4123
|
const reroutedAvoidsEndpointInteriors = !routeIntersectsEndpointInteriors(
|
|
3996
4124
|
rerouted,
|
|
@@ -4025,7 +4153,7 @@ function routeEdge(input) {
|
|
|
4025
4153
|
const rerouted = greedyRerouteAroundObstacles(
|
|
4026
4154
|
candidate.points,
|
|
4027
4155
|
allObstacles,
|
|
4028
|
-
|
|
4156
|
+
maxAttempts
|
|
4029
4157
|
);
|
|
4030
4158
|
if (!routeCrossesBoxes(rerouted, allObstacles)) {
|
|
4031
4159
|
return {
|
|
@@ -4042,7 +4170,7 @@ function routeEdge(input) {
|
|
|
4042
4170
|
bestPoints2 = greedyRerouteAroundObstacles(
|
|
4043
4171
|
candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors),
|
|
4044
4172
|
allObstacles,
|
|
4045
|
-
|
|
4173
|
+
maxAttempts
|
|
4046
4174
|
);
|
|
4047
4175
|
}
|
|
4048
4176
|
diagnostics.push({
|
|
@@ -4067,7 +4195,7 @@ function routeEdge(input) {
|
|
|
4067
4195
|
const rerouted = greedyRerouteAroundObstacles(
|
|
4068
4196
|
candidate.points,
|
|
4069
4197
|
allObstacles,
|
|
4070
|
-
|
|
4198
|
+
maxAttempts
|
|
4071
4199
|
);
|
|
4072
4200
|
if (!routeCrossesBoxes(rerouted, allObstacles)) {
|
|
4073
4201
|
return {
|
|
@@ -4084,7 +4212,7 @@ function routeEdge(input) {
|
|
|
4084
4212
|
bestPoints = greedyRerouteAroundObstacles(
|
|
4085
4213
|
candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors),
|
|
4086
4214
|
allObstacles,
|
|
4087
|
-
|
|
4215
|
+
maxAttempts
|
|
4088
4216
|
);
|
|
4089
4217
|
}
|
|
4090
4218
|
diagnostics.push({
|
|
@@ -4752,9 +4880,7 @@ function solveDiagram(diagram, options = {}) {
|
|
|
4752
4880
|
options?.overlapSpacing ?? 40,
|
|
4753
4881
|
Math.max(0, options?.minLaneGutter ?? 0)
|
|
4754
4882
|
);
|
|
4755
|
-
|
|
4756
|
-
removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
|
|
4757
|
-
}
|
|
4883
|
+
removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
|
|
4758
4884
|
diagnostics.push(...swimlaneContracts.diagnostics);
|
|
4759
4885
|
const coordinatedNodes = coordinateNodes(
|
|
4760
4886
|
styledNodes,
|
|
@@ -4919,7 +5045,9 @@ function solveDiagram(diagram, options = {}) {
|
|
|
4919
5045
|
...baseTextAnnotations.map((annotation) => annotation.box),
|
|
4920
5046
|
...frameTextAnnotation.map((annotation) => annotation.box)
|
|
4921
5047
|
],
|
|
4922
|
-
options.textMeasurer
|
|
5048
|
+
options.textMeasurer,
|
|
5049
|
+
options.labelPlacement,
|
|
5050
|
+
options.labelOffset
|
|
4923
5051
|
);
|
|
4924
5052
|
const textAnnotations = [
|
|
4925
5053
|
...baseTextAnnotations,
|
|
@@ -6698,7 +6826,8 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
|
|
|
6698
6826
|
...softObstacles,
|
|
6699
6827
|
...routeTextObstacles
|
|
6700
6828
|
],
|
|
6701
|
-
hardObstacles
|
|
6829
|
+
hardObstacles,
|
|
6830
|
+
...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts }
|
|
6702
6831
|
});
|
|
6703
6832
|
diagnostics.push(
|
|
6704
6833
|
...route.diagnostics.map((diagnostic) => ({
|
|
@@ -6860,7 +6989,8 @@ function coordinateBaseTextAnnotations(input) {
|
|
|
6860
6989
|
}
|
|
6861
6990
|
return annotations;
|
|
6862
6991
|
}
|
|
6863
|
-
function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer) {
|
|
6992
|
+
function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer, labelPlacement, labelOffset3) {
|
|
6993
|
+
const labelBaseOffset = labelPlacement === "beside" ? labelOffset3 ?? 16 : 10;
|
|
6864
6994
|
const measurer = textMeasurer ?? createDefaultTextMeasurer();
|
|
6865
6995
|
const annotations = [];
|
|
6866
6996
|
const placedLabelBoxes = [];
|
|
@@ -6887,7 +7017,8 @@ function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer) {
|
|
|
6887
7017
|
layout2,
|
|
6888
7018
|
edges,
|
|
6889
7019
|
obstacleBoxes,
|
|
6890
|
-
placedLabelBoxes
|
|
7020
|
+
placedLabelBoxes,
|
|
7021
|
+
labelBaseOffset
|
|
6891
7022
|
);
|
|
6892
7023
|
placedLabelBoxes.push({
|
|
6893
7024
|
x: center.x - layout2.box.width / 2,
|
|
@@ -7171,15 +7302,16 @@ function fallbackLabelLayout(text) {
|
|
|
7171
7302
|
diagnostics: []
|
|
7172
7303
|
};
|
|
7173
7304
|
}
|
|
7174
|
-
function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes) {
|
|
7175
|
-
const placement = labelPlacementOnPolyline2(edge.points);
|
|
7305
|
+
function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes, baseOffset = 10) {
|
|
7306
|
+
const placement = labelPlacementOnPolyline2(edge.points, baseOffset);
|
|
7176
7307
|
if (placement === void 0) {
|
|
7177
7308
|
return { x: 0, y: 0 };
|
|
7178
7309
|
}
|
|
7179
7310
|
for (const candidate of edgeLabelAnchorCandidates(
|
|
7180
7311
|
edge.points,
|
|
7181
7312
|
placement,
|
|
7182
|
-
layout2
|
|
7313
|
+
layout2,
|
|
7314
|
+
baseOffset
|
|
7183
7315
|
)) {
|
|
7184
7316
|
const labelBox = {
|
|
7185
7317
|
x: candidate.x - layout2.box.width / 2,
|
|
@@ -7211,8 +7343,8 @@ function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes)
|
|
|
7211
7343
|
}
|
|
7212
7344
|
return placement;
|
|
7213
7345
|
}
|
|
7214
|
-
function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
7215
|
-
const segment = labelSegmentOnPolyline(points);
|
|
7346
|
+
function edgeLabelAnchorCandidates(points, placement, layout2, baseOffset = 10) {
|
|
7347
|
+
const segment = labelSegmentOnPolyline(points, baseOffset);
|
|
7216
7348
|
if (segment === void 0) {
|
|
7217
7349
|
return [placement];
|
|
7218
7350
|
}
|
|
@@ -7262,7 +7394,7 @@ function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
|
7262
7394
|
}, 0);
|
|
7263
7395
|
if (totalLen > 200) {
|
|
7264
7396
|
for (const ratio of [0.25, 0.75]) {
|
|
7265
|
-
const qp = labelPlacementAtRatio(points, ratio, totalLen);
|
|
7397
|
+
const qp = labelPlacementAtRatio(points, ratio, totalLen, baseOffset);
|
|
7266
7398
|
if (qp !== void 0) {
|
|
7267
7399
|
candidates.push(qp);
|
|
7268
7400
|
const qTargetDist = totalLen * ratio;
|
|
@@ -7317,10 +7449,10 @@ function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
|
7317
7449
|
}
|
|
7318
7450
|
return candidates;
|
|
7319
7451
|
}
|
|
7320
|
-
function labelPlacementOnPolyline2(points) {
|
|
7321
|
-
return labelSegmentOnPolyline(points)?.placement;
|
|
7452
|
+
function labelPlacementOnPolyline2(points, baseOffset = 10) {
|
|
7453
|
+
return labelSegmentOnPolyline(points, baseOffset)?.placement;
|
|
7322
7454
|
}
|
|
7323
|
-
function labelSegmentOnPolyline(points) {
|
|
7455
|
+
function labelSegmentOnPolyline(points, baseOffset = 10) {
|
|
7324
7456
|
const segments = nonZeroSegments2(points);
|
|
7325
7457
|
const totalLength = segments.reduce(
|
|
7326
7458
|
(sum, segment) => sum + segment.length,
|
|
@@ -7335,7 +7467,7 @@ function labelSegmentOnPolyline(points) {
|
|
|
7335
7467
|
const ratio = remaining / segment.length;
|
|
7336
7468
|
const x = segment.start.x + (segment.end.x - segment.start.x) * ratio;
|
|
7337
7469
|
const y = segment.start.y + (segment.end.y - segment.start.y) * ratio;
|
|
7338
|
-
const offset2 = labelOffset2(segment);
|
|
7470
|
+
const offset2 = labelOffset2(segment, baseOffset);
|
|
7339
7471
|
return {
|
|
7340
7472
|
start: segment.start,
|
|
7341
7473
|
end: segment.end,
|
|
@@ -7348,7 +7480,7 @@ function labelSegmentOnPolyline(points) {
|
|
|
7348
7480
|
if (last === void 0) {
|
|
7349
7481
|
return void 0;
|
|
7350
7482
|
}
|
|
7351
|
-
const offset = labelOffset2(last);
|
|
7483
|
+
const offset = labelOffset2(last, baseOffset);
|
|
7352
7484
|
return {
|
|
7353
7485
|
start: last.start,
|
|
7354
7486
|
end: last.end,
|
|
@@ -7370,7 +7502,7 @@ function nonZeroSegments2(points) {
|
|
|
7370
7502
|
}
|
|
7371
7503
|
return segments;
|
|
7372
7504
|
}
|
|
7373
|
-
function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
7505
|
+
function labelPlacementAtRatio(points, ratio, totalLength, baseOffset = 10) {
|
|
7374
7506
|
if (points.length < 2 || ratio < 0 || ratio > 1) {
|
|
7375
7507
|
return void 0;
|
|
7376
7508
|
}
|
|
@@ -7388,7 +7520,10 @@ function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
|
7388
7520
|
}
|
|
7389
7521
|
if (travelled + segLen >= targetDist) {
|
|
7390
7522
|
const t = (targetDist - travelled) / segLen;
|
|
7391
|
-
const offset = labelOffset2(
|
|
7523
|
+
const offset = labelOffset2(
|
|
7524
|
+
{ start: prev, end: curr, length: segLen },
|
|
7525
|
+
baseOffset
|
|
7526
|
+
);
|
|
7392
7527
|
return {
|
|
7393
7528
|
x: prev.x + (curr.x - prev.x) * t + offset.x,
|
|
7394
7529
|
y: prev.y + (curr.y - prev.y) * t + offset.y
|
|
@@ -7398,8 +7533,8 @@ function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
|
7398
7533
|
}
|
|
7399
7534
|
return void 0;
|
|
7400
7535
|
}
|
|
7401
|
-
function labelOffset2(segment) {
|
|
7402
|
-
const offset =
|
|
7536
|
+
function labelOffset2(segment, baseOffset = 10) {
|
|
7537
|
+
const offset = baseOffset;
|
|
7403
7538
|
const dx = segment.end.x - segment.start.x;
|
|
7404
7539
|
const dy = segment.end.y - segment.start.y;
|
|
7405
7540
|
return {
|