@jbrowse/bandage-core 10.2.2 → 10.2.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 +8 -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-EYK7DJZV.js → chunk-2CHS5LMM.js} +1 -1
- package/dist/chunks/{chunk-XTCNEKO5.js → chunk-2QLLQJ72.js} +15 -13
- 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-2CVHXFK7.js → chunk-7SRWJLSC.js} +19 -22
- package/dist/chunks/{chunk-SBMJNRTV.js → chunk-A4PFFC4Q.js} +37 -27
- package/dist/chunks/{chunk-FNGIQF43.js → chunk-ABUIN5AK.js} +6 -14
- 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-ASSNZXCF.js → chunk-GINYTQ43.js} +44 -103
- 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-JA2HJIYS.js +71 -0
- package/dist/chunks/{chunk-PBENCR5L.js → chunk-JBCZIBFC.js} +0 -2
- 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-DRG4236Y.js → chunk-KC7T5RWG.js} +2 -20
- 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-TICYLD5F.js → chunk-XAWLIU54.js} +35 -78
- 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-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/bubbleHalos.d.ts +2 -8
- 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/labelLayout.d.ts +1 -5
- 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/chunks/chunk-EHUBJDDB.js +0 -135
- package/dist/loadBandage.js +0 -6
- package/dist/types/bandage/bandage-layout.d.ts +0 -14
- package/dist/types/loadBandage.d.ts +0 -3
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bubbleSegmentIds,
|
|
3
|
+
classifyBubble
|
|
4
|
+
} from "./chunk-URZ3CH2R.js";
|
|
5
|
+
import {
|
|
6
|
+
svgPath
|
|
7
|
+
} from "./chunk-7SRWJLSC.js";
|
|
8
|
+
import {
|
|
9
|
+
isBackbone
|
|
10
|
+
} from "./chunk-FYQWPEEY.js";
|
|
11
|
+
|
|
12
|
+
// src/bubbles/bubbleHalos.ts
|
|
13
|
+
var WHOLE_FRACTION = 0.9;
|
|
14
|
+
function coversGraph(members, nodes) {
|
|
15
|
+
return members + 2 >= nodes || members >= WHOLE_FRACTION * nodes;
|
|
16
|
+
}
|
|
17
|
+
var SMALL_VARIANT_BP = 50;
|
|
18
|
+
function bubbleHalos(graph, bubbles, positions, repeats = []) {
|
|
19
|
+
const byName = new Map(graph.nodes.map((n) => [n.name, n]));
|
|
20
|
+
const halos = [];
|
|
21
|
+
for (const bubble of bubbles) {
|
|
22
|
+
const parts = [];
|
|
23
|
+
let minX = Infinity;
|
|
24
|
+
let maxX = -Infinity;
|
|
25
|
+
let minY = Infinity;
|
|
26
|
+
const nodeIds = [];
|
|
27
|
+
const names = bubbleSegmentIds(bubble);
|
|
28
|
+
for (const [i, name] of names.entries()) {
|
|
29
|
+
const node = byName.get(name);
|
|
30
|
+
const line = node && positions[node.id];
|
|
31
|
+
if (!node || !line?.length) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (bubble.key ? i === 0 || i === names.length - 1 : isBackbone(node) && (node.stable.start < bubble.start || node.stable.start >= bubble.end)) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
nodeIds.push(node.id);
|
|
38
|
+
parts.push(svgPath(line.length === 1 ? [line[0], line[0]] : line));
|
|
39
|
+
for (const p of line) {
|
|
40
|
+
minX = Math.min(minX, p.x);
|
|
41
|
+
maxX = Math.max(maxX, p.x);
|
|
42
|
+
minY = Math.min(minY, p.y);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (nodeIds.length === 0) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const labelAt = { x: (minX + maxX) / 2, y: minY };
|
|
49
|
+
const whole = bubble.covering === true || coversGraph(nodeIds.length, graph.nodes.length);
|
|
50
|
+
halos.push({
|
|
51
|
+
bubble,
|
|
52
|
+
...classifyBubble(bubble, repeats),
|
|
53
|
+
path: parts.join(""),
|
|
54
|
+
labelAt,
|
|
55
|
+
members: nodeIds.length,
|
|
56
|
+
nodeIds,
|
|
57
|
+
whole,
|
|
58
|
+
// The drawing's own bubble keeps its name however small. A partial
|
|
59
|
+
// bubble's lengths are a floor, so it may be no small variant.
|
|
60
|
+
tick: !whole && !bubble.partial && bubble.longestAlleleLength < SMALL_VARIANT_BP
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return halos;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
WHOLE_FRACTION,
|
|
68
|
+
coversGraph,
|
|
69
|
+
SMALL_VARIANT_BP,
|
|
70
|
+
bubbleHalos
|
|
71
|
+
};
|
|
@@ -11,7 +11,6 @@ var NODE_WIDTHS = [
|
|
|
11
11
|
description: "Every node the same thickness."
|
|
12
12
|
}
|
|
13
13
|
];
|
|
14
|
-
var NODE_WIDTH_VALUES = NODE_WIDTHS.map((w) => w.value);
|
|
15
14
|
var MIN_FACTOR = 0.3;
|
|
16
15
|
var MAX_FACTOR = 3;
|
|
17
16
|
function meanDepth(graph) {
|
|
@@ -51,7 +50,6 @@ function nodeInk(graph, nodeById, contigThickness, nodeWidth) {
|
|
|
51
50
|
|
|
52
51
|
export {
|
|
53
52
|
NODE_WIDTHS,
|
|
54
|
-
NODE_WIDTH_VALUES,
|
|
55
53
|
meanDepth,
|
|
56
54
|
depthWidthFactor,
|
|
57
55
|
nodeWidthPx,
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadBandage
|
|
3
|
-
} from "./chunk-7XHHVYG7.js";
|
|
4
|
-
|
|
5
1
|
// src/layoutEngines.ts
|
|
2
|
+
import { fmmmLayout } from "@jbrowse/graph-fmmm-layout";
|
|
6
3
|
import { stressLayout } from "@jbrowse/graph-stress-layout";
|
|
7
4
|
var LAYOUT_ENGINES = [
|
|
8
5
|
{
|
|
@@ -26,9 +23,8 @@ var layoutEngine = async (request) => {
|
|
|
26
23
|
const result2 = stressLayout(request);
|
|
27
24
|
return { result: result2, duration: performance.now() - start2 };
|
|
28
25
|
}
|
|
29
|
-
const bandage = await loadBandage();
|
|
30
26
|
const start = performance.now();
|
|
31
|
-
const result =
|
|
27
|
+
const result = await fmmmLayout(request);
|
|
32
28
|
return { result, duration: performance.now() - start };
|
|
33
29
|
};
|
|
34
30
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
baseEdgeCurves
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZY2AFL4Y.js";
|
|
4
4
|
import {
|
|
5
5
|
curveBounds,
|
|
6
6
|
pathRibbonOffsets
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7SRWJLSC.js";
|
|
8
8
|
|
|
9
9
|
// src/util/SpatialIndex.ts
|
|
10
10
|
var FALLBACK_CELL_SIZE = 50;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
nodesUnderBox
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4HWM3FNK.js";
|
|
4
4
|
import {
|
|
5
5
|
nodeLabelBudget,
|
|
6
6
|
placeSizeLabels,
|
|
7
7
|
rowLabelBox,
|
|
8
8
|
sizeLabelCandidates
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PTABFYQ7.js";
|
|
10
10
|
import {
|
|
11
11
|
LABEL_CHAR_PX,
|
|
12
12
|
LABEL_PAD,
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
// src/labelLayout.ts
|
|
19
19
|
var HALO_FACTOR = 3.4;
|
|
20
20
|
var LEGEND_INSET_PX = 6;
|
|
21
|
-
var ROUTE_STACK = 8;
|
|
22
21
|
var GENE_PIN_DROP_PX = 18;
|
|
23
22
|
var GENE_STACK = 2;
|
|
24
23
|
var BUBBLE_STACK = 3;
|
|
@@ -147,22 +146,6 @@ function layoutLabels(m) {
|
|
|
147
146
|
version: m.positionsVersion
|
|
148
147
|
}) : { deletions: [], nodes: [] };
|
|
149
148
|
const deletionLabels = placeSizeLabels(sizeCandidates.deletions, take);
|
|
150
|
-
const routes = placeLabels(
|
|
151
|
-
byBubble.flatMap(
|
|
152
|
-
(h) => h.routes.map((route) => {
|
|
153
|
-
const { x, y } = screen(route.at);
|
|
154
|
-
return {
|
|
155
|
-
item: { halo: h, route },
|
|
156
|
-
x,
|
|
157
|
-
y: y + 4,
|
|
158
|
-
text: route.text,
|
|
159
|
-
stack: ROUTE_STACK
|
|
160
|
-
};
|
|
161
|
-
})
|
|
162
|
-
),
|
|
163
|
-
frame,
|
|
164
|
-
take
|
|
165
|
-
);
|
|
166
149
|
const nodeLabels = placeSizeLabels(
|
|
167
150
|
sizeCandidates.nodes,
|
|
168
151
|
take,
|
|
@@ -172,7 +155,6 @@ function layoutLabels(m) {
|
|
|
172
155
|
bubbles,
|
|
173
156
|
ticks,
|
|
174
157
|
genes,
|
|
175
|
-
routes,
|
|
176
158
|
sizes: [...deletionLabels, ...nodeLabels]
|
|
177
159
|
};
|
|
178
160
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ownStrand,
|
|
3
3
|
strandSides
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7SRWJLSC.js";
|
|
5
5
|
import {
|
|
6
6
|
isBackbone
|
|
7
7
|
} from "./chunk-FYQWPEEY.js";
|
|
@@ -122,7 +122,7 @@ function splitRuns(positions, runs, weightOf) {
|
|
|
122
122
|
const arc = arcPrefix(line);
|
|
123
123
|
const total = arc.at(-1);
|
|
124
124
|
const weights = members.map((m) => Math.max(weightOf(m), 0));
|
|
125
|
-
const weightSum = weights.reduce((a, b) => a + b, 0)
|
|
125
|
+
const weightSum = weights.reduce((a, b) => a + b, 0);
|
|
126
126
|
let from = 0;
|
|
127
127
|
members.forEach((member, k) => {
|
|
128
128
|
const share = weightSum ? weights[k] / weightSum * total : total / members.length;
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
} from "./chunk-AB35TJST.js";
|
|
4
4
|
import {
|
|
5
5
|
polylineMidpoint
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-N73TI3VG.js";
|
|
7
7
|
import {
|
|
8
8
|
deletionArcCurves
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-24WITXQY.js";
|
|
10
10
|
import {
|
|
11
11
|
curveBounds,
|
|
12
12
|
curveMidpoint
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7SRWJLSC.js";
|
|
14
14
|
|
|
15
15
|
// src/graphLabels.ts
|
|
16
16
|
var MIN_DELETION_LABEL_PX = 26;
|
|
@@ -50,10 +50,11 @@ function groupDigits(n) {
|
|
|
50
50
|
return String(n).replace(/\B(?=(\d{3})+$)/g, ",");
|
|
51
51
|
}
|
|
52
52
|
function formatBp(bp) {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const [value, unit] = bp >= 1e6 ? [bp / 1e6, "Mb"] : bp >= 1e3 ? [bp / 1e3, "kb"] : [];
|
|
54
|
+
if (value === void 0) {
|
|
55
|
+
return `${bp} bp`;
|
|
55
56
|
}
|
|
56
|
-
return
|
|
57
|
+
return `${+value.toFixed(value >= 100 ? 0 : 1)} ${unit}`;
|
|
57
58
|
}
|
|
58
59
|
function deletionText(bp) {
|
|
59
60
|
return `${formatBp(bp)} del`;
|
|
@@ -181,6 +182,9 @@ function sizeLabelCandidates({
|
|
|
181
182
|
const box = boxAt(halfW, 0, 0);
|
|
182
183
|
const arcX = apex.x * scaleX + translateX;
|
|
183
184
|
const arcY = apex.y * scaleY + translateY;
|
|
185
|
+
if (arcX < 0 || arcX > width || arcY < 0 || arcY > height) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
184
188
|
const fits = extent >= halfW * 2 / MAX_LABEL_OVERHANG;
|
|
185
189
|
const bow = arcOutward(curves, apex, scaleX, scaleY);
|
|
186
190
|
const offset = boxSupport(box, bow) + LEADER_GAP_PX;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
getDpr,
|
|
2
3
|
syncCanvasSize
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RBCE2OQH.js";
|
|
4
5
|
import {
|
|
5
6
|
abgrToCssRgba,
|
|
6
7
|
brightenAbgr,
|
|
@@ -15,6 +16,7 @@ var Canvas2DRenderer = class {
|
|
|
15
16
|
this.nodeHighlights = /* @__PURE__ */ new Map();
|
|
16
17
|
this.highlightedEdge = null;
|
|
17
18
|
this.highlightFactor = 1;
|
|
19
|
+
this.fit = 1;
|
|
18
20
|
const ctx = canvas.getContext("2d");
|
|
19
21
|
if (!ctx) {
|
|
20
22
|
throw new Error("Canvas 2D context not available");
|
|
@@ -26,12 +28,11 @@ var Canvas2DRenderer = class {
|
|
|
26
28
|
}
|
|
27
29
|
releaseOffscreenTargets() {
|
|
28
30
|
}
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
// independently of the backing size.
|
|
31
|
+
// A host builds its transform at `getDpr()`. Where syncCanvasSize had to
|
|
32
|
+
// shrink the ratio to stay under MAX_CANVAS_DIM_PX, `fit` shrinks the
|
|
33
|
+
// transform to match, so the picture still fills the css box.
|
|
33
34
|
resize(width, height) {
|
|
34
|
-
syncCanvasSize(this.canvas, width, height);
|
|
35
|
+
this.fit = syncCanvasSize(this.canvas, width, height) / getDpr();
|
|
35
36
|
}
|
|
36
37
|
uploadGeometry(batch) {
|
|
37
38
|
this.batch = batch;
|
|
@@ -45,7 +46,15 @@ var Canvas2DRenderer = class {
|
|
|
45
46
|
this.highlightFactor = factor;
|
|
46
47
|
}
|
|
47
48
|
updateTransform(transform) {
|
|
48
|
-
|
|
49
|
+
const k = this.fit;
|
|
50
|
+
this.transform = k === 1 ? transform : {
|
|
51
|
+
...transform,
|
|
52
|
+
scaleX: transform.scaleX * k,
|
|
53
|
+
scaleY: transform.scaleY * k,
|
|
54
|
+
translateX: transform.translateX * k,
|
|
55
|
+
translateY: transform.translateY * k,
|
|
56
|
+
dpr: transform.dpr * k
|
|
57
|
+
};
|
|
49
58
|
}
|
|
50
59
|
render(clearColor) {
|
|
51
60
|
const t = this.transform;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/renderer/canvas.ts
|
|
2
|
+
var MAX_DPR = 2;
|
|
3
|
+
var MAX_CANVAS_DIM_PX = 8192;
|
|
4
|
+
function getDpr(width = 0, height = 0) {
|
|
5
|
+
const dpr = typeof devicePixelRatio === "undefined" ? 1 : Math.min(devicePixelRatio, MAX_DPR);
|
|
6
|
+
return Math.min(dpr, MAX_CANVAS_DIM_PX / Math.max(width, height, 1));
|
|
7
|
+
}
|
|
8
|
+
function syncCanvasSize(canvas, width, height) {
|
|
9
|
+
const dpr = getDpr(width, height);
|
|
10
|
+
const pw = Math.round(width * dpr);
|
|
11
|
+
const ph = Math.round(height * dpr);
|
|
12
|
+
if (canvas.width !== pw || canvas.height !== ph) {
|
|
13
|
+
canvas.width = pw;
|
|
14
|
+
canvas.height = ph;
|
|
15
|
+
}
|
|
16
|
+
const cssWidth = `${width}px`;
|
|
17
|
+
const cssHeight = `${height}px`;
|
|
18
|
+
if (canvas.style.width !== cssWidth) {
|
|
19
|
+
canvas.style.width = cssWidth;
|
|
20
|
+
}
|
|
21
|
+
if (canvas.style.height !== cssHeight) {
|
|
22
|
+
canvas.style.height = cssHeight;
|
|
23
|
+
}
|
|
24
|
+
return dpr;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
MAX_DPR,
|
|
29
|
+
MAX_CANVAS_DIM_PX,
|
|
30
|
+
getDpr,
|
|
31
|
+
syncCanvasSize
|
|
32
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
polylineSlice
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-N73TI3VG.js";
|
|
4
4
|
import {
|
|
5
5
|
svgPath
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7SRWJLSC.js";
|
|
7
7
|
import {
|
|
8
8
|
firstNodeAtOrAfter,
|
|
9
9
|
isAnchored
|
|
@@ -74,12 +74,8 @@ function genePins(graph, genes, positions) {
|
|
|
74
74
|
const distance = Math.abs(pinBp - mid);
|
|
75
75
|
if (distance < atDistance) {
|
|
76
76
|
atDistance = distance;
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
(pinBp - nodeStart) / node.length,
|
|
80
|
-
(pinBp - nodeStart) / node.length
|
|
81
|
-
);
|
|
82
|
-
at = p;
|
|
77
|
+
const along = node.length ? (pinBp - nodeStart) / node.length : 0;
|
|
78
|
+
at = polylineSlice(line, along, along)[0];
|
|
83
79
|
}
|
|
84
80
|
}
|
|
85
81
|
if (at) {
|
|
@@ -90,6 +90,10 @@ function svgCanvas(width, height) {
|
|
|
90
90
|
out.push(`<path d="${d}" ${paintAttrs("fill", ctx.fillStyle)}/>`);
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
+
// the renderer only ever clears the whole canvas
|
|
94
|
+
clearRect() {
|
|
95
|
+
out.length = 0;
|
|
96
|
+
},
|
|
93
97
|
fillRect(x, y, w, h) {
|
|
94
98
|
out.push(
|
|
95
99
|
`<rect x="${n(x)}" y="${n(y)}" width="${n(w)}" height="${n(h)}" ${paintAttrs("fill", ctx.fillStyle)}/>`
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SATURATED_PATH_COUNT
|
|
3
3
|
} from "./chunk-FX4RDMDN.js";
|
|
4
|
+
import {
|
|
5
|
+
formatBp
|
|
6
|
+
} from "./chunk-PTABFYQ7.js";
|
|
4
7
|
|
|
5
8
|
// src/bubbles/classifyBubble.ts
|
|
6
9
|
var REPEAT_GROWTH = 10;
|
|
@@ -12,15 +15,6 @@ function coveringRepeat(b, repeats) {
|
|
|
12
15
|
);
|
|
13
16
|
}
|
|
14
17
|
var SUPERBUBBLE_SEGMENTS = 40;
|
|
15
|
-
function formatBp(bp) {
|
|
16
|
-
if (bp >= 1e4) {
|
|
17
|
-
return `${(bp / 1e3).toFixed(0)} kb`;
|
|
18
|
-
}
|
|
19
|
-
if (bp >= 1e3) {
|
|
20
|
-
return `${(bp / 1e3).toFixed(1)} kb`;
|
|
21
|
-
}
|
|
22
|
-
return `${bp} bp`;
|
|
23
|
-
}
|
|
24
18
|
function formatBpRange(shortest, longest) {
|
|
25
19
|
const low = formatBp(shortest);
|
|
26
20
|
const high = formatBp(longest);
|
|
@@ -119,7 +113,6 @@ function bubbleSegmentIds(b) {
|
|
|
119
113
|
}
|
|
120
114
|
|
|
121
115
|
export {
|
|
122
|
-
formatBp,
|
|
123
116
|
classifyBubble,
|
|
124
117
|
BUBBLE_KIND_COLORS,
|
|
125
118
|
BUBBLE_KIND_NAMES,
|
|
@@ -25,7 +25,11 @@ function parseRegion(text) {
|
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
const n = (s) => Number(s.replaceAll(",", ""));
|
|
28
|
-
|
|
28
|
+
const region = { refName: m[1], start: n(m[2]), end: n(m[3]) };
|
|
29
|
+
if (region.end <= region.start) {
|
|
30
|
+
throw new Error(`"${text}" ends at or before it starts`);
|
|
31
|
+
}
|
|
32
|
+
return region;
|
|
29
33
|
}
|
|
30
34
|
async function openGbz(db, index) {
|
|
31
35
|
const base = await GBZBase.open({ source: db, haplotypeIndex: index });
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
hasTubeMapPaths,
|
|
7
7
|
tubeMapLayout,
|
|
8
8
|
tubeMapReferenceLayout
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XI3ZUTWF.js";
|
|
10
10
|
import {
|
|
11
11
|
anchoredLayout
|
|
12
12
|
} from "./chunk-L3O7AWLI.js";
|
|
13
13
|
import {
|
|
14
14
|
orderedLayout
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-CM6LO6OC.js";
|
|
16
16
|
import {
|
|
17
17
|
walkRowLayout
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-54POIBVC.js";
|
|
19
19
|
import {
|
|
20
20
|
isBackbone,
|
|
21
21
|
isOffReference
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
engineKey,
|
|
3
3
|
forceLayout
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2QLLQJ72.js";
|
|
5
5
|
|
|
6
6
|
// src/layout/forceCache.ts
|
|
7
7
|
var DEFAULT_SIZE = 4;
|
|
@@ -33,7 +33,11 @@ function createForceLayoutCache(size = DEFAULT_SIZE) {
|
|
|
33
33
|
return { ...r, duration: r.duration || performance.now() - started };
|
|
34
34
|
})
|
|
35
35
|
};
|
|
36
|
-
entry.run.catch(() =>
|
|
36
|
+
entry.run.catch(() => {
|
|
37
|
+
if (cache.get(key) === entry) {
|
|
38
|
+
cache.delete(key);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
37
41
|
cache.set(key, entry);
|
|
38
42
|
return entry.run;
|
|
39
43
|
},
|
|
@@ -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-2CHS5LMM.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
|
};
|