@jbrowse/bandage-core 11.7.1 → 11.8.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/README.md +106 -48
- 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-3PZSBNLI.js → chunk-22ZMVREZ.js} +19 -14
- package/dist/chunks/{chunk-VB4IXIPM.js → chunk-2H3ALI6L.js} +223 -45
- package/dist/chunks/{chunk-FBPAX5K6.js → chunk-2RCKHCF7.js} +1 -1
- package/dist/chunks/{chunk-5NZRT7GL.js → chunk-3CXZUC2Y.js} +2 -2
- package/dist/chunks/{chunk-WUZH2OJ6.js → chunk-3XYLEK4H.js} +2 -2
- package/dist/chunks/{chunk-F7O56DVR.js → chunk-4OVIUCSB.js} +2 -2
- package/dist/chunks/{chunk-JGH2V54E.js → chunk-4YPCUVMC.js} +2 -2
- package/dist/chunks/{chunk-FU57ZNRQ.js → chunk-6CXLLJ2C.js} +3 -3
- package/dist/chunks/{chunk-SACSQ45G.js → chunk-6MD4VS2F.js} +1 -1
- package/dist/chunks/{chunk-VACK24HF.js → chunk-735MPLUL.js} +35 -9
- package/dist/chunks/chunk-7GDNDQD7.js +504 -0
- package/dist/chunks/{chunk-IN4IYSA2.js → chunk-7PEYA3NA.js} +2 -2
- package/dist/chunks/{chunk-CWCVQJYY.js → chunk-AXE3RR7J.js} +1 -1
- package/dist/chunks/{chunk-BXE3SBBN.js → chunk-C3KAPREU.js} +1 -1
- package/dist/chunks/{chunk-ATDVS2CW.js → chunk-G3GLGDKV.js} +2 -2
- package/dist/chunks/{chunk-RB2MDFQU.js → chunk-G4WQBRDS.js} +4 -4
- package/dist/chunks/{chunk-SDI6BVG7.js → chunk-J4PDHWP2.js} +1 -1
- package/dist/chunks/{chunk-3UGWYQNY.js → chunk-JKIAHYAW.js} +14 -8
- package/dist/chunks/{chunk-TCSV3II7.js → chunk-L2RQV23D.js} +1 -1
- package/dist/chunks/{chunk-6XDTAKO7.js → chunk-LA6JHEVV.js} +1 -1
- package/dist/chunks/{chunk-G7SG4XMK.js → chunk-LODKC7PJ.js} +7 -0
- package/dist/chunks/{chunk-RK7ZOFPR.js → chunk-MO4DIRHD.js} +80 -38
- package/dist/chunks/{chunk-PCHEUVHB.js → chunk-N2GAA7RB.js} +1 -1
- package/dist/chunks/{chunk-I5SGYTRM.js → chunk-N4AJV4GH.js} +25 -14
- package/dist/chunks/{chunk-Q7I563MH.js → chunk-NHOXLUIL.js} +2 -2
- package/dist/chunks/{chunk-RT4K2JMZ.js → chunk-NQWEYJDD.js} +1 -1
- package/dist/chunks/{chunk-3Y2EFDID.js → chunk-OIOAK7BS.js} +1 -1
- package/dist/chunks/{chunk-EZGNBDHD.js → chunk-R3NPBUKT.js} +8 -8
- package/dist/chunks/{chunk-KJDERUQF.js → chunk-R4XCTRIU.js} +45 -10
- package/dist/chunks/{chunk-HTF32WSW.js → chunk-S3ICPPXC.js} +3 -3
- package/dist/chunks/{chunk-OXW5OHYQ.js → chunk-S4CH434Z.js} +1 -1
- package/dist/chunks/{chunk-HMEAGAGC.js → chunk-S7BCZVRK.js} +2 -2
- package/dist/chunks/{chunk-UV2IJMIG.js → chunk-SDDMV2MM.js} +1 -1
- package/dist/chunks/{chunk-J6XHW4KI.js → chunk-SIXFXXRI.js} +3 -3
- package/dist/chunks/{chunk-LKQOIPGE.js → chunk-U6JPSXJ3.js} +90 -21
- package/dist/chunks/{chunk-SENPGW4O.js → chunk-VCUOYVLC.js} +1 -1
- package/dist/chunks/{chunk-XTF2VWJN.js → chunk-VSRRIFRF.js} +1 -1
- package/dist/chunks/{chunk-BFUS3ENH.js → chunk-X5ULFAMM.js} +2 -2
- package/dist/chunks/{chunk-PJWLYGRL.js → chunk-XOIYBEU7.js} +1 -1
- package/dist/chunks/{chunk-JLIVX2SF.js → chunk-YEDZ37PH.js} +1 -1
- package/dist/chunks/{chunk-APLWFV4I.js → chunk-YF6T33PU.js} +10 -2
- package/dist/chunks/{chunk-2VMKQKVO.js → chunk-YIWN32ZX.js} +1 -1
- package/dist/chunks/{chunk-3WSA4NNP.js → chunk-ZKIH2USC.js} +1 -1
- package/dist/cli/figure.js +31 -30
- package/dist/cli/fold.js +6 -6
- package/dist/deletionEdges.js +2 -2
- package/dist/figure.js +27 -26
- package/dist/figureData.js +25 -24
- package/dist/figureScene.js +18 -17
- 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 +45 -44
- 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 +3 -1
- package/dist/layout/tubeMapLayout.js +9 -9
- package/dist/layout/walkRowDraw.js +9 -8
- package/dist/layout/walkRowLayout.js +3 -3
- package/dist/layout/walkRowRuns.js +1 -1
- package/dist/layout/walkRows.js +2 -2
- package/dist/layout/walkStrip.js +13 -12
- package/dist/layoutModes.js +11 -11
- package/dist/pathColors.js +5 -5
- package/dist/pipeline.js +5 -5
- package/dist/referenceStrip.js +9 -8
- package/dist/renderer/GeometryBuilder.js +8 -7
- package/dist/renderer/walkLanes.js +44 -0
- package/dist/tubeMap/axis.js +5 -5
- package/dist/tubeMap/bundle.js +10 -10
- package/dist/tubeMap/coarsen.js +10 -10
- package/dist/tubeMap/deviations.js +11 -11
- package/dist/tubeMap/draw.js +5 -5
- package/dist/tubeMap/genes.js +6 -6
- package/dist/tubeMap/nodeColors.js +9 -8
- package/dist/tubeMap/reads.js +2 -2
- package/dist/types/figureData.d.ts +22 -0
- package/dist/types/foldVariants.d.ts +3 -1
- package/dist/types/renderer/types.d.ts +20 -0
- package/dist/types/renderer/walkLanes.d.ts +60 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types/util/geometry.d.ts +13 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/walkEncoding.d.ts +7 -5
- package/dist/types/walkHighlight.d.ts +3 -0
- package/dist/util/SpatialIndex.js +4 -4
- package/dist/util/edgeCurves.js +3 -3
- package/dist/util/geometry.js +7 -1
- package/dist/util/hitDetection.js +5 -5
- package/dist/version.js +1 -1
- package/dist/viewport.js +6 -6
- package/dist/walkEncoding.js +9 -8
- package/dist/walkHighlight.js +10 -9
- package/dist/walkKey.js +5 -5
- package/package.json +1 -1
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LANE_SMOOTHING_PX,
|
|
3
|
+
THREAD_PITCH_PX,
|
|
4
|
+
THREAD_PX,
|
|
5
|
+
THREAD_REACH_PX,
|
|
6
|
+
THREAD_TAPER_PX,
|
|
7
|
+
bandScale,
|
|
8
|
+
bandSpans,
|
|
9
|
+
bandWidthPx,
|
|
10
|
+
laneLines,
|
|
11
|
+
laneRuns,
|
|
12
|
+
laneSlideAt,
|
|
13
|
+
slotCentres,
|
|
14
|
+
threadsPasses,
|
|
15
|
+
walkThreads
|
|
16
|
+
} from "./chunk-7GDNDQD7.js";
|
|
1
17
|
import {
|
|
2
18
|
abgrToCssRgba,
|
|
3
19
|
fadeAbgr,
|
|
@@ -10,13 +26,13 @@ import {
|
|
|
10
26
|
} from "./chunk-GQZVR5DW.js";
|
|
11
27
|
import {
|
|
12
28
|
baseEdgeCurves
|
|
13
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-VSRRIFRF.js";
|
|
14
30
|
import {
|
|
15
31
|
PATH_LIGHTNESS,
|
|
16
32
|
PATH_SATURATION,
|
|
17
33
|
nameHue,
|
|
18
34
|
pathHueAt
|
|
19
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-JKIAHYAW.js";
|
|
20
36
|
import {
|
|
21
37
|
meanDepth,
|
|
22
38
|
nodeWidthPx,
|
|
@@ -26,13 +42,14 @@ import {
|
|
|
26
42
|
referenceMidpoints
|
|
27
43
|
} from "./chunk-VX656OAZ.js";
|
|
28
44
|
import {
|
|
29
|
-
|
|
45
|
+
dashSpans,
|
|
30
46
|
pathRibbonOffsets,
|
|
31
47
|
polylinePx,
|
|
48
|
+
slideCurves,
|
|
32
49
|
strandSides,
|
|
33
50
|
translateCurves,
|
|
34
51
|
yToXOf
|
|
35
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-735MPLUL.js";
|
|
36
53
|
import {
|
|
37
54
|
pushTo
|
|
38
55
|
} from "./chunk-BSOZW3FC.js";
|
|
@@ -149,13 +166,16 @@ function arrowheadFor({
|
|
|
149
166
|
color
|
|
150
167
|
};
|
|
151
168
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const gap = (p) => Math.hypot(p.x -
|
|
169
|
+
var FIRST_THREADS = [[0, 0]];
|
|
170
|
+
var ONE_PASS = [0];
|
|
171
|
+
var NO_SHIFT = { dx: 0, dy: 0 };
|
|
172
|
+
function nearerStart(at, segments, yToX) {
|
|
173
|
+
const gap = (p) => Math.hypot(p.x - at.x, (p.y - at.y) * yToX);
|
|
157
174
|
return gap(segments[0]) < gap(segments.at(-1));
|
|
158
175
|
}
|
|
176
|
+
function leavesStart(edge, segments, first, stranded, yToX) {
|
|
177
|
+
return stranded ? strandSides(edge).from === "start" : nearerStart({ x: first.x0, y: first.y0 }, segments, yToX);
|
|
178
|
+
}
|
|
159
179
|
function intoDirection(last, toSegments) {
|
|
160
180
|
if (toSegments.length < 2) {
|
|
161
181
|
return void 0;
|
|
@@ -496,6 +516,74 @@ function buildGeometry(options) {
|
|
|
496
516
|
const { pathColorByIndex, pathIndexByName } = pathPaletteOf(graph);
|
|
497
517
|
const pathColorByName = (name) => pathColorByIndex[pathIndexByName.get(name) ?? -1] ?? EDGE_PATH_FALLBACK_COLOR;
|
|
498
518
|
const nodePathSlots = drawPaths && pathCount > 1 ? pathSlotsOf(graph) : NO_SLOTS;
|
|
519
|
+
const liftedWalks = highlight?.walks ?? [];
|
|
520
|
+
const threaded = threadsPasses(liftedWalks);
|
|
521
|
+
const lanePasses = liftedWalks.map((w) => w.mostPasses);
|
|
522
|
+
const thinned = threaded ? bandScale(lanePasses) : 1;
|
|
523
|
+
const runs = liftedWalks.length > 1 ? laneRuns(
|
|
524
|
+
liftedWalks.flatMap((w) => w.route),
|
|
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
|
+
}
|
|
553
|
+
) : void 0;
|
|
554
|
+
const edgeKeys = new Set(
|
|
555
|
+
threads ? graph.edges.map((e) => `${e.from}>${e.to}`) : []
|
|
556
|
+
);
|
|
557
|
+
const centresByNode = /* @__PURE__ */ new Map();
|
|
558
|
+
const laneOffset = (nodeId, laneWidth, lane, pass) => {
|
|
559
|
+
if (!threaded) {
|
|
560
|
+
return (lane - (liftedWalks.length - 1) / 2) * laneWidth;
|
|
561
|
+
}
|
|
562
|
+
let centres = centresByNode.get(nodeId);
|
|
563
|
+
if (!centres) {
|
|
564
|
+
const spans = spanField?.get(nodeId);
|
|
565
|
+
centres = slotCentres(spans?.slot ?? lanePasses, lanePasses, spans?.held);
|
|
566
|
+
centresByNode.set(nodeId, centres);
|
|
567
|
+
}
|
|
568
|
+
return (centres[lane] + pass * THREAD_PITCH_PX) * thinned;
|
|
569
|
+
};
|
|
570
|
+
const laneHalfWidth = (laneWidth) => threaded ? THREAD_PX / 2 * thinned : laneWidth / 2;
|
|
571
|
+
const laneNormals = /* @__PURE__ */ new Map();
|
|
572
|
+
const laneNormalsOf = (nodeId, segments) => {
|
|
573
|
+
let normals = laneNormals.get(nodeId);
|
|
574
|
+
if (!normals) {
|
|
575
|
+
const smoothed = lines?.normals.get(nodeId);
|
|
576
|
+
normals = smoothed ? pointNormalsOf(segments, yToX).map((n, i) => smoothed[i] ?? n) : pointNormalsOf(segments, yToX);
|
|
577
|
+
laneNormals.set(nodeId, normals);
|
|
578
|
+
}
|
|
579
|
+
return normals;
|
|
580
|
+
};
|
|
581
|
+
const laneWidths = /* @__PURE__ */ new Map();
|
|
582
|
+
const laneShiftOf = (nodeId, index) => lines?.shifts.get(nodeId)?.[index] ?? NO_SHIFT;
|
|
583
|
+
const lanePointsOf = (nodeId, segments) => lines?.shifts.has(nodeId) ? segments.map((p, i) => {
|
|
584
|
+
const { dx, dy } = laneShiftOf(nodeId, i);
|
|
585
|
+
return { ...p, x: p.x + dx, y: p.y + dy };
|
|
586
|
+
}) : segments;
|
|
499
587
|
const showArrows = scale > (linearLayout ? 1 : MIN_ARROW_SCALE);
|
|
500
588
|
for (let ei = 0; ei < graph.edges.length; ei++) {
|
|
501
589
|
const edge = graph.edges[ei];
|
|
@@ -516,18 +604,37 @@ function buildGeometry(options) {
|
|
|
516
604
|
const toNode = nodeById.get(edge.to);
|
|
517
605
|
const intoHalfWidth = (toNode ? nodeWidthPx(toNode, contigThickness, nodeWidth, depthNorm) : contigThickness) / 2;
|
|
518
606
|
const inView = (curves) => !viewportBounds || isBezierInBounds(curves, viewportBounds);
|
|
519
|
-
const stroke = (curves, thickness, color) => {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
curves,
|
|
523
|
-
|
|
524
|
-
yToX,
|
|
525
|
-
viewportBounds
|
|
526
|
-
)) {
|
|
527
|
-
edgeCurves.push({ curves: dash, thickness, color });
|
|
607
|
+
const stroke = (curves, thickness, color, lane) => {
|
|
608
|
+
const push = (pieces, from = 0, to = 1) => {
|
|
609
|
+
if (!lane) {
|
|
610
|
+
edgeCurves.push({ curves: pieces, thickness, color });
|
|
611
|
+
return;
|
|
528
612
|
}
|
|
529
|
-
|
|
530
|
-
|
|
613
|
+
const start = from === 0 ? lane.start : laneSlideAt(lane.start, lane.end, from);
|
|
614
|
+
const end = to === 1 ? lane.end : laneSlideAt(lane.start, lane.end, to);
|
|
615
|
+
edgeCurves.push({
|
|
616
|
+
curves: pieces,
|
|
617
|
+
thickness,
|
|
618
|
+
color,
|
|
619
|
+
walk: lane.walk,
|
|
620
|
+
pass: lane.pass,
|
|
621
|
+
normal: start.normal,
|
|
622
|
+
offsetX: start.offsetX,
|
|
623
|
+
endNormal: end.normal,
|
|
624
|
+
endOffsetX: end.offsetX
|
|
625
|
+
});
|
|
626
|
+
};
|
|
627
|
+
if (!isDeletion) {
|
|
628
|
+
push(curves);
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
for (const dash of dashSpans(
|
|
632
|
+
curves,
|
|
633
|
+
DELETION_DASH_PX / scale,
|
|
634
|
+
yToX,
|
|
635
|
+
viewportBounds
|
|
636
|
+
)) {
|
|
637
|
+
push(dash.curves, dash.startAlong, dash.endAlong);
|
|
531
638
|
}
|
|
532
639
|
};
|
|
533
640
|
const arrowOn = (curves) => {
|
|
@@ -549,32 +656,86 @@ function buildGeometry(options) {
|
|
|
549
656
|
const arrowStart = arrows.length;
|
|
550
657
|
const laneWalks = highlight?.walks.length && onWalk && !ribbons ? highlight.walks : void 0;
|
|
551
658
|
if (laneWalks) {
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
659
|
+
const laneWidthOf = (id) => {
|
|
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(
|
|
681
|
+
edge.from,
|
|
558
682
|
fromSegments,
|
|
559
|
-
baseCurves[0],
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
683
|
+
leavesStart(edge, fromSegments, baseCurves[0], stranded, yToX)
|
|
684
|
+
);
|
|
685
|
+
const last = baseCurves.at(-1);
|
|
686
|
+
const to = threaded ? endOf(
|
|
687
|
+
edge.to,
|
|
688
|
+
toSegments,
|
|
689
|
+
nearerStart({ x: last.x1, y: last.y1 }, toSegments, yToX)
|
|
690
|
+
) : 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;
|
|
565
709
|
};
|
|
710
|
+
const single = laneWalks.length === 1;
|
|
566
711
|
laneWalks.forEach((walk, lane) => {
|
|
567
712
|
if (!walk.edgeIndexes.has(ei)) {
|
|
568
713
|
return;
|
|
569
714
|
}
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
laneWidth
|
|
576
|
-
|
|
715
|
+
for (const [pass, toPass] of pairsOf(lane)) {
|
|
716
|
+
const offsetX = single ? 0 : laneOffset(from.id, from.laneWidth, lane, pass) * worldPerScreenPx;
|
|
717
|
+
const start = { normal: from.normal, offsetX };
|
|
718
|
+
const end = threaded ? {
|
|
719
|
+
normal: to.normal,
|
|
720
|
+
offsetX: laneOffset(to.id, to.laneWidth, lane, toPass) * worldPerScreenPx
|
|
721
|
+
} : start;
|
|
722
|
+
const curves = threaded ? slideCurves(
|
|
723
|
+
baseCurves,
|
|
724
|
+
slideOf(from, start.offsetX),
|
|
725
|
+
slideOf(to, end.offsetX)
|
|
726
|
+
) : offsetX === 0 ? baseCurves : translateCurves(
|
|
727
|
+
baseCurves,
|
|
728
|
+
from.normal.nx * offsetX,
|
|
729
|
+
from.normal.ny * offsetX / yToX
|
|
577
730
|
);
|
|
731
|
+
if (inView(curves)) {
|
|
732
|
+
stroke(
|
|
733
|
+
curves,
|
|
734
|
+
laneHalfWidth(from.laneWidth),
|
|
735
|
+
walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor,
|
|
736
|
+
{ walk: lane, pass, start, end }
|
|
737
|
+
);
|
|
738
|
+
}
|
|
578
739
|
}
|
|
579
740
|
});
|
|
580
741
|
if (edgeCurves.length > edgeCurveStart) {
|
|
@@ -644,17 +805,34 @@ function buildGeometry(options) {
|
|
|
644
805
|
const lanes = highlight?.walks.length && !faded && !slots?.length ? highlight.walks : void 0;
|
|
645
806
|
if (drawable && lanes) {
|
|
646
807
|
const laneWidth = walkLaneWidthPx(width, lanes.length);
|
|
647
|
-
const normals =
|
|
808
|
+
const normals = lanes.length > 1 ? laneNormalsOf(nodeId, segments) : [];
|
|
809
|
+
const points = lanes.length > 1 ? lanePointsOf(nodeId, segments) : segments;
|
|
648
810
|
lanes.forEach((walk, lane) => {
|
|
649
811
|
const laneColor = walk.colors.get(nodeId);
|
|
650
812
|
if (laneColor === void 0) {
|
|
651
813
|
return;
|
|
652
814
|
}
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
815
|
+
const onThreads = threads?.[lane]?.nodeThreads.get(nodeId) ?? ONE_PASS;
|
|
816
|
+
const thickness = laneHalfWidth(laneWidth);
|
|
817
|
+
onThreads.forEach((pass) => {
|
|
818
|
+
const offsetX = lanes.length === 1 ? 0 : laneOffset(nodeId, laneWidth, lane, pass) * worldPerScreenPx;
|
|
819
|
+
nodeStrokes.push(
|
|
820
|
+
lanes.length === 1 ? {
|
|
821
|
+
points: segments,
|
|
822
|
+
thickness,
|
|
823
|
+
color: laneColor,
|
|
824
|
+
walk: lane,
|
|
825
|
+
pass
|
|
826
|
+
} : {
|
|
827
|
+
points: offsetPolyline(points, normals, offsetX, yToX),
|
|
828
|
+
thickness,
|
|
829
|
+
color: laneColor,
|
|
830
|
+
walk: lane,
|
|
831
|
+
pass,
|
|
832
|
+
normals,
|
|
833
|
+
offsetX
|
|
834
|
+
}
|
|
835
|
+
);
|
|
658
836
|
});
|
|
659
837
|
});
|
|
660
838
|
} else if (drawable && slots?.length && slotWidth >= MIN_PATH_STRIPE_PX) {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
edgeJoinOf,
|
|
10
10
|
routedEdgeCurves,
|
|
11
11
|
strandSides
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-735MPLUL.js";
|
|
13
13
|
import {
|
|
14
14
|
groupBy
|
|
15
15
|
} from "./chunk-BSOZW3FC.js";
|
|
@@ -131,7 +131,7 @@ function deletionEdges(cut) {
|
|
|
131
131
|
const edge = graph.edges[edgeIndex];
|
|
132
132
|
const from = byId.get(edge.from);
|
|
133
133
|
const to = byId.get(edge.to);
|
|
134
|
-
if (from !== void 0 && to !== void 0 && isBackbone(from) && isBackbone(to) && from.stable.refName === to.stable.refName) {
|
|
134
|
+
if (!edge.foldBridge && from !== void 0 && to !== void 0 && isBackbone(from) && isBackbone(to) && from.stable.refName === to.stable.refName) {
|
|
135
135
|
const span = skippedSpan(edge, from, to, startsOf);
|
|
136
136
|
const refName = from.stable.refName;
|
|
137
137
|
const bp = span ? span.end - span.start : 0;
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
hasTubeMapPaths,
|
|
4
4
|
tubeMapLayout,
|
|
5
5
|
tubeMapReferenceLayout
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-G4WQBRDS.js";
|
|
7
7
|
import {
|
|
8
8
|
sampleRowLayout
|
|
9
9
|
} from "./chunk-XR2HMGAS.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./chunk-UAFATXYA.js";
|
|
16
16
|
import {
|
|
17
17
|
walkRowLayout
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-VCUOYVLC.js";
|
|
19
19
|
import {
|
|
20
20
|
isBackbone,
|
|
21
21
|
isOffReference
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
boxesGenes,
|
|
4
4
|
rowPitch,
|
|
5
5
|
rowSpan
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LA6JHEVV.js";
|
|
7
7
|
import {
|
|
8
8
|
el
|
|
9
9
|
} from "./chunk-H2H4Y3TV.js";
|
|
10
10
|
import {
|
|
11
11
|
READOUT_ROOM,
|
|
12
12
|
longestBar
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-VCUOYVLC.js";
|
|
14
14
|
import {
|
|
15
15
|
LABEL_CHAR_PX
|
|
16
16
|
} from "./chunk-AB35TJST.js";
|
|
@@ -7,15 +7,15 @@ import {
|
|
|
7
7
|
} from "./chunk-AB35TJST.js";
|
|
8
8
|
import {
|
|
9
9
|
polylineMidpoint
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YIWN32ZX.js";
|
|
11
11
|
import {
|
|
12
12
|
edgeCurvesOf
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-3CXZUC2Y.js";
|
|
14
14
|
import {
|
|
15
15
|
curveBounds,
|
|
16
16
|
curveMidpoint,
|
|
17
17
|
polylinePx
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-735MPLUL.js";
|
|
19
19
|
|
|
20
20
|
// src/graphLabels.ts
|
|
21
21
|
var MIN_DELETION_LABEL_PX = 26;
|
|
@@ -97,7 +97,8 @@ function visibleStretches(curves, lengths, bounds, yToX) {
|
|
|
97
97
|
});
|
|
98
98
|
return stretches;
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
var dashCurves = (curves, dashWorld, yToX = 1, bounds) => dashSpans(curves, dashWorld, yToX, bounds).map((d) => d.curves);
|
|
101
|
+
function dashSpans(curves, dashWorld, yToX = 1, bounds) {
|
|
101
102
|
const lengths = curves.map(
|
|
102
103
|
(c) => Math.hypot(c.cx0 - c.x0, (c.cy0 - c.y0) * yToX) + Math.hypot(c.cx1 - c.cx0, (c.cy1 - c.cy0) * yToX) + Math.hypot(c.x1 - c.cx1, (c.y1 - c.cy1) * yToX)
|
|
103
104
|
);
|
|
@@ -122,27 +123,49 @@ function dashCurves(curves, dashWorld, yToX = 1, bounds) {
|
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
const dash = [];
|
|
126
|
+
const along = [];
|
|
125
127
|
let start = 0;
|
|
126
128
|
curves.forEach((c, k) => {
|
|
127
129
|
const length = lengths[k];
|
|
128
130
|
const end = start + length;
|
|
129
131
|
if (length > 0 && end > from && start < to) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Math.min(1, (to - start) / length)
|
|
135
|
-
)
|
|
136
|
-
);
|
|
132
|
+
const t0 = Math.max(0, (from - start) / length);
|
|
133
|
+
const t1 = Math.min(1, (to - start) / length);
|
|
134
|
+
dash.push(subCurve(c, t0, t1));
|
|
135
|
+
along.push((k + t0) / curves.length, (k + t1) / curves.length);
|
|
137
136
|
}
|
|
138
137
|
start = end;
|
|
139
138
|
});
|
|
140
139
|
if (dash.length) {
|
|
141
|
-
out.push(
|
|
140
|
+
out.push({
|
|
141
|
+
curves: dash,
|
|
142
|
+
startAlong: along[0],
|
|
143
|
+
endAlong: along.at(-1)
|
|
144
|
+
});
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
return out;
|
|
145
148
|
}
|
|
149
|
+
var slideAt = (from, to, along) => ({
|
|
150
|
+
dx: from.dx + (to.dx - from.dx) * along,
|
|
151
|
+
dy: from.dy + (to.dy - from.dy) * along
|
|
152
|
+
});
|
|
153
|
+
function slideCurves(curves, from, to) {
|
|
154
|
+
return curves.map((c, i) => {
|
|
155
|
+
const a = slideAt(from, to, i / curves.length);
|
|
156
|
+
const b = slideAt(from, to, (i + 1) / curves.length);
|
|
157
|
+
return {
|
|
158
|
+
x0: c.x0 + a.dx,
|
|
159
|
+
y0: c.y0 + a.dy,
|
|
160
|
+
cx0: c.cx0 + a.dx,
|
|
161
|
+
cy0: c.cy0 + a.dy,
|
|
162
|
+
cx1: c.cx1 + b.dx,
|
|
163
|
+
cy1: c.cy1 + b.dy,
|
|
164
|
+
x1: c.x1 + b.dx,
|
|
165
|
+
y1: c.y1 + b.dy
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
}
|
|
146
169
|
function translateCurves(curves, dx, dy) {
|
|
147
170
|
const out = new Array(curves.length);
|
|
148
171
|
for (let i = 0; i < curves.length; i++) {
|
|
@@ -555,6 +578,9 @@ export {
|
|
|
555
578
|
curveMidpoint,
|
|
556
579
|
curveBounds,
|
|
557
580
|
dashCurves,
|
|
581
|
+
dashSpans,
|
|
582
|
+
slideAt,
|
|
583
|
+
slideCurves,
|
|
558
584
|
translateCurves,
|
|
559
585
|
ownStrand,
|
|
560
586
|
strandSides,
|