@jbrowse/bandage-core 9.8.0 → 9.8.1
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/chunks/{chunk-75HR3756.js → chunk-G3SZWUPA.js} +47 -16
- package/dist/chunks/chunk-IJYFJVIT.js +77 -0
- package/dist/chunks/{chunk-VZQ4FKLR.js → chunk-JABM3MUS.js} +1 -1
- package/dist/chunks/{chunk-CG77WIFD.js → chunk-JRADQSGK.js} +1 -1
- package/dist/chunks/{chunk-JEF73V3A.js → chunk-YMMZUMYE.js} +1 -1
- package/dist/cli/figure.js +2 -2
- package/dist/figure.js +2 -2
- package/dist/index.js +5 -5
- package/dist/tubeMap/draw.js +4 -1
- package/dist/tubeMap/frame.js +2 -2
- package/dist/tubeMap/warp.js +1 -1
- package/dist/types/tubeMap/draw.d.ts +2 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/chunk-KQFOCDFY.js +0 -73
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
readColor
|
|
6
6
|
} from "./chunk-CWFNEKST.js";
|
|
7
|
+
import {
|
|
8
|
+
pathOrigin
|
|
9
|
+
} from "./chunk-ST2IBUAN.js";
|
|
7
10
|
|
|
8
11
|
// src/tubeMap/draw.ts
|
|
9
12
|
import { curvePaths, nodeOutlinePath } from "@jbrowse/tubemap-core";
|
|
@@ -53,9 +56,9 @@ function extentOf(commands) {
|
|
|
53
56
|
}
|
|
54
57
|
return { x0, x1 };
|
|
55
58
|
}
|
|
56
|
-
function shapeOf(d, color, id, haplotype) {
|
|
59
|
+
function shapeOf(d, color, id, haplotype, reference) {
|
|
57
60
|
const commands = parsePath(d);
|
|
58
|
-
return { commands, color, id, haplotype, ...extentOf(commands) };
|
|
61
|
+
return { commands, color, id, haplotype, reference, ...extentOf(commands) };
|
|
59
62
|
}
|
|
60
63
|
function trackColors(layout, pathColors) {
|
|
61
64
|
return new Map(
|
|
@@ -65,30 +68,43 @@ function trackColors(layout, pathColors) {
|
|
|
65
68
|
])
|
|
66
69
|
);
|
|
67
70
|
}
|
|
68
|
-
function layerOf(layout, type, colors) {
|
|
71
|
+
function layerOf(layout, type, colors, referenceIds) {
|
|
69
72
|
const { shapes } = layout;
|
|
70
73
|
const haplotype = type === "haplotype";
|
|
71
74
|
const colorOf = (s) => colors.get(s.id);
|
|
75
|
+
const isReference = (s) => haplotype && referenceIds.has(s.id);
|
|
72
76
|
const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({
|
|
73
77
|
color: colorOf(r),
|
|
74
78
|
id: r.id,
|
|
75
79
|
haplotype,
|
|
80
|
+
reference: isReference(r),
|
|
76
81
|
x0: r.xStart,
|
|
77
82
|
x1: r.xEnd + 1,
|
|
78
83
|
y0: r.yStart,
|
|
79
84
|
y1: r.yEnd + 1
|
|
80
85
|
}));
|
|
81
86
|
const curves = curvePaths(shapes.curves, type).map(
|
|
82
|
-
(c) => shapeOf(c.path, colorOf(c), c.id, haplotype)
|
|
87
|
+
(c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c))
|
|
83
88
|
);
|
|
84
|
-
const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), c.id, haplotype));
|
|
89
|
+
const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), c.id, haplotype, isReference(c)));
|
|
85
90
|
return { rects, shapes: [...curves, ...corners] };
|
|
86
91
|
}
|
|
92
|
+
function referenceTrackIds(graph) {
|
|
93
|
+
const ids = /* @__PURE__ */ new Set();
|
|
94
|
+
graph?.paths?.forEach((path, i) => {
|
|
95
|
+
if (pathOrigin(path.name).name === graph.referencePath) {
|
|
96
|
+
ids.add(i);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return ids;
|
|
100
|
+
}
|
|
87
101
|
function tubeMapPicture({
|
|
88
102
|
layout,
|
|
89
|
-
pathColors
|
|
103
|
+
pathColors,
|
|
104
|
+
graph
|
|
90
105
|
}) {
|
|
91
106
|
const colors = trackColors(layout, pathColors);
|
|
107
|
+
const referenceIds = referenceTrackIds(graph);
|
|
92
108
|
const nodes = [];
|
|
93
109
|
layout.nodes.forEach((node) => {
|
|
94
110
|
if (node.order >= 0) {
|
|
@@ -99,8 +115,8 @@ function tubeMapPicture({
|
|
|
99
115
|
return {
|
|
100
116
|
bounds: layout.bounds,
|
|
101
117
|
layers: [
|
|
102
|
-
layerOf(layout, "haplotype", colors),
|
|
103
|
-
layerOf(layout, "read", colors)
|
|
118
|
+
layerOf(layout, "haplotype", colors, referenceIds),
|
|
119
|
+
layerOf(layout, "read", colors, referenceIds)
|
|
104
120
|
],
|
|
105
121
|
nodes,
|
|
106
122
|
mismatches: tubeMapMismatches(layout).filter(
|
|
@@ -181,14 +197,29 @@ function drawTubeMap(ctx, picture, frame) {
|
|
|
181
197
|
const colorOf = (item) => item.haplotype && frame.tubeColors?.[item.id] || item.color;
|
|
182
198
|
ctx.globalAlpha = 1;
|
|
183
199
|
for (const layer of picture.layers) {
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
200
|
+
for (const reference of [false, true]) {
|
|
201
|
+
const inPass = (item) => item.reference === reference;
|
|
202
|
+
fillByColor(
|
|
203
|
+
ctx,
|
|
204
|
+
layer.rects,
|
|
205
|
+
(r) => inPass(r) && visible(r),
|
|
206
|
+
colorOf,
|
|
207
|
+
(r) => {
|
|
208
|
+
const left = x(r.x0);
|
|
209
|
+
const top = y(r.y0);
|
|
210
|
+
ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
fillByColor(
|
|
214
|
+
ctx,
|
|
215
|
+
layer.shapes,
|
|
216
|
+
(s) => inPass(s) && visible(s),
|
|
217
|
+
colorOf,
|
|
218
|
+
(s) => {
|
|
219
|
+
trace(ctx, s.commands, x, y);
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
192
223
|
}
|
|
193
224
|
const stroke = frame.darkMode ? "#d0d0d0" : "#000000";
|
|
194
225
|
const fill = frame.darkMode ? "rgba(40,40,40,0.4)" : "rgba(255,255,255,0.4)";
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// src/tubeMap/warp.ts
|
|
2
|
+
var MAX_GAP_PX = 24;
|
|
3
|
+
var MAX_GAP_SHARE = 0.5;
|
|
4
|
+
var isReal = (c) => c.bp1 > c.bp0;
|
|
5
|
+
function referenceKnots(columns, bpToScreen) {
|
|
6
|
+
const real = columns.filter(isReal);
|
|
7
|
+
if (real.length === 0) {
|
|
8
|
+
const first = columns[0];
|
|
9
|
+
return first ? [{ tx: first.x0, sx: bpToScreen(first.bp0) }] : [];
|
|
10
|
+
}
|
|
11
|
+
const tx = [];
|
|
12
|
+
const target = [];
|
|
13
|
+
const gap = [];
|
|
14
|
+
real.forEach((c, i) => {
|
|
15
|
+
tx.push(c.x0, c.x1);
|
|
16
|
+
target.push(bpToScreen(c.bp0), bpToScreen(c.bp1));
|
|
17
|
+
gap.push(i === 0 ? 0 : Math.min(c.x0 - real[i - 1].x1, MAX_GAP_PX), 0);
|
|
18
|
+
});
|
|
19
|
+
const span = target.at(-1) - target[0];
|
|
20
|
+
const demand = gap.reduce((a, b) => a + b, 0);
|
|
21
|
+
const scale = demand > 0 ? Math.min(1, MAX_GAP_SHARE * span / demand) : 1;
|
|
22
|
+
return spread(target, gap, scale).map((sx, k) => ({ tx: tx[k], sx }));
|
|
23
|
+
}
|
|
24
|
+
function spread(target, gap, scale) {
|
|
25
|
+
const offset = [];
|
|
26
|
+
let sum = 0;
|
|
27
|
+
for (const g of gap) {
|
|
28
|
+
sum += g * scale;
|
|
29
|
+
offset.push(sum);
|
|
30
|
+
}
|
|
31
|
+
const blocks = [];
|
|
32
|
+
target.forEach((t, k) => {
|
|
33
|
+
let block = { mean: t - offset[k], n: 1 };
|
|
34
|
+
let last = blocks.at(-1);
|
|
35
|
+
while (last && last.mean >= block.mean) {
|
|
36
|
+
blocks.pop();
|
|
37
|
+
const n = last.n + block.n;
|
|
38
|
+
block = { mean: (last.mean * last.n + block.mean * block.n) / n, n };
|
|
39
|
+
last = blocks.at(-1);
|
|
40
|
+
}
|
|
41
|
+
blocks.push(block);
|
|
42
|
+
});
|
|
43
|
+
return blocks.flatMap((b) => Array(b.n).fill(b.mean)).map((q, k) => q + offset[k]);
|
|
44
|
+
}
|
|
45
|
+
function warpX(knots, tx) {
|
|
46
|
+
const n = knots.length;
|
|
47
|
+
if (n === 0) {
|
|
48
|
+
return tx;
|
|
49
|
+
}
|
|
50
|
+
const first = knots[0];
|
|
51
|
+
const last = knots[n - 1];
|
|
52
|
+
if (tx <= first.tx) {
|
|
53
|
+
return first.sx + (tx - first.tx);
|
|
54
|
+
}
|
|
55
|
+
if (tx >= last.tx) {
|
|
56
|
+
return last.sx + (tx - last.tx);
|
|
57
|
+
}
|
|
58
|
+
let lo = 0;
|
|
59
|
+
let hi = n - 1;
|
|
60
|
+
while (hi - lo > 1) {
|
|
61
|
+
const mid = lo + hi >> 1;
|
|
62
|
+
if (knots[mid].tx <= tx) {
|
|
63
|
+
lo = mid;
|
|
64
|
+
} else {
|
|
65
|
+
hi = mid;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const a = knots[lo];
|
|
69
|
+
const b = knots[hi];
|
|
70
|
+
const span = b.tx - a.tx;
|
|
71
|
+
return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export {
|
|
75
|
+
referenceKnots,
|
|
76
|
+
warpX
|
|
77
|
+
};
|
package/dist/cli/figure.js
CHANGED
|
@@ -35,7 +35,7 @@ import "../chunks/chunk-LTUWJKHD.js";
|
|
|
35
35
|
import "../chunks/chunk-WSIFAZU7.js";
|
|
36
36
|
import {
|
|
37
37
|
figureSvg
|
|
38
|
-
} from "../chunks/chunk-
|
|
38
|
+
} from "../chunks/chunk-JRADQSGK.js";
|
|
39
39
|
import "../chunks/chunk-QMJXHYVQ.js";
|
|
40
40
|
import "../chunks/chunk-WBCOREDZ.js";
|
|
41
41
|
import "../chunks/chunk-4BYTEJGW.js";
|
|
@@ -54,7 +54,7 @@ import "../chunks/chunk-2LQ5BWT7.js";
|
|
|
54
54
|
import "../chunks/chunk-QG5IVMRS.js";
|
|
55
55
|
import "../chunks/chunk-BOHK5BD3.js";
|
|
56
56
|
import "../chunks/chunk-G2FD7S3C.js";
|
|
57
|
-
import "../chunks/chunk-
|
|
57
|
+
import "../chunks/chunk-YMMZUMYE.js";
|
|
58
58
|
import "../chunks/chunk-3C5UXR2U.js";
|
|
59
59
|
import {
|
|
60
60
|
filterSamples,
|
package/dist/figure.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
figureSvg
|
|
3
|
-
} from "./chunks/chunk-
|
|
3
|
+
} from "./chunks/chunk-JRADQSGK.js";
|
|
4
4
|
import "./chunks/chunk-QMJXHYVQ.js";
|
|
5
5
|
import "./chunks/chunk-WBCOREDZ.js";
|
|
6
6
|
import "./chunks/chunk-4BYTEJGW.js";
|
|
@@ -16,7 +16,7 @@ import "./chunks/chunk-2LQ5BWT7.js";
|
|
|
16
16
|
import "./chunks/chunk-QG5IVMRS.js";
|
|
17
17
|
import "./chunks/chunk-BOHK5BD3.js";
|
|
18
18
|
import "./chunks/chunk-G2FD7S3C.js";
|
|
19
|
-
import "./chunks/chunk-
|
|
19
|
+
import "./chunks/chunk-YMMZUMYE.js";
|
|
20
20
|
import "./chunks/chunk-3C5UXR2U.js";
|
|
21
21
|
import "./chunks/chunk-MAUEPAMG.js";
|
|
22
22
|
import "./chunks/chunk-7GBL7SJY.js";
|
package/dist/index.js
CHANGED
|
@@ -29,16 +29,16 @@ import {
|
|
|
29
29
|
tubeMapMismatchAt,
|
|
30
30
|
tubeMapPicture,
|
|
31
31
|
tubeMapTrackAt
|
|
32
|
-
} from "./chunks/chunk-
|
|
32
|
+
} from "./chunks/chunk-G3SZWUPA.js";
|
|
33
33
|
import "./chunks/chunk-XXT2JCAC.js";
|
|
34
34
|
import {
|
|
35
35
|
tubeMapFrame,
|
|
36
36
|
tubeMapNodeAt
|
|
37
|
-
} from "./chunks/chunk-
|
|
37
|
+
} from "./chunks/chunk-JABM3MUS.js";
|
|
38
38
|
import {
|
|
39
39
|
referenceKnots,
|
|
40
40
|
warpX
|
|
41
|
-
} from "./chunks/chunk-
|
|
41
|
+
} from "./chunks/chunk-IJYFJVIT.js";
|
|
42
42
|
import {
|
|
43
43
|
createForceLayoutCache
|
|
44
44
|
} from "./chunks/chunk-BV64PQ2C.js";
|
|
@@ -122,7 +122,7 @@ import {
|
|
|
122
122
|
} from "./chunks/chunk-AZFVORTC.js";
|
|
123
123
|
import {
|
|
124
124
|
figureSvg
|
|
125
|
-
} from "./chunks/chunk-
|
|
125
|
+
} from "./chunks/chunk-JRADQSGK.js";
|
|
126
126
|
import {
|
|
127
127
|
WALK_STRIP_CEILING_PX,
|
|
128
128
|
cutsWholeWalks,
|
|
@@ -222,7 +222,7 @@ import {
|
|
|
222
222
|
import "./chunks/chunk-G2FD7S3C.js";
|
|
223
223
|
import {
|
|
224
224
|
version
|
|
225
|
-
} from "./chunks/chunk-
|
|
225
|
+
} from "./chunks/chunk-YMMZUMYE.js";
|
|
226
226
|
import {
|
|
227
227
|
walkRowLabels,
|
|
228
228
|
walkRowsExtent
|
package/dist/tubeMap/draw.js
CHANGED
|
@@ -8,10 +8,13 @@ import {
|
|
|
8
8
|
tubeMapMismatchAt,
|
|
9
9
|
tubeMapPicture,
|
|
10
10
|
tubeMapTrackAt
|
|
11
|
-
} from "../chunks/chunk-
|
|
11
|
+
} from "../chunks/chunk-G3SZWUPA.js";
|
|
12
12
|
import "../chunks/chunk-XXT2JCAC.js";
|
|
13
13
|
import "../chunks/chunk-CWFNEKST.js";
|
|
14
14
|
import "../chunks/chunk-C44YRP5F.js";
|
|
15
|
+
import "../chunks/chunk-ST2IBUAN.js";
|
|
16
|
+
import "../chunks/chunk-BPLIXMH7.js";
|
|
17
|
+
import "../chunks/chunk-FYQWPEEY.js";
|
|
15
18
|
export {
|
|
16
19
|
drawTubeMap,
|
|
17
20
|
drawTubeMapHighlight,
|
package/dist/tubeMap/frame.js
CHANGED
package/dist/tubeMap/warp.js
CHANGED
|
@@ -34,6 +34,7 @@ interface Filled {
|
|
|
34
34
|
color: string;
|
|
35
35
|
id: number;
|
|
36
36
|
haplotype: boolean;
|
|
37
|
+
reference: boolean;
|
|
37
38
|
x0: number;
|
|
38
39
|
x1: number;
|
|
39
40
|
}
|
|
@@ -60,7 +61,7 @@ export interface TubeMapPicture {
|
|
|
60
61
|
mismatches: TubeMapMismatch[];
|
|
61
62
|
}
|
|
62
63
|
export declare function trackColors(layout: TubeMapLayout, pathColors: readonly string[]): ReadonlyMap<number, string>;
|
|
63
|
-
export declare function tubeMapPicture({ layout, pathColors, }: Pick<TubeMapDrawing, 'layout' | 'pathColors'>): TubeMapPicture;
|
|
64
|
+
export declare function tubeMapPicture({ layout, pathColors, graph, }: Pick<TubeMapDrawing, 'layout' | 'pathColors'> & Partial<Pick<TubeMapDrawing, 'graph'>>): TubeMapPicture;
|
|
64
65
|
export interface TubeMapFrame extends TubeMapTransform {
|
|
65
66
|
width: number;
|
|
66
67
|
highlightNode?: string | null;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "9.8.
|
|
1
|
+
export declare const version = "9.8.1";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/bandage-core",
|
|
3
|
-
"version": "9.8.
|
|
3
|
+
"version": "9.8.1",
|
|
4
4
|
"description": "Pangenome graph layout and drawing with no host: GFA in, the Bandage force-directed engine and reference-anchored layouts, a Canvas2D renderer, hit testing and labels out",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"repository": {
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// src/tubeMap/warp.ts
|
|
2
|
-
var MAX_GAP_PX = 24;
|
|
3
|
-
var isReal = (c) => c.bp1 > c.bp0;
|
|
4
|
-
function referenceKnots(columns, bpToScreen) {
|
|
5
|
-
const real = columns.filter(isReal);
|
|
6
|
-
if (real.length === 0) {
|
|
7
|
-
const first = columns[0];
|
|
8
|
-
return first ? [{ tx: first.x0, sx: bpToScreen(first.bp0) }] : [];
|
|
9
|
-
}
|
|
10
|
-
const screen = real.map((c) => ({
|
|
11
|
-
c,
|
|
12
|
-
s0: bpToScreen(c.bp0),
|
|
13
|
-
s1: bpToScreen(c.bp1),
|
|
14
|
-
trimLeft: 0,
|
|
15
|
-
trimRight: 0
|
|
16
|
-
}));
|
|
17
|
-
for (let i = 0; i + 1 < screen.length; i++) {
|
|
18
|
-
const left = screen[i];
|
|
19
|
-
const right = screen[i + 1];
|
|
20
|
-
const demand = Math.min(right.c.x0 - left.c.x1, MAX_GAP_PX);
|
|
21
|
-
const short = demand - (right.s0 - left.s1);
|
|
22
|
-
if (short > 0) {
|
|
23
|
-
const capLeft = (left.s1 - left.s0) / 2;
|
|
24
|
-
const capRight = (right.s1 - right.s0) / 2;
|
|
25
|
-
let fromLeft = Math.min(short / 2, capLeft);
|
|
26
|
-
const fromRight = Math.min(short - fromLeft, capRight);
|
|
27
|
-
fromLeft = Math.min(short - fromRight, capLeft);
|
|
28
|
-
left.trimRight = fromLeft;
|
|
29
|
-
right.trimLeft = fromRight;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const knots = [];
|
|
33
|
-
for (const { c, s0, s1, trimLeft, trimRight } of screen) {
|
|
34
|
-
knots.push(
|
|
35
|
-
{ tx: c.x0, sx: s0 + trimLeft },
|
|
36
|
-
{ tx: c.x1, sx: s1 - trimRight }
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
return knots;
|
|
40
|
-
}
|
|
41
|
-
function warpX(knots, tx) {
|
|
42
|
-
const n = knots.length;
|
|
43
|
-
if (n === 0) {
|
|
44
|
-
return tx;
|
|
45
|
-
}
|
|
46
|
-
const first = knots[0];
|
|
47
|
-
const last = knots[n - 1];
|
|
48
|
-
if (tx <= first.tx) {
|
|
49
|
-
return first.sx + (tx - first.tx);
|
|
50
|
-
}
|
|
51
|
-
if (tx >= last.tx) {
|
|
52
|
-
return last.sx + (tx - last.tx);
|
|
53
|
-
}
|
|
54
|
-
let lo = 0;
|
|
55
|
-
let hi = n - 1;
|
|
56
|
-
while (hi - lo > 1) {
|
|
57
|
-
const mid = lo + hi >> 1;
|
|
58
|
-
if (knots[mid].tx <= tx) {
|
|
59
|
-
lo = mid;
|
|
60
|
-
} else {
|
|
61
|
-
hi = mid;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const a = knots[lo];
|
|
65
|
-
const b = knots[hi];
|
|
66
|
-
const span = b.tx - a.tx;
|
|
67
|
-
return span > 0 ? a.sx + (tx - a.tx) / span * (b.sx - a.sx) : a.sx;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export {
|
|
71
|
-
referenceKnots,
|
|
72
|
-
warpX
|
|
73
|
-
};
|