@jbrowse/bandage-core 5.0.1 → 5.2.0
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-RS23442A.js → chunk-ZMVFSZI5.js} +800 -230
- package/dist/cli/figure.js +4 -2
- package/dist/index.js +11 -361
- package/dist/types/cli/figure.d.ts +2 -0
- package/dist/types/colorSchemes.d.ts +1 -1
- package/dist/types/deletionEdges.d.ts +3 -1
- package/dist/types/figure.d.ts +1 -0
- package/dist/types/gbzWindow.d.ts +2 -0
- package/dist/types/genes/exonOutline.d.ts +18 -0
- package/dist/types/genes/genePins.d.ts +1 -0
- package/dist/types/graphLabels.d.ts +2 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/labelLayout.d.ts +4 -2
- package/dist/types/overlayLabels.d.ts +1 -0
- package/dist/types/pipeline.d.ts +3 -0
- package/dist/types/reference.d.ts +3 -0
- package/dist/types/renderer/GeometryBuilder.d.ts +1 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types/util/SpatialIndex.d.ts +1 -1
- package/dist/types/util/edgeCurves.d.ts +1 -1
- package/dist/types/util/geometry.d.ts +10 -2
- package/dist/types/util/hitDetection.d.ts +8 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/figure.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
placeRowGenes,
|
|
22
22
|
refNameBinding,
|
|
23
23
|
walkRows
|
|
24
|
-
} from "../chunks/chunk-
|
|
24
|
+
} from "../chunks/chunk-ZMVFSZI5.js";
|
|
25
25
|
|
|
26
26
|
// src/cli/figure.ts
|
|
27
27
|
import { access, open, readFile, writeFile } from "node:fs/promises";
|
|
@@ -171,7 +171,9 @@ async function renderSpec(spec, base) {
|
|
|
171
171
|
{
|
|
172
172
|
quality: spec.quality ?? 2,
|
|
173
173
|
linearLayout: false,
|
|
174
|
-
bubbleSpread: spec.bubbleSpread ?? "auto"
|
|
174
|
+
bubbleSpread: spec.bubbleSpread ?? "auto",
|
|
175
|
+
spacing: spec.spacing,
|
|
176
|
+
componentSeparation: spec.componentSeparation
|
|
175
177
|
},
|
|
176
178
|
engine
|
|
177
179
|
)).result;
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
COLOR_SCHEMES,
|
|
5
5
|
Canvas2DRenderer,
|
|
6
6
|
DISAGREES,
|
|
7
|
+
EXON_COLOR,
|
|
7
8
|
FACET_GAP_PX,
|
|
8
9
|
FACET_PAD_PX,
|
|
9
10
|
FACET_TITLE_PX,
|
|
@@ -35,14 +36,12 @@ import {
|
|
|
35
36
|
assemblyWalk,
|
|
36
37
|
axisScaleOf,
|
|
37
38
|
backboneAssembly,
|
|
38
|
-
baseEdgeCurves,
|
|
39
39
|
buildGeometry,
|
|
40
40
|
clampZoom,
|
|
41
41
|
coalesceRuns,
|
|
42
42
|
computeColorSchemeRange,
|
|
43
43
|
computeReferenceRamp,
|
|
44
44
|
contains,
|
|
45
|
-
curveBounds,
|
|
46
45
|
cutGbzRegion,
|
|
47
46
|
cutWindowGFA,
|
|
48
47
|
deletionEdges,
|
|
@@ -52,6 +51,8 @@ import {
|
|
|
52
51
|
encodingSwatchCss,
|
|
53
52
|
engineKey,
|
|
54
53
|
engineRequest,
|
|
54
|
+
exonOutlineTree,
|
|
55
|
+
exonStretches,
|
|
55
56
|
facetCells,
|
|
56
57
|
facetGrid,
|
|
57
58
|
facetLifts,
|
|
@@ -59,6 +60,8 @@ import {
|
|
|
59
60
|
featuresOnBackbone,
|
|
60
61
|
figureSvg,
|
|
61
62
|
filterSamples,
|
|
63
|
+
findHoveredEdge,
|
|
64
|
+
findHoveredNode,
|
|
62
65
|
fitTransform,
|
|
63
66
|
forceLayout,
|
|
64
67
|
formatBp,
|
|
@@ -91,7 +94,6 @@ import {
|
|
|
91
94
|
parseRegion,
|
|
92
95
|
pathColorsLegible,
|
|
93
96
|
pathLegend,
|
|
94
|
-
pathRibbonOffsets,
|
|
95
97
|
placeRowGenes,
|
|
96
98
|
rampHue,
|
|
97
99
|
rampHueCss,
|
|
@@ -99,6 +101,7 @@ import {
|
|
|
99
101
|
rangeText,
|
|
100
102
|
readoutPlacement,
|
|
101
103
|
refNameBinding,
|
|
104
|
+
referenceLabel,
|
|
102
105
|
referenceOrder,
|
|
103
106
|
referencePathQuery,
|
|
104
107
|
referenceSamplesOf,
|
|
@@ -117,7 +120,6 @@ import {
|
|
|
117
120
|
stripRowAt,
|
|
118
121
|
svgCanvas,
|
|
119
122
|
svgPath,
|
|
120
|
-
translateCurves,
|
|
121
123
|
trimOrigins,
|
|
122
124
|
unitTicks,
|
|
123
125
|
version,
|
|
@@ -136,368 +138,12 @@ import {
|
|
|
136
138
|
walkStripFrame,
|
|
137
139
|
walkStripLabelsTree,
|
|
138
140
|
wellKnownSample,
|
|
139
|
-
yToXOf,
|
|
140
141
|
zoomAbout
|
|
141
|
-
} from "./chunks/chunk-
|
|
142
|
+
} from "./chunks/chunk-ZMVFSZI5.js";
|
|
142
143
|
|
|
143
144
|
// src/index.ts
|
|
144
145
|
import { getDpr } from "@jbrowse/render-core/canvas2dUtils";
|
|
145
146
|
|
|
146
|
-
// src/util/SpatialIndex.ts
|
|
147
|
-
var FALLBACK_CELL_SIZE = 50;
|
|
148
|
-
function meanExtentCellSize(extentTotal, count) {
|
|
149
|
-
return count > 0 ? Math.max(1, extentTotal / count) : FALLBACK_CELL_SIZE;
|
|
150
|
-
}
|
|
151
|
-
function rowPitchOf(boxes) {
|
|
152
|
-
const distinct = /* @__PURE__ */ new Set();
|
|
153
|
-
let min = Infinity;
|
|
154
|
-
let max = -Infinity;
|
|
155
|
-
for (const box of boxes) {
|
|
156
|
-
distinct.add(box.minY);
|
|
157
|
-
min = Math.min(min, box.minY);
|
|
158
|
-
max = Math.max(max, box.minY);
|
|
159
|
-
}
|
|
160
|
-
return distinct.size > 1 ? (max - min) / (distinct.size - 1) : void 0;
|
|
161
|
-
}
|
|
162
|
-
function cellSizeFrom(boxes, extentX, extentY) {
|
|
163
|
-
const x = meanExtentCellSize(extentX, boxes.length);
|
|
164
|
-
return {
|
|
165
|
-
x,
|
|
166
|
-
y: extentY > 0 ? meanExtentCellSize(extentY, boxes.length) : rowPitchOf(boxes) ?? x
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
function resolveCellSize(given, boxes, extentX, extentY) {
|
|
170
|
-
return given === void 0 ? cellSizeFrom(boxes, extentX, extentY) : typeof given === "number" ? { x: given, y: given } : given;
|
|
171
|
-
}
|
|
172
|
-
function getOrCreateCell(cells, cx, cy) {
|
|
173
|
-
let row = cells.get(cx);
|
|
174
|
-
if (!row) {
|
|
175
|
-
row = /* @__PURE__ */ new Map();
|
|
176
|
-
cells.set(cx, row);
|
|
177
|
-
}
|
|
178
|
-
let cell = row.get(cy);
|
|
179
|
-
if (!cell) {
|
|
180
|
-
cell = [];
|
|
181
|
-
row.set(cy, cell);
|
|
182
|
-
}
|
|
183
|
-
return cell;
|
|
184
|
-
}
|
|
185
|
-
function addToGrid(cells, cellSize, minX, minY, maxX, maxY, entry) {
|
|
186
|
-
const cx0 = Math.floor(minX / cellSize.x);
|
|
187
|
-
const cx1 = Math.floor(maxX / cellSize.x);
|
|
188
|
-
const cy0 = Math.floor(minY / cellSize.y);
|
|
189
|
-
const cy1 = Math.floor(maxY / cellSize.y);
|
|
190
|
-
for (let cx = cx0; cx <= cx1; cx++) {
|
|
191
|
-
for (let cy = cy0; cy <= cy1; cy++) {
|
|
192
|
-
getOrCreateCell(cells, cx, cy).push(entry);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
function queryGrid(cells, cellSize, x, y, radiusX, radiusY) {
|
|
197
|
-
const cx0 = Math.floor((x - radiusX) / cellSize.x);
|
|
198
|
-
const cx1 = Math.floor((x + radiusX) / cellSize.x);
|
|
199
|
-
const cy0 = Math.floor((y - radiusY) / cellSize.y);
|
|
200
|
-
const cy1 = Math.floor((y + radiusY) / cellSize.y);
|
|
201
|
-
const results = [];
|
|
202
|
-
const seen = /* @__PURE__ */ new Set();
|
|
203
|
-
for (let cx = cx0; cx <= cx1; cx++) {
|
|
204
|
-
const row = cells.get(cx);
|
|
205
|
-
if (row) {
|
|
206
|
-
for (let cy = cy0; cy <= cy1; cy++) {
|
|
207
|
-
const cell = row.get(cy);
|
|
208
|
-
if (cell) {
|
|
209
|
-
for (const entry of cell) {
|
|
210
|
-
if (!seen.has(entry)) {
|
|
211
|
-
seen.add(entry);
|
|
212
|
-
results.push(entry);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return results;
|
|
220
|
-
}
|
|
221
|
-
var SpatialIndex = class {
|
|
222
|
-
constructor(nodePositions, cellSize) {
|
|
223
|
-
this.cells = /* @__PURE__ */ new Map();
|
|
224
|
-
const boxes = [];
|
|
225
|
-
let extentX = 0;
|
|
226
|
-
let extentY = 0;
|
|
227
|
-
for (const [nodeId, segments] of Object.entries(nodePositions)) {
|
|
228
|
-
for (let i = 0; i < segments.length - 1; i++) {
|
|
229
|
-
const seg = segments[i];
|
|
230
|
-
const next = segments[i + 1];
|
|
231
|
-
const minX = Math.min(seg.x, next.x);
|
|
232
|
-
const minY = Math.min(seg.y, next.y);
|
|
233
|
-
const maxX = Math.max(seg.x, next.x);
|
|
234
|
-
const maxY = Math.max(seg.y, next.y);
|
|
235
|
-
extentX += maxX - minX;
|
|
236
|
-
extentY += maxY - minY;
|
|
237
|
-
boxes.push({ entry: { nodeId, segmentIdx: i }, minX, minY, maxX, maxY });
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);
|
|
241
|
-
for (const b of boxes) {
|
|
242
|
-
addToGrid(
|
|
243
|
-
this.cells,
|
|
244
|
-
this.cellSize,
|
|
245
|
-
b.minX,
|
|
246
|
-
b.minY,
|
|
247
|
-
b.maxX,
|
|
248
|
-
b.maxY,
|
|
249
|
-
b.entry
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
query(x, y, radiusX, radiusY = radiusX) {
|
|
254
|
-
return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
var EdgeSpatialIndex = class {
|
|
258
|
-
constructor(nodePositions, graph, drawPaths, axis, cellSize, deletions, version2 = 0, routes2) {
|
|
259
|
-
this.cells = /* @__PURE__ */ new Map();
|
|
260
|
-
this.edgeCurves = baseEdgeCurves(
|
|
261
|
-
nodePositions,
|
|
262
|
-
graph,
|
|
263
|
-
axis,
|
|
264
|
-
deletions,
|
|
265
|
-
version2,
|
|
266
|
-
routes2
|
|
267
|
-
);
|
|
268
|
-
const boxes = [];
|
|
269
|
-
let extentX = 0;
|
|
270
|
-
let extentY = 0;
|
|
271
|
-
for (let ei = 0; ei < graph.edges.length; ei++) {
|
|
272
|
-
const edge = graph.edges[ei];
|
|
273
|
-
const fromSegments = nodePositions[edge.from];
|
|
274
|
-
const toSegments = nodePositions[edge.to];
|
|
275
|
-
const curves = this.edgeCurves.get(ei);
|
|
276
|
-
if (fromSegments?.length && toSegments?.length && curves) {
|
|
277
|
-
let { minX, minY, maxX, maxY } = curveBounds(curves);
|
|
278
|
-
const numPaths = edge.pathIds?.length ?? 0;
|
|
279
|
-
if (drawPaths && numPaths > 0) {
|
|
280
|
-
let padX = 0;
|
|
281
|
-
let padY = 0;
|
|
282
|
-
for (const o of pathRibbonOffsets(
|
|
283
|
-
fromSegments,
|
|
284
|
-
toSegments,
|
|
285
|
-
numPaths,
|
|
286
|
-
axis
|
|
287
|
-
)) {
|
|
288
|
-
padX = Math.max(padX, Math.abs(o.x));
|
|
289
|
-
padY = Math.max(padY, Math.abs(o.y));
|
|
290
|
-
}
|
|
291
|
-
minX -= padX;
|
|
292
|
-
minY -= padY;
|
|
293
|
-
maxX += padX;
|
|
294
|
-
maxY += padY;
|
|
295
|
-
}
|
|
296
|
-
extentX += maxX - minX;
|
|
297
|
-
extentY += maxY - minY;
|
|
298
|
-
boxes.push({ ei, minX, minY, maxX, maxY });
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
this.cellSize = resolveCellSize(cellSize, boxes, extentX, extentY);
|
|
302
|
-
for (const b of boxes) {
|
|
303
|
-
addToGrid(this.cells, this.cellSize, b.minX, b.minY, b.maxX, b.maxY, b.ei);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
getCurves(ei) {
|
|
307
|
-
return this.edgeCurves.get(ei);
|
|
308
|
-
}
|
|
309
|
-
query(x, y, radiusX, radiusY = radiusX) {
|
|
310
|
-
return queryGrid(this.cells, this.cellSize, x, y, radiusX, radiusY);
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
// src/util/hitDetection.ts
|
|
315
|
-
function distanceToSegment(px, py, x1, y1, x2, y2) {
|
|
316
|
-
const dx = x2 - x1;
|
|
317
|
-
const dy = y2 - y1;
|
|
318
|
-
const lenSq = dx * dx + dy * dy;
|
|
319
|
-
if (lenSq === 0) {
|
|
320
|
-
return Math.hypot(px - x1, py - y1);
|
|
321
|
-
}
|
|
322
|
-
const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / lenSq));
|
|
323
|
-
return Math.hypot(px - (x1 + t * dx), py - (y1 + t * dy));
|
|
324
|
-
}
|
|
325
|
-
function distanceToCubicBezier(px, py, x1, y1, cx1, cy1, cx2, cy2, x2, y2) {
|
|
326
|
-
let minDist = Infinity;
|
|
327
|
-
const samples = 20;
|
|
328
|
-
let lastX = x1;
|
|
329
|
-
let lastY = y1;
|
|
330
|
-
for (let i = 1; i <= samples; i++) {
|
|
331
|
-
const t = i / samples;
|
|
332
|
-
const u = 1 - t;
|
|
333
|
-
const bx = u * u * u * x1 + 3 * u * u * t * cx1 + 3 * u * t * t * cx2 + t * t * t * x2;
|
|
334
|
-
const by = u * u * u * y1 + 3 * u * u * t * cy1 + 3 * u * t * t * cy2 + t * t * t * y2;
|
|
335
|
-
minDist = Math.min(minDist, distanceToSegment(px, py, lastX, lastY, bx, by));
|
|
336
|
-
lastX = bx;
|
|
337
|
-
lastY = by;
|
|
338
|
-
}
|
|
339
|
-
return minDist;
|
|
340
|
-
}
|
|
341
|
-
function distanceToBezierCurve(px, py, c) {
|
|
342
|
-
return distanceToCubicBezier(
|
|
343
|
-
px,
|
|
344
|
-
py,
|
|
345
|
-
c.x0,
|
|
346
|
-
c.y0,
|
|
347
|
-
c.cx0,
|
|
348
|
-
c.cy0,
|
|
349
|
-
c.cx1,
|
|
350
|
-
c.cy1,
|
|
351
|
-
c.x1,
|
|
352
|
-
c.y1
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
function distanceToEdgeCurves(px, py, curves, yToX = 1) {
|
|
356
|
-
let minDist = Infinity;
|
|
357
|
-
for (const c of curves) {
|
|
358
|
-
const d = distanceToBezierCurve(
|
|
359
|
-
px,
|
|
360
|
-
py,
|
|
361
|
-
yToX === 1 ? c : {
|
|
362
|
-
x0: c.x0,
|
|
363
|
-
y0: c.y0 * yToX,
|
|
364
|
-
cx0: c.cx0,
|
|
365
|
-
cy0: c.cy0 * yToX,
|
|
366
|
-
cx1: c.cx1,
|
|
367
|
-
cy1: c.cy1 * yToX,
|
|
368
|
-
x1: c.x1,
|
|
369
|
-
y1: c.y1 * yToX
|
|
370
|
-
}
|
|
371
|
-
);
|
|
372
|
-
if (d < minDist) {
|
|
373
|
-
minDist = d;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return minDist;
|
|
377
|
-
}
|
|
378
|
-
var nodeCache = /* @__PURE__ */ new WeakMap();
|
|
379
|
-
function getSpatialIndex(nodePositions, version2) {
|
|
380
|
-
const cached = nodeCache.get(nodePositions);
|
|
381
|
-
if (cached?.version === version2) {
|
|
382
|
-
return cached.index;
|
|
383
|
-
}
|
|
384
|
-
const index = new SpatialIndex(nodePositions);
|
|
385
|
-
nodeCache.set(nodePositions, { version: version2, index });
|
|
386
|
-
return index;
|
|
387
|
-
}
|
|
388
|
-
var edgeCache = /* @__PURE__ */ new WeakMap();
|
|
389
|
-
function getEdgeSpatialIndex(nodePositions, graph, drawPaths, axis, version2, deletions, routes2) {
|
|
390
|
-
const cached = edgeCache.get(nodePositions);
|
|
391
|
-
if (cached?.graph === graph && cached.drawPaths === drawPaths && cached.scaleX === axis.scaleX && cached.scaleY === axis.scaleY && cached.version === version2 && cached.deletions === deletions && cached.routes === routes2) {
|
|
392
|
-
return cached.index;
|
|
393
|
-
}
|
|
394
|
-
const index = new EdgeSpatialIndex(
|
|
395
|
-
nodePositions,
|
|
396
|
-
graph,
|
|
397
|
-
drawPaths,
|
|
398
|
-
axis,
|
|
399
|
-
void 0,
|
|
400
|
-
deletions,
|
|
401
|
-
version2,
|
|
402
|
-
routes2
|
|
403
|
-
);
|
|
404
|
-
edgeCache.set(nodePositions, {
|
|
405
|
-
graph,
|
|
406
|
-
drawPaths,
|
|
407
|
-
scaleX: axis.scaleX,
|
|
408
|
-
scaleY: axis.scaleY,
|
|
409
|
-
version: version2,
|
|
410
|
-
index,
|
|
411
|
-
deletions,
|
|
412
|
-
routes: routes2
|
|
413
|
-
});
|
|
414
|
-
return index;
|
|
415
|
-
}
|
|
416
|
-
var MIN_NODE_REACH_PX = 5;
|
|
417
|
-
function findHoveredNode(nodePositions, graphX, graphY, axis, version2 = 0, ink) {
|
|
418
|
-
const yToX = yToXOf(axis);
|
|
419
|
-
const index = getSpatialIndex(nodePositions, version2);
|
|
420
|
-
const reach = (px) => Math.max(MIN_NODE_REACH_PX, px) / axis.scaleX;
|
|
421
|
-
const queryReach = reach(ink?.maxHalfWidthPx ?? 0);
|
|
422
|
-
const candidates = index.query(graphX, graphY, queryReach, queryReach / yToX);
|
|
423
|
-
let hovered = null;
|
|
424
|
-
let best = Infinity;
|
|
425
|
-
for (const { nodeId, segmentIdx } of candidates) {
|
|
426
|
-
const segments = nodePositions[nodeId];
|
|
427
|
-
const dist = distanceToSegment(
|
|
428
|
-
graphX,
|
|
429
|
-
graphY * yToX,
|
|
430
|
-
segments[segmentIdx].x,
|
|
431
|
-
segments[segmentIdx].y * yToX,
|
|
432
|
-
segments[segmentIdx + 1].x,
|
|
433
|
-
segments[segmentIdx + 1].y * yToX
|
|
434
|
-
);
|
|
435
|
-
if (dist < best && dist < reach(ink?.halfWidthPx(nodeId) ?? 0)) {
|
|
436
|
-
best = dist;
|
|
437
|
-
hovered = nodeId;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
return hovered;
|
|
441
|
-
}
|
|
442
|
-
function findHoveredEdge(nodePositions, graph, graphX, graphY, axis, drawPaths, version2 = 0, deletions, hiddenEdges, deletionRoutes) {
|
|
443
|
-
const yToX = yToXOf(axis);
|
|
444
|
-
const edgeThreshold = 10 / axis.scaleX;
|
|
445
|
-
const edgeIndex = getEdgeSpatialIndex(
|
|
446
|
-
nodePositions,
|
|
447
|
-
graph,
|
|
448
|
-
drawPaths,
|
|
449
|
-
axis,
|
|
450
|
-
version2,
|
|
451
|
-
deletions,
|
|
452
|
-
deletionRoutes
|
|
453
|
-
);
|
|
454
|
-
const candidates = edgeIndex.query(
|
|
455
|
-
graphX,
|
|
456
|
-
graphY,
|
|
457
|
-
edgeThreshold,
|
|
458
|
-
edgeThreshold / yToX
|
|
459
|
-
);
|
|
460
|
-
let hovered = null;
|
|
461
|
-
let best = edgeThreshold;
|
|
462
|
-
for (const edgeIdx of candidates) {
|
|
463
|
-
const edge = graph.edges[edgeIdx];
|
|
464
|
-
const fromSegments = nodePositions[edge.from];
|
|
465
|
-
const toSegments = nodePositions[edge.to];
|
|
466
|
-
if (!fromSegments?.length || !toSegments?.length || hiddenEdges?.has(edgeIdx)) {
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
const numPaths = edge.pathIds?.length ?? 0;
|
|
470
|
-
const baseCurves = edgeIndex.getCurves(edgeIdx);
|
|
471
|
-
if (!baseCurves) {
|
|
472
|
-
continue;
|
|
473
|
-
}
|
|
474
|
-
let dist;
|
|
475
|
-
if (!drawPaths || numPaths === 0) {
|
|
476
|
-
dist = distanceToEdgeCurves(graphX, graphY * yToX, baseCurves, yToX);
|
|
477
|
-
} else {
|
|
478
|
-
let minDist = Infinity;
|
|
479
|
-
for (const offset of pathRibbonOffsets(
|
|
480
|
-
fromSegments,
|
|
481
|
-
toSegments,
|
|
482
|
-
numPaths,
|
|
483
|
-
axis
|
|
484
|
-
)) {
|
|
485
|
-
const curves = offset.x === 0 && offset.y === 0 ? baseCurves : translateCurves(baseCurves, offset.x, offset.y);
|
|
486
|
-
const d = distanceToEdgeCurves(graphX, graphY * yToX, curves, yToX);
|
|
487
|
-
if (d < minDist) {
|
|
488
|
-
minDist = d;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
dist = minDist;
|
|
492
|
-
}
|
|
493
|
-
if (dist < best) {
|
|
494
|
-
best = dist;
|
|
495
|
-
hovered = edgeIdx;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
return hovered;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
147
|
// src/util/wheelZoom.ts
|
|
502
148
|
var ZOOM_PER_NOTCH = 1.1;
|
|
503
149
|
var NOTCH_PX = 100;
|
|
@@ -1792,6 +1438,7 @@ export {
|
|
|
1792
1438
|
BUBBLE_SPREADS,
|
|
1793
1439
|
COLOR_SCHEMES,
|
|
1794
1440
|
Canvas2DRenderer,
|
|
1441
|
+
EXON_COLOR,
|
|
1795
1442
|
FACET_GAP_PX,
|
|
1796
1443
|
FACET_PAD_PX,
|
|
1797
1444
|
FACET_TITLE_PX,
|
|
@@ -1850,6 +1497,8 @@ export {
|
|
|
1850
1497
|
encodingSwatchCss,
|
|
1851
1498
|
engineKey,
|
|
1852
1499
|
engineRequest,
|
|
1500
|
+
exonOutlineTree,
|
|
1501
|
+
exonStretches,
|
|
1853
1502
|
facetCells,
|
|
1854
1503
|
facetGrid,
|
|
1855
1504
|
facetLifts,
|
|
@@ -1899,6 +1548,7 @@ export {
|
|
|
1899
1548
|
refNameBinding,
|
|
1900
1549
|
referenceBoxes,
|
|
1901
1550
|
referenceKnots,
|
|
1551
|
+
referenceLabel,
|
|
1902
1552
|
referenceNodes,
|
|
1903
1553
|
referencePathQuery,
|
|
1904
1554
|
referenceSamplesOf,
|
|
@@ -11,6 +11,8 @@ export interface FigureSpec extends Omit<FigureOptions, 'walks' | 'region' | 'ge
|
|
|
11
11
|
layout?: LayoutModeValue;
|
|
12
12
|
quality?: number;
|
|
13
13
|
bubbleSpread?: BubbleSpread;
|
|
14
|
+
spacing?: number;
|
|
15
|
+
componentSeparation?: number;
|
|
14
16
|
walks?: (string | WalkLayer)[];
|
|
15
17
|
walkStrip?: boolean;
|
|
16
18
|
walkRowSamples?: string[];
|
|
@@ -16,7 +16,7 @@ export declare const COLOR_SCHEMES: readonly [{
|
|
|
16
16
|
readonly label: "Depth";
|
|
17
17
|
}, {
|
|
18
18
|
readonly value: "node-length";
|
|
19
|
-
readonly label: "Node
|
|
19
|
+
readonly label: "Node length";
|
|
20
20
|
}, {
|
|
21
21
|
readonly value: "stable-rank";
|
|
22
22
|
readonly label: "Stable rank";
|
|
@@ -4,6 +4,8 @@ export interface DeletionEdge {
|
|
|
4
4
|
edgeIndex: number;
|
|
5
5
|
from: string;
|
|
6
6
|
to: string;
|
|
7
|
+
fromStrand?: '+' | '-';
|
|
8
|
+
toStrand?: '+' | '-';
|
|
7
9
|
refName: string;
|
|
8
10
|
start: number;
|
|
9
11
|
end: number;
|
|
@@ -20,5 +22,5 @@ export declare function bypassedPoints(nodePositions: Record<string, {
|
|
|
20
22
|
export declare function deletionArcCurves(nodePositions: Record<string, {
|
|
21
23
|
x: number;
|
|
22
24
|
y: number;
|
|
23
|
-
}[]>, deletion: DeletionEdge, axis: AxisScale, route?: NodeSegment[]): import("./util/geometry.js").BezierCurve[] | undefined;
|
|
25
|
+
}[]>, deletion: DeletionEdge, axis: AxisScale, route?: NodeSegment[], stranded?: boolean): import("./util/geometry.js").BezierCurve[] | undefined;
|
|
24
26
|
export declare function deletionEdges(graph: Graph): DeletionEdge[];
|
package/dist/types/figure.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ export declare class NoReferenceSampleError extends Error {
|
|
|
4
4
|
constructor(anchor: string, referenceSamples: string[]);
|
|
5
5
|
}
|
|
6
6
|
export declare class NodeLimitError extends Error {
|
|
7
|
+
readonly fitsBp: number;
|
|
7
8
|
name: string;
|
|
9
|
+
readonly regionTooLarge = true;
|
|
8
10
|
constructor(limit: number, windowBp: number, fitsBp: number);
|
|
9
11
|
}
|
|
10
12
|
export declare function haplotypePrefix(name: Pick<PathName, 'sample' | 'haplotype'>): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { El } from '../el.js';
|
|
2
|
+
import type { GenePin } from './genePins.js';
|
|
3
|
+
export declare const EXON_COLOR = "#daa520";
|
|
4
|
+
export interface ExonStretch {
|
|
5
|
+
key: string;
|
|
6
|
+
d: string;
|
|
7
|
+
inner: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function exonStretches(pins: GenePin[], halfWidthPx: (nodeId: string) => number, lift?: {
|
|
10
|
+
nodeIds: ReadonlySet<string>;
|
|
11
|
+
walks: readonly unknown[];
|
|
12
|
+
}, pathOf?: (d: string) => string): ExonStretch[];
|
|
13
|
+
export declare function exonOutlineTree(stretches: ExonStretch[], o: {
|
|
14
|
+
id: string;
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
transform?: string;
|
|
18
|
+
}): El | undefined;
|
|
@@ -25,6 +25,7 @@ interface SizeLabelArgs {
|
|
|
25
25
|
nodeLengths: Map<string, number>;
|
|
26
26
|
deletions: DeletionEdge[];
|
|
27
27
|
deletionRoutes?: DeletionRoutes;
|
|
28
|
+
stranded?: boolean;
|
|
28
29
|
alleleDeletions?: AlleleDeletion[];
|
|
29
30
|
axis: AxisScale;
|
|
30
31
|
translateX: number;
|
|
@@ -37,7 +38,7 @@ export interface SizeLabelCandidate {
|
|
|
37
38
|
label: GraphLabel;
|
|
38
39
|
box: Box;
|
|
39
40
|
}
|
|
40
|
-
export declare function sizeLabelCandidates({ nodePositions, nodeLengths, deletions, deletionRoutes, alleleDeletions, axis, translateX, translateY, width, height, version, }: SizeLabelArgs): {
|
|
41
|
+
export declare function sizeLabelCandidates({ nodePositions, nodeLengths, deletions, deletionRoutes, stranded, alleleDeletions, axis, translateX, translateY, width, height, version, }: SizeLabelArgs): {
|
|
41
42
|
deletions: SizeLabelCandidate[];
|
|
42
43
|
nodes: SizeLabelCandidate[];
|
|
43
44
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -68,9 +68,11 @@ export { ROW_HEIGHT_PX } from './layout/rowSpacing.js';
|
|
|
68
68
|
export { HALO_FACTOR, LEGEND_INSET_PX, geneCoverageNote, layoutLabels, } from './labelLayout.js';
|
|
69
69
|
export type { LabelLayout, LabelLayoutSource } from './labelLayout.js';
|
|
70
70
|
export { formatBp } from './graphLabels.js';
|
|
71
|
+
export { EXON_COLOR, exonOutlineTree, exonStretches } from './genes/exonOutline.js';
|
|
72
|
+
export type { ExonStretch } from './genes/exonOutline.js';
|
|
71
73
|
export { genePins } from './genes/genePins.js';
|
|
72
74
|
export type { GeneModel, GenePin } from './genes/genePins.js';
|
|
73
|
-
export { WELL_KNOWN_SAMPLES, assemblyWalk, backboneAssembly, featuresOnBackbone, graphBackbone, refNameBinding, wellKnownSample, } from './reference.js';
|
|
75
|
+
export { WELL_KNOWN_SAMPLES, assemblyWalk, backboneAssembly, featuresOnBackbone, graphBackbone, refNameBinding, referenceLabel, wellKnownSample, } from './reference.js';
|
|
74
76
|
export type { AssemblyNames, Backbone, BackboneContig } from './reference.js';
|
|
75
77
|
export { LABEL_CHAR_PX, LABEL_PAD, LABEL_PX } from './overlayLabels.js';
|
|
76
78
|
export type { Graph, GraphEdge, GraphNode, LayoutResult, NodeSegment, } from './types.js';
|
|
@@ -3,7 +3,7 @@ import type { DeletionEdge } from './deletionEdges.js';
|
|
|
3
3
|
import type { GenePin } from './genes/genePins.js';
|
|
4
4
|
import type { GraphLabel } from './graphLabels.js';
|
|
5
5
|
import type { DeletionRoutes } from './layout/deletionRoutes.js';
|
|
6
|
-
import type { PlacedLabel } from './overlayLabels.js';
|
|
6
|
+
import type { Box, PlacedLabel } from './overlayLabels.js';
|
|
7
7
|
import type { AlleleDeletion, NodeSegment } from './types.js';
|
|
8
8
|
import type { AxisScale } from './util/geometry.js';
|
|
9
9
|
export declare const HALO_FACTOR = 3.4;
|
|
@@ -35,6 +35,7 @@ export interface LabelLayoutSource {
|
|
|
35
35
|
showDeletionEdges: boolean;
|
|
36
36
|
deletions: DeletionEdge[];
|
|
37
37
|
deletionRoutes?: DeletionRoutes;
|
|
38
|
+
stranded?: boolean;
|
|
38
39
|
alleleDeletions: AlleleDeletion[];
|
|
39
40
|
positionsVersion: number;
|
|
40
41
|
}
|
|
@@ -54,12 +55,13 @@ export declare function geneLabelCandidates(pins: GenePin[], screen: (p: {
|
|
|
54
55
|
}) => {
|
|
55
56
|
x: number;
|
|
56
57
|
y: number;
|
|
57
|
-
}, contigThickness: number): {
|
|
58
|
+
}, contigThickness: number, nodesUnder: (box: Box) => ReadonlySet<string>): {
|
|
58
59
|
item: GenePin;
|
|
59
60
|
x: number;
|
|
60
61
|
y: number;
|
|
61
62
|
text: string;
|
|
62
63
|
fallback: string | undefined;
|
|
63
64
|
stack: number;
|
|
65
|
+
fits: (box: Box) => boolean;
|
|
64
66
|
}[];
|
|
65
67
|
export declare function layoutLabels(m: LabelLayoutSource): LabelLayout;
|
package/dist/types/pipeline.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ export interface EngineSettings {
|
|
|
27
27
|
quality: number;
|
|
28
28
|
linearLayout: boolean;
|
|
29
29
|
bubbleSpread: BubbleSpread;
|
|
30
|
+
spacing?: number;
|
|
31
|
+
componentSeparation?: number;
|
|
30
32
|
}
|
|
31
33
|
export declare function engineRequest(graph: Graph, scaling: LayoutScaling, settings: EngineSettings): EngineRequest;
|
|
32
34
|
export declare function engineKey(graph: Graph, settings: EngineSettings): string;
|
|
@@ -42,6 +44,7 @@ export declare function forceLayout(graph: Graph, settings: EngineSettings, engi
|
|
|
42
44
|
nodePositions: {
|
|
43
45
|
[x: string]: NodeSegment[];
|
|
44
46
|
};
|
|
47
|
+
stranded: boolean;
|
|
45
48
|
rowLabels?: import("./types.js").RowLabel[];
|
|
46
49
|
sampleRows?: string[];
|
|
47
50
|
alleleDeletions?: import("./types.js").AlleleDeletion[];
|
|
@@ -17,6 +17,9 @@ export interface AssemblyNames {
|
|
|
17
17
|
export declare const WELL_KNOWN_SAMPLES: ReadonlyMap<string, string>;
|
|
18
18
|
export declare function wellKnownSample(assemblyName: string): string | undefined;
|
|
19
19
|
export declare function graphBackbone(graph: Graph): Backbone | undefined;
|
|
20
|
+
export declare function referenceLabel(graph: Graph, region?: {
|
|
21
|
+
refName: string;
|
|
22
|
+
}): string | undefined;
|
|
20
23
|
export declare function backboneAssembly<T extends AssemblyNames>(backbone: Backbone | undefined, assemblies: T[]): T | undefined;
|
|
21
24
|
export declare function assemblyWalk(graph: Graph, assembly: AssemblyNames): PathOrigin | undefined;
|
|
22
25
|
export declare function contigNames(contig: string): string[];
|
package/dist/types/types.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare class EdgeSpatialIndex {
|
|
|
19
19
|
private cellSize;
|
|
20
20
|
private cells;
|
|
21
21
|
private edgeCurves;
|
|
22
|
-
constructor(nodePositions: Record<string, NodeSegment[]>, graph: Graph, drawPaths: boolean, axis: AxisScale, cellSize?: number | CellSize, deletions?: Map<number, string[]>, version?: number, routes?: DeletionRoutes);
|
|
22
|
+
constructor(nodePositions: Record<string, NodeSegment[]>, graph: Graph, drawPaths: boolean, axis: AxisScale, cellSize?: number | CellSize, deletions?: Map<number, string[]>, version?: number, routes?: DeletionRoutes, stranded?: boolean);
|
|
23
23
|
getCurves(ei: number): import("./geometry.js").BezierCurve[] | undefined;
|
|
24
24
|
query(x: number, y: number, radiusX: number, radiusY?: number): number[];
|
|
25
25
|
}
|