@jbrowse/bandage-core 10.2.2 → 10.2.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 -7
- package/dist/bubbles/bubbleHalos.js +7 -3
- package/dist/bubbles/bubblesFromGraph.js +4 -2
- package/dist/bubbles/classifyBubble.js +10 -5
- package/dist/bubbles/superbubbles.js +10 -6
- package/dist/chunks/{chunk-N6FECAXP.js → chunk-24WITXQY.js} +17 -8
- package/dist/chunks/{chunk-XTCNEKO5.js → chunk-2QLLQJ72.js} +15 -13
- package/dist/chunks/{chunk-ASSNZXCF.js → chunk-3AOGOCCQ.js} +44 -103
- package/dist/chunks/{chunk-TWRLC3KK.js → chunk-3XSM4OZU.js} +1 -1
- package/dist/chunks/{chunk-WEDZ76AK.js → chunk-4DRQTBBE.js} +1 -1
- package/dist/chunks/{chunk-2LQ5BWT7.js → chunk-4ETPXDO6.js} +1 -1
- package/dist/chunks/{chunk-FP4H7SFT.js → chunk-4HWM3FNK.js} +2 -2
- package/dist/chunks/{chunk-C7MZJSPT.js → chunk-54POIBVC.js} +2 -8
- package/dist/chunks/{chunk-PKFMP65V.js → chunk-5GMFEPWR.js} +1 -1
- package/dist/chunks/{chunk-CDLPYR5O.js → chunk-5I3K4R2G.js} +7 -6
- package/dist/chunks/{chunk-TICYLD5F.js → chunk-7CC7N3XC.js} +35 -78
- package/dist/chunks/{chunk-2CVHXFK7.js → chunk-7SRWJLSC.js} +19 -22
- package/dist/chunks/{chunk-SBMJNRTV.js → chunk-A4PFFC4Q.js} +37 -27
- package/dist/chunks/{chunk-IW6CYVX2.js → chunk-AR4BUBMU.js} +6 -1
- package/dist/chunks/{chunk-IUDJKOLB.js → chunk-B6IW3IRE.js} +15 -33
- package/dist/chunks/{chunk-JUIJI7RC.js → chunk-BAETMD3J.js} +9 -4
- package/dist/chunks/{chunk-L5WF4ZPS.js → chunk-BS4UZ44I.js} +1 -1
- package/dist/chunks/{chunk-HNQPEMYE.js → chunk-CM6LO6OC.js} +0 -1
- package/dist/chunks/{chunk-CLOP7UVD.js → chunk-CQHUZHET.js} +11 -8
- package/dist/chunks/{chunk-R456ME6J.js → chunk-CU6P5RUG.js} +17 -6
- package/dist/chunks/chunk-D5D36ZF6.js +107 -0
- package/dist/chunks/{chunk-AFP3NWSL.js → chunk-DY3JCAMX.js} +1 -1
- package/dist/chunks/{chunk-NRV7R36Q.js → chunk-EFQLEGWM.js} +3 -3
- package/dist/chunks/{chunk-BXEPA4KS.js → chunk-G6UIYQZR.js} +5 -2
- package/dist/chunks/{chunk-NNODIW4U.js → chunk-H2H4Y3TV.js} +1 -0
- package/dist/chunks/{chunk-MVFDSFV2.js → chunk-HNCXR2VS.js} +1 -1
- package/dist/chunks/{chunk-EYK7DJZV.js → chunk-J5FWKGOY.js} +1 -1
- package/dist/chunks/{chunk-PBENCR5L.js → chunk-JBCZIBFC.js} +0 -2
- package/dist/chunks/{chunk-EHUBJDDB.js → chunk-JFY5PWQC.js} +5 -3
- package/dist/chunks/{chunk-5BGP5Z64.js → chunk-JLSJMCDJ.js} +1 -1
- package/dist/chunks/{chunk-DT2GGH4D.js → chunk-JMABOQWL.js} +2 -6
- package/dist/chunks/{chunk-3S3YVOJ7.js → chunk-JSUCGZ6K.js} +1 -1
- package/dist/chunks/{chunk-MLSWIMZO.js → chunk-KBEP7VYK.js} +2 -2
- package/dist/chunks/{chunk-TAMCZHLW.js → chunk-N73TI3VG.js} +2 -2
- package/dist/chunks/chunk-O4EGE27I.js +10 -0
- package/dist/chunks/{chunk-3ZZSX5HN.js → chunk-PTABFYQ7.js} +10 -6
- package/dist/chunks/{chunk-WBCOREDZ.js → chunk-QLWI2PZ3.js} +16 -7
- package/dist/chunks/chunk-RBCE2OQH.js +32 -0
- package/dist/chunks/{chunk-BUBZ32IC.js → chunk-RPRHR56C.js} +4 -8
- package/dist/chunks/{chunk-47DYCZOK.js → chunk-RUCH6ZFL.js} +4 -0
- package/dist/chunks/{chunk-GNTTI6LA.js → chunk-T2PCSAFY.js} +1 -1
- package/dist/chunks/{chunk-XKWD2RY3.js → chunk-URZ3CH2R.js} +3 -10
- package/dist/chunks/{chunk-ALDGONEI.js → chunk-VQC7KELB.js} +1 -1
- package/dist/chunks/{chunk-FLFBYSJO.js → chunk-VQWHMWLF.js} +5 -1
- package/dist/chunks/{chunk-4R6QNG23.js → chunk-WL6ZKUVC.js} +3 -3
- package/dist/chunks/{chunk-CRTD2SBP.js → chunk-WZNPX7Q6.js} +6 -2
- package/dist/chunks/{chunk-FNGIQF43.js → chunk-XA5A27CS.js} +6 -14
- package/dist/chunks/{chunk-DK5P2YOL.js → chunk-XI3ZUTWF.js} +2 -2
- package/dist/chunks/{chunk-ZIUKZUPJ.js → chunk-XL472HHD.js} +1 -1
- package/dist/chunks/{chunk-BPRXQ2SS.js → chunk-XMW266WS.js} +1 -1
- package/dist/chunks/{chunk-DRG4236Y.js → chunk-YN6FDIBT.js} +2 -2
- package/dist/chunks/{chunk-WFB5TXRA.js → chunk-ZY2AFL4Y.js} +13 -31
- package/dist/cli/decodeText.js +6 -0
- package/dist/cli/figure.js +59 -60
- package/dist/cli/fold.js +13 -13
- package/dist/deletionEdges.js +6 -4
- package/dist/el.js +3 -1
- package/dist/figure.js +33 -31
- package/dist/figureData.js +32 -27
- package/dist/figureScene.js +43 -0
- package/dist/figureSettings.js +8 -8
- package/dist/foldVariants.js +2 -2
- package/dist/gbzCut.js +1 -1
- package/dist/genes/exonOutline.js +2 -2
- package/dist/genes/geneFiles.js +1 -1
- package/dist/genes/genePins.js +3 -3
- package/dist/gfa/gfaConverter.js +2 -2
- package/dist/gfa-core/gfaParser.js +1 -1
- package/dist/gfa-core/index.js +1 -1
- package/dist/graphLabels.js +4 -4
- package/dist/index.js +72 -73
- package/dist/labelLayout.js +8 -8
- package/dist/layout/forceCache.js +8 -8
- package/dist/layout/mergeRuns.js +2 -2
- package/dist/layout/orderedLayout.js +1 -3
- package/dist/layout/tubeMapLayout.js +6 -6
- package/dist/layout/walkRowDraw.js +11 -11
- package/dist/layout/walkRowLayout.js +3 -1
- package/dist/layout/walkStrip.js +14 -12
- package/dist/layoutEngines.js +1 -2
- package/dist/layoutModes.js +9 -9
- package/dist/nodeWidths.js +1 -3
- package/dist/pathColors.js +5 -5
- package/dist/pipeline.js +7 -7
- package/dist/referenceRampCss.js +9 -9
- package/dist/referenceStrip.js +9 -9
- package/dist/renderer/Canvas2DRenderer.js +2 -2
- package/dist/renderer/GeometryBuilder.js +8 -8
- package/dist/renderer/canvas.js +1 -1
- package/dist/renderer/svgCanvas.js +1 -1
- package/dist/tubeMap/axis.js +5 -5
- package/dist/tubeMap/bundle.js +7 -7
- package/dist/tubeMap/coarsen.js +6 -6
- package/dist/tubeMap/deviations.js +5 -5
- package/dist/tubeMap/draw.js +1 -1
- package/dist/tubeMap/genes.js +6 -6
- package/dist/tubeMap/nodeColors.js +9 -9
- package/dist/types/bubbles/bubblesFromGraph.d.ts +1 -0
- package/dist/types/bubbles/classifyBubble.d.ts +0 -1
- package/dist/types/cli/decodeText.d.ts +1 -0
- package/dist/types/cli/figure.d.ts +4 -15
- package/dist/types/deletionEdges.d.ts +3 -5
- package/dist/types/el.d.ts +1 -0
- package/dist/types/figureData.d.ts +7 -26
- package/dist/types/figureScene.d.ts +31 -0
- package/dist/types/genes/geneFiles.d.ts +2 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/layout/deletionRoutes.d.ts +1 -1
- package/dist/types/layout/orderedLayout.d.ts +0 -6
- package/dist/types/layout/walkRowLayout.d.ts +1 -0
- package/dist/types/nodeWidths.d.ts +0 -1
- package/dist/types/renderer/Canvas2DRenderer.d.ts +1 -0
- package/dist/types/renderer/canvas.d.ts +2 -2
- package/dist/types/tubeMap/draw.d.ts +1 -0
- package/dist/types/util/geometry.d.ts +3 -3
- package/dist/types/version.d.ts +1 -1
- package/dist/util/SpatialIndex.js +4 -4
- package/dist/util/edgeCurves.js +3 -3
- package/dist/util/geometry.js +3 -3
- package/dist/util/hitDetection.js +5 -5
- package/dist/version.js +1 -1
- package/dist/viewport.js +8 -8
- package/dist/walkEncoding.js +9 -9
- package/dist/walkHighlight.js +10 -10
- package/dist/walkKey.js +5 -5
- package/package.json +3 -6
- package/dist/chunks/bandage-layout-3AR6BCUD.js +0 -4694
- package/dist/chunks/chunk-4BYTEJGW.js +0 -44
- package/dist/chunks/chunk-7XHHVYG7.js +0 -13
- package/dist/loadBandage.js +0 -6
- package/dist/types/bandage/bandage-layout.d.ts +0 -14
- package/dist/types/loadBandage.d.ts +0 -3
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
layoutEngine
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JMABOQWL.js";
|
|
4
4
|
import {
|
|
5
5
|
layoutModeByValue
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WL6ZKUVC.js";
|
|
7
7
|
import {
|
|
8
8
|
parseRegion
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
layoutGeometryInputs
|
|
12
|
-
} from "./chunk-LOCJN3BZ.js";
|
|
9
|
+
} from "./chunk-VQWHMWLF.js";
|
|
13
10
|
import {
|
|
14
11
|
version
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-J5FWKGOY.js";
|
|
16
13
|
import {
|
|
17
14
|
axisScaleOf
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import {
|
|
20
|
-
facetLifts,
|
|
21
|
-
walkLift
|
|
22
|
-
} from "./chunk-R456ME6J.js";
|
|
15
|
+
} from "./chunk-BS4UZ44I.js";
|
|
23
16
|
import {
|
|
24
17
|
walkKey
|
|
25
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-4ETPXDO6.js";
|
|
26
19
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} from "./chunk-SBMJNRTV.js";
|
|
20
|
+
figureScene
|
|
21
|
+
} from "./chunk-D5D36ZF6.js";
|
|
30
22
|
import {
|
|
31
23
|
abgrAlpha,
|
|
32
24
|
abgrBlue,
|
|
@@ -34,32 +26,16 @@ import {
|
|
|
34
26
|
abgrRed
|
|
35
27
|
} from "./chunk-G2FD7S3C.js";
|
|
36
28
|
import {
|
|
37
|
-
pathLegend,
|
|
38
|
-
walkLabelsOf
|
|
39
|
-
} from "./chunk-TWRLC3KK.js";
|
|
40
|
-
import {
|
|
41
|
-
drawingBounds,
|
|
42
29
|
engineSettingsOf,
|
|
43
30
|
fitTransform,
|
|
44
31
|
forceLayout,
|
|
45
32
|
loadGraph
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import {
|
|
48
|
-
referenceLabel
|
|
49
|
-
} from "./chunk-RAKOB6IV.js";
|
|
50
|
-
import {
|
|
51
|
-
resolveColorScheme
|
|
52
|
-
} from "./chunk-JKJWSY4V.js";
|
|
53
|
-
import {
|
|
54
|
-
deletionDrawing,
|
|
55
|
-
deletionEdges
|
|
56
|
-
} from "./chunk-N6FECAXP.js";
|
|
33
|
+
} from "./chunk-2QLLQJ72.js";
|
|
57
34
|
import {
|
|
58
35
|
isBackbone
|
|
59
36
|
} from "./chunk-FYQWPEEY.js";
|
|
60
37
|
import {
|
|
61
|
-
facetCells
|
|
62
|
-
facetSettingOf
|
|
38
|
+
facetCells
|
|
63
39
|
} from "./chunk-XV4P5KEQ.js";
|
|
64
40
|
|
|
65
41
|
// src/figureData.ts
|
|
@@ -85,39 +61,24 @@ function figureData(graph, layout, o = {}) {
|
|
|
85
61
|
}
|
|
86
62
|
const width = o.width ?? 1200;
|
|
87
63
|
const height = o.height ?? 800;
|
|
88
|
-
const region = o.region;
|
|
89
64
|
const pixelRows = layout.pixelRows ?? false;
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
65
|
+
const {
|
|
66
|
+
bounds,
|
|
67
|
+
colorScheme,
|
|
68
|
+
drawnDeletions,
|
|
69
|
+
lift,
|
|
70
|
+
facet,
|
|
71
|
+
panels: facetted,
|
|
72
|
+
labelOf,
|
|
73
|
+
referenceName,
|
|
74
|
+
reference,
|
|
75
|
+
geometry
|
|
76
|
+
} = figureScene(graph, layout, o);
|
|
93
77
|
const fit = fitTransform(bounds, width, height, pixelRows);
|
|
94
78
|
if (!fit) {
|
|
95
79
|
throw new Error("the layout drew nothing to fit");
|
|
96
80
|
}
|
|
97
81
|
const axis = axisScaleOf(fit.scale, pixelRows);
|
|
98
|
-
const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
99
|
-
const colorScheme = resolveColorScheme(o.colorScheme ?? "auto", graph);
|
|
100
|
-
const rampDomain = o.colorDomain ?? region;
|
|
101
|
-
const referenceRamp = colorScheme === "reference-position" ? computeReferenceRamp(graph, rampDomain) : void 0;
|
|
102
|
-
const drawnDeletions = deletionDrawing(
|
|
103
|
-
graph,
|
|
104
|
-
deletionEdges(graph),
|
|
105
|
-
o.showDeletionEdges
|
|
106
|
-
);
|
|
107
|
-
const layers = o.walks ?? [];
|
|
108
|
-
const walkRamp = layers.some((l) => l.color?.field === "reference") ? referenceRamp ?? computeReferenceRamp(graph, rampDomain) : void 0;
|
|
109
|
-
const lift = layers.length > 0 ? walkLift(graph, layers, walkRamp) : void 0;
|
|
110
|
-
const facet = facetSettingOf(o.facet);
|
|
111
|
-
const facetted = facet.field && lift && lift.walks.length > 1 ? facetLifts(graph, lift, layers, walkRamp) : void 0;
|
|
112
|
-
const labels = walkLabelsOf(
|
|
113
|
-
graph.paths?.length ? pathLegend(graph.paths) : []
|
|
114
|
-
);
|
|
115
|
-
const labelOf = (name) => labels.get(name) ?? name;
|
|
116
|
-
const referenceName = o.referenceName ?? referenceLabel(graph, region);
|
|
117
|
-
const reference = lift?.referenceDomain && {
|
|
118
|
-
...lift.referenceDomain,
|
|
119
|
-
name: referenceName
|
|
120
|
-
};
|
|
121
82
|
const panels = [];
|
|
122
83
|
if (facetted) {
|
|
123
84
|
const place = facetCells(
|
|
@@ -178,20 +139,7 @@ function figureData(graph, layout, o = {}) {
|
|
|
178
139
|
"alpha"
|
|
179
140
|
]);
|
|
180
141
|
for (const { highlight, name: panel } of panels) {
|
|
181
|
-
const batch =
|
|
182
|
-
...layoutGeometryInputs(layout, drawnDeletions),
|
|
183
|
-
graph,
|
|
184
|
-
nodeById,
|
|
185
|
-
colorScheme,
|
|
186
|
-
contigThickness: o.contigThickness ?? 6,
|
|
187
|
-
connectorThickness: o.connectorThickness ?? 2,
|
|
188
|
-
drawPaths: false,
|
|
189
|
-
nodeWidth: o.nodeWidth ?? "depth",
|
|
190
|
-
linearLayout: o.linearLayout,
|
|
191
|
-
highlight,
|
|
192
|
-
axis,
|
|
193
|
-
referenceRamp
|
|
194
|
-
});
|
|
142
|
+
const batch = geometry(highlight, axis);
|
|
195
143
|
for (const [node, run] of batch.nodeStrokeRuns) {
|
|
196
144
|
for (let i = run.start; i < run.start + run.count; i++) {
|
|
197
145
|
const s = batch.nodeStrokes[i];
|
|
@@ -275,18 +223,27 @@ function figureData(graph, layout, o = {}) {
|
|
|
275
223
|
}
|
|
276
224
|
};
|
|
277
225
|
}
|
|
278
|
-
async function
|
|
279
|
-
const region = spec.region ? parseRegion(spec.region) : void 0;
|
|
226
|
+
async function laidOutGraph(text, name, region, spec) {
|
|
280
227
|
const graph = loadGraph(text, name, { referencePath: spec.referencePath });
|
|
281
228
|
const layout = layoutModeByValue(spec.layout ?? "force").run(graph, region) ?? (await forceLayout(graph, engineSettingsOf(spec), layoutEngine)).result;
|
|
229
|
+
return { graph, layout };
|
|
230
|
+
}
|
|
231
|
+
function walkLayers(walks) {
|
|
232
|
+
return walks?.map((w) => typeof w === "string" ? { walk: w } : w);
|
|
233
|
+
}
|
|
234
|
+
async function gfaFigureData(text, name, spec = {}) {
|
|
235
|
+
const region = spec.region ? parseRegion(spec.region) : void 0;
|
|
236
|
+
const { graph, layout } = await laidOutGraph(text, name, region, spec);
|
|
282
237
|
return figureData(graph, layout, {
|
|
283
238
|
...spec,
|
|
284
239
|
region,
|
|
285
|
-
walks: spec.walks
|
|
240
|
+
walks: walkLayers(spec.walks)
|
|
286
241
|
});
|
|
287
242
|
}
|
|
288
243
|
|
|
289
244
|
export {
|
|
290
245
|
figureData,
|
|
246
|
+
laidOutGraph,
|
|
247
|
+
walkLayers,
|
|
291
248
|
gfaFigureData
|
|
292
249
|
};
|
|
@@ -206,15 +206,16 @@ function bowAround(p1x, p1y, p2x, p2y, toward, maxBow) {
|
|
|
206
206
|
function yToXOf({ scaleX, scaleY }) {
|
|
207
207
|
return scaleY / scaleX;
|
|
208
208
|
}
|
|
209
|
-
var
|
|
209
|
+
var PATH_RIBBON_SPACING_PX = 3;
|
|
210
210
|
function drawnDirection(a, b, yToX) {
|
|
211
211
|
const dx = b.x - a.x;
|
|
212
212
|
const dy = (b.y - a.y) * yToX;
|
|
213
213
|
const len = Math.hypot(dx, dy);
|
|
214
214
|
return len === 0 ? void 0 : { x: dx / len, y: dy / len };
|
|
215
215
|
}
|
|
216
|
-
function pathRibbonOffsets(fromSegments, toSegments, count, axis
|
|
216
|
+
function pathRibbonOffsets(fromSegments, toSegments, count, axis) {
|
|
217
217
|
const yToX = yToXOf(axis);
|
|
218
|
+
const spacing = PATH_RIBBON_SPACING_PX / Math.max(axis.scaleX, 1e-6);
|
|
218
219
|
const dir = drawnDirection(
|
|
219
220
|
fromSegments[fromSegments.length - 1],
|
|
220
221
|
toSegments[0],
|
|
@@ -270,15 +271,15 @@ function edgeJoinOf(edge, stranded = false) {
|
|
|
270
271
|
const sides = strandSides(edge);
|
|
271
272
|
return self === false ? sides : sides.from === sides.to ? sides.from : true;
|
|
272
273
|
}
|
|
273
|
-
function hairpinCurves(attach, reach
|
|
274
|
+
function hairpinCurves(attach, reach) {
|
|
274
275
|
const { at, inward } = attach;
|
|
275
276
|
const dx = inward ? at.x - inward.x : 1;
|
|
276
277
|
const dy = inward ? at.y - inward.y : 0;
|
|
277
278
|
const len = Math.hypot(dx, dy) || 1;
|
|
278
279
|
const ux = dx / len;
|
|
279
280
|
const uy = dy / len;
|
|
280
|
-
const px = at.x
|
|
281
|
-
const py = at.y
|
|
281
|
+
const px = at.x;
|
|
282
|
+
const py = at.y;
|
|
282
283
|
const nearX = px + ux * reach / 3;
|
|
283
284
|
const nearY = py + uy * reach / 3;
|
|
284
285
|
const apexX = px + ux * reach;
|
|
@@ -308,7 +309,7 @@ function hairpinCurves(attach, reach, offsetX, offsetY) {
|
|
|
308
309
|
}
|
|
309
310
|
];
|
|
310
311
|
}
|
|
311
|
-
function computeEdgeCurves(fromSegments, toSegments, join,
|
|
312
|
+
function computeEdgeCurves(fromSegments, toSegments, join, axis, bypassed = [], maxBowIn) {
|
|
312
313
|
const scale = axis.scaleX;
|
|
313
314
|
const yToX = yToXOf(axis);
|
|
314
315
|
const maxBow = maxBowIn ?? (axis.pixelRows ? MAX_ROW_BOW_PX : void 0);
|
|
@@ -321,8 +322,6 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
|
|
|
321
322
|
scaleYOf(fromSegments, yToX),
|
|
322
323
|
scaleYOf(toSegments, yToX),
|
|
323
324
|
join,
|
|
324
|
-
offsetX,
|
|
325
|
-
offsetY * yToX,
|
|
326
325
|
{ scaleX: scale, scaleY: scale },
|
|
327
326
|
scaleYOf(bypassed, yToX),
|
|
328
327
|
// the cap is a y measure and the body works in x units, so it converts
|
|
@@ -335,9 +334,7 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
|
|
|
335
334
|
if (typeof join === "string") {
|
|
336
335
|
return hairpinCurves(
|
|
337
336
|
attachment(fromSegments, join),
|
|
338
|
-
selfLoopReach(fromSegments, scale)
|
|
339
|
-
offsetX,
|
|
340
|
-
offsetY
|
|
337
|
+
selfLoopReach(fromSegments, scale)
|
|
341
338
|
);
|
|
342
339
|
}
|
|
343
340
|
const loop = join === true;
|
|
@@ -346,10 +343,10 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
|
|
|
346
343
|
const toAttach = attachment(toSegments, sides.to);
|
|
347
344
|
const fromEnd = fromAttach.at;
|
|
348
345
|
const toStart = toAttach.at;
|
|
349
|
-
const p1x = fromEnd.x
|
|
350
|
-
const p1y = fromEnd.y
|
|
351
|
-
const p2x = toStart.x
|
|
352
|
-
const p2y = toStart.y
|
|
346
|
+
const p1x = fromEnd.x;
|
|
347
|
+
const p1y = fromEnd.y;
|
|
348
|
+
const p2x = toStart.x;
|
|
349
|
+
const p2y = toStart.y;
|
|
353
350
|
if (loop) {
|
|
354
351
|
let segDirX = 1;
|
|
355
352
|
let segDirY = 0;
|
|
@@ -365,8 +362,8 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
|
|
|
365
362
|
const ext = selfLoopReach(fromSegments, scale);
|
|
366
363
|
const perpX = -segDirY;
|
|
367
364
|
const perpY = segDirX;
|
|
368
|
-
const midX = (fromEnd.x + toStart.x) / 2 +
|
|
369
|
-
const midY = (fromEnd.y + toStart.y) / 2 +
|
|
365
|
+
const midX = (fromEnd.x + toStart.x) / 2 + perpX * ext;
|
|
366
|
+
const midY = (fromEnd.y + toStart.y) / 2 + perpY * ext;
|
|
370
367
|
const cp1x = p1x + segDirX * ext;
|
|
371
368
|
const cp1y = p1y + segDirY * ext;
|
|
372
369
|
const cp2x = p2x - segDirX * ext;
|
|
@@ -441,10 +438,10 @@ function computeEdgeCurves(fromSegments, toSegments, join, offsetX, offsetY, axi
|
|
|
441
438
|
{
|
|
442
439
|
x0: p1x,
|
|
443
440
|
y0: p1y,
|
|
444
|
-
cx0: cx1 +
|
|
445
|
-
cy0: cy1 +
|
|
446
|
-
cx1: cx2 +
|
|
447
|
-
cy1: cy2 +
|
|
441
|
+
cx0: cx1 + bulgeX - spreadX,
|
|
442
|
+
cy0: cy1 + bulgeY - spreadY,
|
|
443
|
+
cx1: cx2 + bulgeX + spreadX,
|
|
444
|
+
cy1: cy2 + bulgeY + spreadY,
|
|
448
445
|
x1: p2x,
|
|
449
446
|
y1: p2y
|
|
450
447
|
}
|
|
@@ -521,7 +518,7 @@ export {
|
|
|
521
518
|
strandSides,
|
|
522
519
|
bowAround,
|
|
523
520
|
yToXOf,
|
|
524
|
-
|
|
521
|
+
PATH_RIBBON_SPACING_PX,
|
|
525
522
|
pathRibbonOffsets,
|
|
526
523
|
selfLinkOf,
|
|
527
524
|
edgeJoinOf,
|
|
@@ -5,17 +5,17 @@ import {
|
|
|
5
5
|
} from "./chunk-G2FD7S3C.js";
|
|
6
6
|
import {
|
|
7
7
|
baseEdgeCurves
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ZY2AFL4Y.js";
|
|
9
9
|
import {
|
|
10
10
|
PATH_LIGHTNESS,
|
|
11
11
|
PATH_SATURATION,
|
|
12
12
|
nameHue,
|
|
13
13
|
pathHueAt
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-3XSM4OZU.js";
|
|
15
15
|
import {
|
|
16
16
|
meanDepth,
|
|
17
17
|
nodeWidthPx
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-JBCZIBFC.js";
|
|
19
19
|
import {
|
|
20
20
|
referenceMidpoints
|
|
21
21
|
} from "./chunk-ES2N6V56.js";
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
strandSides,
|
|
26
26
|
translateCurves,
|
|
27
27
|
yToXOf
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-7SRWJLSC.js";
|
|
29
29
|
|
|
30
30
|
// src/renderer/GeometryBuilder.ts
|
|
31
31
|
var EDGE_DEFAULT_COLOR = packAbgr(119, 119, 119, 217);
|
|
@@ -551,25 +551,24 @@ function buildGeometry(options) {
|
|
|
551
551
|
const edgeColor = !highlight || onWalk ? plainEdgeColor : fadeAbgr(plainEdgeColor, FADED_ALPHA);
|
|
552
552
|
const toNode = nodeById.get(edge.to);
|
|
553
553
|
const intoHalfWidth = (toNode ? nodeWidthPx(toNode, contigThickness, nodeWidth, depthNorm) : contigThickness) / 2;
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
if (viewportBounds && !isBezierInBounds(curves, viewportBounds)) {
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
554
|
+
const inView = (curves) => !viewportBounds || isBezierInBounds(curves, viewportBounds);
|
|
555
|
+
const stroke = (curves, thickness, color) => {
|
|
559
556
|
if (isDeletion) {
|
|
560
557
|
for (const dash of dashCurves(curves, DELETION_DASH_PX / scale)) {
|
|
561
|
-
edgeCurves.push({ curves: dash, thickness
|
|
558
|
+
edgeCurves.push({ curves: dash, thickness, color });
|
|
562
559
|
}
|
|
563
560
|
} else {
|
|
564
|
-
edgeCurves.push({ curves, thickness
|
|
561
|
+
edgeCurves.push({ curves, thickness, color });
|
|
565
562
|
}
|
|
566
|
-
|
|
563
|
+
};
|
|
564
|
+
const arrowOn = (curves) => {
|
|
565
|
+
const head = showArrows ? arrowheadFor({
|
|
567
566
|
curves,
|
|
568
567
|
edgeHalfWidth: connectorThickness / 2,
|
|
569
568
|
nodeHalfWidth: intoHalfWidth,
|
|
570
569
|
scale,
|
|
571
570
|
yToX,
|
|
572
|
-
color:
|
|
571
|
+
color: edgeColor,
|
|
573
572
|
fromSegments,
|
|
574
573
|
toSegments
|
|
575
574
|
}) : void 0;
|
|
@@ -602,17 +601,22 @@ function buildGeometry(options) {
|
|
|
602
601
|
}
|
|
603
602
|
const offset = (lane - (laneWalks.length - 1) / 2) * laneWidth * worldPerScreenPx;
|
|
604
603
|
const curves = offset === 0 ? baseCurves : translateCurves(baseCurves, nx * offset, ny * offset / yToX);
|
|
605
|
-
if (
|
|
606
|
-
|
|
604
|
+
if (inView(curves)) {
|
|
605
|
+
stroke(
|
|
606
|
+
curves,
|
|
607
|
+
laneWidth / 2,
|
|
608
|
+
walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor
|
|
609
|
+
);
|
|
607
610
|
}
|
|
608
|
-
edgeCurves.push({
|
|
609
|
-
curves,
|
|
610
|
-
thickness: laneWidth / 2,
|
|
611
|
-
color: walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor
|
|
612
|
-
});
|
|
613
611
|
});
|
|
612
|
+
if (edgeCurves.length > edgeCurveStart) {
|
|
613
|
+
arrowOn(baseCurves);
|
|
614
|
+
}
|
|
614
615
|
} else if (!ribbons) {
|
|
615
|
-
|
|
616
|
+
if (inView(baseCurves)) {
|
|
617
|
+
stroke(baseCurves, edgeThickness, edgeColor);
|
|
618
|
+
arrowOn(baseCurves);
|
|
619
|
+
}
|
|
616
620
|
} else {
|
|
617
621
|
const offsets = pathRibbonOffsets(
|
|
618
622
|
fromSegments,
|
|
@@ -622,14 +626,20 @@ function buildGeometry(options) {
|
|
|
622
626
|
);
|
|
623
627
|
const arrowRibbon = Math.floor((numPaths - 1) / 2);
|
|
624
628
|
for (let pathIdx = 0; pathIdx < numPaths; pathIdx++) {
|
|
625
|
-
const
|
|
629
|
+
const { x, y } = offsets[pathIdx];
|
|
630
|
+
const curves = x === 0 && y === 0 ? baseCurves : translateCurves(baseCurves, x, y);
|
|
631
|
+
if (!inView(curves)) {
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
626
634
|
const ribbonColor = pathColorByName(edge.pathIds[pathIdx]);
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
highlight && (highlight.walks.length ? !highlight.names.has(edge.pathIds[pathIdx]) : !onWalk) ? fadeAbgr(ribbonColor, FADED_ALPHA) : ribbonColor
|
|
631
|
-
pathIdx === arrowRibbon ? edgeColor : void 0
|
|
635
|
+
stroke(
|
|
636
|
+
curves,
|
|
637
|
+
edgeThickness,
|
|
638
|
+
highlight && (highlight.walks.length ? !highlight.names.has(edge.pathIds[pathIdx]) : !onWalk) ? fadeAbgr(ribbonColor, FADED_ALPHA) : ribbonColor
|
|
632
639
|
);
|
|
640
|
+
if (pathIdx === arrowRibbon) {
|
|
641
|
+
arrowOn(curves);
|
|
642
|
+
}
|
|
633
643
|
}
|
|
634
644
|
}
|
|
635
645
|
const edgeCurveCount = edgeCurves.length - edgeCurveStart;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
stableCoordinate
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5I3K4R2G.js";
|
|
4
4
|
import {
|
|
5
5
|
pathOrigin,
|
|
6
6
|
surveyPaths
|
|
@@ -95,7 +95,12 @@ function convertGFAToGraph(gfaGraph, name = "Imported GFA") {
|
|
|
95
95
|
}
|
|
96
96
|
return id;
|
|
97
97
|
};
|
|
98
|
+
const declared = /* @__PURE__ */ new Set();
|
|
98
99
|
for (const gfaNode of gfaGraph.nodes) {
|
|
100
|
+
if (declared.has(gfaNode.id)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
declared.add(gfaNode.id);
|
|
99
104
|
const depth = statedDepth(gfaNode) ?? Math.max(traversals.get(gfaNode.id) ?? 1, 1);
|
|
100
105
|
nodes.push(makeNode(gfaNode, canonical.get(gfaNode.id) ?? "+", depth));
|
|
101
106
|
}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-M6LK4GII.js";
|
|
13
13
|
|
|
14
14
|
// src/tubeMap/draw.ts
|
|
15
|
-
import { curvePaths, nodeOutlinePath } from "@jbrowse/tubemap-core";
|
|
15
|
+
import { curvePaths, flattenPath, nodeOutlinePath } from "@jbrowse/tubemap-core";
|
|
16
16
|
function parsePath(d) {
|
|
17
17
|
const tokens = d.trim().split(/[\s,]+/);
|
|
18
18
|
const commands = [];
|
|
@@ -61,7 +61,15 @@ function extentOf(commands) {
|
|
|
61
61
|
}
|
|
62
62
|
function shapeOf(d, color, id, haplotype, reference) {
|
|
63
63
|
const commands = parsePath(d);
|
|
64
|
-
return {
|
|
64
|
+
return {
|
|
65
|
+
commands,
|
|
66
|
+
outline: flattenPath(d, 12),
|
|
67
|
+
color,
|
|
68
|
+
id,
|
|
69
|
+
haplotype,
|
|
70
|
+
reference,
|
|
71
|
+
...extentOf(commands)
|
|
72
|
+
};
|
|
65
73
|
}
|
|
66
74
|
function trackColors(layout, pathColors) {
|
|
67
75
|
return new Map(
|
|
@@ -302,36 +310,6 @@ function drawMismatches(ctx, marks, frame) {
|
|
|
302
310
|
}
|
|
303
311
|
}
|
|
304
312
|
}
|
|
305
|
-
function outline(commands, x, y) {
|
|
306
|
-
const points = [];
|
|
307
|
-
let cx = 0;
|
|
308
|
-
let cy = 0;
|
|
309
|
-
const STEPS = 12;
|
|
310
|
-
for (const c of commands) {
|
|
311
|
-
if (c.op === "C" || c.op === "Q") {
|
|
312
|
-
for (let i = 1; i <= STEPS; i++) {
|
|
313
|
-
const t = i / STEPS;
|
|
314
|
-
const u = 1 - t;
|
|
315
|
-
const [px, py] = c.op === "C" ? [
|
|
316
|
-
u * u * u * cx + 3 * u * u * t * c.x1 + 3 * u * t * t * c.x2 + t * t * t * c.x,
|
|
317
|
-
u * u * u * cy + 3 * u * u * t * c.y1 + 3 * u * t * t * c.y2 + t * t * t * c.y
|
|
318
|
-
] : [
|
|
319
|
-
u * u * cx + 2 * u * t * c.x1 + t * t * c.x,
|
|
320
|
-
u * u * cy + 2 * u * t * c.y1 + t * t * c.y
|
|
321
|
-
];
|
|
322
|
-
points.push([x(px), y(py)]);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (c.op !== "Z") {
|
|
326
|
-
cx = "x" in c ? c.x : cx;
|
|
327
|
-
cy = "y" in c ? c.y : cy;
|
|
328
|
-
if (c.op !== "C" && c.op !== "Q") {
|
|
329
|
-
points.push([x(cx), y(cy)]);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return points;
|
|
334
|
-
}
|
|
335
313
|
function inside(points, sx, sy) {
|
|
336
314
|
let hit = false;
|
|
337
315
|
for (let i = 0, j = points.length - 1; i < points.length; j = i++) {
|
|
@@ -353,7 +331,11 @@ function tubeMapTrackAt(picture, { x, y }, sx, sy) {
|
|
|
353
331
|
}
|
|
354
332
|
}
|
|
355
333
|
for (const s of shapes) {
|
|
356
|
-
if (s.reference === reference && x(s.x0) <= sx && sx <= x(s.x1) && inside(
|
|
334
|
+
if (s.reference === reference && x(s.x0) <= sx && sx <= x(s.x1) && inside(
|
|
335
|
+
s.outline.map(([px, py]) => [x(px), y(py)]),
|
|
336
|
+
sx,
|
|
337
|
+
sy
|
|
338
|
+
)) {
|
|
357
339
|
return s.id;
|
|
358
340
|
}
|
|
359
341
|
}
|
|
@@ -2,10 +2,13 @@ import {
|
|
|
2
2
|
alongRow,
|
|
3
3
|
boxesGenes,
|
|
4
4
|
rowPitch
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EFQLEGWM.js";
|
|
6
6
|
import {
|
|
7
7
|
el
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-H2H4Y3TV.js";
|
|
9
|
+
import {
|
|
10
|
+
READOUT_ROOM
|
|
11
|
+
} from "./chunk-54POIBVC.js";
|
|
9
12
|
import {
|
|
10
13
|
pathOrigin
|
|
11
14
|
} from "./chunk-M6LK4GII.js";
|
|
@@ -24,7 +27,6 @@ var PAD_PX = 6;
|
|
|
24
27
|
var WALK_STRIP_CEILING_PX = 260;
|
|
25
28
|
var LABEL_FONT_PX = 11;
|
|
26
29
|
var MIN_ROW_PX = 3;
|
|
27
|
-
var READOUT_ROOM = 1.3;
|
|
28
30
|
var MARK_INK = "#111";
|
|
29
31
|
var TICK_PX = 3;
|
|
30
32
|
function stripMarks(graph, rows, node) {
|
|
@@ -59,7 +61,10 @@ function spansOf(graph, name) {
|
|
|
59
61
|
return byName.get(name);
|
|
60
62
|
}
|
|
61
63
|
const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));
|
|
62
|
-
const
|
|
64
|
+
const origin = pathOrigin(name).name;
|
|
65
|
+
const pieces = (graph.paths ?? []).filter(
|
|
66
|
+
(p) => origin === graph.referencePath ? pathOrigin(p.name).name === origin : p.name === name
|
|
67
|
+
);
|
|
63
68
|
let spans;
|
|
64
69
|
if (pieces.every((p) => p.start !== void 0)) {
|
|
65
70
|
spans = { ids: [], starts: [], ends: [] };
|
|
@@ -3,12 +3,20 @@ import {
|
|
|
3
3
|
} from "./chunk-FX4RDMDN.js";
|
|
4
4
|
import {
|
|
5
5
|
referenceOrder
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CM6LO6OC.js";
|
|
7
7
|
import {
|
|
8
8
|
isBackbone
|
|
9
9
|
} from "./chunk-FYQWPEEY.js";
|
|
10
10
|
|
|
11
11
|
// src/bubbles/bubblesFromGraph.ts
|
|
12
|
+
function relax(best, to, cur, add) {
|
|
13
|
+
const prev = best.get(to);
|
|
14
|
+
best.set(to, {
|
|
15
|
+
min: Math.min(prev?.min ?? Infinity, cur.min + add),
|
|
16
|
+
max: Math.max(prev?.max ?? -Infinity, cur.max + add),
|
|
17
|
+
n: Math.min(SATURATED_PATH_COUNT, cur.n + (prev?.n ?? 0))
|
|
18
|
+
});
|
|
19
|
+
}
|
|
12
20
|
function bubblesFromGraph(graph) {
|
|
13
21
|
if (!graph.nodes.some(isBackbone)) {
|
|
14
22
|
return [];
|
|
@@ -61,13 +69,7 @@ function bubblesFromGraph(graph) {
|
|
|
61
69
|
if (ti > i1) {
|
|
62
70
|
continue;
|
|
63
71
|
}
|
|
64
|
-
|
|
65
|
-
const prev = best.get(t);
|
|
66
|
-
best.set(t, {
|
|
67
|
-
min: Math.min(prev?.min ?? Infinity, cur.min + add),
|
|
68
|
-
max: Math.max(prev?.max ?? -Infinity, cur.max + add),
|
|
69
|
-
n: Math.min(SATURATED_PATH_COUNT, cur.n + (prev?.n ?? 0))
|
|
70
|
-
});
|
|
72
|
+
relax(best, t, cur, t === end.id ? 0 : byId.get(t).length);
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
const walked = walkIndex && walkRoutes(graph, byId, walkIndex, start.id, end.id);
|
|
@@ -167,6 +169,7 @@ function walkRoutes(graph, byId, walkIndex, startId, endId) {
|
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
export {
|
|
172
|
+
relax,
|
|
170
173
|
bubblesFromGraph,
|
|
171
174
|
walkIndexOf,
|
|
172
175
|
walkRoutes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodedColor,
|
|
3
3
|
resolveEncoding
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VQC7KELB.js";
|
|
5
5
|
import {
|
|
6
6
|
pathOrigin
|
|
7
7
|
} from "./chunk-M6LK4GII.js";
|
|
@@ -28,10 +28,14 @@ function walkHighlight(graph, name) {
|
|
|
28
28
|
const lengthOf = (id) => byId.get(id)?.length ?? 0;
|
|
29
29
|
const bpOf = (path) => path.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0);
|
|
30
30
|
const bp = pieces.reduce((sum, piece) => sum + bpOf(piece), 0);
|
|
31
|
-
const
|
|
31
|
+
const extentOf = (ps) => {
|
|
32
|
+
const start = Math.min(...ps.map((p) => p.start ?? Infinity));
|
|
33
|
+
return Number.isFinite(start) ? { start, end: Math.max(...ps.map((p) => (p.start ?? 0) + bpOf(p))) } : void 0;
|
|
34
|
+
};
|
|
35
|
+
const extent = extentOf(pieces);
|
|
36
|
+
const range = extent && {
|
|
32
37
|
contig: first.contig ?? panSNContig(pathOrigin(name).name),
|
|
33
|
-
|
|
34
|
-
end: Math.max(...pieces.map((p) => (p.start ?? 0) + bpOf(p)))
|
|
38
|
+
...extent
|
|
35
39
|
};
|
|
36
40
|
const span = range ? range.end - range.start : bp;
|
|
37
41
|
const nodeIds = /* @__PURE__ */ new Set();
|
|
@@ -59,7 +63,14 @@ function walkHighlight(graph, name) {
|
|
|
59
63
|
});
|
|
60
64
|
}
|
|
61
65
|
const reference = isReference(graph, name);
|
|
62
|
-
const
|
|
66
|
+
const referenceSpan = () => {
|
|
67
|
+
const referencePieces = reference ? [] : (graph.paths ?? []).filter((p) => isReference(graph, p.name));
|
|
68
|
+
if (referencePieces.length === 0) {
|
|
69
|
+
return void 0;
|
|
70
|
+
}
|
|
71
|
+
const e = extentOf(referencePieces);
|
|
72
|
+
return e ? e.end - e.start : referencePieces.reduce((sum, piece) => sum + bpOf(piece), 0);
|
|
73
|
+
};
|
|
63
74
|
return {
|
|
64
75
|
name,
|
|
65
76
|
reference,
|
|
@@ -69,7 +80,7 @@ function walkHighlight(graph, name) {
|
|
|
69
80
|
progress,
|
|
70
81
|
steps: pieces.reduce((sum, piece) => sum + piece.nodeIds.length, 0),
|
|
71
82
|
bp,
|
|
72
|
-
referenceBp:
|
|
83
|
+
referenceBp: referenceSpan()
|
|
73
84
|
};
|
|
74
85
|
}
|
|
75
86
|
function laneColors(graph, walk, encoding, ramp) {
|