@jbrowse/bandage-core 0.1.14 → 0.1.16
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
CHANGED
|
@@ -2147,6 +2147,7 @@ var LAYOUT_MODES = [
|
|
|
2147
2147
|
description: "x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.",
|
|
2148
2148
|
run: anchoredLayout,
|
|
2149
2149
|
cutMargins: true,
|
|
2150
|
+
wholeWalks: false,
|
|
2150
2151
|
available: hasBackbone,
|
|
2151
2152
|
drawsLocally: hasBackbone
|
|
2152
2153
|
},
|
|
@@ -2156,6 +2157,7 @@ var LAYOUT_MODES = [
|
|
|
2156
2157
|
description: "x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.",
|
|
2157
2158
|
run: sampleRowLayout,
|
|
2158
2159
|
cutMargins: true,
|
|
2160
|
+
wholeWalks: false,
|
|
2159
2161
|
available: hasAlleles,
|
|
2160
2162
|
drawsLocally: hasAlleles
|
|
2161
2163
|
},
|
|
@@ -2165,6 +2167,7 @@ var LAYOUT_MODES = [
|
|
|
2165
2167
|
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
2168
|
run: walkRowLayout,
|
|
2167
2169
|
cutMargins: false,
|
|
2170
|
+
wholeWalks: true,
|
|
2168
2171
|
available: hasWalks,
|
|
2169
2172
|
drawsLocally: hasWalks
|
|
2170
2173
|
},
|
|
@@ -2174,6 +2177,7 @@ var LAYOUT_MODES = [
|
|
|
2174
2177
|
description: "x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.",
|
|
2175
2178
|
run: orderedLayout,
|
|
2176
2179
|
cutMargins: false,
|
|
2180
|
+
wholeWalks: false,
|
|
2177
2181
|
available: hasBackbone,
|
|
2178
2182
|
drawsLocally: hasBackbone
|
|
2179
2183
|
},
|
|
@@ -2183,6 +2187,7 @@ var LAYOUT_MODES = [
|
|
|
2183
2187
|
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
2188
|
run: tubeMapLayout,
|
|
2185
2189
|
cutMargins: false,
|
|
2190
|
+
wholeWalks: false,
|
|
2186
2191
|
available: hasTubeMapPaths,
|
|
2187
2192
|
drawsLocally: hasTubeMapPaths
|
|
2188
2193
|
},
|
|
@@ -2192,6 +2197,7 @@ var LAYOUT_MODES = [
|
|
|
2192
2197
|
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
2198
|
run: tubeMapReferenceLayout,
|
|
2194
2199
|
cutMargins: true,
|
|
2200
|
+
wholeWalks: false,
|
|
2195
2201
|
available: hasTubeMapBackbone,
|
|
2196
2202
|
drawsLocally: hasTubeMapBackbone
|
|
2197
2203
|
},
|
|
@@ -2201,6 +2207,7 @@ var LAYOUT_MODES = [
|
|
|
2201
2207
|
description: "OGDF FMMM, via the external Bandage engine.",
|
|
2202
2208
|
run: () => void 0,
|
|
2203
2209
|
cutMargins: false,
|
|
2210
|
+
wholeWalks: false,
|
|
2204
2211
|
available: () => true,
|
|
2205
2212
|
drawsLocally: () => false
|
|
2206
2213
|
}
|
|
@@ -2848,11 +2855,10 @@ var EDGE_DEFAULT_COLOR = packAbgr2(119, 119, 119, 217);
|
|
|
2848
2855
|
var EDGE_PATH_FALLBACK_COLOR = packAbgr2(136, 136, 136, 217);
|
|
2849
2856
|
var EDGE_DELETION_COLOR = packAbgr2(24, 24, 28, 240);
|
|
2850
2857
|
var DELETION_THICKNESS_FACTOR = 2.2;
|
|
2851
|
-
var EDGE_WALK_COLOR = packAbgr2(30, 30, 36, 245);
|
|
2852
|
-
var WALK_EDGE_THICKNESS_FACTOR = 1.8;
|
|
2853
2858
|
var FADED_ALPHA = 0.18;
|
|
2854
2859
|
var DELETION_DASH_PX = 11;
|
|
2855
2860
|
var MIN_PATH_STRIPE_PX = 1.2;
|
|
2861
|
+
var MIN_WALK_LANE_PX = 3;
|
|
2856
2862
|
var MIN_SCALE_FOR_OFFSET = 1e-6;
|
|
2857
2863
|
var ARROW_LENGTH_BASE_PX = 7;
|
|
2858
2864
|
var ARROW_LENGTH_PER_EDGE_PX = 3;
|
|
@@ -3341,10 +3347,10 @@ function buildGeometry(options) {
|
|
|
3341
3347
|
const bypassed = deletions?.get(ei);
|
|
3342
3348
|
const isDeletion = bypassed !== void 0;
|
|
3343
3349
|
const onWalk = highlight?.edgeIndexes.has(ei) ?? false;
|
|
3344
|
-
const edgeThickness = connectorThickness / 2 * (isDeletion ? DELETION_THICKNESS_FACTOR : 1)
|
|
3350
|
+
const edgeThickness = connectorThickness / 2 * (isDeletion ? DELETION_THICKNESS_FACTOR : 1);
|
|
3345
3351
|
const ribbons = drawPaths && numPaths > 0;
|
|
3346
3352
|
const plainEdgeColor = isDeletion ? EDGE_DELETION_COLOR : EDGE_DEFAULT_COLOR;
|
|
3347
|
-
const edgeColor = !highlight
|
|
3353
|
+
const edgeColor = !highlight || onWalk ? plainEdgeColor : fadeAbgr(plainEdgeColor, FADED_ALPHA);
|
|
3348
3354
|
const toNode = nodeById.get(edge.to);
|
|
3349
3355
|
const intoHalfWidth = (toNode ? nodeWidthPx(toNode, contigThickness, nodeWidth2, depthNorm) : contigThickness) / 2;
|
|
3350
3356
|
const buildSingleEdge = (offsetX, offsetY, color, arrowColor) => {
|
|
@@ -3375,7 +3381,33 @@ function buildGeometry(options) {
|
|
|
3375
3381
|
};
|
|
3376
3382
|
const edgeCurveStart = edgeCurves.length;
|
|
3377
3383
|
const arrowStart = arrows.length;
|
|
3378
|
-
|
|
3384
|
+
const laneWalks = highlight && onWalk && !ribbons ? highlight.walks : void 0;
|
|
3385
|
+
if (laneWalks) {
|
|
3386
|
+
const fromNode = nodeById.get(edge.from);
|
|
3387
|
+
const width = fromNode ? nodeWidthPx(fromNode, contigThickness, nodeWidth2, depthNorm) : contigThickness;
|
|
3388
|
+
const laneWidth = Math.max(width / laneWalks.length, MIN_WALK_LANE_PX);
|
|
3389
|
+
const normals = pointNormalsOf(fromSegments, yToX);
|
|
3390
|
+
const { nx, ny } = (edge.fromStrand === "-" ? normals[0] : normals.at(-1)) ?? {
|
|
3391
|
+
nx: 0,
|
|
3392
|
+
ny: 0
|
|
3393
|
+
};
|
|
3394
|
+
const worldPerScreenPx = 1 / Math.max(scale, MIN_SCALE_FOR_OFFSET);
|
|
3395
|
+
laneWalks.forEach((walk, lane) => {
|
|
3396
|
+
if (!walk.edgeIndexes.has(ei)) {
|
|
3397
|
+
return;
|
|
3398
|
+
}
|
|
3399
|
+
const offset = (lane - (laneWalks.length - 1) / 2) * laneWidth * worldPerScreenPx;
|
|
3400
|
+
const curves = offset === 0 ? baseCurves : translateCurves(baseCurves, nx * offset, ny * offset / yToX);
|
|
3401
|
+
if (viewportBounds && !isBezierInBounds(curves, viewportBounds)) {
|
|
3402
|
+
return;
|
|
3403
|
+
}
|
|
3404
|
+
edgeCurves.push({
|
|
3405
|
+
curves,
|
|
3406
|
+
thickness: laneWidth / 2,
|
|
3407
|
+
color: walk.colors.get(edge.from) ?? walk.colors.get(edge.to) ?? plainEdgeColor
|
|
3408
|
+
});
|
|
3409
|
+
});
|
|
3410
|
+
} else if (!ribbons) {
|
|
3379
3411
|
buildSingleEdge(0, 0, edgeColor, edgeColor);
|
|
3380
3412
|
} else {
|
|
3381
3413
|
const offsets = pathRibbonOffsets(
|
|
@@ -3391,7 +3423,7 @@ function buildGeometry(options) {
|
|
|
3391
3423
|
buildSingleEdge(
|
|
3392
3424
|
offset.x,
|
|
3393
3425
|
offset.y,
|
|
3394
|
-
highlight && edge.pathIds[pathIdx]
|
|
3426
|
+
highlight && !highlight.names.has(edge.pathIds[pathIdx]) ? fadeAbgr(ribbonColor, FADED_ALPHA) : ribbonColor,
|
|
3395
3427
|
pathIdx === arrowRibbon ? edgeColor : void 0
|
|
3396
3428
|
);
|
|
3397
3429
|
}
|
|
@@ -3427,7 +3459,24 @@ function buildGeometry(options) {
|
|
|
3427
3459
|
const slots = nodePathSlots.get(nodeId);
|
|
3428
3460
|
const slotWidth = width / pathCount;
|
|
3429
3461
|
const drawable = segments.length >= 2;
|
|
3430
|
-
|
|
3462
|
+
const lanes = highlight && !faded && !slots?.length ? highlight.walks : void 0;
|
|
3463
|
+
if (drawable && lanes) {
|
|
3464
|
+
const laneWidth = Math.max(width / lanes.length, MIN_WALK_LANE_PX);
|
|
3465
|
+
const normals = pointNormalsOf(segments, yToX);
|
|
3466
|
+
const worldPerScreenPx = 1 / Math.max(scale, MIN_SCALE_FOR_OFFSET);
|
|
3467
|
+
lanes.forEach((walk, lane) => {
|
|
3468
|
+
const laneColor = walk.colors.get(nodeId);
|
|
3469
|
+
if (laneColor === void 0) {
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
const offset = (lane - (lanes.length - 1) / 2) * laneWidth * worldPerScreenPx;
|
|
3473
|
+
nodeStrokes.push({
|
|
3474
|
+
points: lanes.length === 1 ? segments : offsetPolyline(segments, normals, offset, yToX),
|
|
3475
|
+
thickness: laneWidth / 2,
|
|
3476
|
+
color: laneColor
|
|
3477
|
+
});
|
|
3478
|
+
});
|
|
3479
|
+
} else if (drawable && slots?.length && slotWidth >= MIN_PATH_STRIPE_PX) {
|
|
3431
3480
|
const normals = pointNormalsOf(segments, yToX);
|
|
3432
3481
|
const worldPerScreenPx = 1 / Math.max(scale, MIN_SCALE_FOR_OFFSET);
|
|
3433
3482
|
for (const slot of slots) {
|
|
@@ -5191,7 +5240,99 @@ function drawTubeMapConnectors(ctx, connectors, bottom, {
|
|
|
5191
5240
|
}
|
|
5192
5241
|
}
|
|
5193
5242
|
|
|
5243
|
+
// src/walkEncoding.ts
|
|
5244
|
+
import { packAbgr as packAbgr3 } from "@jbrowse/core/util/colorBits";
|
|
5245
|
+
var WALK_FIELDS = [
|
|
5246
|
+
{
|
|
5247
|
+
value: "progress",
|
|
5248
|
+
label: "Progress along the walk",
|
|
5249
|
+
legend: "pale where the walk starts, deep where it ends"
|
|
5250
|
+
},
|
|
5251
|
+
{
|
|
5252
|
+
value: "reference",
|
|
5253
|
+
label: "Reference position",
|
|
5254
|
+
legend: "along the reference left to right, charcoal off it"
|
|
5255
|
+
},
|
|
5256
|
+
{
|
|
5257
|
+
value: "strand",
|
|
5258
|
+
label: "Strand against the reference",
|
|
5259
|
+
legend: "pale where the walk runs as the reference does, deep where reversed"
|
|
5260
|
+
},
|
|
5261
|
+
{
|
|
5262
|
+
value: "visits",
|
|
5263
|
+
label: "Visits",
|
|
5264
|
+
legend: "pale where the walk passes once, deep four times or more"
|
|
5265
|
+
}
|
|
5266
|
+
];
|
|
5267
|
+
var WALK_SCHEMES = [
|
|
5268
|
+
{ value: "rainbow", label: "Rainbow" },
|
|
5269
|
+
{ value: "blues", label: "Blues", hue: 215 },
|
|
5270
|
+
{ value: "reds", label: "Reds", hue: 0 },
|
|
5271
|
+
{ value: "greens", label: "Greens", hue: 130 },
|
|
5272
|
+
{ value: "oranges", label: "Oranges", hue: 30 },
|
|
5273
|
+
{ value: "purples", label: "Purples", hue: 280 },
|
|
5274
|
+
{ value: "greys", label: "Greys" }
|
|
5275
|
+
];
|
|
5276
|
+
var DEFAULT_FAMILIES = [
|
|
5277
|
+
"blues",
|
|
5278
|
+
"reds",
|
|
5279
|
+
"greens",
|
|
5280
|
+
"oranges",
|
|
5281
|
+
"purples"
|
|
5282
|
+
];
|
|
5283
|
+
function resolveEncoding(layer, reference, picked) {
|
|
5284
|
+
return {
|
|
5285
|
+
field: layer.color?.field ?? (reference ? "reference" : "progress"),
|
|
5286
|
+
scheme: layer.color?.scheme ?? (reference ? "rainbow" : DEFAULT_FAMILIES[picked % DEFAULT_FAMILIES.length])
|
|
5287
|
+
};
|
|
5288
|
+
}
|
|
5289
|
+
var PALE = 0.82;
|
|
5290
|
+
var DEEP = 0.28;
|
|
5291
|
+
function schemeHsl(scheme, t) {
|
|
5292
|
+
const x = Math.max(0, Math.min(1, t));
|
|
5293
|
+
if (scheme === "rainbow") {
|
|
5294
|
+
return { h: x * REFERENCE_RAMP_MAX_HUE, s: 0.7, l: 0.5 };
|
|
5295
|
+
}
|
|
5296
|
+
const family = WALK_SCHEMES.find((s) => s.value === scheme);
|
|
5297
|
+
const l = PALE + (DEEP - PALE) * x;
|
|
5298
|
+
return family && "hue" in family ? { h: family.hue, s: 0.75, l } : { h: 0, s: 0, l };
|
|
5299
|
+
}
|
|
5300
|
+
function schemeCss(scheme, t) {
|
|
5301
|
+
const { h, s, l } = schemeHsl(scheme, t);
|
|
5302
|
+
return `hsl(${h}, ${s * 100}%, ${l * 100}%)`;
|
|
5303
|
+
}
|
|
5304
|
+
function schemeColor(scheme, t) {
|
|
5305
|
+
const { h, s, l } = schemeHsl(scheme, t);
|
|
5306
|
+
const [r, g, b] = hslToRgb(h, s, l);
|
|
5307
|
+
return packAbgr3(
|
|
5308
|
+
Math.round(r * 255),
|
|
5309
|
+
Math.round(g * 255),
|
|
5310
|
+
Math.round(b * 255),
|
|
5311
|
+
255
|
|
5312
|
+
);
|
|
5313
|
+
}
|
|
5314
|
+
var NO_VALUE_COLOR = REFERENCE_RAMP_ALT_COLOR;
|
|
5315
|
+
var STRAND_T = { same: 0.2, reversed: 0.95 };
|
|
5316
|
+
function encodingSwatchCss({ field, scheme }) {
|
|
5317
|
+
if (field === "strand") {
|
|
5318
|
+
const same = schemeCss(scheme, STRAND_T.same);
|
|
5319
|
+
const reversed = schemeCss(scheme, STRAND_T.reversed);
|
|
5320
|
+
return `linear-gradient(to right, ${same} 50%, ${reversed} 50%)`;
|
|
5321
|
+
}
|
|
5322
|
+
const stops = Array.from({ length: 7 }, (_, i) => {
|
|
5323
|
+
const t = i / 6;
|
|
5324
|
+
return `${schemeCss(scheme, t)} ${t * 100}%`;
|
|
5325
|
+
});
|
|
5326
|
+
return `linear-gradient(to right, ${stops.join(", ")})`;
|
|
5327
|
+
}
|
|
5328
|
+
function fieldLegend(field) {
|
|
5329
|
+
return WALK_FIELDS.find((f) => f.value === field).legend;
|
|
5330
|
+
}
|
|
5331
|
+
|
|
5194
5332
|
// src/walkHighlight.ts
|
|
5333
|
+
function referenceOf(graph) {
|
|
5334
|
+
return graph.referencePath ? graph.paths?.find((p) => pathOrigin(p.name).name === graph.referencePath) : void 0;
|
|
5335
|
+
}
|
|
5195
5336
|
function walkHighlight(graph, name) {
|
|
5196
5337
|
const path = graph.paths?.find((p) => p.name === name);
|
|
5197
5338
|
if (!path) {
|
|
@@ -5202,7 +5343,6 @@ function walkHighlight(graph, name) {
|
|
|
5202
5343
|
graph.edges.forEach((e, i) => {
|
|
5203
5344
|
edgeAt.set(`${e.from}>${e.to}`, i);
|
|
5204
5345
|
});
|
|
5205
|
-
const nodeIds = new Set(path.nodeIds);
|
|
5206
5346
|
const edgeIndexes = /* @__PURE__ */ new Set();
|
|
5207
5347
|
for (let i = 1; i < path.nodeIds.length; i++) {
|
|
5208
5348
|
const a = path.nodeIds[i - 1];
|
|
@@ -5212,15 +5352,87 @@ function walkHighlight(graph, name) {
|
|
|
5212
5352
|
edgeIndexes.add(index);
|
|
5213
5353
|
}
|
|
5214
5354
|
}
|
|
5215
|
-
const
|
|
5216
|
-
const
|
|
5355
|
+
const lengthOf = (id) => byId.get(id)?.length ?? 0;
|
|
5356
|
+
const bp = path.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0);
|
|
5357
|
+
const progress = /* @__PURE__ */ new Map();
|
|
5358
|
+
let before = 0;
|
|
5359
|
+
for (const id of path.nodeIds) {
|
|
5360
|
+
const length = lengthOf(id);
|
|
5361
|
+
if (!progress.has(id)) {
|
|
5362
|
+
progress.set(id, bp > 0 ? (before + length / 2) / bp : 0);
|
|
5363
|
+
}
|
|
5364
|
+
before += length;
|
|
5365
|
+
}
|
|
5366
|
+
const reference = referenceOf(graph);
|
|
5217
5367
|
return {
|
|
5218
5368
|
name,
|
|
5219
|
-
|
|
5369
|
+
reference: reference === path,
|
|
5370
|
+
nodeIds: new Set(path.nodeIds),
|
|
5220
5371
|
edgeIndexes,
|
|
5372
|
+
progress,
|
|
5221
5373
|
steps: path.nodeIds.length,
|
|
5222
|
-
bp
|
|
5223
|
-
referenceBp: reference && reference !== path ?
|
|
5374
|
+
bp,
|
|
5375
|
+
referenceBp: reference && reference !== path ? reference.nodeIds.reduce((sum, id) => sum + lengthOf(id), 0) : void 0
|
|
5376
|
+
};
|
|
5377
|
+
}
|
|
5378
|
+
function laneColors(graph, walk, { field, scheme }, ramp) {
|
|
5379
|
+
const colors = /* @__PURE__ */ new Map();
|
|
5380
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
5381
|
+
const walkPath = pathOrigin(walk.name).name;
|
|
5382
|
+
const reference = referenceOf(graph);
|
|
5383
|
+
const referencePath = reference ? pathOrigin(reference.name).name : void 0;
|
|
5384
|
+
const path = graph.paths.find((p) => p.name === walk.name);
|
|
5385
|
+
const visits = /* @__PURE__ */ new Map();
|
|
5386
|
+
for (const id of path.nodeIds) {
|
|
5387
|
+
visits.set(id, (visits.get(id) ?? 0) + 1);
|
|
5388
|
+
}
|
|
5389
|
+
const strandOf = (segment, of) => graph.pathVisits?.get(segment)?.find((v) => v.path === of)?.strand;
|
|
5390
|
+
for (const [id, progress] of walk.progress) {
|
|
5391
|
+
const node = byId.get(id);
|
|
5392
|
+
let t;
|
|
5393
|
+
if (field === "progress") {
|
|
5394
|
+
t = progress;
|
|
5395
|
+
} else if (field === "visits") {
|
|
5396
|
+
t = (Math.min(visits.get(id) ?? 1, 4) - 1) / 3;
|
|
5397
|
+
} else if (field === "reference") {
|
|
5398
|
+
const mid = ramp?.midpoints.get(id);
|
|
5399
|
+
t = ramp && mid !== void 0 && !(node?.stable && node.stable.rank > 0) ? (mid - ramp.start) / ramp.span : void 0;
|
|
5400
|
+
} else if (node) {
|
|
5401
|
+
const own = strandOf(node.name, walkPath);
|
|
5402
|
+
const theirs = strandOf(node.name, referencePath);
|
|
5403
|
+
t = own && theirs ? own === theirs ? STRAND_T.same : STRAND_T.reversed : void 0;
|
|
5404
|
+
}
|
|
5405
|
+
colors.set(id, t === void 0 ? NO_VALUE_COLOR : schemeColor(scheme, t));
|
|
5406
|
+
}
|
|
5407
|
+
return colors;
|
|
5408
|
+
}
|
|
5409
|
+
function walkLift(graph, layers, ramp) {
|
|
5410
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5411
|
+
const lifted = layers.filter((layer) => !seen.has(layer.walk) && seen.add(layer.walk)).flatMap((layer) => {
|
|
5412
|
+
const walk = walkHighlight(graph, layer.walk);
|
|
5413
|
+
return walk ? [{ walk, layer }] : [];
|
|
5414
|
+
}).sort((a, b) => Number(b.walk.reference) - Number(a.walk.reference));
|
|
5415
|
+
if (lifted.length === 0) {
|
|
5416
|
+
return void 0;
|
|
5417
|
+
}
|
|
5418
|
+
let picked = 0;
|
|
5419
|
+
const walks = lifted.map(({ walk, layer }) => {
|
|
5420
|
+
const encoding = resolveEncoding(
|
|
5421
|
+
layer,
|
|
5422
|
+
walk.reference,
|
|
5423
|
+
walk.reference ? 0 : picked++
|
|
5424
|
+
);
|
|
5425
|
+
return {
|
|
5426
|
+
...walk,
|
|
5427
|
+
encoding,
|
|
5428
|
+
colors: laneColors(graph, walk, encoding, ramp)
|
|
5429
|
+
};
|
|
5430
|
+
});
|
|
5431
|
+
return {
|
|
5432
|
+
walks,
|
|
5433
|
+
nodeIds: new Set(walks.flatMap((w) => [...w.nodeIds])),
|
|
5434
|
+
edgeIndexes: new Set(walks.flatMap((w) => [...w.edgeIndexes])),
|
|
5435
|
+
names: new Set(walks.map((w) => w.name))
|
|
5224
5436
|
};
|
|
5225
5437
|
}
|
|
5226
5438
|
|
|
@@ -6053,6 +6265,8 @@ export {
|
|
|
6053
6265
|
REFERENCE_RAMP_MAX_HUE,
|
|
6054
6266
|
REFERENCE_STRIP_ZONE_PX,
|
|
6055
6267
|
ROW_HEIGHT_PX,
|
|
6268
|
+
WALK_FIELDS,
|
|
6269
|
+
WALK_SCHEMES,
|
|
6056
6270
|
WELL_KNOWN_SAMPLES,
|
|
6057
6271
|
assemblyWalk,
|
|
6058
6272
|
axisScaleOf,
|
|
@@ -6075,9 +6289,11 @@ export {
|
|
|
6075
6289
|
drawTubeMapGenes,
|
|
6076
6290
|
drawTubeMapRuler,
|
|
6077
6291
|
drawingBounds,
|
|
6292
|
+
encodingSwatchCss,
|
|
6078
6293
|
engineKey,
|
|
6079
6294
|
engineRequest,
|
|
6080
6295
|
featuresOnBackbone,
|
|
6296
|
+
fieldLegend,
|
|
6081
6297
|
findHoveredEdge,
|
|
6082
6298
|
findHoveredNode,
|
|
6083
6299
|
fitTransform,
|
|
@@ -6111,8 +6327,10 @@ export {
|
|
|
6111
6327
|
referenceSamplesOf,
|
|
6112
6328
|
referenceStripBlocks,
|
|
6113
6329
|
resolveColorScheme,
|
|
6330
|
+
resolveEncoding,
|
|
6114
6331
|
resolveReferenceSample,
|
|
6115
6332
|
rulerBoxes,
|
|
6333
|
+
schemeCss,
|
|
6116
6334
|
screenToLayout,
|
|
6117
6335
|
stripBlockAt,
|
|
6118
6336
|
tubeMapConnectors,
|
|
@@ -6123,6 +6341,7 @@ export {
|
|
|
6123
6341
|
tubeX,
|
|
6124
6342
|
viewportOf,
|
|
6125
6343
|
walkHighlight,
|
|
6344
|
+
walkLift,
|
|
6126
6345
|
walkRows,
|
|
6127
6346
|
walkRowsExtent,
|
|
6128
6347
|
warpX,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -32,7 +32,10 @@ export type { Connector, ReferenceNode } from './tubeMap/connectors.js';
|
|
|
32
32
|
export type { TubeMapColumn, TubeMapDrawing } from './layout/tubeMapLayout.js';
|
|
33
33
|
export { deletionEdges } from './deletionEdges.js';
|
|
34
34
|
export type { DeletionEdge } from './deletionEdges.js';
|
|
35
|
-
export { walkHighlight } from './walkHighlight.js';
|
|
35
|
+
export { walkHighlight, walkLift } from './walkHighlight.js';
|
|
36
|
+
export type { LiftedWalk, WalkLift } from './walkHighlight.js';
|
|
37
|
+
export { WALK_FIELDS, WALK_SCHEMES, encodingSwatchCss, fieldLegend, resolveEncoding, schemeCss, } from './walkEncoding.js';
|
|
38
|
+
export type { WalkEncoding, WalkField, WalkLayer, WalkScheme, } from './walkEncoding.js';
|
|
36
39
|
export { pathColorsLegible, pathLegend } from './pathColors.js';
|
|
37
40
|
export { bubblesFromGraph } from './bubbles/bubblesFromGraph.js';
|
|
38
41
|
export { bubbleHalos } from './bubbles/bubbleHalos.js';
|
|
@@ -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
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ResolvedColorScheme } from '../colorSchemes.js';
|
|
2
2
|
import type { NodeWidth } from '../nodeWidths.js';
|
|
3
3
|
import type { Graph, GraphNode, NodeSegment } from '../types.js';
|
|
4
|
-
import type {
|
|
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
7
|
export declare const FADED_ALPHA = 0.18;
|
|
@@ -14,7 +14,7 @@ export interface BuildOptions {
|
|
|
14
14
|
connectorThickness: number;
|
|
15
15
|
drawPaths: boolean;
|
|
16
16
|
nodeWidth?: NodeWidth;
|
|
17
|
-
highlight?:
|
|
17
|
+
highlight?: WalkLift;
|
|
18
18
|
axis: AxisScale;
|
|
19
19
|
linearLayout?: boolean;
|
|
20
20
|
viewportBounds?: {
|
|
@@ -30,6 +30,7 @@ export interface BuildOptions {
|
|
|
30
30
|
}
|
|
31
31
|
export declare function hslToRgb(h: number, s: number, l: number): [number, number, number];
|
|
32
32
|
export declare const REFERENCE_RAMP_MAX_HUE = 300;
|
|
33
|
+
export declare const REFERENCE_RAMP_ALT_COLOR: number;
|
|
33
34
|
export declare const REFERENCE_RAMP_ALT_CSS: string;
|
|
34
35
|
export interface ReferenceRamp {
|
|
35
36
|
start: number;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export declare const WALK_FIELDS: readonly [{
|
|
2
|
+
readonly value: "progress";
|
|
3
|
+
readonly label: "Progress along the walk";
|
|
4
|
+
readonly legend: "pale where the walk starts, deep where it ends";
|
|
5
|
+
}, {
|
|
6
|
+
readonly value: "reference";
|
|
7
|
+
readonly label: "Reference position";
|
|
8
|
+
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
|
+
}];
|
|
18
|
+
export type WalkField = (typeof WALK_FIELDS)[number]['value'];
|
|
19
|
+
export declare const WALK_SCHEMES: readonly [{
|
|
20
|
+
readonly value: "rainbow";
|
|
21
|
+
readonly label: "Rainbow";
|
|
22
|
+
}, {
|
|
23
|
+
readonly value: "blues";
|
|
24
|
+
readonly label: "Blues";
|
|
25
|
+
readonly hue: 215;
|
|
26
|
+
}, {
|
|
27
|
+
readonly value: "reds";
|
|
28
|
+
readonly label: "Reds";
|
|
29
|
+
readonly hue: 0;
|
|
30
|
+
}, {
|
|
31
|
+
readonly value: "greens";
|
|
32
|
+
readonly label: "Greens";
|
|
33
|
+
readonly hue: 130;
|
|
34
|
+
}, {
|
|
35
|
+
readonly value: "oranges";
|
|
36
|
+
readonly label: "Oranges";
|
|
37
|
+
readonly hue: 30;
|
|
38
|
+
}, {
|
|
39
|
+
readonly value: "purples";
|
|
40
|
+
readonly label: "Purples";
|
|
41
|
+
readonly hue: 280;
|
|
42
|
+
}, {
|
|
43
|
+
readonly value: "greys";
|
|
44
|
+
readonly label: "Greys";
|
|
45
|
+
}];
|
|
46
|
+
export type WalkScheme = (typeof WALK_SCHEMES)[number]['value'];
|
|
47
|
+
export interface WalkEncoding {
|
|
48
|
+
field: WalkField;
|
|
49
|
+
scheme: WalkScheme;
|
|
50
|
+
}
|
|
51
|
+
export interface WalkLayer {
|
|
52
|
+
walk: string;
|
|
53
|
+
color?: Partial<WalkEncoding>;
|
|
54
|
+
}
|
|
55
|
+
export declare function resolveEncoding(layer: WalkLayer, reference: boolean, picked: number): WalkEncoding;
|
|
56
|
+
export declare function schemeHsl(scheme: WalkScheme, t: number): {
|
|
57
|
+
h: number;
|
|
58
|
+
s: number;
|
|
59
|
+
l: number;
|
|
60
|
+
};
|
|
61
|
+
export declare function schemeCss(scheme: WalkScheme, t: number): string;
|
|
62
|
+
export declare function schemeColor(scheme: WalkScheme, t: number): number;
|
|
63
|
+
export declare const NO_VALUE_COLOR: number;
|
|
64
|
+
export declare const NO_VALUE_CSS: string;
|
|
65
|
+
export declare const STRAND_T: {
|
|
66
|
+
same: number;
|
|
67
|
+
reversed: number;
|
|
68
|
+
};
|
|
69
|
+
export declare function encodingSwatchCss({ field, scheme }: WalkEncoding): string;
|
|
70
|
+
export declare function fieldLegend(field: WalkField): "pale where the walk starts, deep where it ends" | "along the reference left to right, charcoal off it" | "pale where the walk runs as the reference does, deep where reversed" | "pale where the walk passes once, deep four times or more";
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
import type { ReferenceRamp } from './renderer/GeometryBuilder.js';
|
|
1
2
|
import type { Graph } from './types.js';
|
|
3
|
+
import type { WalkEncoding, WalkLayer } from './walkEncoding.js';
|
|
2
4
|
export interface WalkHighlight {
|
|
3
5
|
name: string;
|
|
6
|
+
reference: boolean;
|
|
4
7
|
nodeIds: Set<string>;
|
|
5
8
|
edgeIndexes: Set<number>;
|
|
9
|
+
progress: Map<string, number>;
|
|
6
10
|
steps: number;
|
|
7
11
|
bp: number;
|
|
8
12
|
referenceBp?: number;
|
|
9
13
|
}
|
|
14
|
+
export interface LiftedWalk extends WalkHighlight {
|
|
15
|
+
encoding: WalkEncoding;
|
|
16
|
+
colors: Map<string, number>;
|
|
17
|
+
}
|
|
18
|
+
export interface WalkLift {
|
|
19
|
+
walks: LiftedWalk[];
|
|
20
|
+
nodeIds: Set<string>;
|
|
21
|
+
edgeIndexes: Set<number>;
|
|
22
|
+
names: Set<string>;
|
|
23
|
+
}
|
|
10
24
|
export declare function walkHighlight(graph: Graph, name: string): WalkHighlight | undefined;
|
|
25
|
+
export declare function walkLift(graph: Graph, layers: readonly WalkLayer[], ramp?: ReferenceRamp): WalkLift | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/bandage-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
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": {
|