@jbrowse/bandage-core 11.8.0 → 11.9.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/dist/bubbles/bubbleHalos.js +6 -6
- package/dist/bubbles/classifyBubble.js +5 -5
- package/dist/bubbles/superbubbles.js +7 -7
- package/dist/chunks/{chunk-S4CH434Z.js → chunk-2A6Z2DHF.js} +1 -1
- package/dist/chunks/{chunk-6MD4VS2F.js → chunk-2MXFG3W7.js} +1 -1
- package/dist/chunks/{chunk-7GDNDQD7.js → chunk-3BDQQTXY.js} +163 -99
- package/dist/chunks/{chunk-MO4DIRHD.js → chunk-3BOREHCJ.js} +13 -13
- package/dist/chunks/{chunk-2RCKHCF7.js → chunk-3DHGSHC3.js} +1 -1
- package/dist/chunks/{chunk-3CXZUC2Y.js → chunk-3GORESBG.js} +1 -1
- package/dist/chunks/{chunk-R4XCTRIU.js → chunk-4BYGFDQB.js} +1 -1
- package/dist/chunks/{chunk-NHOXLUIL.js → chunk-4JDO7ZLN.js} +2 -2
- package/dist/chunks/{chunk-7PEYA3NA.js → chunk-7YSIP3O2.js} +2 -2
- package/dist/chunks/{chunk-3XYLEK4H.js → chunk-ARXDNQLF.js} +1 -1
- package/dist/chunks/{chunk-6CXLLJ2C.js → chunk-AURNOR27.js} +3 -3
- package/dist/chunks/{chunk-G4WQBRDS.js → chunk-BDS5VZYZ.js} +3 -3
- package/dist/chunks/{chunk-2H3ALI6L.js → chunk-GDZQFELP.js} +180 -159
- package/dist/chunks/{chunk-ZKIH2USC.js → chunk-GYJMPVOU.js} +1 -1
- package/dist/chunks/{chunk-X5ULFAMM.js → chunk-HEYIAMTC.js} +2 -2
- package/dist/chunks/{chunk-S7BCZVRK.js → chunk-HIN56TLA.js} +1 -1
- package/dist/chunks/{chunk-YIWN32ZX.js → chunk-HNNP5QUN.js} +1 -1
- package/dist/chunks/{chunk-XOIYBEU7.js → chunk-I53QYITQ.js} +1 -1
- package/dist/chunks/{chunk-R3NPBUKT.js → chunk-I5CHAYDZ.js} +7 -7
- package/dist/chunks/{chunk-LA6JHEVV.js → chunk-IXLT3JJX.js} +1 -1
- package/dist/chunks/{chunk-SDDMV2MM.js → chunk-IZKM4NY7.js} +1 -1
- package/dist/chunks/{chunk-SIXFXXRI.js → chunk-J7RNXBXA.js} +3 -3
- package/dist/chunks/{chunk-735MPLUL.js → chunk-JJV2GT2Z.js} +22 -14
- package/dist/chunks/{chunk-4OVIUCSB.js → chunk-JO2T77NW.js} +1 -1
- package/dist/chunks/{chunk-S3ICPPXC.js → chunk-JVT3XTKN.js} +3 -3
- package/dist/chunks/{chunk-J4PDHWP2.js → chunk-KKHXMJEE.js} +1 -1
- package/dist/chunks/{chunk-L2RQV23D.js → chunk-N3DCLT7M.js} +1 -1
- package/dist/chunks/{chunk-22ZMVREZ.js → chunk-NAYS472K.js} +1 -1
- package/dist/chunks/{chunk-OIOAK7BS.js → chunk-NWEVR2OQ.js} +1 -1
- package/dist/chunks/{chunk-VSRRIFRF.js → chunk-P2GJBFNA.js} +1 -1
- package/dist/chunks/{chunk-N2GAA7RB.js → chunk-RT4U3DH3.js} +1 -1
- package/dist/chunks/{chunk-AXE3RR7J.js → chunk-S6E3PMH7.js} +1 -1
- package/dist/chunks/{chunk-4YPCUVMC.js → chunk-SZYFZNCO.js} +2 -2
- package/dist/chunks/{chunk-U6JPSXJ3.js → chunk-T2UNTWU5.js} +9 -9
- package/dist/chunks/{chunk-G3GLGDKV.js → chunk-TQ26XEFL.js} +2 -2
- package/dist/chunks/{chunk-N4AJV4GH.js → chunk-UEWIGD52.js} +36 -10
- package/dist/chunks/{chunk-YEDZ37PH.js → chunk-VNCHWWLG.js} +1 -1
- package/dist/chunks/{chunk-JKIAHYAW.js → chunk-VQ353UDK.js} +1 -1
- package/dist/chunks/{chunk-NQWEYJDD.js → chunk-VTGQCLGI.js} +1 -1
- package/dist/chunks/{chunk-YF6T33PU.js → chunk-ZWBQ4RRK.js} +16 -10
- package/dist/cli/figure.js +28 -28
- package/dist/cli/fold.js +6 -6
- package/dist/deletionEdges.js +2 -2
- package/dist/figure.js +24 -24
- package/dist/figureData.js +22 -22
- package/dist/figureScene.js +15 -15
- package/dist/figureSettings.js +6 -6
- package/dist/foldVariants.js +2 -2
- package/dist/genes/genePins.js +3 -3
- package/dist/graphLabels.js +4 -4
- package/dist/index.js +38 -38
- package/dist/labelLayout.js +8 -8
- package/dist/layout/forceCache.js +6 -6
- package/dist/layout/mergeRuns.js +2 -2
- package/dist/layout/orientToReference.js +2 -2
- package/dist/layout/tubeMapLayout.js +7 -7
- package/dist/layout/walkRowDraw.js +9 -9
- package/dist/layout/walkStrip.js +10 -10
- package/dist/layoutModes.js +8 -8
- package/dist/pathColors.js +5 -5
- package/dist/pipeline.js +5 -5
- package/dist/referenceStrip.js +9 -9
- package/dist/renderer/GeometryBuilder.js +8 -8
- package/dist/renderer/walkLanes.js +4 -2
- package/dist/tubeMap/axis.js +5 -5
- package/dist/tubeMap/bundle.js +8 -8
- package/dist/tubeMap/coarsen.js +8 -8
- package/dist/tubeMap/deviations.js +9 -9
- package/dist/tubeMap/draw.js +3 -3
- package/dist/tubeMap/genes.js +6 -6
- package/dist/tubeMap/nodeColors.js +9 -9
- package/dist/tubeMap/reads.js +2 -2
- package/dist/types/renderer/walkLanes.d.ts +18 -2
- package/dist/types/util/geometry.d.ts +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/walkEncoding.d.ts +4 -2
- package/dist/util/SpatialIndex.js +4 -4
- package/dist/util/edgeCurves.js +3 -3
- package/dist/util/geometry.js +1 -1
- package/dist/util/hitDetection.js +5 -5
- package/dist/version.js +1 -1
- package/dist/viewport.js +6 -6
- package/dist/walkEncoding.js +13 -11
- package/dist/walkHighlight.js +10 -10
- package/dist/walkKey.js +5 -5
- package/package.json +1 -1
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
LANE_SMOOTHING_PX,
|
|
3
2
|
THREAD_PITCH_PX,
|
|
4
3
|
THREAD_PX,
|
|
5
|
-
THREAD_REACH_PX,
|
|
6
|
-
THREAD_TAPER_PX,
|
|
7
4
|
bandScale,
|
|
8
|
-
bandSpans,
|
|
9
5
|
bandWidthPx,
|
|
10
|
-
laneLines,
|
|
11
|
-
laneRuns,
|
|
12
6
|
laneSlideAt,
|
|
7
|
+
liftLanes,
|
|
13
8
|
slotCentres,
|
|
14
|
-
threadsPasses
|
|
15
|
-
|
|
16
|
-
} from "./chunk-7GDNDQD7.js";
|
|
9
|
+
threadsPasses
|
|
10
|
+
} from "./chunk-3BDQQTXY.js";
|
|
17
11
|
import {
|
|
18
12
|
abgrToCssRgba,
|
|
19
13
|
fadeAbgr,
|
|
@@ -26,13 +20,13 @@ import {
|
|
|
26
20
|
} from "./chunk-GQZVR5DW.js";
|
|
27
21
|
import {
|
|
28
22
|
baseEdgeCurves
|
|
29
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-P2GJBFNA.js";
|
|
30
24
|
import {
|
|
31
25
|
PATH_LIGHTNESS,
|
|
32
26
|
PATH_SATURATION,
|
|
33
27
|
nameHue,
|
|
34
28
|
pathHueAt
|
|
35
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-VQ353UDK.js";
|
|
36
30
|
import {
|
|
37
31
|
meanDepth,
|
|
38
32
|
nodeWidthPx,
|
|
@@ -41,6 +35,9 @@ import {
|
|
|
41
35
|
import {
|
|
42
36
|
referenceMidpoints
|
|
43
37
|
} from "./chunk-VX656OAZ.js";
|
|
38
|
+
import {
|
|
39
|
+
weakMemo
|
|
40
|
+
} from "./chunk-HMXCN6PG.js";
|
|
44
41
|
import {
|
|
45
42
|
dashSpans,
|
|
46
43
|
pathRibbonOffsets,
|
|
@@ -49,7 +46,7 @@ import {
|
|
|
49
46
|
strandSides,
|
|
50
47
|
translateCurves,
|
|
51
48
|
yToXOf
|
|
52
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-JJV2GT2Z.js";
|
|
53
50
|
import {
|
|
54
51
|
pushTo
|
|
55
52
|
} from "./chunk-BSOZW3FC.js";
|
|
@@ -194,6 +191,8 @@ function normal(a, b) {
|
|
|
194
191
|
const len = Math.hypot(dx, dy);
|
|
195
192
|
return len > 0 ? { nx: -dy / len, ny: dx / len } : void 0;
|
|
196
193
|
}
|
|
194
|
+
var MITRE_LIMIT = 0.1;
|
|
195
|
+
var LONGEST_NORMAL = 1 / Math.sqrt(MITRE_LIMIT);
|
|
197
196
|
function pointNormalsOf(rawPoints, yToX = 1) {
|
|
198
197
|
const points = yToX === 1 ? rawPoints : rawPoints.map((p) => ({ x: p.x, y: p.y * yToX }));
|
|
199
198
|
return points.map((p, i) => {
|
|
@@ -203,16 +202,20 @@ function pointNormalsOf(rawPoints, yToX = 1) {
|
|
|
203
202
|
const nx = (before.nx + after.nx) / 2;
|
|
204
203
|
const ny = (before.ny + after.ny) / 2;
|
|
205
204
|
const dot = before.nx * nx + before.ny * ny;
|
|
206
|
-
return dot >
|
|
205
|
+
return dot > MITRE_LIMIT ? { nx: nx / dot, ny: ny / dot } : { nx, ny };
|
|
207
206
|
}
|
|
208
207
|
return before ?? after ?? { nx: 0, ny: 0 };
|
|
209
208
|
});
|
|
210
209
|
}
|
|
211
210
|
function offsetPolyline(points, normals, distance, yToX = 1) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
const out = new Array(points.length);
|
|
212
|
+
for (let i = 0; i < points.length; i++) {
|
|
213
|
+
out[i] = {
|
|
214
|
+
x: points[i].x + normals[i].nx * distance,
|
|
215
|
+
y: points[i].y + normals[i].ny * distance / yToX
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return out;
|
|
216
219
|
}
|
|
217
220
|
function hslToRgb(h, s, l) {
|
|
218
221
|
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
@@ -413,13 +416,13 @@ function isPolylineInBounds(segments, bounds) {
|
|
|
413
416
|
}
|
|
414
417
|
return hit;
|
|
415
418
|
}
|
|
416
|
-
function isBezierInBounds(curves, bounds) {
|
|
419
|
+
function isBezierInBounds(curves, bounds, growX = 0, growY = 0) {
|
|
417
420
|
for (const c of curves) {
|
|
418
421
|
const cMinX = Math.min(c.x0, c.cx0, c.cx1, c.x1);
|
|
419
422
|
const cMaxX = Math.max(c.x0, c.cx0, c.cx1, c.x1);
|
|
420
423
|
const cMinY = Math.min(c.y0, c.cy0, c.cy1, c.y1);
|
|
421
424
|
const cMaxY = Math.max(c.y0, c.cy0, c.cy1, c.y1);
|
|
422
|
-
if (cMaxX >= bounds.minX && cMinX <= bounds.maxX && cMaxY >= bounds.minY && cMinY <= bounds.maxY) {
|
|
425
|
+
if (cMaxX >= bounds.minX - growX && cMinX <= bounds.maxX + growX && cMaxY >= bounds.minY - growY && cMinY <= bounds.maxY + growY) {
|
|
423
426
|
return true;
|
|
424
427
|
}
|
|
425
428
|
}
|
|
@@ -465,6 +468,24 @@ function pathSlotsOf(graph) {
|
|
|
465
468
|
}
|
|
466
469
|
return slots;
|
|
467
470
|
}
|
|
471
|
+
var lanesCache = weakMemo();
|
|
472
|
+
var linksCache = /* @__PURE__ */ new WeakMap();
|
|
473
|
+
function linksOf(graph) {
|
|
474
|
+
let links = linksCache.get(graph);
|
|
475
|
+
if (!links) {
|
|
476
|
+
links = /* @__PURE__ */ new Map();
|
|
477
|
+
for (const { from, to } of graph.edges) {
|
|
478
|
+
let out = links.get(from);
|
|
479
|
+
if (!out) {
|
|
480
|
+
out = /* @__PURE__ */ new Set();
|
|
481
|
+
links.set(from, out);
|
|
482
|
+
}
|
|
483
|
+
out.add(to);
|
|
484
|
+
}
|
|
485
|
+
linksCache.set(graph, links);
|
|
486
|
+
}
|
|
487
|
+
return links;
|
|
488
|
+
}
|
|
468
489
|
function buildGeometry(options) {
|
|
469
490
|
const {
|
|
470
491
|
nodePositions,
|
|
@@ -520,53 +541,26 @@ function buildGeometry(options) {
|
|
|
520
541
|
const threaded = threadsPasses(liftedWalks);
|
|
521
542
|
const lanePasses = liftedWalks.map((w) => w.mostPasses);
|
|
522
543
|
const thinned = threaded ? bandScale(lanePasses) : 1;
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
nodePositions,
|
|
526
|
-
yToX,
|
|
527
|
-
LANE_SMOOTHING_PX * worldPerScreenPx
|
|
528
|
-
) : void 0;
|
|
529
|
-
const lines = runs ? laneLines(
|
|
530
|
-
runs,
|
|
531
|
-
nodePositions,
|
|
532
|
-
yToX,
|
|
533
|
-
LANE_SMOOTHING_PX * worldPerScreenPx,
|
|
534
|
-
bandWidthPx(lanePasses) * thinned * worldPerScreenPx,
|
|
535
|
-
threaded
|
|
536
|
-
) : void 0;
|
|
537
|
-
const threads = threaded ? liftedWalks.map(
|
|
538
|
-
(w) => walkThreads(
|
|
539
|
-
w.route,
|
|
540
|
-
w.passes,
|
|
541
|
-
nodePositions,
|
|
542
|
-
yToX,
|
|
543
|
-
THREAD_REACH_PX * worldPerScreenPx
|
|
544
|
-
)
|
|
545
|
-
) : void 0;
|
|
546
|
-
const spanField = runs && threads ? bandSpans(
|
|
547
|
-
runs,
|
|
548
|
-
threads.map((t) => t.span),
|
|
549
|
-
{
|
|
550
|
-
reach: THREAD_REACH_PX * worldPerScreenPx,
|
|
551
|
-
taper: THREAD_TAPER_PX * worldPerScreenPx
|
|
552
|
-
}
|
|
544
|
+
const fields = highlight && liftedWalks.length > 1 ? lanesCache(
|
|
545
|
+
highlight,
|
|
546
|
+
[nodePositions, version, axis.scaleX, axis.scaleY],
|
|
547
|
+
() => liftLanes(liftedWalks, nodePositions, yToX, worldPerScreenPx)
|
|
553
548
|
) : void 0;
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
|
|
549
|
+
const lines = fields?.lines;
|
|
550
|
+
const threads = fields?.threads;
|
|
551
|
+
const spanField = fields?.spans;
|
|
552
|
+
const plainCentres = threaded ? slotCentres(lanePasses, lanePasses) : [];
|
|
557
553
|
const centresByNode = /* @__PURE__ */ new Map();
|
|
558
|
-
const
|
|
559
|
-
if (!threaded) {
|
|
560
|
-
return (lane - (liftedWalks.length - 1) / 2) * laneWidth;
|
|
561
|
-
}
|
|
554
|
+
const centresOf = (nodeId) => {
|
|
562
555
|
let centres = centresByNode.get(nodeId);
|
|
563
556
|
if (!centres) {
|
|
564
557
|
const spans = spanField?.get(nodeId);
|
|
565
|
-
centres = slotCentres(spans
|
|
558
|
+
centres = spans ? slotCentres(spans.slot, lanePasses, spans.held) : plainCentres;
|
|
566
559
|
centresByNode.set(nodeId, centres);
|
|
567
560
|
}
|
|
568
|
-
return
|
|
561
|
+
return centres;
|
|
569
562
|
};
|
|
563
|
+
const laneOffset = (nodeId, laneWidth, lane, pass) => threaded ? (centresOf(nodeId)[lane] + pass * THREAD_PITCH_PX) * thinned : (lane - (liftedWalks.length - 1) / 2) * laneWidth;
|
|
570
564
|
const laneHalfWidth = (laneWidth) => threaded ? THREAD_PX / 2 * thinned : laneWidth / 2;
|
|
571
565
|
const laneNormals = /* @__PURE__ */ new Map();
|
|
572
566
|
const laneNormalsOf = (nodeId, segments) => {
|
|
@@ -579,7 +573,54 @@ function buildGeometry(options) {
|
|
|
579
573
|
return normals;
|
|
580
574
|
};
|
|
581
575
|
const laneWidths = /* @__PURE__ */ new Map();
|
|
576
|
+
const laneWidthOf = (id) => {
|
|
577
|
+
let width = laneWidths.get(id);
|
|
578
|
+
if (width === void 0) {
|
|
579
|
+
const node = nodeById.get(id);
|
|
580
|
+
width = walkLaneWidthPx(
|
|
581
|
+
node ? nodeWidthPx(node, contigThickness, nodeWidth, depthNorm) : contigThickness,
|
|
582
|
+
liftedWalks.length
|
|
583
|
+
);
|
|
584
|
+
laneWidths.set(id, width);
|
|
585
|
+
}
|
|
586
|
+
return width;
|
|
587
|
+
};
|
|
582
588
|
const laneShiftOf = (nodeId, index) => lines?.shifts.get(nodeId)?.[index] ?? NO_SHIFT;
|
|
589
|
+
const laneEndOf = (id, segments, atStart) => {
|
|
590
|
+
const at = atStart ? 0 : segments.length - 1;
|
|
591
|
+
return {
|
|
592
|
+
id,
|
|
593
|
+
laneWidth: laneWidthOf(id),
|
|
594
|
+
normal: laneNormalsOf(id, segments)[at] ?? { nx: 0, ny: 0 },
|
|
595
|
+
shift: laneShiftOf(id, at)
|
|
596
|
+
};
|
|
597
|
+
};
|
|
598
|
+
const lanesMayShow = (curves, fromId) => {
|
|
599
|
+
if (!viewportBounds) {
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
const offset = threaded ? bandWidthPx(lanePasses) * thinned : (liftedWalks.length - 1) / 2 * laneWidthOf(fromId);
|
|
603
|
+
const reach = LONGEST_NORMAL * offset * worldPerScreenPx;
|
|
604
|
+
return isBezierInBounds(
|
|
605
|
+
curves,
|
|
606
|
+
viewportBounds,
|
|
607
|
+
reach + (fields?.furthestShift.dx ?? 0),
|
|
608
|
+
reach / yToX + (fields?.furthestShift.dy ?? 0)
|
|
609
|
+
);
|
|
610
|
+
};
|
|
611
|
+
const threadPairs = (lane, from, to) => {
|
|
612
|
+
const own = threads?.[lane]?.linkThreads;
|
|
613
|
+
if (!own?.size) {
|
|
614
|
+
return FIRST_THREADS;
|
|
615
|
+
}
|
|
616
|
+
const ahead = own.get(from)?.get(to);
|
|
617
|
+
const back = linksOf(graph).get(to)?.has(from) ? void 0 : own.get(to)?.get(from);
|
|
618
|
+
if (!back) {
|
|
619
|
+
return ahead ?? FIRST_THREADS;
|
|
620
|
+
}
|
|
621
|
+
const turned = back.map(([a, b]) => [b, a]);
|
|
622
|
+
return ahead ? [...ahead, ...turned] : turned;
|
|
623
|
+
};
|
|
583
624
|
const lanePointsOf = (nodeId, segments) => lines?.shifts.has(nodeId) ? segments.map((p, i) => {
|
|
584
625
|
const { dx, dy } = laneShiftOf(nodeId, i);
|
|
585
626
|
return { ...p, x: p.x + dx, y: p.y + dy };
|
|
@@ -604,37 +645,47 @@ function buildGeometry(options) {
|
|
|
604
645
|
const toNode = nodeById.get(edge.to);
|
|
605
646
|
const intoHalfWidth = (toNode ? nodeWidthPx(toNode, contigThickness, nodeWidth, depthNorm) : contigThickness) / 2;
|
|
606
647
|
const inView = (curves) => !viewportBounds || isBezierInBounds(curves, viewportBounds);
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
648
|
+
const dashesOf = (curves) => dashSpans(curves, DELETION_DASH_PX / scale, yToX, viewportBounds);
|
|
649
|
+
const stroke = (curves, thickness, color) => {
|
|
650
|
+
if (!isDeletion) {
|
|
651
|
+
edgeCurves.push({ curves, thickness, color });
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
for (const dash of dashesOf(curves)) {
|
|
655
|
+
edgeCurves.push({ curves: dash.curves, thickness, color });
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
const laneStroke = (curves, thickness, color, walk, pass, normal2, offsetX, endNormal, endOffsetX) => {
|
|
659
|
+
if (!isDeletion) {
|
|
615
660
|
edgeCurves.push({
|
|
616
|
-
curves
|
|
661
|
+
curves,
|
|
617
662
|
thickness,
|
|
618
663
|
color,
|
|
619
|
-
walk
|
|
620
|
-
pass
|
|
621
|
-
normal:
|
|
622
|
-
offsetX
|
|
623
|
-
endNormal
|
|
624
|
-
endOffsetX
|
|
664
|
+
walk,
|
|
665
|
+
pass,
|
|
666
|
+
normal: normal2,
|
|
667
|
+
offsetX,
|
|
668
|
+
endNormal,
|
|
669
|
+
endOffsetX
|
|
625
670
|
});
|
|
626
|
-
};
|
|
627
|
-
if (!isDeletion) {
|
|
628
|
-
push(curves);
|
|
629
671
|
return;
|
|
630
672
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
673
|
+
const start = { normal: normal2, offsetX };
|
|
674
|
+
const end = { normal: endNormal, offsetX: endOffsetX };
|
|
675
|
+
for (const dash of dashesOf(curves)) {
|
|
676
|
+
const a = dash.startAlong === 0 ? start : laneSlideAt(start, end, dash.startAlong);
|
|
677
|
+
const b = dash.endAlong === 1 ? end : laneSlideAt(start, end, dash.endAlong);
|
|
678
|
+
edgeCurves.push({
|
|
679
|
+
curves: dash.curves,
|
|
680
|
+
thickness,
|
|
681
|
+
color,
|
|
682
|
+
walk,
|
|
683
|
+
pass,
|
|
684
|
+
normal: a.normal,
|
|
685
|
+
offsetX: a.offsetX,
|
|
686
|
+
endNormal: b.normal,
|
|
687
|
+
endOffsetX: b.offsetX
|
|
688
|
+
});
|
|
638
689
|
}
|
|
639
690
|
};
|
|
640
691
|
const arrowOn = (curves) => {
|
|
@@ -655,89 +706,57 @@ function buildGeometry(options) {
|
|
|
655
706
|
const edgeCurveStart = edgeCurves.length;
|
|
656
707
|
const arrowStart = arrows.length;
|
|
657
708
|
const laneWalks = highlight?.walks.length && onWalk && !ribbons ? highlight.walks : void 0;
|
|
709
|
+
if (laneWalks && !lanesMayShow(baseCurves, edge.from)) {
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
658
712
|
if (laneWalks) {
|
|
659
|
-
const
|
|
660
|
-
let width = laneWidths.get(id);
|
|
661
|
-
if (width === void 0) {
|
|
662
|
-
const node = nodeById.get(id);
|
|
663
|
-
width = walkLaneWidthPx(
|
|
664
|
-
node ? nodeWidthPx(node, contigThickness, nodeWidth, depthNorm) : contigThickness,
|
|
665
|
-
laneWalks.length
|
|
666
|
-
);
|
|
667
|
-
laneWidths.set(id, width);
|
|
668
|
-
}
|
|
669
|
-
return width;
|
|
670
|
-
};
|
|
671
|
-
const endOf = (id, segments, atStart) => {
|
|
672
|
-
const at = atStart ? 0 : segments.length - 1;
|
|
673
|
-
return {
|
|
674
|
-
id,
|
|
675
|
-
laneWidth: laneWidthOf(id),
|
|
676
|
-
normal: laneNormalsOf(id, segments)[at] ?? { nx: 0, ny: 0 },
|
|
677
|
-
shift: laneShiftOf(id, at)
|
|
678
|
-
};
|
|
679
|
-
};
|
|
680
|
-
const from = endOf(
|
|
713
|
+
const from = laneEndOf(
|
|
681
714
|
edge.from,
|
|
682
715
|
fromSegments,
|
|
683
716
|
leavesStart(edge, fromSegments, baseCurves[0], stranded, yToX)
|
|
684
717
|
);
|
|
685
718
|
const last = baseCurves.at(-1);
|
|
686
|
-
const to = threaded ?
|
|
719
|
+
const to = threaded ? laneEndOf(
|
|
687
720
|
edge.to,
|
|
688
721
|
toSegments,
|
|
689
722
|
nearerStart({ x: last.x1, y: last.y1 }, toSegments, yToX)
|
|
690
723
|
) : from;
|
|
691
|
-
const slideOf = (end, offsetX) => ({
|
|
692
|
-
dx: end.shift.dx + end.normal.nx * offsetX,
|
|
693
|
-
dy: end.shift.dy + end.normal.ny * offsetX / yToX
|
|
694
|
-
});
|
|
695
|
-
const aheadKey = threads ? `${edge.from}>${edge.to}` : "";
|
|
696
|
-
const backKey = threads ? `${edge.to}>${edge.from}` : "";
|
|
697
|
-
const pairsOf = (lane) => {
|
|
698
|
-
const own = threads?.[lane]?.linkThreads;
|
|
699
|
-
if (!own?.size) {
|
|
700
|
-
return FIRST_THREADS;
|
|
701
|
-
}
|
|
702
|
-
const ahead = own.get(aheadKey);
|
|
703
|
-
const back = edgeKeys.has(backKey) ? void 0 : own.get(backKey);
|
|
704
|
-
if (!back) {
|
|
705
|
-
return ahead ?? FIRST_THREADS;
|
|
706
|
-
}
|
|
707
|
-
const turned = back.map(([a, b]) => [b, a]);
|
|
708
|
-
return ahead ? [...ahead, ...turned] : turned;
|
|
709
|
-
};
|
|
710
724
|
const single = laneWalks.length === 1;
|
|
711
|
-
|
|
725
|
+
const thickness = laneHalfWidth(from.laneWidth);
|
|
726
|
+
for (let lane = 0; lane < laneWalks.length; lane++) {
|
|
727
|
+
const walk = laneWalks[lane];
|
|
712
728
|
if (!walk.edgeIndexes.has(ei)) {
|
|
713
|
-
|
|
729
|
+
continue;
|
|
714
730
|
}
|
|
715
|
-
for (const [pass, toPass] of
|
|
731
|
+
for (const [pass, toPass] of threadPairs(lane, edge.from, edge.to)) {
|
|
716
732
|
const offsetX = single ? 0 : laneOffset(from.id, from.laneWidth, lane, pass) * worldPerScreenPx;
|
|
717
|
-
const
|
|
718
|
-
const end = threaded ? {
|
|
719
|
-
normal: to.normal,
|
|
720
|
-
offsetX: laneOffset(to.id, to.laneWidth, lane, toPass) * worldPerScreenPx
|
|
721
|
-
} : start;
|
|
733
|
+
const endOffsetX = threaded ? laneOffset(to.id, to.laneWidth, lane, toPass) * worldPerScreenPx : offsetX;
|
|
722
734
|
const curves = threaded ? slideCurves(
|
|
723
735
|
baseCurves,
|
|
724
|
-
|
|
725
|
-
|
|
736
|
+
from.shift.dx + from.normal.nx * offsetX,
|
|
737
|
+
from.shift.dy + from.normal.ny * offsetX / yToX,
|
|
738
|
+
to.shift.dx + to.normal.nx * endOffsetX,
|
|
739
|
+
to.shift.dy + to.normal.ny * endOffsetX / yToX
|
|
726
740
|
) : offsetX === 0 ? baseCurves : translateCurves(
|
|
727
741
|
baseCurves,
|
|
728
742
|
from.normal.nx * offsetX,
|
|
729
743
|
from.normal.ny * offsetX / yToX
|
|
730
744
|
);
|
|
731
745
|
if (inView(curves)) {
|
|
732
|
-
|
|
746
|
+
laneStroke(
|
|
733
747
|
curves,
|
|
734
|
-
|
|
748
|
+
thickness,
|
|
735
749
|
walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor,
|
|
736
|
-
|
|
750
|
+
lane,
|
|
751
|
+
pass,
|
|
752
|
+
from.normal,
|
|
753
|
+
offsetX,
|
|
754
|
+
to.normal,
|
|
755
|
+
endOffsetX
|
|
737
756
|
);
|
|
738
757
|
}
|
|
739
758
|
}
|
|
740
|
-
}
|
|
759
|
+
}
|
|
741
760
|
if (edgeCurves.length > edgeCurveStart) {
|
|
742
761
|
arrowOn(baseCurves);
|
|
743
762
|
}
|
|
@@ -807,34 +826,36 @@ function buildGeometry(options) {
|
|
|
807
826
|
const laneWidth = walkLaneWidthPx(width, lanes.length);
|
|
808
827
|
const normals = lanes.length > 1 ? laneNormalsOf(nodeId, segments) : [];
|
|
809
828
|
const points = lanes.length > 1 ? lanePointsOf(nodeId, segments) : segments;
|
|
810
|
-
|
|
811
|
-
|
|
829
|
+
const thickness = laneHalfWidth(laneWidth);
|
|
830
|
+
for (let lane = 0; lane < lanes.length; lane++) {
|
|
831
|
+
const laneColor = lanes[lane].colors.get(nodeId);
|
|
812
832
|
if (laneColor === void 0) {
|
|
813
|
-
|
|
833
|
+
continue;
|
|
814
834
|
}
|
|
815
835
|
const onThreads = threads?.[lane]?.nodeThreads.get(nodeId) ?? ONE_PASS;
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
nodeStrokes.push(
|
|
820
|
-
lanes.length === 1 ? {
|
|
836
|
+
for (const pass of onThreads) {
|
|
837
|
+
if (lanes.length === 1) {
|
|
838
|
+
nodeStrokes.push({
|
|
821
839
|
points: segments,
|
|
822
840
|
thickness,
|
|
823
841
|
color: laneColor,
|
|
824
842
|
walk: lane,
|
|
825
843
|
pass
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
844
|
+
});
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
const offsetX = laneOffset(nodeId, laneWidth, lane, pass) * worldPerScreenPx;
|
|
848
|
+
nodeStrokes.push({
|
|
849
|
+
points: offsetPolyline(points, normals, offsetX, yToX),
|
|
850
|
+
thickness,
|
|
851
|
+
color: laneColor,
|
|
852
|
+
walk: lane,
|
|
853
|
+
pass,
|
|
854
|
+
normals,
|
|
855
|
+
offsetX
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
}
|
|
838
859
|
} else if (drawable && slots?.length && slotWidth >= MIN_PATH_STRIPE_PX) {
|
|
839
860
|
const normals = pointNormalsOf(segments, yToX);
|
|
840
861
|
for (const slot of slots) {
|
|
@@ -4,27 +4,27 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
facetLifts,
|
|
6
6
|
walkLift
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZWBQ4RRK.js";
|
|
8
8
|
import {
|
|
9
9
|
buildGeometry,
|
|
10
10
|
computeReferenceRamp
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GDZQFELP.js";
|
|
12
12
|
import {
|
|
13
13
|
walkKey
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-IZKM4NY7.js";
|
|
15
15
|
import {
|
|
16
16
|
walkRowsExtent
|
|
17
17
|
} from "./chunk-VCUOYVLC.js";
|
|
18
18
|
import {
|
|
19
19
|
pathLegend,
|
|
20
20
|
walkLabelsOf
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-VQ353UDK.js";
|
|
22
22
|
import {
|
|
23
23
|
FIGURE_DEFAULTS
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-2MXFG3W7.js";
|
|
25
25
|
import {
|
|
26
26
|
drawingBounds
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-JVT3XTKN.js";
|
|
28
28
|
import {
|
|
29
29
|
referenceLabel
|
|
30
30
|
} from "./chunk-5ORP7EFJ.js";
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
import {
|
|
35
35
|
deletionDrawing,
|
|
36
36
|
deletionEdges
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-3GORESBG.js";
|
|
38
38
|
import {
|
|
39
39
|
facetCells,
|
|
40
40
|
facetSettingOf
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
coversGraph
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SZYFZNCO.js";
|
|
4
4
|
import {
|
|
5
5
|
bubblesFromGraph,
|
|
6
6
|
derivedBubble,
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
} from "./chunk-RFG42VIO.js";
|
|
11
11
|
import {
|
|
12
12
|
bubbleSegmentIds
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NWEVR2OQ.js";
|
|
14
14
|
import {
|
|
15
15
|
bubbleSubgraph
|
|
16
16
|
} from "./chunk-MHZTTLBU.js";
|
|
17
17
|
import {
|
|
18
18
|
strandSides
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-JJV2GT2Z.js";
|
|
20
20
|
import {
|
|
21
21
|
pushTo
|
|
22
22
|
} from "./chunk-BSOZW3FC.js";
|
|
@@ -150,21 +150,29 @@ var slideAt = (from, to, along) => ({
|
|
|
150
150
|
dx: from.dx + (to.dx - from.dx) * along,
|
|
151
151
|
dy: from.dy + (to.dy - from.dy) * along
|
|
152
152
|
});
|
|
153
|
-
function slideCurves(curves,
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
153
|
+
function slideCurves(curves, fromDx, fromDy, toDx, toDy) {
|
|
154
|
+
const n = curves.length;
|
|
155
|
+
const out = new Array(n);
|
|
156
|
+
for (let i = 0; i < n; i++) {
|
|
157
|
+
const c = curves[i];
|
|
158
|
+
const a = i / n;
|
|
159
|
+
const b = (i + 1) / n;
|
|
160
|
+
const adx = fromDx + (toDx - fromDx) * a;
|
|
161
|
+
const ady = fromDy + (toDy - fromDy) * a;
|
|
162
|
+
const bdx = fromDx + (toDx - fromDx) * b;
|
|
163
|
+
const bdy = fromDy + (toDy - fromDy) * b;
|
|
164
|
+
out[i] = {
|
|
165
|
+
x0: c.x0 + adx,
|
|
166
|
+
y0: c.y0 + ady,
|
|
167
|
+
cx0: c.cx0 + adx,
|
|
168
|
+
cy0: c.cy0 + ady,
|
|
169
|
+
cx1: c.cx1 + bdx,
|
|
170
|
+
cy1: c.cy1 + bdy,
|
|
171
|
+
x1: c.x1 + bdx,
|
|
172
|
+
y1: c.y1 + bdy
|
|
166
173
|
};
|
|
167
|
-
}
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
168
176
|
}
|
|
169
177
|
function translateCurves(curves, dx, dy) {
|
|
170
178
|
const out = new Array(curves.length);
|