@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/cli/index.js
CHANGED
|
@@ -1289,6 +1289,9 @@ function applyLayoutConstraints(input) {
|
|
|
1289
1289
|
const nodeById = new Map(input.nodes.map((node) => [node.id, node]));
|
|
1290
1290
|
applyFixedPositionLocks(input.nodes, boxes, locks, diagnostics);
|
|
1291
1291
|
applyExactPositions(input.constraints, boxes, locks, diagnostics, nodeById);
|
|
1292
|
+
if (input.distributeContainedChildren) {
|
|
1293
|
+
yieldFixedPositionLocks(input, boxes, locks);
|
|
1294
|
+
}
|
|
1292
1295
|
applyContainment(input.constraints, boxes, locks, diagnostics, false);
|
|
1293
1296
|
applyRelative(input.constraints, boxes, locks, diagnostics);
|
|
1294
1297
|
applyAlign(input.constraints, boxes, locks, diagnostics);
|
|
@@ -1302,6 +1305,13 @@ function applyLayoutConstraints(input) {
|
|
|
1302
1305
|
);
|
|
1303
1306
|
applyContainment(input.constraints, boxes, locks, diagnostics, true);
|
|
1304
1307
|
applyDistributeContained(input, boxes, locks, diagnostics);
|
|
1308
|
+
if (input.distributeContainedChildren) {
|
|
1309
|
+
const diagBefore = diagnostics.length;
|
|
1310
|
+
applyContainment(input.constraints, boxes, locks, diagnostics, true);
|
|
1311
|
+
applyDistributeContained(input, boxes, locks, diagnostics);
|
|
1312
|
+
dedupReplayDiagnostics(diagnostics, diagBefore);
|
|
1313
|
+
}
|
|
1314
|
+
removeResolvedConstraintDiagnostics(input.constraints, boxes, diagnostics);
|
|
1305
1315
|
reportOverlaps(boxes, diagnostics, containmentOverlapKeys(input.constraints));
|
|
1306
1316
|
reportIntraContainerOverflow(input, boxes, diagnostics);
|
|
1307
1317
|
return { boxes, locks, diagnostics };
|
|
@@ -1347,6 +1357,62 @@ function applyFixedPositionLocks(nodes, boxes, locks, diagnostics) {
|
|
|
1347
1357
|
locks.set(node.id, { nodeId: node.id, source: "fixed-position" });
|
|
1348
1358
|
}
|
|
1349
1359
|
}
|
|
1360
|
+
function dedupReplayDiagnostics(diagnostics, keepUpTo) {
|
|
1361
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1362
|
+
for (let i = 0; i < keepUpTo && i < diagnostics.length; i += 1) {
|
|
1363
|
+
const d = diagnostics[i];
|
|
1364
|
+
if (d === void 0) continue;
|
|
1365
|
+
seen.add(diagnosticFingerprint(d));
|
|
1366
|
+
}
|
|
1367
|
+
for (let i = diagnostics.length - 1; i >= keepUpTo; i -= 1) {
|
|
1368
|
+
const d = diagnostics[i];
|
|
1369
|
+
if (d === void 0) continue;
|
|
1370
|
+
const fp = diagnosticFingerprint(d);
|
|
1371
|
+
if (seen.has(fp)) {
|
|
1372
|
+
diagnostics.splice(i, 1);
|
|
1373
|
+
} else {
|
|
1374
|
+
seen.add(fp);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
function diagnosticFingerprint(d) {
|
|
1379
|
+
const nodeId = typeof d.detail?.nodeId === "string" ? d.detail.nodeId : "";
|
|
1380
|
+
const containerId = typeof d.detail?.containerId === "string" ? d.detail.containerId : "";
|
|
1381
|
+
return `${d.code}|${nodeId}|${containerId}`;
|
|
1382
|
+
}
|
|
1383
|
+
function yieldFixedPositionLocks(input, boxes, locks) {
|
|
1384
|
+
for (const c of input.constraints) {
|
|
1385
|
+
if (c.kind !== "containment") continue;
|
|
1386
|
+
const container = boxes.get(c.containerId);
|
|
1387
|
+
if (container === void 0) continue;
|
|
1388
|
+
const content = contentBox(container, c.padding);
|
|
1389
|
+
const mainAxis = input.direction === "LR" || input.direction === "RL" ? "width" : "height";
|
|
1390
|
+
const crossAxis = mainAxis === "width" ? "height" : "width";
|
|
1391
|
+
let eligible = 0;
|
|
1392
|
+
for (const childId of c.childIds) {
|
|
1393
|
+
const box = boxes.get(childId);
|
|
1394
|
+
if (box === void 0) continue;
|
|
1395
|
+
const lock = locks.get(childId);
|
|
1396
|
+
if (lock?.source === "exact-position") continue;
|
|
1397
|
+
const fits = box[mainAxis] <= content[mainAxis] && box[crossAxis] <= content[crossAxis];
|
|
1398
|
+
if (fits) {
|
|
1399
|
+
eligible += 1;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
if (eligible < 2) continue;
|
|
1403
|
+
for (const childId of c.childIds) {
|
|
1404
|
+
const lock = locks.get(childId);
|
|
1405
|
+
if (lock?.source === "fixed-position") {
|
|
1406
|
+
const box = boxes.get(childId);
|
|
1407
|
+
if (box === void 0) continue;
|
|
1408
|
+
const fits = box[mainAxis] <= content[mainAxis] && box[crossAxis] <= content[crossAxis];
|
|
1409
|
+
if (fits) {
|
|
1410
|
+
locks.delete(childId);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1350
1416
|
function applyExactPositions(constraints, boxes, locks, diagnostics, nodeById) {
|
|
1351
1417
|
for (const constraint of constraints) {
|
|
1352
1418
|
if (constraint.kind !== "exact-position") {
|
|
@@ -1419,7 +1485,7 @@ function applyContainment(constraints, boxes, locks, diagnostics, reportOverflow
|
|
|
1419
1485
|
code: "constraints.locked-target-not-moved",
|
|
1420
1486
|
message: `Locked child ${childId} was not moved into containment.`,
|
|
1421
1487
|
path: ["constraints", constraint.id ?? constraint.containerId],
|
|
1422
|
-
detail: { nodeId: childId }
|
|
1488
|
+
detail: { nodeId: childId, containerId: constraint.containerId }
|
|
1423
1489
|
});
|
|
1424
1490
|
if (!isInside(child, content)) {
|
|
1425
1491
|
diagnostics.push({
|
|
@@ -1571,6 +1637,60 @@ function repairOverlaps(input, boxes, locks, diagnostics, siblingPairs) {
|
|
|
1571
1637
|
}
|
|
1572
1638
|
reportOverlaps(boxes, diagnostics, ignoredPairs);
|
|
1573
1639
|
}
|
|
1640
|
+
function removeResolvedConstraintDiagnostics(constraints, boxes, diagnostics) {
|
|
1641
|
+
for (let i = diagnostics.length - 1; i >= 0; i -= 1) {
|
|
1642
|
+
const d = diagnostics[i];
|
|
1643
|
+
if (d === void 0) continue;
|
|
1644
|
+
if (d.code === "constraints.overlap.unresolved") {
|
|
1645
|
+
const aId = d.detail?.firstId;
|
|
1646
|
+
const bId = d.detail?.secondId;
|
|
1647
|
+
if (typeof aId !== "string" || typeof bId !== "string") continue;
|
|
1648
|
+
const a = boxes.get(aId);
|
|
1649
|
+
const b = boxes.get(bId);
|
|
1650
|
+
if (a !== void 0 && b !== void 0 && !intersectsAabb(a, b)) {
|
|
1651
|
+
diagnostics.splice(i, 1);
|
|
1652
|
+
}
|
|
1653
|
+
continue;
|
|
1654
|
+
}
|
|
1655
|
+
if (d.code === "constraints.containment.impossible" || d.code === "constraints.locked-target-not-moved" && typeof d.message === "string" && d.message.includes("not moved into containment")) {
|
|
1656
|
+
const nodeId = d.detail?.nodeId;
|
|
1657
|
+
if (typeof nodeId !== "string") continue;
|
|
1658
|
+
const child = boxes.get(nodeId);
|
|
1659
|
+
if (child === void 0) continue;
|
|
1660
|
+
const diagContainerId = typeof d.detail?.containerId === "string" ? d.detail.containerId : void 0;
|
|
1661
|
+
let resolved = false;
|
|
1662
|
+
for (const c of constraints) {
|
|
1663
|
+
if (c.kind !== "containment") continue;
|
|
1664
|
+
if (!c.childIds.includes(nodeId)) continue;
|
|
1665
|
+
if (diagContainerId !== void 0 && c.containerId !== diagContainerId) {
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
const container = boxes.get(c.containerId);
|
|
1669
|
+
if (container === void 0) continue;
|
|
1670
|
+
const content = contentBox(container, c.padding);
|
|
1671
|
+
if (isInside(child, content)) {
|
|
1672
|
+
diagnostics.splice(i, 1);
|
|
1673
|
+
resolved = true;
|
|
1674
|
+
}
|
|
1675
|
+
break;
|
|
1676
|
+
}
|
|
1677
|
+
if (!resolved && diagContainerId !== void 0) {
|
|
1678
|
+
for (const c of constraints) {
|
|
1679
|
+
if (c.kind !== "containment") continue;
|
|
1680
|
+
if (c.containerId !== diagContainerId) continue;
|
|
1681
|
+
if (!c.childIds.includes(nodeId)) continue;
|
|
1682
|
+
const container = boxes.get(c.containerId);
|
|
1683
|
+
if (container === void 0) continue;
|
|
1684
|
+
const content = contentBox(container, c.padding);
|
|
1685
|
+
if (isInside(child, content)) {
|
|
1686
|
+
diagnostics.splice(i, 1);
|
|
1687
|
+
}
|
|
1688
|
+
break;
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1574
1694
|
function reportOverlaps(boxes, diagnostics, ignoredPairs = /* @__PURE__ */ new Set()) {
|
|
1575
1695
|
const ids = [...boxes.keys()].sort();
|
|
1576
1696
|
const reported = new Set(
|
|
@@ -1878,6 +1998,12 @@ function applyDistributeContained(input, boxes, locks, diagnostics) {
|
|
|
1878
1998
|
continue;
|
|
1879
1999
|
}
|
|
1880
2000
|
if (locks.has(childId)) {
|
|
2001
|
+
const lock = locks.get(childId);
|
|
2002
|
+
if (lock?.source === "fixed-position") {
|
|
2003
|
+
unlocked.push({ id: childId, box });
|
|
2004
|
+
locks.delete(childId);
|
|
2005
|
+
continue;
|
|
2006
|
+
}
|
|
1881
2007
|
diagnostics.push({
|
|
1882
2008
|
severity: "warning",
|
|
1883
2009
|
code: "constraints.locked-target-not-moved",
|
|
@@ -1936,6 +2062,7 @@ function applyDistributeContained(input, boxes, locks, diagnostics) {
|
|
|
1936
2062
|
});
|
|
1937
2063
|
}
|
|
1938
2064
|
boxes.set(child.id, clamped);
|
|
2065
|
+
locks.delete(child.id);
|
|
1939
2066
|
pos = clamped[axis] + clamped[mainSize] + minGap;
|
|
1940
2067
|
}
|
|
1941
2068
|
diagnostics.push({
|
|
@@ -3256,6 +3383,7 @@ function routeEdge(input) {
|
|
|
3256
3383
|
const diagnostics = [];
|
|
3257
3384
|
const softObstacles = input.obstacles ?? [];
|
|
3258
3385
|
const hardObstacles = input.hardObstacles ?? [];
|
|
3386
|
+
const maxAttempts = input.maxRoutingAttempts ?? 5;
|
|
3259
3387
|
const defaultAnchors = defaultAnchorsForGeometry(
|
|
3260
3388
|
input.source.box,
|
|
3261
3389
|
input.target.box,
|
|
@@ -3364,7 +3492,7 @@ function routeEdge(input) {
|
|
|
3364
3492
|
const rerouted2 = greedyRerouteAroundObstacles(
|
|
3365
3493
|
candidate.points,
|
|
3366
3494
|
allObstacles,
|
|
3367
|
-
|
|
3495
|
+
maxAttempts
|
|
3368
3496
|
);
|
|
3369
3497
|
if (!routeCrossesBoxes(rerouted2, allObstacles) && !routeIntersectsEndpointInteriors(
|
|
3370
3498
|
rerouted2,
|
|
@@ -3384,7 +3512,7 @@ function routeEdge(input) {
|
|
|
3384
3512
|
const rerouted = greedyRerouteAroundObstacles(
|
|
3385
3513
|
bestPoints2,
|
|
3386
3514
|
allObstacles,
|
|
3387
|
-
|
|
3515
|
+
maxAttempts
|
|
3388
3516
|
);
|
|
3389
3517
|
const reroutedAvoidsEndpointInteriors = !routeIntersectsEndpointInteriors(
|
|
3390
3518
|
rerouted,
|
|
@@ -3419,7 +3547,7 @@ function routeEdge(input) {
|
|
|
3419
3547
|
const rerouted = greedyRerouteAroundObstacles(
|
|
3420
3548
|
candidate.points,
|
|
3421
3549
|
allObstacles,
|
|
3422
|
-
|
|
3550
|
+
maxAttempts
|
|
3423
3551
|
);
|
|
3424
3552
|
if (!routeCrossesBoxes(rerouted, allObstacles)) {
|
|
3425
3553
|
return {
|
|
@@ -3436,7 +3564,7 @@ function routeEdge(input) {
|
|
|
3436
3564
|
bestPoints2 = greedyRerouteAroundObstacles(
|
|
3437
3565
|
candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors),
|
|
3438
3566
|
allObstacles,
|
|
3439
|
-
|
|
3567
|
+
maxAttempts
|
|
3440
3568
|
);
|
|
3441
3569
|
}
|
|
3442
3570
|
diagnostics.push({
|
|
@@ -3461,7 +3589,7 @@ function routeEdge(input) {
|
|
|
3461
3589
|
const rerouted = greedyRerouteAroundObstacles(
|
|
3462
3590
|
candidate.points,
|
|
3463
3591
|
allObstacles,
|
|
3464
|
-
|
|
3592
|
+
maxAttempts
|
|
3465
3593
|
);
|
|
3466
3594
|
if (!routeCrossesBoxes(rerouted, allObstacles)) {
|
|
3467
3595
|
return {
|
|
@@ -3478,7 +3606,7 @@ function routeEdge(input) {
|
|
|
3478
3606
|
bestPoints = greedyRerouteAroundObstacles(
|
|
3479
3607
|
candidateRoutes[0]?.points ?? fallbackRoute(input, defaultAnchors),
|
|
3480
3608
|
allObstacles,
|
|
3481
|
-
|
|
3609
|
+
maxAttempts
|
|
3482
3610
|
);
|
|
3483
3611
|
}
|
|
3484
3612
|
diagnostics.push({
|
|
@@ -4146,9 +4274,7 @@ function solveDiagram(diagram, options = {}) {
|
|
|
4146
4274
|
options?.overlapSpacing ?? 40,
|
|
4147
4275
|
Math.max(0, options?.minLaneGutter ?? 0)
|
|
4148
4276
|
);
|
|
4149
|
-
|
|
4150
|
-
removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
|
|
4151
|
-
}
|
|
4277
|
+
removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
|
|
4152
4278
|
diagnostics.push(...swimlaneContracts.diagnostics);
|
|
4153
4279
|
const coordinatedNodes = coordinateNodes(
|
|
4154
4280
|
styledNodes,
|
|
@@ -4313,7 +4439,9 @@ function solveDiagram(diagram, options = {}) {
|
|
|
4313
4439
|
...baseTextAnnotations.map((annotation) => annotation.box),
|
|
4314
4440
|
...frameTextAnnotation.map((annotation) => annotation.box)
|
|
4315
4441
|
],
|
|
4316
|
-
options.textMeasurer
|
|
4442
|
+
options.textMeasurer,
|
|
4443
|
+
options.labelPlacement,
|
|
4444
|
+
options.labelOffset
|
|
4317
4445
|
);
|
|
4318
4446
|
const textAnnotations = [
|
|
4319
4447
|
...baseTextAnnotations,
|
|
@@ -6089,7 +6217,8 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
|
|
|
6089
6217
|
...softObstacles,
|
|
6090
6218
|
...routeTextObstacles
|
|
6091
6219
|
],
|
|
6092
|
-
hardObstacles
|
|
6220
|
+
hardObstacles,
|
|
6221
|
+
...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts }
|
|
6093
6222
|
});
|
|
6094
6223
|
diagnostics.push(
|
|
6095
6224
|
...route.diagnostics.map((diagnostic) => ({
|
|
@@ -6251,7 +6380,8 @@ function coordinateBaseTextAnnotations(input) {
|
|
|
6251
6380
|
}
|
|
6252
6381
|
return annotations;
|
|
6253
6382
|
}
|
|
6254
|
-
function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer) {
|
|
6383
|
+
function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer, labelPlacement, labelOffset3) {
|
|
6384
|
+
const labelBaseOffset = labelPlacement === "beside" ? labelOffset3 ?? 16 : 10;
|
|
6255
6385
|
const measurer = textMeasurer ?? createDefaultTextMeasurer();
|
|
6256
6386
|
const annotations = [];
|
|
6257
6387
|
const placedLabelBoxes = [];
|
|
@@ -6278,7 +6408,8 @@ function coordinateEdgeTextAnnotations(edges, obstacleBoxes, textMeasurer) {
|
|
|
6278
6408
|
layout2,
|
|
6279
6409
|
edges,
|
|
6280
6410
|
obstacleBoxes,
|
|
6281
|
-
placedLabelBoxes
|
|
6411
|
+
placedLabelBoxes,
|
|
6412
|
+
labelBaseOffset
|
|
6282
6413
|
);
|
|
6283
6414
|
placedLabelBoxes.push({
|
|
6284
6415
|
x: center.x - layout2.box.width / 2,
|
|
@@ -6562,15 +6693,16 @@ function fallbackLabelLayout(text) {
|
|
|
6562
6693
|
diagnostics: []
|
|
6563
6694
|
};
|
|
6564
6695
|
}
|
|
6565
|
-
function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes) {
|
|
6566
|
-
const placement = labelPlacementOnPolyline2(edge.points);
|
|
6696
|
+
function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes, baseOffset = 10) {
|
|
6697
|
+
const placement = labelPlacementOnPolyline2(edge.points, baseOffset);
|
|
6567
6698
|
if (placement === void 0) {
|
|
6568
6699
|
return { x: 0, y: 0 };
|
|
6569
6700
|
}
|
|
6570
6701
|
for (const candidate of edgeLabelAnchorCandidates(
|
|
6571
6702
|
edge.points,
|
|
6572
6703
|
placement,
|
|
6573
|
-
layout2
|
|
6704
|
+
layout2,
|
|
6705
|
+
baseOffset
|
|
6574
6706
|
)) {
|
|
6575
6707
|
const labelBox = {
|
|
6576
6708
|
x: candidate.x - layout2.box.width / 2,
|
|
@@ -6602,8 +6734,8 @@ function edgeLabelAnchor(edge, layout2, edges, obstacleBoxes, placedLabelBoxes)
|
|
|
6602
6734
|
}
|
|
6603
6735
|
return placement;
|
|
6604
6736
|
}
|
|
6605
|
-
function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
6606
|
-
const segment = labelSegmentOnPolyline(points);
|
|
6737
|
+
function edgeLabelAnchorCandidates(points, placement, layout2, baseOffset = 10) {
|
|
6738
|
+
const segment = labelSegmentOnPolyline(points, baseOffset);
|
|
6607
6739
|
if (segment === void 0) {
|
|
6608
6740
|
return [placement];
|
|
6609
6741
|
}
|
|
@@ -6653,7 +6785,7 @@ function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
|
6653
6785
|
}, 0);
|
|
6654
6786
|
if (totalLen > 200) {
|
|
6655
6787
|
for (const ratio of [0.25, 0.75]) {
|
|
6656
|
-
const qp = labelPlacementAtRatio(points, ratio, totalLen);
|
|
6788
|
+
const qp = labelPlacementAtRatio(points, ratio, totalLen, baseOffset);
|
|
6657
6789
|
if (qp !== void 0) {
|
|
6658
6790
|
candidates.push(qp);
|
|
6659
6791
|
const qTargetDist = totalLen * ratio;
|
|
@@ -6708,10 +6840,10 @@ function edgeLabelAnchorCandidates(points, placement, layout2) {
|
|
|
6708
6840
|
}
|
|
6709
6841
|
return candidates;
|
|
6710
6842
|
}
|
|
6711
|
-
function labelPlacementOnPolyline2(points) {
|
|
6712
|
-
return labelSegmentOnPolyline(points)?.placement;
|
|
6843
|
+
function labelPlacementOnPolyline2(points, baseOffset = 10) {
|
|
6844
|
+
return labelSegmentOnPolyline(points, baseOffset)?.placement;
|
|
6713
6845
|
}
|
|
6714
|
-
function labelSegmentOnPolyline(points) {
|
|
6846
|
+
function labelSegmentOnPolyline(points, baseOffset = 10) {
|
|
6715
6847
|
const segments = nonZeroSegments2(points);
|
|
6716
6848
|
const totalLength = segments.reduce(
|
|
6717
6849
|
(sum, segment) => sum + segment.length,
|
|
@@ -6726,7 +6858,7 @@ function labelSegmentOnPolyline(points) {
|
|
|
6726
6858
|
const ratio = remaining / segment.length;
|
|
6727
6859
|
const x = segment.start.x + (segment.end.x - segment.start.x) * ratio;
|
|
6728
6860
|
const y = segment.start.y + (segment.end.y - segment.start.y) * ratio;
|
|
6729
|
-
const offset2 = labelOffset2(segment);
|
|
6861
|
+
const offset2 = labelOffset2(segment, baseOffset);
|
|
6730
6862
|
return {
|
|
6731
6863
|
start: segment.start,
|
|
6732
6864
|
end: segment.end,
|
|
@@ -6739,7 +6871,7 @@ function labelSegmentOnPolyline(points) {
|
|
|
6739
6871
|
if (last === void 0) {
|
|
6740
6872
|
return void 0;
|
|
6741
6873
|
}
|
|
6742
|
-
const offset = labelOffset2(last);
|
|
6874
|
+
const offset = labelOffset2(last, baseOffset);
|
|
6743
6875
|
return {
|
|
6744
6876
|
start: last.start,
|
|
6745
6877
|
end: last.end,
|
|
@@ -6761,7 +6893,7 @@ function nonZeroSegments2(points) {
|
|
|
6761
6893
|
}
|
|
6762
6894
|
return segments;
|
|
6763
6895
|
}
|
|
6764
|
-
function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
6896
|
+
function labelPlacementAtRatio(points, ratio, totalLength, baseOffset = 10) {
|
|
6765
6897
|
if (points.length < 2 || ratio < 0 || ratio > 1) {
|
|
6766
6898
|
return void 0;
|
|
6767
6899
|
}
|
|
@@ -6779,7 +6911,10 @@ function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
|
6779
6911
|
}
|
|
6780
6912
|
if (travelled + segLen >= targetDist) {
|
|
6781
6913
|
const t = (targetDist - travelled) / segLen;
|
|
6782
|
-
const offset = labelOffset2(
|
|
6914
|
+
const offset = labelOffset2(
|
|
6915
|
+
{ start: prev, end: curr, length: segLen },
|
|
6916
|
+
baseOffset
|
|
6917
|
+
);
|
|
6783
6918
|
return {
|
|
6784
6919
|
x: prev.x + (curr.x - prev.x) * t + offset.x,
|
|
6785
6920
|
y: prev.y + (curr.y - prev.y) * t + offset.y
|
|
@@ -6789,8 +6924,8 @@ function labelPlacementAtRatio(points, ratio, totalLength) {
|
|
|
6789
6924
|
}
|
|
6790
6925
|
return void 0;
|
|
6791
6926
|
}
|
|
6792
|
-
function labelOffset2(segment) {
|
|
6793
|
-
const offset =
|
|
6927
|
+
function labelOffset2(segment, baseOffset = 10) {
|
|
6928
|
+
const offset = baseOffset;
|
|
6794
6929
|
const dx = segment.end.x - segment.start.x;
|
|
6795
6930
|
const dy = segment.end.y - segment.start.y;
|
|
6796
6931
|
return {
|