@jbrowse/bandage-core 0.1.15 → 0.1.17
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/index.js +123 -88
- package/dist/types/layoutModes.d.ts +15 -0
- package/dist/types/pipeline.d.ts +3 -1
- package/dist/types/referenceStrip.d.ts +2 -1
- package/dist/types/renderer/GeometryBuilder.d.ts +1 -0
- package/dist/types/walkEncoding.d.ts +26 -40
- package/dist/types/walkHighlight.d.ts +11 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -979,9 +979,15 @@ function fittedTranslateY(bounds, usableHeight, yScale, padTop = FIT_PADDING) {
|
|
|
979
979
|
const leftoverY = usableHeight - bounds.h * yScale;
|
|
980
980
|
return padTop - bounds.minY * yScale + Math.max(0, leftoverY) / 2;
|
|
981
981
|
}
|
|
982
|
-
function fitTransform(bounds, paneWidth, paneHeight, pixelRows, {
|
|
983
|
-
|
|
984
|
-
|
|
982
|
+
function fitTransform(bounds, paneWidth, paneHeight, pixelRows, {
|
|
983
|
+
minScale = 0,
|
|
984
|
+
padLeft = FIT_PADDING,
|
|
985
|
+
padTop = FIT_PADDING,
|
|
986
|
+
padRight = FIT_PADDING,
|
|
987
|
+
padBottom = FIT_PADDING
|
|
988
|
+
} = {}) {
|
|
989
|
+
const usableWidth = paneWidth - padLeft - padRight;
|
|
990
|
+
const usableHeight = paneHeight - padTop - padBottom;
|
|
985
991
|
if (usableWidth <= 0 || usableHeight <= 0 || !(bounds.w > 0 || !pixelRows && bounds.h > 0)) {
|
|
986
992
|
return void 0;
|
|
987
993
|
}
|
|
@@ -2147,6 +2153,7 @@ var LAYOUT_MODES = [
|
|
|
2147
2153
|
description: "x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.",
|
|
2148
2154
|
run: anchoredLayout,
|
|
2149
2155
|
cutMargins: true,
|
|
2156
|
+
wholeWalks: false,
|
|
2150
2157
|
available: hasBackbone,
|
|
2151
2158
|
drawsLocally: hasBackbone
|
|
2152
2159
|
},
|
|
@@ -2156,6 +2163,7 @@ var LAYOUT_MODES = [
|
|
|
2156
2163
|
description: "x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.",
|
|
2157
2164
|
run: sampleRowLayout,
|
|
2158
2165
|
cutMargins: true,
|
|
2166
|
+
wholeWalks: false,
|
|
2159
2167
|
available: hasAlleles,
|
|
2160
2168
|
drawsLocally: hasAlleles
|
|
2161
2169
|
},
|
|
@@ -2165,6 +2173,7 @@ var LAYOUT_MODES = [
|
|
|
2165
2173
|
description: "x is each walk's own bp: one bar per haplotype, sequence the reference also carries in blue and sequence it does not in purple, so a repeat expansion reads as bar length. Needs W or P lines.",
|
|
2166
2174
|
run: walkRowLayout,
|
|
2167
2175
|
cutMargins: false,
|
|
2176
|
+
wholeWalks: true,
|
|
2168
2177
|
available: hasWalks,
|
|
2169
2178
|
drawsLocally: hasWalks
|
|
2170
2179
|
},
|
|
@@ -2174,6 +2183,7 @@ var LAYOUT_MODES = [
|
|
|
2174
2183
|
description: "x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.",
|
|
2175
2184
|
run: orderedLayout,
|
|
2176
2185
|
cutMargins: false,
|
|
2186
|
+
wholeWalks: false,
|
|
2177
2187
|
available: hasBackbone,
|
|
2178
2188
|
drawsLocally: hasBackbone
|
|
2179
2189
|
},
|
|
@@ -2183,6 +2193,7 @@ var LAYOUT_MODES = [
|
|
|
2183
2193
|
description: "sequenceTubeMap: every path a coloured tube through boxed nodes, columns in node order and node widths log-scaled. Needs P or W lines.",
|
|
2184
2194
|
run: tubeMapLayout,
|
|
2185
2195
|
cutMargins: false,
|
|
2196
|
+
wholeWalks: false,
|
|
2186
2197
|
available: hasTubeMapPaths,
|
|
2187
2198
|
drawsLocally: hasTubeMapPaths
|
|
2188
2199
|
},
|
|
@@ -2192,6 +2203,7 @@ var LAYOUT_MODES = [
|
|
|
2192
2203
|
description: "The tube map with each column at the reference bp it covers, so the tubes line up with the tracks around them. Needs P or W lines and a reference path.",
|
|
2193
2204
|
run: tubeMapReferenceLayout,
|
|
2194
2205
|
cutMargins: true,
|
|
2206
|
+
wholeWalks: false,
|
|
2195
2207
|
available: hasTubeMapBackbone,
|
|
2196
2208
|
drawsLocally: hasTubeMapBackbone
|
|
2197
2209
|
},
|
|
@@ -2201,6 +2213,7 @@ var LAYOUT_MODES = [
|
|
|
2201
2213
|
description: "OGDF FMMM, via the external Bandage engine.",
|
|
2202
2214
|
run: () => void 0,
|
|
2203
2215
|
cutMargins: false,
|
|
2216
|
+
wholeWalks: false,
|
|
2204
2217
|
available: () => true,
|
|
2205
2218
|
drawsLocally: () => false
|
|
2206
2219
|
}
|
|
@@ -2848,10 +2861,11 @@ var EDGE_DEFAULT_COLOR = packAbgr2(119, 119, 119, 217);
|
|
|
2848
2861
|
var EDGE_PATH_FALLBACK_COLOR = packAbgr2(136, 136, 136, 217);
|
|
2849
2862
|
var EDGE_DELETION_COLOR = packAbgr2(24, 24, 28, 240);
|
|
2850
2863
|
var DELETION_THICKNESS_FACTOR = 2.2;
|
|
2864
|
+
var LIFT_BACKDROP_COLOR = packAbgr2(160, 160, 160, 255);
|
|
2851
2865
|
var FADED_ALPHA = 0.18;
|
|
2852
2866
|
var DELETION_DASH_PX = 11;
|
|
2853
2867
|
var MIN_PATH_STRIPE_PX = 1.2;
|
|
2854
|
-
var MIN_WALK_LANE_PX =
|
|
2868
|
+
var MIN_WALK_LANE_PX = 4;
|
|
2855
2869
|
var MIN_SCALE_FOR_OFFSET = 1e-6;
|
|
2856
2870
|
var ARROW_LENGTH_BASE_PX = 7;
|
|
2857
2871
|
var ARROW_LENGTH_PER_EDGE_PX = 3;
|
|
@@ -3438,13 +3452,13 @@ function buildGeometry(options) {
|
|
|
3438
3452
|
if (viewportBounds && !isPolylineInBounds(segments, viewportBounds)) {
|
|
3439
3453
|
continue;
|
|
3440
3454
|
}
|
|
3441
|
-
const
|
|
3455
|
+
const faded = highlight !== void 0 && !highlight.nodeIds.has(nodeId);
|
|
3456
|
+
const own = faded ? LIFT_BACKDROP_COLOR : getNodeColor(
|
|
3442
3457
|
node,
|
|
3443
3458
|
nodeIndexMap.get(nodeId) ?? 0,
|
|
3444
3459
|
colorScheme,
|
|
3445
3460
|
colorRange
|
|
3446
3461
|
);
|
|
3447
|
-
const faded = highlight !== void 0 && !highlight.nodeIds.has(nodeId);
|
|
3448
3462
|
const color = faded ? fadeAbgr(own, FADED_ALPHA) : own;
|
|
3449
3463
|
const width = nodeWidthPx(node, contigThickness, nodeWidth2, depthNorm);
|
|
3450
3464
|
const nodeThickness = width / 2;
|
|
@@ -4074,13 +4088,14 @@ var OVERHANG_PX = 5;
|
|
|
4074
4088
|
function referenceStripBlocks(graph, {
|
|
4075
4089
|
colorScheme,
|
|
4076
4090
|
referenceRamp,
|
|
4077
|
-
walkNodes
|
|
4091
|
+
walkNodes,
|
|
4092
|
+
walkColors
|
|
4078
4093
|
}) {
|
|
4079
4094
|
const range = { ...computeColorSchemeRange(graph), referenceRamp };
|
|
4080
4095
|
const out = [];
|
|
4081
4096
|
graph.nodes.forEach((node, index) => {
|
|
4082
4097
|
if (isBackbone(node)) {
|
|
4083
|
-
const own = getNodeColor(node, index, colorScheme, range);
|
|
4098
|
+
const own = walkNodes ? walkColors?.get(node.id) ?? LIFT_BACKDROP_COLOR : getNodeColor(node, index, colorScheme, range);
|
|
4084
4099
|
out.push({
|
|
4085
4100
|
node: node.id,
|
|
4086
4101
|
bp0: node.stable.start,
|
|
@@ -5239,78 +5254,84 @@ var WALK_FIELDS = [
|
|
|
5239
5254
|
{
|
|
5240
5255
|
value: "progress",
|
|
5241
5256
|
label: "Progress along the walk",
|
|
5242
|
-
legend: "
|
|
5257
|
+
legend: "light where each walk starts, dark where it ends"
|
|
5243
5258
|
},
|
|
5259
|
+
{ value: "walk", label: "One colour for the walk", legend: "" },
|
|
5244
5260
|
{
|
|
5245
5261
|
value: "reference",
|
|
5246
5262
|
label: "Reference position",
|
|
5247
5263
|
legend: "along the reference left to right, charcoal off it"
|
|
5248
|
-
},
|
|
5249
|
-
{
|
|
5250
|
-
value: "strand",
|
|
5251
|
-
label: "Strand against the reference",
|
|
5252
|
-
legend: "pale where the walk runs as the reference does, deep where reversed"
|
|
5253
|
-
},
|
|
5254
|
-
{
|
|
5255
|
-
value: "visits",
|
|
5256
|
-
label: "Visits",
|
|
5257
|
-
legend: "pale where the walk passes once, deep four times or more"
|
|
5258
5264
|
}
|
|
5259
5265
|
];
|
|
5260
5266
|
var WALK_SCHEMES = [
|
|
5261
|
-
{ value: "
|
|
5262
|
-
{ value: "
|
|
5263
|
-
{ value: "
|
|
5264
|
-
{ value: "
|
|
5265
|
-
{ value: "
|
|
5266
|
-
{ value: "
|
|
5267
|
-
{ value: "greys", label: "Greys" }
|
|
5268
|
-
];
|
|
5269
|
-
var DEFAULT_FAMILIES = [
|
|
5270
|
-
"blues",
|
|
5271
|
-
"reds",
|
|
5272
|
-
"greens",
|
|
5273
|
-
"oranges",
|
|
5274
|
-
"purples"
|
|
5267
|
+
{ value: "grey", label: "Grey to black", ends: ["#a3a3a3", "#151515"] },
|
|
5268
|
+
{ value: "blue", label: "Cyan to navy", ends: ["#6ee0f0", "#0b2c7a"] },
|
|
5269
|
+
{ value: "red", label: "Yellow to red", ends: ["#ffd24a", "#b3121b"] },
|
|
5270
|
+
{ value: "purple", label: "Pink to plum", ends: ["#f5a3d8", "#5e1a6e"] },
|
|
5271
|
+
{ value: "green", label: "Lime to forest", ends: ["#b6e36c", "#0b5d3b"] },
|
|
5272
|
+
{ value: "rainbow", label: "Rainbow" }
|
|
5275
5273
|
];
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
};
|
|
5274
|
+
var FAMILIES = ["blue", "red", "purple", "green"];
|
|
5275
|
+
var isField = (v) => WALK_FIELDS.some((f) => f.value === v);
|
|
5276
|
+
var isScheme = (v) => WALK_SCHEMES.some((s) => s.value === v);
|
|
5277
|
+
function resolveEncoding(layer, reference, picked, alone = true) {
|
|
5278
|
+
const { field: askedField, scheme: askedScheme } = layer.color ?? {};
|
|
5279
|
+
const field = isField(askedField) ? askedField : alone ? "progress" : "walk";
|
|
5280
|
+
const family = reference ? "grey" : FAMILIES[picked % FAMILIES.length];
|
|
5281
|
+
const scheme = isScheme(askedScheme) ? askedScheme === "rainbow" && field !== "reference" ? family : askedScheme : family;
|
|
5282
|
+
return { field, scheme };
|
|
5283
|
+
}
|
|
5284
|
+
var BASE_T = 0.5;
|
|
5285
|
+
var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
5286
|
+
var toGamma = (c) => c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055;
|
|
5287
|
+
function oklab(hex) {
|
|
5288
|
+
const [r, g, b] = [1, 3, 5].map(
|
|
5289
|
+
(i) => toLinear(Number.parseInt(hex.slice(i, i + 2), 16) / 255)
|
|
5290
|
+
);
|
|
5291
|
+
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
5292
|
+
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
5293
|
+
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
5294
|
+
return [
|
|
5295
|
+
0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
|
|
5296
|
+
1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
|
|
5297
|
+
0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s
|
|
5298
|
+
];
|
|
5299
|
+
}
|
|
5300
|
+
function oklabToRgb([L, a, b]) {
|
|
5301
|
+
const l = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3;
|
|
5302
|
+
const m = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3;
|
|
5303
|
+
const s = (L - 0.0894841775 * a - 1.291485548 * b) ** 3;
|
|
5304
|
+
return [
|
|
5305
|
+
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
5306
|
+
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
5307
|
+
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
5308
|
+
].map((c) => toGamma(Math.max(0, Math.min(1, c))) * 255);
|
|
5281
5309
|
}
|
|
5282
|
-
|
|
5283
|
-
var DEEP = 0.28;
|
|
5284
|
-
function schemeHsl(scheme, t) {
|
|
5310
|
+
function schemeRgb(scheme, t) {
|
|
5285
5311
|
const x = Math.max(0, Math.min(1, t));
|
|
5286
|
-
if (scheme === "rainbow") {
|
|
5287
|
-
return { h: x * REFERENCE_RAMP_MAX_HUE, s: 0.7, l: 0.5 };
|
|
5288
|
-
}
|
|
5289
5312
|
const family = WALK_SCHEMES.find((s) => s.value === scheme);
|
|
5290
|
-
|
|
5291
|
-
|
|
5313
|
+
if (!family || !("ends" in family)) {
|
|
5314
|
+
return hslToRgb(x * REFERENCE_RAMP_MAX_HUE, 0.7, 0.5).map((c) => c * 255);
|
|
5315
|
+
}
|
|
5316
|
+
const from = oklab(family.ends[0]);
|
|
5317
|
+
const to = oklab(family.ends[1]);
|
|
5318
|
+
return oklabToRgb(from.map((v, i) => v + (to[i] - v) * x));
|
|
5292
5319
|
}
|
|
5293
5320
|
function schemeCss(scheme, t) {
|
|
5294
|
-
const
|
|
5295
|
-
return `
|
|
5321
|
+
const [r, g, b] = schemeRgb(scheme, t).map(Math.round);
|
|
5322
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
5296
5323
|
}
|
|
5297
5324
|
function schemeColor(scheme, t) {
|
|
5298
|
-
const
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
Math.round(b * 255),
|
|
5304
|
-
255
|
|
5305
|
-
);
|
|
5325
|
+
const [r, g, b] = schemeRgb(scheme, t).map(Math.round);
|
|
5326
|
+
return packAbgr3(r, g, b, 255);
|
|
5327
|
+
}
|
|
5328
|
+
function encodedColor({ field, scheme }, t) {
|
|
5329
|
+
return field === "walk" ? schemeColor(scheme, BASE_T) : t === void 0 ? NO_VALUE_COLOR : schemeColor(scheme, t);
|
|
5306
5330
|
}
|
|
5307
5331
|
var NO_VALUE_COLOR = REFERENCE_RAMP_ALT_COLOR;
|
|
5308
|
-
var STRAND_T = { same: 0.2, reversed: 0.95 };
|
|
5309
5332
|
function encodingSwatchCss({ field, scheme }) {
|
|
5310
|
-
if (field === "
|
|
5311
|
-
|
|
5312
|
-
const reversed = schemeCss(scheme, STRAND_T.reversed);
|
|
5313
|
-
return `linear-gradient(to right, ${same} 50%, ${reversed} 50%)`;
|
|
5333
|
+
if (field === "walk") {
|
|
5334
|
+
return schemeCss(scheme, BASE_T);
|
|
5314
5335
|
}
|
|
5315
5336
|
const stops = Array.from({ length: 7 }, (_, i) => {
|
|
5316
5337
|
const t = i / 6;
|
|
@@ -5357,9 +5378,16 @@ function walkHighlight(graph, name) {
|
|
|
5357
5378
|
before += length;
|
|
5358
5379
|
}
|
|
5359
5380
|
const reference = referenceOf(graph);
|
|
5381
|
+
const originName = pathOrigin(name).name;
|
|
5382
|
+
const origin = graph.anchorPaths?.find((a) => a.name === originName && a.length === bp) ?? graph.anchorPaths?.find((a) => a.name === originName);
|
|
5360
5383
|
return {
|
|
5361
5384
|
name,
|
|
5362
5385
|
reference: reference === path,
|
|
5386
|
+
range: origin ? {
|
|
5387
|
+
contig: path.contig ?? panSNContig(origin.name),
|
|
5388
|
+
start: origin.start,
|
|
5389
|
+
end: origin.start + origin.length
|
|
5390
|
+
} : void 0,
|
|
5363
5391
|
nodeIds: new Set(path.nodeIds),
|
|
5364
5392
|
edgeIndexes,
|
|
5365
5393
|
progress,
|
|
@@ -5368,37 +5396,39 @@ function walkHighlight(graph, name) {
|
|
|
5368
5396
|
referenceBp: reference && reference !== path ? reference.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0) : void 0
|
|
5369
5397
|
};
|
|
5370
5398
|
}
|
|
5371
|
-
function laneColors(graph, walk,
|
|
5372
|
-
const colors = /* @__PURE__ */ new Map();
|
|
5399
|
+
function laneColors(graph, walk, encoding, ramp) {
|
|
5373
5400
|
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
5374
|
-
const
|
|
5375
|
-
const reference = referenceOf(graph);
|
|
5376
|
-
const referencePath = reference ? pathOrigin(reference.name).name : void 0;
|
|
5377
|
-
const path = graph.paths.find((p) => p.name === walk.name);
|
|
5378
|
-
const visits = /* @__PURE__ */ new Map();
|
|
5379
|
-
for (const id of path.nodeIds) {
|
|
5380
|
-
visits.set(id, (visits.get(id) ?? 0) + 1);
|
|
5381
|
-
}
|
|
5382
|
-
const strandOf = (segment, of) => graph.pathVisits?.get(segment)?.find((v) => v.path === of)?.strand;
|
|
5401
|
+
const colors = /* @__PURE__ */ new Map();
|
|
5383
5402
|
for (const [id, progress] of walk.progress) {
|
|
5384
5403
|
const node = byId.get(id);
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
} else if (field === "visits") {
|
|
5389
|
-
t = (Math.min(visits.get(id) ?? 1, 4) - 1) / 3;
|
|
5390
|
-
} else if (field === "reference") {
|
|
5391
|
-
const mid = ramp?.midpoints.get(id);
|
|
5392
|
-
t = ramp && mid !== void 0 && !(node?.stable && node.stable.rank > 0) ? (mid - ramp.start) / ramp.span : void 0;
|
|
5393
|
-
} else if (node) {
|
|
5394
|
-
const own = strandOf(node.name, walkPath);
|
|
5395
|
-
const theirs = strandOf(node.name, referencePath);
|
|
5396
|
-
t = own && theirs ? own === theirs ? STRAND_T.same : STRAND_T.reversed : void 0;
|
|
5397
|
-
}
|
|
5398
|
-
colors.set(id, t === void 0 ? NO_VALUE_COLOR : schemeColor(scheme, t));
|
|
5404
|
+
const mid = ramp?.midpoints.get(id);
|
|
5405
|
+
const t = encoding.field === "progress" ? progress : ramp && mid !== void 0 && !(node?.stable && node.stable.rank > 0) ? (mid - ramp.start) / ramp.span : void 0;
|
|
5406
|
+
colors.set(id, encodedColor(encoding, t));
|
|
5399
5407
|
}
|
|
5400
5408
|
return colors;
|
|
5401
5409
|
}
|
|
5410
|
+
function reversedNodes(graph, walk) {
|
|
5411
|
+
const reference = referenceOf(graph);
|
|
5412
|
+
const reversed = /* @__PURE__ */ new Set();
|
|
5413
|
+
let bp = 0;
|
|
5414
|
+
if (!reference || walk.reference) {
|
|
5415
|
+
return { reversed, bp };
|
|
5416
|
+
}
|
|
5417
|
+
const walkPath = pathOrigin(walk.name).name;
|
|
5418
|
+
const referencePath = pathOrigin(reference.name).name;
|
|
5419
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
5420
|
+
for (const id of walk.progress.keys()) {
|
|
5421
|
+
const node = byId.get(id);
|
|
5422
|
+
const visits = node ? graph.pathVisits?.get(node.name) : void 0;
|
|
5423
|
+
const own = visits?.find((v) => v.path === walkPath)?.strand;
|
|
5424
|
+
const theirs = visits?.find((v) => v.path === referencePath)?.strand;
|
|
5425
|
+
if (own && theirs && own !== theirs) {
|
|
5426
|
+
reversed.add(id);
|
|
5427
|
+
bp += node.length;
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5430
|
+
return { reversed, bp };
|
|
5431
|
+
}
|
|
5402
5432
|
function walkLift(graph, layers, ramp) {
|
|
5403
5433
|
const seen = /* @__PURE__ */ new Set();
|
|
5404
5434
|
const lifted = layers.filter((layer) => !seen.has(layer.walk) && seen.add(layer.walk)).flatMap((layer) => {
|
|
@@ -5413,16 +5443,21 @@ function walkLift(graph, layers, ramp) {
|
|
|
5413
5443
|
const encoding = resolveEncoding(
|
|
5414
5444
|
layer,
|
|
5415
5445
|
walk.reference,
|
|
5416
|
-
walk.reference ? 0 : picked
|
|
5446
|
+
walk.reference ? 0 : picked++,
|
|
5447
|
+
lifted.length === 1
|
|
5417
5448
|
);
|
|
5449
|
+
const { reversed, bp } = reversedNodes(graph, walk);
|
|
5418
5450
|
return {
|
|
5419
5451
|
...walk,
|
|
5420
5452
|
encoding,
|
|
5421
|
-
colors: laneColors(graph, walk, encoding, ramp)
|
|
5453
|
+
colors: laneColors(graph, walk, encoding, ramp),
|
|
5454
|
+
reversed,
|
|
5455
|
+
reversedBp: bp
|
|
5422
5456
|
};
|
|
5423
5457
|
});
|
|
5424
5458
|
return {
|
|
5425
5459
|
walks,
|
|
5460
|
+
referenceDomain: ramp ? { start: ramp.start, end: ramp.start + ramp.span } : void 0,
|
|
5426
5461
|
nodeIds: new Set(walks.flatMap((w) => [...w.nodeIds])),
|
|
5427
5462
|
edgeIndexes: new Set(walks.flatMap((w) => [...w.edgeIndexes])),
|
|
5428
5463
|
names: new Set(walks.map((w) => w.name))
|
|
@@ -15,6 +15,7 @@ export interface LayoutMode {
|
|
|
15
15
|
}, keepRows?: readonly string[]) => LayoutResult | undefined;
|
|
16
16
|
available: (graph: Graph) => boolean;
|
|
17
17
|
cutMargins: boolean;
|
|
18
|
+
wholeWalks: boolean;
|
|
18
19
|
drawsLocally: (graph: Graph) => boolean;
|
|
19
20
|
}
|
|
20
21
|
export declare const LAYOUT_MODES: readonly [{
|
|
@@ -23,6 +24,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
23
24
|
readonly description: "x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.";
|
|
24
25
|
readonly run: typeof anchoredLayout;
|
|
25
26
|
readonly cutMargins: true;
|
|
27
|
+
readonly wholeWalks: false;
|
|
26
28
|
readonly available: (graph: Graph) => boolean;
|
|
27
29
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
28
30
|
}, {
|
|
@@ -31,6 +33,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
31
33
|
readonly description: "x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.";
|
|
32
34
|
readonly run: typeof sampleRowLayout;
|
|
33
35
|
readonly cutMargins: true;
|
|
36
|
+
readonly wholeWalks: false;
|
|
34
37
|
readonly available: (graph: Graph) => boolean;
|
|
35
38
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
36
39
|
}, {
|
|
@@ -39,6 +42,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
39
42
|
readonly description: "x is each walk's own bp: one bar per haplotype, sequence the reference also carries in blue and sequence it does not in purple, so a repeat expansion reads as bar length. Needs W or P lines.";
|
|
40
43
|
readonly run: typeof walkRowLayout;
|
|
41
44
|
readonly cutMargins: false;
|
|
45
|
+
readonly wholeWalks: true;
|
|
42
46
|
readonly available: (graph: Graph) => boolean;
|
|
43
47
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
44
48
|
}, {
|
|
@@ -47,6 +51,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
47
51
|
readonly description: "x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.";
|
|
48
52
|
readonly run: typeof orderedLayout;
|
|
49
53
|
readonly cutMargins: false;
|
|
54
|
+
readonly wholeWalks: false;
|
|
50
55
|
readonly available: (graph: Graph) => boolean;
|
|
51
56
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
52
57
|
}, {
|
|
@@ -55,6 +60,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
55
60
|
readonly description: "sequenceTubeMap: every path a coloured tube through boxed nodes, columns in node order and node widths log-scaled. Needs P or W lines.";
|
|
56
61
|
readonly run: typeof tubeMapLayout;
|
|
57
62
|
readonly cutMargins: false;
|
|
63
|
+
readonly wholeWalks: false;
|
|
58
64
|
readonly available: typeof hasTubeMapPaths;
|
|
59
65
|
readonly drawsLocally: typeof hasTubeMapPaths;
|
|
60
66
|
}, {
|
|
@@ -63,6 +69,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
63
69
|
readonly description: "The tube map with each column at the reference bp it covers, so the tubes line up with the tracks around them. Needs P or W lines and a reference path.";
|
|
64
70
|
readonly run: typeof tubeMapReferenceLayout;
|
|
65
71
|
readonly cutMargins: true;
|
|
72
|
+
readonly wholeWalks: false;
|
|
66
73
|
readonly available: (graph: Graph) => boolean;
|
|
67
74
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
68
75
|
}, {
|
|
@@ -71,6 +78,7 @@ export declare const LAYOUT_MODES: readonly [{
|
|
|
71
78
|
readonly description: "OGDF FMMM, via the external Bandage engine.";
|
|
72
79
|
readonly run: () => undefined;
|
|
73
80
|
readonly cutMargins: false;
|
|
81
|
+
readonly wholeWalks: false;
|
|
74
82
|
readonly available: () => true;
|
|
75
83
|
readonly drawsLocally: () => false;
|
|
76
84
|
}];
|
|
@@ -83,6 +91,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
83
91
|
readonly description: "x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.";
|
|
84
92
|
readonly run: typeof anchoredLayout;
|
|
85
93
|
readonly cutMargins: true;
|
|
94
|
+
readonly wholeWalks: false;
|
|
86
95
|
readonly available: (graph: Graph) => boolean;
|
|
87
96
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
88
97
|
} | {
|
|
@@ -91,6 +100,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
91
100
|
readonly description: "x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.";
|
|
92
101
|
readonly run: typeof sampleRowLayout;
|
|
93
102
|
readonly cutMargins: true;
|
|
103
|
+
readonly wholeWalks: false;
|
|
94
104
|
readonly available: (graph: Graph) => boolean;
|
|
95
105
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
96
106
|
} | {
|
|
@@ -99,6 +109,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
99
109
|
readonly description: "x is each walk's own bp: one bar per haplotype, sequence the reference also carries in blue and sequence it does not in purple, so a repeat expansion reads as bar length. Needs W or P lines.";
|
|
100
110
|
readonly run: typeof walkRowLayout;
|
|
101
111
|
readonly cutMargins: false;
|
|
112
|
+
readonly wholeWalks: true;
|
|
102
113
|
readonly available: (graph: Graph) => boolean;
|
|
103
114
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
104
115
|
} | {
|
|
@@ -107,6 +118,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
107
118
|
readonly description: "x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.";
|
|
108
119
|
readonly run: typeof orderedLayout;
|
|
109
120
|
readonly cutMargins: false;
|
|
121
|
+
readonly wholeWalks: false;
|
|
110
122
|
readonly available: (graph: Graph) => boolean;
|
|
111
123
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
112
124
|
} | {
|
|
@@ -115,6 +127,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
115
127
|
readonly description: "sequenceTubeMap: every path a coloured tube through boxed nodes, columns in node order and node widths log-scaled. Needs P or W lines.";
|
|
116
128
|
readonly run: typeof tubeMapLayout;
|
|
117
129
|
readonly cutMargins: false;
|
|
130
|
+
readonly wholeWalks: false;
|
|
118
131
|
readonly available: typeof hasTubeMapPaths;
|
|
119
132
|
readonly drawsLocally: typeof hasTubeMapPaths;
|
|
120
133
|
} | {
|
|
@@ -123,6 +136,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
123
136
|
readonly description: "The tube map with each column at the reference bp it covers, so the tubes line up with the tracks around them. Needs P or W lines and a reference path.";
|
|
124
137
|
readonly run: typeof tubeMapReferenceLayout;
|
|
125
138
|
readonly cutMargins: true;
|
|
139
|
+
readonly wholeWalks: false;
|
|
126
140
|
readonly available: (graph: Graph) => boolean;
|
|
127
141
|
readonly drawsLocally: (graph: Graph) => boolean;
|
|
128
142
|
} | {
|
|
@@ -131,6 +145,7 @@ export declare function layoutModeByValue(value: string): {
|
|
|
131
145
|
readonly description: "OGDF FMMM, via the external Bandage engine.";
|
|
132
146
|
readonly run: () => undefined;
|
|
133
147
|
readonly cutMargins: false;
|
|
148
|
+
readonly wholeWalks: false;
|
|
134
149
|
readonly available: () => true;
|
|
135
150
|
readonly drawsLocally: () => false;
|
|
136
151
|
};
|
package/dist/types/pipeline.d.ts
CHANGED
|
@@ -60,10 +60,12 @@ export declare function fitTransform(bounds: {
|
|
|
60
60
|
minY: number;
|
|
61
61
|
w: number;
|
|
62
62
|
h: number;
|
|
63
|
-
}, paneWidth: number, paneHeight: number, pixelRows: boolean, { minScale, padLeft, padTop }?: {
|
|
63
|
+
}, paneWidth: number, paneHeight: number, pixelRows: boolean, { minScale, padLeft, padTop, padRight, padBottom, }?: {
|
|
64
64
|
minScale?: number | undefined;
|
|
65
65
|
padLeft?: number | undefined;
|
|
66
66
|
padTop?: number | undefined;
|
|
67
|
+
padRight?: number | undefined;
|
|
68
|
+
padBottom?: number | undefined;
|
|
67
69
|
}): {
|
|
68
70
|
scale: number;
|
|
69
71
|
translateX: number;
|
|
@@ -9,10 +9,11 @@ export interface StripBlock {
|
|
|
9
9
|
bp1: number;
|
|
10
10
|
color: string;
|
|
11
11
|
}
|
|
12
|
-
export declare function referenceStripBlocks(graph: Graph, { colorScheme, referenceRamp, walkNodes, }: {
|
|
12
|
+
export declare function referenceStripBlocks(graph: Graph, { colorScheme, referenceRamp, walkNodes, walkColors, }: {
|
|
13
13
|
colorScheme: ResolvedColorScheme;
|
|
14
14
|
referenceRamp?: ReferenceRamp;
|
|
15
15
|
walkNodes?: ReadonlySet<string>;
|
|
16
|
+
walkColors?: ReadonlyMap<string, number>;
|
|
16
17
|
}): StripBlock[];
|
|
17
18
|
export interface BpFrame {
|
|
18
19
|
scale: number;
|
|
@@ -4,6 +4,7 @@ import type { Graph, GraphNode, NodeSegment } from '../types.js';
|
|
|
4
4
|
import type { WalkLift } from '../walkHighlight.js';
|
|
5
5
|
import type { RenderBatch } from './types.js';
|
|
6
6
|
import type { AxisScale, BezierCurve } from '../util/geometry.js';
|
|
7
|
+
export declare const LIFT_BACKDROP_COLOR: number;
|
|
7
8
|
export declare const FADED_ALPHA = 0.18;
|
|
8
9
|
export interface BuildOptions {
|
|
9
10
|
nodePositions: Record<string, NodeSegment[]>;
|
|
@@ -1,47 +1,40 @@
|
|
|
1
1
|
export declare const WALK_FIELDS: readonly [{
|
|
2
2
|
readonly value: "progress";
|
|
3
3
|
readonly label: "Progress along the walk";
|
|
4
|
-
readonly legend: "
|
|
4
|
+
readonly legend: "light where each walk starts, dark where it ends";
|
|
5
|
+
}, {
|
|
6
|
+
readonly value: "walk";
|
|
7
|
+
readonly label: "One colour for the walk";
|
|
8
|
+
readonly legend: "";
|
|
5
9
|
}, {
|
|
6
10
|
readonly value: "reference";
|
|
7
11
|
readonly label: "Reference position";
|
|
8
12
|
readonly legend: "along the reference left to right, charcoal off it";
|
|
9
|
-
}, {
|
|
10
|
-
readonly value: "strand";
|
|
11
|
-
readonly label: "Strand against the reference";
|
|
12
|
-
readonly legend: "pale where the walk runs as the reference does, deep where reversed";
|
|
13
|
-
}, {
|
|
14
|
-
readonly value: "visits";
|
|
15
|
-
readonly label: "Visits";
|
|
16
|
-
readonly legend: "pale where the walk passes once, deep four times or more";
|
|
17
13
|
}];
|
|
18
14
|
export type WalkField = (typeof WALK_FIELDS)[number]['value'];
|
|
19
15
|
export declare const WALK_SCHEMES: readonly [{
|
|
20
|
-
readonly value: "
|
|
21
|
-
readonly label: "
|
|
22
|
-
|
|
23
|
-
readonly value: "blues";
|
|
24
|
-
readonly label: "Blues";
|
|
25
|
-
readonly hue: 215;
|
|
16
|
+
readonly value: "grey";
|
|
17
|
+
readonly label: "Grey to black";
|
|
18
|
+
readonly ends: readonly ["#a3a3a3", "#151515"];
|
|
26
19
|
}, {
|
|
27
|
-
readonly value: "
|
|
28
|
-
readonly label: "
|
|
29
|
-
readonly
|
|
20
|
+
readonly value: "blue";
|
|
21
|
+
readonly label: "Cyan to navy";
|
|
22
|
+
readonly ends: readonly ["#6ee0f0", "#0b2c7a"];
|
|
30
23
|
}, {
|
|
31
|
-
readonly value: "
|
|
32
|
-
readonly label: "
|
|
33
|
-
readonly
|
|
24
|
+
readonly value: "red";
|
|
25
|
+
readonly label: "Yellow to red";
|
|
26
|
+
readonly ends: readonly ["#ffd24a", "#b3121b"];
|
|
34
27
|
}, {
|
|
35
|
-
readonly value: "
|
|
36
|
-
readonly label: "
|
|
37
|
-
readonly
|
|
28
|
+
readonly value: "purple";
|
|
29
|
+
readonly label: "Pink to plum";
|
|
30
|
+
readonly ends: readonly ["#f5a3d8", "#5e1a6e"];
|
|
38
31
|
}, {
|
|
39
|
-
readonly value: "
|
|
40
|
-
readonly label: "
|
|
41
|
-
readonly
|
|
32
|
+
readonly value: "green";
|
|
33
|
+
readonly label: "Lime to forest";
|
|
34
|
+
readonly ends: readonly ["#b6e36c", "#0b5d3b"];
|
|
42
35
|
}, {
|
|
43
|
-
readonly value: "
|
|
44
|
-
readonly label: "
|
|
36
|
+
readonly value: "rainbow";
|
|
37
|
+
readonly label: "Rainbow";
|
|
45
38
|
}];
|
|
46
39
|
export type WalkScheme = (typeof WALK_SCHEMES)[number]['value'];
|
|
47
40
|
export interface WalkEncoding {
|
|
@@ -52,19 +45,12 @@ export interface WalkLayer {
|
|
|
52
45
|
walk: string;
|
|
53
46
|
color?: Partial<WalkEncoding>;
|
|
54
47
|
}
|
|
55
|
-
export declare function resolveEncoding(layer: WalkLayer, reference: boolean, picked: number): WalkEncoding;
|
|
56
|
-
export declare function
|
|
57
|
-
h: number;
|
|
58
|
-
s: number;
|
|
59
|
-
l: number;
|
|
60
|
-
};
|
|
48
|
+
export declare function resolveEncoding(layer: WalkLayer, reference: boolean, picked: number, alone?: boolean): WalkEncoding;
|
|
49
|
+
export declare function schemeRgb(scheme: WalkScheme, t: number): number[];
|
|
61
50
|
export declare function schemeCss(scheme: WalkScheme, t: number): string;
|
|
62
51
|
export declare function schemeColor(scheme: WalkScheme, t: number): number;
|
|
52
|
+
export declare function encodedColor({ field, scheme }: WalkEncoding, t?: number): number;
|
|
63
53
|
export declare const NO_VALUE_COLOR: number;
|
|
64
54
|
export declare const NO_VALUE_CSS: string;
|
|
65
|
-
export declare const STRAND_T: {
|
|
66
|
-
same: number;
|
|
67
|
-
reversed: number;
|
|
68
|
-
};
|
|
69
55
|
export declare function encodingSwatchCss({ field, scheme }: WalkEncoding): string;
|
|
70
|
-
export declare function fieldLegend(field: WalkField): "
|
|
56
|
+
export declare function fieldLegend(field: WalkField): "" | "light where each walk starts, dark where it ends" | "along the reference left to right, charcoal off it";
|
|
@@ -10,13 +10,24 @@ export interface WalkHighlight {
|
|
|
10
10
|
steps: number;
|
|
11
11
|
bp: number;
|
|
12
12
|
referenceBp?: number;
|
|
13
|
+
range?: {
|
|
14
|
+
contig: string;
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
};
|
|
13
18
|
}
|
|
14
19
|
export interface LiftedWalk extends WalkHighlight {
|
|
15
20
|
encoding: WalkEncoding;
|
|
16
21
|
colors: Map<string, number>;
|
|
22
|
+
reversed: Set<string>;
|
|
23
|
+
reversedBp: number;
|
|
17
24
|
}
|
|
18
25
|
export interface WalkLift {
|
|
19
26
|
walks: LiftedWalk[];
|
|
27
|
+
referenceDomain?: {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
};
|
|
20
31
|
nodeIds: Set<string>;
|
|
21
32
|
edgeIndexes: Set<number>;
|
|
22
33
|
names: Set<string>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/bandage-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
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": {
|