@jbrowse/bandage-core 4.0.25 → 4.0.27
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-B5ZHLU4N.js → chunk-VNCGWA2N.js} +2826 -2768
- package/dist/cli/figure.js +101 -29
- package/dist/index.js +45 -13
- package/dist/types/cli/figure.d.ts +1 -0
- package/dist/types/figure.d.ts +5 -0
- package/dist/types/gbzCut.d.ts +1 -0
- package/dist/types/graphLabels.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/layoutModes.d.ts +15 -0
- package/dist/types/pathAnchoring.d.ts +4 -0
- package/dist/types/reference.d.ts +3 -2
- package/dist/types/tubeMap/draw.d.ts +3 -0
- package/dist/types/tubeMap/nodeColors.d.ts +4 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/figure.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
HPRC_GBZ,
|
|
4
|
+
LAYOUT_MODES,
|
|
4
5
|
cutGbzRegion,
|
|
5
6
|
featuresOnBackbone,
|
|
6
7
|
figureSvg,
|
|
@@ -9,15 +10,17 @@ import {
|
|
|
9
10
|
genesFromGff3Lines,
|
|
10
11
|
genesFromText,
|
|
11
12
|
graphBackbone,
|
|
13
|
+
haplotypeIndexBeside,
|
|
12
14
|
layoutModeByValue,
|
|
13
15
|
loadBandage,
|
|
14
16
|
loadGraph,
|
|
15
17
|
openGbz,
|
|
16
|
-
parseRegion
|
|
17
|
-
|
|
18
|
+
parseRegion,
|
|
19
|
+
refNameBinding
|
|
20
|
+
} from "../chunks/chunk-VNCGWA2N.js";
|
|
18
21
|
|
|
19
22
|
// src/cli/figure.ts
|
|
20
|
-
import { open, readFile, writeFile } from "node:fs/promises";
|
|
23
|
+
import { access, open, readFile, writeFile } from "node:fs/promises";
|
|
21
24
|
import path from "node:path";
|
|
22
25
|
import { parseArgs } from "node:util";
|
|
23
26
|
import { gunzipSync } from "node:zlib";
|
|
@@ -27,16 +30,13 @@ function byteSource(location) {
|
|
|
27
30
|
if (isUrl(location)) {
|
|
28
31
|
return {
|
|
29
32
|
async read(length, position) {
|
|
30
|
-
const res = await
|
|
33
|
+
const res = await fetchOk(location, {
|
|
31
34
|
headers: { range: `bytes=${position}-${position + length - 1}` }
|
|
32
35
|
});
|
|
33
|
-
if (!res.ok) {
|
|
34
|
-
throw new Error(`HTTP ${res.status} reading ${location}`);
|
|
35
|
-
}
|
|
36
36
|
return new Uint8Array(await res.arrayBuffer());
|
|
37
37
|
},
|
|
38
38
|
async stat() {
|
|
39
|
-
const res = await
|
|
39
|
+
const res = await fetchOk(location, { method: "HEAD" });
|
|
40
40
|
return { size: Number(res.headers.get("content-length")) };
|
|
41
41
|
}
|
|
42
42
|
};
|
|
@@ -53,8 +53,15 @@ function byteSource(location) {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
+
async function fetchOk(location, init) {
|
|
57
|
+
const res = await fetch(location, init);
|
|
58
|
+
if (!res.ok) {
|
|
59
|
+
throw new Error(`HTTP ${res.status} reading ${location}`);
|
|
60
|
+
}
|
|
61
|
+
return res;
|
|
62
|
+
}
|
|
56
63
|
async function text(location) {
|
|
57
|
-
const bytes = isUrl(location) ? new Uint8Array(await (await
|
|
64
|
+
const bytes = isUrl(location) ? new Uint8Array(await (await fetchOk(location)).arrayBuffer()) : await readFile(location);
|
|
58
65
|
const gzipped = bytes[0] === 31 && bytes[1] === 139;
|
|
59
66
|
return new TextDecoder().decode(gzipped ? gunzipSync(bytes) : bytes);
|
|
60
67
|
}
|
|
@@ -63,30 +70,48 @@ async function readGenes(genes, graph, resolve) {
|
|
|
63
70
|
if (!backbone) {
|
|
64
71
|
return [];
|
|
65
72
|
}
|
|
66
|
-
const
|
|
73
|
+
const bind = refNameBinding(
|
|
74
|
+
backbone.contigs.map((c) => c.refName),
|
|
75
|
+
genes.refNames
|
|
76
|
+
);
|
|
67
77
|
const format = genes.format ?? (/\.bed(\.gz)?$/i.test(genes.file) ? "bed" : "gff3");
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
const { names, features } = genes.index ? await indexedGenes(
|
|
79
|
+
resolve(genes.file),
|
|
80
|
+
resolve(genes.index),
|
|
81
|
+
format,
|
|
82
|
+
backbone.contigs,
|
|
83
|
+
bind
|
|
84
|
+
) : namedBy(genesFromText(await text(resolve(genes.file))));
|
|
85
|
+
if (!names.some((name) => bind(name) !== void 0)) {
|
|
86
|
+
const shown = names.slice(0, 4).join(", ");
|
|
87
|
+
console.warn(
|
|
88
|
+
`bandage-figure: no sequence in ${genes.file} names ${backbone.contigs.map((c) => c.contig).join(", ")}` + (names.length ? `; it has ${shown}${names.length > 4 ? ", \u2026" : ""}` : "") + `. Give the file's name under genes.refNames, as { "chr6": "NC_000006.12" }`
|
|
89
|
+
);
|
|
70
90
|
}
|
|
71
|
-
|
|
91
|
+
return featuresOnBackbone(features, backbone, genes.refNames);
|
|
92
|
+
}
|
|
93
|
+
function namedBy(features) {
|
|
94
|
+
return { names: [...new Set(features.map((f) => f.refName))], features };
|
|
95
|
+
}
|
|
96
|
+
async function indexedGenes(file, index, format, contigs, bind) {
|
|
72
97
|
const csi = index.endsWith(".csi");
|
|
73
98
|
const tabix = new TabixIndexedFile(
|
|
74
99
|
isUrl(file) ? { url: file, ...csi ? { csiUrl: index } : { tbiUrl: index } } : { path: file, ...csi ? { csiPath: index } : { tbiPath: index } }
|
|
75
100
|
);
|
|
76
|
-
const
|
|
101
|
+
const names = await tabix.getReferenceSequenceNames();
|
|
77
102
|
const lines = [];
|
|
78
|
-
for (const contig of
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
await tabix.getLines(
|
|
103
|
+
for (const contig of contigs) {
|
|
104
|
+
const name = names.find((n) => bind(n) === contig.refName);
|
|
105
|
+
if (name !== void 0) {
|
|
106
|
+
await tabix.getLines(name, contig.start, contig.end, {
|
|
82
107
|
lineCallback: (line) => lines.push(line)
|
|
83
108
|
});
|
|
84
109
|
}
|
|
85
110
|
}
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
return {
|
|
112
|
+
names,
|
|
113
|
+
features: format === "gff3" ? genesFromGff3Lines(lines) : genesFromBed(lines.join("\n"))
|
|
114
|
+
};
|
|
90
115
|
}
|
|
91
116
|
var engine = async (request) => {
|
|
92
117
|
const bandage = await loadBandage();
|
|
@@ -94,15 +119,39 @@ var engine = async (request) => {
|
|
|
94
119
|
const result = bandage.computeLayout(request.graph, request.options);
|
|
95
120
|
return { result, duration: performance.now() - start };
|
|
96
121
|
};
|
|
122
|
+
async function exists(location) {
|
|
123
|
+
try {
|
|
124
|
+
await (isUrl(location) ? fetchOk(location, { method: "HEAD" }) : access(location));
|
|
125
|
+
return true;
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function siblingIndex(db) {
|
|
131
|
+
const sibling = haplotypeIndexBeside(db);
|
|
132
|
+
return sibling && await exists(sibling) ? sibling : void 0;
|
|
133
|
+
}
|
|
134
|
+
var DRAWABLE = LAYOUT_MODES.filter((m) => m.drawsNodes).map(
|
|
135
|
+
(m) => m.value
|
|
136
|
+
);
|
|
137
|
+
function checkLayout(layout) {
|
|
138
|
+
if (layout !== void 0 && !DRAWABLE.includes(layout)) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`a figure draws no "${layout}" layout: one of ${DRAWABLE.join(", ")}`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
97
144
|
async function renderSpec(spec, base) {
|
|
145
|
+
checkLayout(spec.layout);
|
|
98
146
|
const resolve = (location) => isUrl(location) ? location : path.resolve(base, location);
|
|
99
147
|
let source;
|
|
100
148
|
if (spec.gbz) {
|
|
101
149
|
const { db, index } = spec.gbz.db === "hprc" ? HPRC_GBZ : spec.gbz;
|
|
150
|
+
const indexLocation = index ? resolve(index) : await siblingIndex(resolve(db));
|
|
102
151
|
const cut = await cutGbzRegion(
|
|
103
152
|
await openGbz(
|
|
104
153
|
byteSource(resolve(db)),
|
|
105
|
-
|
|
154
|
+
indexLocation ? byteSource(indexLocation) : void 0
|
|
106
155
|
),
|
|
107
156
|
spec.gbz
|
|
108
157
|
);
|
|
@@ -136,14 +185,32 @@ async function renderSpec(spec, base) {
|
|
|
136
185
|
spec
|
|
137
186
|
});
|
|
138
187
|
}
|
|
188
|
+
var USAGE = "usage: bandage-figure <spec.json> [-o figure.svg]";
|
|
189
|
+
function args() {
|
|
190
|
+
try {
|
|
191
|
+
return parseArgs({
|
|
192
|
+
allowPositionals: true,
|
|
193
|
+
options: {
|
|
194
|
+
out: { type: "string", short: "o" },
|
|
195
|
+
help: { type: "boolean", short: "h" }
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
} catch (e) {
|
|
199
|
+
console.error(`${e instanceof Error ? e.message : String(e)}
|
|
200
|
+
${USAGE}`);
|
|
201
|
+
process.exit(2);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
139
204
|
async function main() {
|
|
140
|
-
const { positionals, values } =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
205
|
+
const { positionals, values } = args();
|
|
206
|
+
if (values.help) {
|
|
207
|
+
process.stdout.write(`${USAGE}
|
|
208
|
+
`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
144
211
|
const file = positionals[0];
|
|
145
212
|
if (!file) {
|
|
146
|
-
console.error(
|
|
213
|
+
console.error(USAGE);
|
|
147
214
|
process.exit(2);
|
|
148
215
|
}
|
|
149
216
|
const spec = JSON.parse(await readFile(file, "utf8"));
|
|
@@ -154,4 +221,9 @@ async function main() {
|
|
|
154
221
|
process.stdout.write(svg);
|
|
155
222
|
}
|
|
156
223
|
}
|
|
157
|
-
|
|
224
|
+
try {
|
|
225
|
+
await main();
|
|
226
|
+
} catch (e) {
|
|
227
|
+
console.error(`bandage-figure: ${e instanceof Error ? e.message : String(e)}`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -90,6 +90,7 @@ import {
|
|
|
90
90
|
svgCanvas,
|
|
91
91
|
svgPath,
|
|
92
92
|
translateCurves,
|
|
93
|
+
trimOrigins,
|
|
93
94
|
version,
|
|
94
95
|
viewportOf,
|
|
95
96
|
walkHighlight,
|
|
@@ -101,7 +102,7 @@ import {
|
|
|
101
102
|
wellKnownSample,
|
|
102
103
|
yToXOf,
|
|
103
104
|
zoomAbout
|
|
104
|
-
} from "./chunks/chunk-
|
|
105
|
+
} from "./chunks/chunk-VNCGWA2N.js";
|
|
105
106
|
|
|
106
107
|
// src/index.ts
|
|
107
108
|
import { getDpr } from "@jbrowse/render-core/canvas2dUtils";
|
|
@@ -721,14 +722,16 @@ function extentOf(commands) {
|
|
|
721
722
|
}
|
|
722
723
|
return { x0, x1 };
|
|
723
724
|
}
|
|
724
|
-
function shapeOf(d, color, alpha) {
|
|
725
|
+
function shapeOf(d, color, alpha, track) {
|
|
725
726
|
const commands = parsePath(d);
|
|
726
|
-
return { commands, color, alpha, ...extentOf(commands) };
|
|
727
|
+
return { commands, color, track, alpha, ...extentOf(commands) };
|
|
727
728
|
}
|
|
728
729
|
function layerOf(layout, type) {
|
|
729
730
|
const { shapes } = layout;
|
|
731
|
+
const trackOf = (s) => type === "haplotype" ? s.id : void 0;
|
|
730
732
|
const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({
|
|
731
733
|
color: r.color,
|
|
734
|
+
track: trackOf(r),
|
|
732
735
|
alpha: r.alpha ?? 1,
|
|
733
736
|
x0: r.xStart,
|
|
734
737
|
x1: r.xEnd + 1,
|
|
@@ -736,9 +739,9 @@ function layerOf(layout, type) {
|
|
|
736
739
|
y1: r.yEnd + 1
|
|
737
740
|
}));
|
|
738
741
|
const curves = curvePaths(shapes.curves, type).map(
|
|
739
|
-
(c) => shapeOf(c.path, c.color, c.alpha ?? 1)
|
|
742
|
+
(c) => shapeOf(c.path, c.color, c.alpha ?? 1, trackOf(c))
|
|
740
743
|
);
|
|
741
|
-
const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, c.color, 1));
|
|
744
|
+
const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, c.color, 1, trackOf(c)));
|
|
742
745
|
return { rects, shapes: [...curves, ...corners] };
|
|
743
746
|
}
|
|
744
747
|
function tubeMapPicture(layout) {
|
|
@@ -797,11 +800,11 @@ function trace(ctx, commands, x, y) {
|
|
|
797
800
|
}
|
|
798
801
|
}
|
|
799
802
|
}
|
|
800
|
-
function fillByColor(ctx, items, visible, addTo) {
|
|
803
|
+
function fillByColor(ctx, items, visible, colorOf, addTo) {
|
|
801
804
|
const byColor = /* @__PURE__ */ new Map();
|
|
802
805
|
for (const item of items) {
|
|
803
806
|
if (visible(item)) {
|
|
804
|
-
const key = `${item
|
|
807
|
+
const key = `${colorOf(item)}|${item.alpha}`;
|
|
805
808
|
const list = byColor.get(key);
|
|
806
809
|
if (list) {
|
|
807
810
|
list.push(item);
|
|
@@ -811,7 +814,7 @@ function fillByColor(ctx, items, visible, addTo) {
|
|
|
811
814
|
}
|
|
812
815
|
}
|
|
813
816
|
for (const list of byColor.values()) {
|
|
814
|
-
ctx.fillStyle = list[0]
|
|
817
|
+
ctx.fillStyle = colorOf(list[0]);
|
|
815
818
|
ctx.globalAlpha = list[0].alpha;
|
|
816
819
|
ctx.beginPath();
|
|
817
820
|
for (const item of list) {
|
|
@@ -826,16 +829,18 @@ var MIN_OUTLINE_ALPHA = 0.15;
|
|
|
826
829
|
function outlineAlpha(screenWidth) {
|
|
827
830
|
return Math.max(MIN_OUTLINE_ALPHA, Math.min(1, screenWidth / FULL_OUTLINE_PX));
|
|
828
831
|
}
|
|
832
|
+
var NODE_TINT_ALPHA = 0.55;
|
|
829
833
|
function drawTubeMap(ctx, picture, frame) {
|
|
830
834
|
const { x, y, width } = frame;
|
|
831
835
|
const visible = (item) => x(item.x1) >= 0 && x(item.x0) <= width;
|
|
836
|
+
const colorOf = (item) => item.track !== void 0 && frame.tubeColors?.[item.track] || item.color;
|
|
832
837
|
for (const layer of picture.layers) {
|
|
833
|
-
fillByColor(ctx, layer.rects, visible, (r) => {
|
|
838
|
+
fillByColor(ctx, layer.rects, visible, colorOf, (r) => {
|
|
834
839
|
const left = x(r.x0);
|
|
835
840
|
const top = y(r.y0);
|
|
836
841
|
ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);
|
|
837
842
|
});
|
|
838
|
-
fillByColor(ctx, layer.shapes, visible, (s) => {
|
|
843
|
+
fillByColor(ctx, layer.shapes, visible, colorOf, (s) => {
|
|
839
844
|
trace(ctx, s.commands, x, y);
|
|
840
845
|
});
|
|
841
846
|
}
|
|
@@ -847,8 +852,10 @@ function drawTubeMap(ctx, picture, frame) {
|
|
|
847
852
|
const lit = node.name === frame.highlightNode;
|
|
848
853
|
ctx.beginPath();
|
|
849
854
|
trace(ctx, node.commands, x, y);
|
|
850
|
-
|
|
855
|
+
const tint = lit ? void 0 : frame.nodeColors?.get(node.name);
|
|
856
|
+
ctx.fillStyle = lit ? "rgba(255,192,203,0.5)" : tint ?? fill;
|
|
851
857
|
ctx.strokeStyle = lit ? "#ff0000" : stroke;
|
|
858
|
+
ctx.globalAlpha = tint ? NODE_TINT_ALPHA : 1;
|
|
852
859
|
ctx.fill();
|
|
853
860
|
ctx.globalAlpha = lit ? 1 : outlineAlpha(x(node.x1) - x(node.x0));
|
|
854
861
|
ctx.stroke();
|
|
@@ -897,6 +904,21 @@ function drawMismatches(ctx, marks, frame) {
|
|
|
897
904
|
}
|
|
898
905
|
}
|
|
899
906
|
|
|
907
|
+
// src/tubeMap/nodeColors.ts
|
|
908
|
+
import { abgrToCssRgba as abgrToCssRgba2 } from "@jbrowse/core/util/colorBits";
|
|
909
|
+
function tubeMapNodeColors(graph, colorScheme, referenceRamp) {
|
|
910
|
+
if (colorScheme === "uniform" || colorScheme === "grey") {
|
|
911
|
+
return void 0;
|
|
912
|
+
}
|
|
913
|
+
const range = { ...computeColorSchemeRange(graph), referenceRamp };
|
|
914
|
+
return new Map(
|
|
915
|
+
graph.nodes.map((node, index) => [
|
|
916
|
+
node.id,
|
|
917
|
+
abgrToCssRgba2(getNodeColor(node, index, colorScheme, range))
|
|
918
|
+
])
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
|
|
900
922
|
// src/tubeMap/warp.ts
|
|
901
923
|
var MAX_GAP_PX = 24;
|
|
902
924
|
var isReal = (c) => c.bp1 > c.bp0;
|
|
@@ -1696,13 +1718,22 @@ function bubbleSubgraph(graph, segmentIds) {
|
|
|
1696
1718
|
const keep = new Set(segmentIds);
|
|
1697
1719
|
const nodes = graph.nodes.filter((n) => keep.has(n.name));
|
|
1698
1720
|
const ids = new Set(nodes.map((n) => n.id));
|
|
1699
|
-
const
|
|
1721
|
+
const kept = /* @__PURE__ */ new Map();
|
|
1722
|
+
const paths = graph.paths?.flatMap((p) => {
|
|
1723
|
+
const first = p.nodeIds.findIndex((id) => ids.has(id));
|
|
1724
|
+
if (first < 0) {
|
|
1725
|
+
return [];
|
|
1726
|
+
}
|
|
1727
|
+
const nodeIds = p.nodeIds.filter((id) => ids.has(id));
|
|
1728
|
+
kept.set(p.name, { first, nodeIds });
|
|
1729
|
+
return [{ ...p, nodeIds }];
|
|
1730
|
+
});
|
|
1700
1731
|
return {
|
|
1701
1732
|
name: graph.name,
|
|
1702
1733
|
nodes,
|
|
1703
1734
|
edges: graph.edges.filter((e) => ids.has(e.from) && ids.has(e.to)),
|
|
1704
1735
|
...paths?.length ? { paths } : {},
|
|
1705
|
-
anchorPaths: graph
|
|
1736
|
+
anchorPaths: trimOrigins(graph, kept),
|
|
1706
1737
|
pathVisits: graph.pathVisits,
|
|
1707
1738
|
anchoredBy: graph.anchoredBy,
|
|
1708
1739
|
referencePath: graph.referencePath
|
|
@@ -1815,6 +1846,7 @@ export {
|
|
|
1815
1846
|
tubeMapFrame,
|
|
1816
1847
|
tubeMapGenes,
|
|
1817
1848
|
tubeMapNodeAt,
|
|
1849
|
+
tubeMapNodeColors,
|
|
1818
1850
|
tubeMapPicture,
|
|
1819
1851
|
tubeX,
|
|
1820
1852
|
version,
|
package/dist/types/figure.d.ts
CHANGED
package/dist/types/gbzCut.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface GraphLabel {
|
|
|
17
17
|
kind: 'node' | 'deletion';
|
|
18
18
|
leader?: Leader;
|
|
19
19
|
}
|
|
20
|
+
export declare function groupDigits(n: number): string;
|
|
20
21
|
export declare function formatBp(bp: number): string;
|
|
21
22
|
interface SizeLabelArgs {
|
|
22
23
|
nodePositions: Record<string, NodeSegment[]>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export { REFERENCE_STRIP_ZONE_PX, drawReferenceStrip, referenceStripBlocks, stri
|
|
|
20
20
|
export type { StripBlock } from './referenceStrip.js';
|
|
21
21
|
export { drawTubeMap, tubeMapPicture } from './tubeMap/draw.js';
|
|
22
22
|
export type { TubeMapFrame, TubeMapPicture } from './tubeMap/draw.js';
|
|
23
|
+
export { tubeMapNodeColors } from './tubeMap/nodeColors.js';
|
|
23
24
|
export { referenceKnots, warpX } from './tubeMap/warp.js';
|
|
24
25
|
export { tubeMapFrame, tubeMapNodeAt } from './tubeMap/frame.js';
|
|
25
26
|
export type { TubeMapTransform, TubeMapView } from './tubeMap/frame.js';
|
|
@@ -17,6 +17,7 @@ export interface LayoutMode {
|
|
|
17
17
|
cutMargins: boolean;
|
|
18
18
|
wholeWalks: boolean;
|
|
19
19
|
drawsLocally: (graph: Graph) => boolean;
|
|
20
|
+
drawsNodes: boolean;
|
|
20
21
|
}
|
|
21
22
|
export declare const LAYOUT_MODES: readonly [{
|
|
22
23
|
readonly value: "auto";
|
|
@@ -27,6 +28,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
27
28
|
readonly wholeWalks: false;
|
|
28
29
|
readonly available: (graph: Graph) => boolean;
|
|
29
30
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
31
|
+
readonly drawsNodes: true;
|
|
30
32
|
}, {
|
|
31
33
|
readonly value: "samplerows";
|
|
32
34
|
readonly label: "Sample rows";
|
|
@@ -36,6 +38,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
36
38
|
readonly wholeWalks: false;
|
|
37
39
|
readonly available: (graph: Graph) => boolean;
|
|
38
40
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
41
|
+
readonly drawsNodes: true;
|
|
39
42
|
}, {
|
|
40
43
|
readonly value: "walkrows";
|
|
41
44
|
readonly label: "Walk rows";
|
|
@@ -45,6 +48,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
45
48
|
readonly wholeWalks: true;
|
|
46
49
|
readonly available: (graph: Graph) => boolean;
|
|
47
50
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
51
|
+
readonly drawsNodes: false;
|
|
48
52
|
}, {
|
|
49
53
|
readonly value: "ordered";
|
|
50
54
|
readonly label: "Ordered";
|
|
@@ -54,6 +58,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
54
58
|
readonly wholeWalks: false;
|
|
55
59
|
readonly available: (graph: Graph) => boolean;
|
|
56
60
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
61
|
+
readonly drawsNodes: true;
|
|
57
62
|
}, {
|
|
58
63
|
readonly value: "tubemap";
|
|
59
64
|
readonly label: "Tube map";
|
|
@@ -63,6 +68,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
63
68
|
readonly wholeWalks: false;
|
|
64
69
|
readonly available: typeof hasTubeMapPaths;
|
|
65
70
|
readonly drawsLocally: typeof hasTubeMapPaths;
|
|
71
|
+
readonly drawsNodes: false;
|
|
66
72
|
}, {
|
|
67
73
|
readonly value: "tubemapref";
|
|
68
74
|
readonly label: "Tube map on reference";
|
|
@@ -72,6 +78,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
72
78
|
readonly wholeWalks: false;
|
|
73
79
|
readonly available: (graph: Graph) => boolean;
|
|
74
80
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
81
|
+
readonly drawsNodes: false;
|
|
75
82
|
}, {
|
|
76
83
|
readonly value: "force";
|
|
77
84
|
readonly label: "Force-directed layout";
|
|
@@ -81,6 +88,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
81
88
|
readonly wholeWalks: false;
|
|
82
89
|
readonly available: () => true;
|
|
83
90
|
readonly drawsLocally: () => false;
|
|
91
|
+
readonly drawsNodes: true;
|
|
84
92
|
}];
|
|
85
93
|
export type LayoutModeValue = (typeof LAYOUT_MODES)[number]['value'];
|
|
86
94
|
export declare const LAYOUT_MODE_VALUES: ("auto" | "ordered" | "samplerows" | "walkrows" | "tubemap" | "tubemapref" | "force")[];
|
|
@@ -94,6 +102,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
94
102
|
readonly wholeWalks: false;
|
|
95
103
|
readonly available: (graph: Graph) => boolean;
|
|
96
104
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
105
|
+
readonly drawsNodes: true;
|
|
97
106
|
} | {
|
|
98
107
|
readonly value: "samplerows";
|
|
99
108
|
readonly label: "Sample rows";
|
|
@@ -103,6 +112,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
103
112
|
readonly wholeWalks: false;
|
|
104
113
|
readonly available: (graph: Graph) => boolean;
|
|
105
114
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
115
|
+
readonly drawsNodes: true;
|
|
106
116
|
} | {
|
|
107
117
|
readonly value: "walkrows";
|
|
108
118
|
readonly label: "Walk rows";
|
|
@@ -112,6 +122,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
112
122
|
readonly wholeWalks: true;
|
|
113
123
|
readonly available: (graph: Graph) => boolean;
|
|
114
124
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
125
|
+
readonly drawsNodes: false;
|
|
115
126
|
} | {
|
|
116
127
|
readonly value: "ordered";
|
|
117
128
|
readonly label: "Ordered";
|
|
@@ -121,6 +132,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
121
132
|
readonly wholeWalks: false;
|
|
122
133
|
readonly available: (graph: Graph) => boolean;
|
|
123
134
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
135
|
+
readonly drawsNodes: true;
|
|
124
136
|
} | {
|
|
125
137
|
readonly value: "tubemap";
|
|
126
138
|
readonly label: "Tube map";
|
|
@@ -130,6 +142,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
130
142
|
readonly wholeWalks: false;
|
|
131
143
|
readonly available: typeof hasTubeMapPaths;
|
|
132
144
|
readonly drawsLocally: typeof hasTubeMapPaths;
|
|
145
|
+
readonly drawsNodes: false;
|
|
133
146
|
} | {
|
|
134
147
|
readonly value: "tubemapref";
|
|
135
148
|
readonly label: "Tube map on reference";
|
|
@@ -139,6 +152,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
139
152
|
readonly wholeWalks: false;
|
|
140
153
|
readonly available: (graph: Graph) => boolean;
|
|
141
154
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
155
|
+
readonly drawsNodes: false;
|
|
142
156
|
} | {
|
|
143
157
|
readonly value: "force";
|
|
144
158
|
readonly label: "Force-directed layout";
|
|
@@ -148,4 +162,5 @@ export declare function layoutModeByValue(value: string): {
|
|
|
148
162
|
readonly wholeWalks: false;
|
|
149
163
|
readonly available: () => true;
|
|
150
164
|
readonly drawsLocally: () => false;
|
|
165
|
+
readonly drawsNodes: true;
|
|
151
166
|
};
|
|
@@ -18,3 +18,7 @@ export declare function surveyPaths(paths: PathSteps[], lengthOf: (segmentId: st
|
|
|
18
18
|
export declare function chooseReferencePath(anchorPaths: PathOrigin[], preferred: string | undefined): PathOrigin | undefined;
|
|
19
19
|
export declare function anchorFromPaths(graph: Graph, preferred: string | undefined): Graph;
|
|
20
20
|
export declare function anchorGraph(graph: Graph, preferred: string | undefined): Graph;
|
|
21
|
+
export declare function trimOrigins(graph: Graph, kept: Map<string, {
|
|
22
|
+
first: number;
|
|
23
|
+
nodeIds: string[];
|
|
24
|
+
}>): PathOrigin[] | undefined;
|
|
@@ -19,7 +19,8 @@ export declare function wellKnownSample(assemblyName: string): string | undefine
|
|
|
19
19
|
export declare function graphBackbone(graph: Graph): Backbone | undefined;
|
|
20
20
|
export declare function backboneAssembly<T extends AssemblyNames>(backbone: Backbone | undefined, assemblies: T[]): T | undefined;
|
|
21
21
|
export declare function assemblyWalk(graph: Graph, assembly: AssemblyNames): PathOrigin | undefined;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function contigNames(contig: string): string[];
|
|
23
|
+
export declare function refNameBinding(refNames: Iterable<string>, aliases?: Record<string, string>): (name: string) => string | undefined;
|
|
23
24
|
export declare function featuresOnBackbone<T extends {
|
|
24
25
|
refName: string;
|
|
25
|
-
}>(features: readonly T[], backbone: Backbone): T[];
|
|
26
|
+
}>(features: readonly T[], backbone: Backbone, aliases?: Record<string, string>): T[];
|
|
@@ -31,6 +31,7 @@ type Command = {
|
|
|
31
31
|
export declare function parsePath(d: string): Command[];
|
|
32
32
|
interface Filled {
|
|
33
33
|
color: string;
|
|
34
|
+
track?: number;
|
|
34
35
|
alpha: number;
|
|
35
36
|
x0: number;
|
|
36
37
|
x1: number;
|
|
@@ -62,6 +63,8 @@ export interface TubeMapFrame extends TubeMapTransform {
|
|
|
62
63
|
width: number;
|
|
63
64
|
highlightNode?: string | null;
|
|
64
65
|
darkMode?: boolean;
|
|
66
|
+
tubeColors?: readonly string[];
|
|
67
|
+
nodeColors?: ReadonlyMap<string, string>;
|
|
65
68
|
}
|
|
66
69
|
export declare function drawTubeMap(ctx: CanvasRenderingContext2D, picture: TubeMapPicture, frame: TubeMapFrame): void;
|
|
67
70
|
export declare function mismatchesLegible(yScale: number): boolean;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ResolvedColorScheme } from '../colorSchemes.js';
|
|
2
|
+
import type { ReferenceRamp } from '../renderer/GeometryBuilder.js';
|
|
3
|
+
import type { Graph } from '../types.js';
|
|
4
|
+
export declare function tubeMapNodeColors(graph: Graph, colorScheme: ResolvedColorScheme, referenceRamp?: ReferenceRamp): Map<string, string> | undefined;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "4.0.
|
|
1
|
+
export declare const version = "4.0.27";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/bandage-core",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.27",
|
|
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": {
|