@jbrowse/bandage-core 4.0.26 → 4.0.28

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  HPRC_GBZ,
4
- LAYOUT_MODE_VALUES,
4
+ LAYOUT_MODES,
5
5
  cutGbzRegion,
6
6
  featuresOnBackbone,
7
7
  figureSvg,
@@ -10,12 +10,14 @@ import {
10
10
  genesFromGff3Lines,
11
11
  genesFromText,
12
12
  graphBackbone,
13
+ haplotypeIndexBeside,
13
14
  layoutModeByValue,
14
15
  loadBandage,
15
16
  loadGraph,
16
17
  openGbz,
17
- parseRegion
18
- } from "../chunks/chunk-75KVO2WV.js";
18
+ parseRegion,
19
+ refNameBinding
20
+ } from "../chunks/chunk-G3HO75W7.js";
19
21
 
20
22
  // src/cli/figure.ts
21
23
  import { access, open, readFile, writeFile } from "node:fs/promises";
@@ -28,12 +30,9 @@ function byteSource(location) {
28
30
  if (isUrl(location)) {
29
31
  return {
30
32
  async read(length, position) {
31
- const res = await fetch(location, {
33
+ const res = await fetchOk(location, {
32
34
  headers: { range: `bytes=${position}-${position + length - 1}` }
33
35
  });
34
- if (!res.ok) {
35
- throw new Error(`HTTP ${res.status} reading ${location}`);
36
- }
37
36
  return new Uint8Array(await res.arrayBuffer());
38
37
  },
39
38
  async stat() {
@@ -71,30 +70,48 @@ async function readGenes(genes, graph, resolve) {
71
70
  if (!backbone) {
72
71
  return [];
73
72
  }
74
- const file = resolve(genes.file);
73
+ const bind = refNameBinding(
74
+ backbone.contigs.map((c) => c.refName),
75
+ genes.refNames
76
+ );
75
77
  const format = genes.format ?? (/\.bed(\.gz)?$/i.test(genes.file) ? "bed" : "gff3");
76
- if (!genes.index) {
77
- return featuresOnBackbone(genesFromText(await text(file)), backbone);
78
+ const { names, features } = genes.index ? await indexedGenes(
79
+ resolve(genes.file),
80
+ resolve(genes.index),
81
+ format,
82
+ backbone.contigs,
83
+ bind
84
+ ) : namedBy(genesFromText(await text(resolve(genes.file))));
85
+ if (!names.some((name) => bind(name) !== void 0)) {
86
+ const shown = names.slice(0, 4).join(", ");
87
+ console.warn(
88
+ `bandage-figure: no sequence in ${genes.file} names ${backbone.contigs.map((c) => c.contig).join(", ")}` + (names.length ? `; it has ${shown}${names.length > 4 ? ", \u2026" : ""}` : "") + `. Give the file's name under genes.refNames, as { "chr6": "NC_000006.12" }`
89
+ );
78
90
  }
79
- const index = resolve(genes.index);
91
+ return featuresOnBackbone(features, backbone, genes.refNames);
92
+ }
93
+ function namedBy(features) {
94
+ return { names: [...new Set(features.map((f) => f.refName))], features };
95
+ }
96
+ async function indexedGenes(file, index, format, contigs, bind) {
80
97
  const csi = index.endsWith(".csi");
81
98
  const tabix = new TabixIndexedFile(
82
99
  isUrl(file) ? { url: file, ...csi ? { csiUrl: index } : { tbiUrl: index } } : { path: file, ...csi ? { csiPath: index } : { tbiPath: index } }
83
100
  );
84
- const indexed = new Set(await tabix.getReferenceSequenceNames());
101
+ const names = await tabix.getReferenceSequenceNames();
85
102
  const lines = [];
86
- for (const contig of backbone.contigs) {
87
- const refName = [contig.contig, contig.refName].find((n) => indexed.has(n));
88
- if (refName !== void 0) {
89
- await tabix.getLines(refName, contig.start, contig.end, {
103
+ for (const contig of contigs) {
104
+ const name = names.find((n) => bind(n) === contig.refName);
105
+ if (name !== void 0) {
106
+ await tabix.getLines(name, contig.start, contig.end, {
90
107
  lineCallback: (line) => lines.push(line)
91
108
  });
92
109
  }
93
110
  }
94
- return featuresOnBackbone(
95
- format === "gff3" ? genesFromGff3Lines(lines) : genesFromBed(lines.join("\n")),
96
- backbone
97
- );
111
+ return {
112
+ names,
113
+ features: format === "gff3" ? genesFromGff3Lines(lines) : genesFromBed(lines.join("\n"))
114
+ };
98
115
  }
99
116
  var engine = async (request) => {
100
117
  const bandage = await loadBandage();
@@ -111,22 +128,18 @@ async function exists(location) {
111
128
  }
112
129
  }
113
130
  async function siblingIndex(db) {
114
- const sibling = db.replace(/\.gbz\.db$/i, ".haplotype-index.db");
115
- return sibling !== db && await exists(sibling) ? sibling : void 0;
131
+ const sibling = haplotypeIndexBeside(db);
132
+ return sibling && await exists(sibling) ? sibling : void 0;
116
133
  }
117
- var UNDRAWABLE = /* @__PURE__ */ new Set(["walkrows", "tubemap", "tubemapref"]);
134
+ var DRAWABLE = LAYOUT_MODES.filter((m) => m.drawsNodes).map(
135
+ (m) => m.value
136
+ );
118
137
  function checkLayout(layout) {
119
- if (layout === void 0) {
120
- return;
121
- }
122
- if (!LAYOUT_MODE_VALUES.includes(layout)) {
138
+ if (layout !== void 0 && !DRAWABLE.includes(layout)) {
123
139
  throw new Error(
124
- `unknown layout "${layout}": one of ${LAYOUT_MODE_VALUES.filter((v) => !UNDRAWABLE.has(v)).join(", ")}`
140
+ `a figure draws no "${layout}" layout: one of ${DRAWABLE.join(", ")}`
125
141
  );
126
142
  }
127
- if (UNDRAWABLE.has(layout)) {
128
- throw new Error(`a figure cannot draw the "${layout}" layout yet`);
129
- }
130
143
  }
131
144
  async function renderSpec(spec, base) {
132
145
  checkLayout(spec.layout);
package/dist/index.js CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  FACET_GAP_PX,
6
6
  FACET_PAD_PX,
7
7
  FACET_TITLE_PX,
8
- FADED_ALPHA,
9
8
  FIT_PADDING,
10
9
  FORCE_LAYOUT_LABEL,
11
10
  HALO_FACTOR,
@@ -15,7 +14,7 @@ import {
15
14
  LABEL_PX,
16
15
  LAYOUT_MODES,
17
16
  LEGEND_INSET_PX,
18
- LIFT_BACKDROP_COLOR,
17
+ LIFT_BACKDROP_CSS,
19
18
  NODE_WIDTHS,
20
19
  REFERENCE_RAMP_MAX_HUE,
21
20
  ROW_HEIGHT_PX,
@@ -43,7 +42,6 @@ import {
43
42
  facetCells,
44
43
  facetGrid,
45
44
  facetLifts,
46
- fadeAbgr,
47
45
  featuresOnBackbone,
48
46
  figureSvg,
49
47
  fitTransform,
@@ -102,7 +100,7 @@ import {
102
100
  wellKnownSample,
103
101
  yToXOf,
104
102
  zoomAbout
105
- } from "./chunks/chunk-75KVO2WV.js";
103
+ } from "./chunks/chunk-G3HO75W7.js";
106
104
 
107
105
  // src/index.ts
108
106
  import { getDpr } from "@jbrowse/render-core/canvas2dUtils";
@@ -478,7 +476,6 @@ var REFERENCE_STRIP_ZONE_PX = REFERENCE_STRIP_PX + 8;
478
476
  var OVERHANG_PX = 8;
479
477
  var OVERHANG_CAP_PX = OVERHANG_PX + 3;
480
478
  var MIN_STAGGER_PX = 12;
481
- var PALE = abgrToCssRgba(fadeAbgr(LIFT_BACKDROP_COLOR, FADED_ALPHA));
482
479
  function referenceStripBlocks(graph, {
483
480
  colorScheme,
484
481
  referenceRamp,
@@ -490,14 +487,14 @@ function referenceStripBlocks(graph, {
490
487
  if (isBackbone(node)) {
491
488
  const colors = walks ? walks.map((w) => {
492
489
  const lane = w.colors.get(node.id);
493
- return lane === void 0 ? PALE : abgrToCssRgba(lane);
490
+ return lane === void 0 ? LIFT_BACKDROP_CSS : abgrToCssRgba(lane);
494
491
  }) : [abgrToCssRgba(getNodeColor(node, index, colorScheme, range))];
495
492
  out.push({
496
493
  node: node.id,
497
494
  bp0: node.stable.start,
498
495
  bp1: node.stable.start + node.length,
499
496
  colors,
500
- faded: colors.includes(PALE)
497
+ faded: colors.includes(LIFT_BACKDROP_CSS)
501
498
  });
502
499
  }
503
500
  });
@@ -722,15 +719,16 @@ function extentOf(commands) {
722
719
  }
723
720
  return { x0, x1 };
724
721
  }
725
- function shapeOf(d, color, alpha) {
722
+ function shapeOf(d, color, alpha, track) {
726
723
  const commands = parsePath(d);
727
- return { commands, color, alpha, ...extentOf(commands) };
724
+ return { commands, color, track, alpha, ...extentOf(commands) };
728
725
  }
729
- function layerOf(layout, type, tubes) {
726
+ function layerOf(layout, type) {
730
727
  const { shapes } = layout;
731
- const colorOf = (s) => tubes?.[s.id] ?? s.color;
728
+ const trackOf = (s) => type === "haplotype" ? s.id : void 0;
732
729
  const rects = [...shapes.rectangles, ...shapes.verticalRectangles].filter((r) => r.type === type).map((r) => ({
733
- color: colorOf(r),
730
+ color: r.color,
731
+ track: trackOf(r),
734
732
  alpha: r.alpha ?? 1,
735
733
  x0: r.xStart,
736
734
  x1: r.xEnd + 1,
@@ -738,30 +736,22 @@ function layerOf(layout, type, tubes) {
738
736
  y1: r.yEnd + 1
739
737
  }));
740
738
  const curves = curvePaths(shapes.curves, type).map(
741
- (c) => shapeOf(c.path, colorOf(c), c.alpha ?? 1)
739
+ (c) => shapeOf(c.path, c.color, c.alpha ?? 1, trackOf(c))
742
740
  );
743
- const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, colorOf(c), 1));
741
+ const corners = shapes.corners.filter((c) => c.type === type).map((c) => shapeOf(c.path, c.color, 1, trackOf(c)));
744
742
  return { rects, shapes: [...curves, ...corners] };
745
743
  }
746
- function tubeMapPicture(layout, colors = {}) {
744
+ function tubeMapPicture(layout) {
747
745
  const nodes = [];
748
746
  layout.nodes.forEach((node) => {
749
747
  if (node.order >= 0) {
750
748
  const commands = parsePath(nodeOutlinePath(node));
751
- nodes.push({
752
- name: node.name,
753
- commands,
754
- ...extentOf(commands),
755
- color: colors.nodes?.get(node.name)
756
- });
749
+ nodes.push({ name: node.name, commands, ...extentOf(commands) });
757
750
  }
758
751
  });
759
752
  return {
760
753
  bounds: layout.bounds,
761
- layers: [
762
- layerOf(layout, "haplotype", colors.tubes),
763
- layerOf(layout, "read")
764
- ],
754
+ layers: [layerOf(layout, "haplotype"), layerOf(layout, "read")],
765
755
  nodes,
766
756
  mismatches: tubeMapMismatches(layout).filter(
767
757
  (m) => m.kind !== "insertion" || !m.softClip
@@ -807,11 +797,11 @@ function trace(ctx, commands, x, y) {
807
797
  }
808
798
  }
809
799
  }
810
- function fillByColor(ctx, items, visible, addTo) {
800
+ function fillByColor(ctx, items, visible, colorOf, addTo) {
811
801
  const byColor = /* @__PURE__ */ new Map();
812
802
  for (const item of items) {
813
803
  if (visible(item)) {
814
- const key = `${item.color}|${item.alpha}`;
804
+ const key = `${colorOf(item)}|${item.alpha}`;
815
805
  const list = byColor.get(key);
816
806
  if (list) {
817
807
  list.push(item);
@@ -821,7 +811,7 @@ function fillByColor(ctx, items, visible, addTo) {
821
811
  }
822
812
  }
823
813
  for (const list of byColor.values()) {
824
- ctx.fillStyle = list[0].color;
814
+ ctx.fillStyle = colorOf(list[0]);
825
815
  ctx.globalAlpha = list[0].alpha;
826
816
  ctx.beginPath();
827
817
  for (const item of list) {
@@ -840,13 +830,14 @@ var NODE_TINT_ALPHA = 0.55;
840
830
  function drawTubeMap(ctx, picture, frame) {
841
831
  const { x, y, width } = frame;
842
832
  const visible = (item) => x(item.x1) >= 0 && x(item.x0) <= width;
833
+ const colorOf = (item) => item.track !== void 0 && frame.tubeColors?.[item.track] || item.color;
843
834
  for (const layer of picture.layers) {
844
- fillByColor(ctx, layer.rects, visible, (r) => {
835
+ fillByColor(ctx, layer.rects, visible, colorOf, (r) => {
845
836
  const left = x(r.x0);
846
837
  const top = y(r.y0);
847
838
  ctx.rect(left, top, x(r.x1) - left, y(r.y1) - top);
848
839
  });
849
- fillByColor(ctx, layer.shapes, visible, (s) => {
840
+ fillByColor(ctx, layer.shapes, visible, colorOf, (s) => {
850
841
  trace(ctx, s.commands, x, y);
851
842
  });
852
843
  }
@@ -858,7 +849,7 @@ function drawTubeMap(ctx, picture, frame) {
858
849
  const lit = node.name === frame.highlightNode;
859
850
  ctx.beginPath();
860
851
  trace(ctx, node.commands, x, y);
861
- const tint = lit ? void 0 : node.color;
852
+ const tint = lit ? void 0 : frame.nodeColors?.get(node.name);
862
853
  ctx.fillStyle = lit ? "rgba(255,192,203,0.5)" : tint ?? fill;
863
854
  ctx.strokeStyle = lit ? "#ff0000" : stroke;
864
855
  ctx.globalAlpha = tint ? NODE_TINT_ALPHA : 1;
@@ -1724,19 +1715,14 @@ function bubbleSubgraph(graph, segmentIds) {
1724
1715
  const keep = new Set(segmentIds);
1725
1716
  const nodes = graph.nodes.filter((n) => keep.has(n.name));
1726
1717
  const ids = new Set(nodes.map((n) => n.id));
1727
- const lengthOf = new Map(graph.nodes.map((n) => [n.id, n.length]));
1728
- const bpOf = (steps) => steps.reduce((sum, id) => sum + (lengthOf.get(id) ?? 0), 0);
1729
- const stretches = /* @__PURE__ */ new Map();
1718
+ const kept = /* @__PURE__ */ new Map();
1730
1719
  const paths = graph.paths?.flatMap((p) => {
1731
1720
  const first = p.nodeIds.findIndex((id) => ids.has(id));
1732
1721
  if (first < 0) {
1733
1722
  return [];
1734
1723
  }
1735
1724
  const nodeIds = p.nodeIds.filter((id) => ids.has(id));
1736
- stretches.set(p.name, {
1737
- dropped: bpOf(p.nodeIds.slice(0, first)),
1738
- bp: bpOf(nodeIds)
1739
- });
1725
+ kept.set(p.name, { first, nodeIds });
1740
1726
  return [{ ...p, nodeIds }];
1741
1727
  });
1742
1728
  return {
@@ -1744,7 +1730,7 @@ function bubbleSubgraph(graph, segmentIds) {
1744
1730
  nodes,
1745
1731
  edges: graph.edges.filter((e) => ids.has(e.from) && ids.has(e.to)),
1746
1732
  ...paths?.length ? { paths } : {},
1747
- anchorPaths: graph.anchorPaths && trimOrigins(graph.anchorPaths, graph.paths ?? [], stretches),
1733
+ anchorPaths: trimOrigins(graph, kept),
1748
1734
  pathVisits: graph.pathVisits,
1749
1735
  anchoredBy: graph.anchoredBy,
1750
1736
  referencePath: graph.referencePath
@@ -16,5 +16,6 @@ export interface FigureSpec extends Omit<FigureOptions, 'walks' | 'region' | 'ge
16
16
  file: string;
17
17
  index?: string;
18
18
  format?: 'gff3' | 'bed';
19
+ refNames?: Record<string, string>;
19
20
  };
20
21
  }
@@ -13,6 +13,7 @@ export declare const HPRC_GBZ: {
13
13
  db: string;
14
14
  index: string;
15
15
  };
16
+ export declare function haplotypeIndexBeside(db: string): string | undefined;
16
17
  export declare function parseRegion(text: string): {
17
18
  refName: string;
18
19
  start: number;
@@ -24,4 +24,13 @@ export interface GbzWindowOptions {
24
24
  keep?: (name: PathName) => boolean;
25
25
  signal?: AbortSignal;
26
26
  }
27
+ export declare const GBZ_CUT_DEFAULTS: {
28
+ readonly context: 1000;
29
+ readonly snarls: "contained";
30
+ readonly limit: 100000;
31
+ };
32
+ export declare function referencePieces(db: GBZBase, query: PathQuery, start: number, end: number): Promise<{
33
+ start: number;
34
+ end: number;
35
+ }[]>;
27
36
  export declare function cutWindowGFA(db: GBZBase, query: PathQuery | undefined, start: number, end: number, { keep, ...opts }: GbzWindowOptions): Promise<string>;
@@ -17,6 +17,7 @@ export interface GraphLabel {
17
17
  kind: 'node' | 'deletion';
18
18
  leader?: Leader;
19
19
  }
20
+ export declare function groupDigits(n: number): string;
20
21
  export declare function formatBp(bp: number): string;
21
22
  interface SizeLabelArgs {
22
23
  nodePositions: Record<string, NodeSegment[]>;
@@ -19,7 +19,7 @@ export { wheelZoomFactor } from './util/wheelZoom.js';
19
19
  export { REFERENCE_STRIP_ZONE_PX, drawReferenceStrip, referenceStripBlocks, stripBlockAt, } from './referenceStrip.js';
20
20
  export type { StripBlock } from './referenceStrip.js';
21
21
  export { drawTubeMap, tubeMapPicture } from './tubeMap/draw.js';
22
- export type { TubeMapColors, TubeMapFrame, TubeMapPicture, } from './tubeMap/draw.js';
22
+ export type { TubeMapFrame, TubeMapPicture } from './tubeMap/draw.js';
23
23
  export { tubeMapNodeColors } from './tubeMap/nodeColors.js';
24
24
  export { referenceKnots, warpX } from './tubeMap/warp.js';
25
25
  export { tubeMapFrame, tubeMapNodeAt } from './tubeMap/frame.js';
@@ -17,6 +17,7 @@ export interface LayoutMode {
17
17
  cutMargins: boolean;
18
18
  wholeWalks: boolean;
19
19
  drawsLocally: (graph: Graph) => boolean;
20
+ drawsNodes: boolean;
20
21
  }
21
22
  export declare const LAYOUT_MODES: readonly [{
22
23
  readonly value: "auto";
@@ -27,6 +28,7 @@ export declare const LAYOUT_MODES: readonly [{
27
28
  readonly wholeWalks: false;
28
29
  readonly available: (graph: Graph) => boolean;
29
30
  readonly drawsLocally: (graph: Graph) => boolean;
31
+ readonly drawsNodes: true;
30
32
  }, {
31
33
  readonly value: "samplerows";
32
34
  readonly label: "Sample rows";
@@ -36,6 +38,7 @@ export declare const LAYOUT_MODES: readonly [{
36
38
  readonly wholeWalks: false;
37
39
  readonly available: (graph: Graph) => boolean;
38
40
  readonly drawsLocally: (graph: Graph) => boolean;
41
+ readonly drawsNodes: true;
39
42
  }, {
40
43
  readonly value: "walkrows";
41
44
  readonly label: "Walk rows";
@@ -45,6 +48,7 @@ export declare const LAYOUT_MODES: readonly [{
45
48
  readonly wholeWalks: true;
46
49
  readonly available: (graph: Graph) => boolean;
47
50
  readonly drawsLocally: (graph: Graph) => boolean;
51
+ readonly drawsNodes: false;
48
52
  }, {
49
53
  readonly value: "ordered";
50
54
  readonly label: "Ordered";
@@ -54,6 +58,7 @@ export declare const LAYOUT_MODES: readonly [{
54
58
  readonly wholeWalks: false;
55
59
  readonly available: (graph: Graph) => boolean;
56
60
  readonly drawsLocally: (graph: Graph) => boolean;
61
+ readonly drawsNodes: true;
57
62
  }, {
58
63
  readonly value: "tubemap";
59
64
  readonly label: "Tube map";
@@ -63,6 +68,7 @@ export declare const LAYOUT_MODES: readonly [{
63
68
  readonly wholeWalks: false;
64
69
  readonly available: typeof hasTubeMapPaths;
65
70
  readonly drawsLocally: typeof hasTubeMapPaths;
71
+ readonly drawsNodes: false;
66
72
  }, {
67
73
  readonly value: "tubemapref";
68
74
  readonly label: "Tube map on reference";
@@ -72,6 +78,7 @@ export declare const LAYOUT_MODES: readonly [{
72
78
  readonly wholeWalks: false;
73
79
  readonly available: (graph: Graph) => boolean;
74
80
  readonly drawsLocally: (graph: Graph) => boolean;
81
+ readonly drawsNodes: false;
75
82
  }, {
76
83
  readonly value: "force";
77
84
  readonly label: "Force-directed layout";
@@ -81,6 +88,7 @@ export declare const LAYOUT_MODES: readonly [{
81
88
  readonly wholeWalks: false;
82
89
  readonly available: () => true;
83
90
  readonly drawsLocally: () => false;
91
+ readonly drawsNodes: true;
84
92
  }];
85
93
  export type LayoutModeValue = (typeof LAYOUT_MODES)[number]['value'];
86
94
  export declare const LAYOUT_MODE_VALUES: ("auto" | "ordered" | "samplerows" | "walkrows" | "tubemap" | "tubemapref" | "force")[];
@@ -94,6 +102,7 @@ export declare function layoutModeByValue(value: string): {
94
102
  readonly wholeWalks: false;
95
103
  readonly available: (graph: Graph) => boolean;
96
104
  readonly drawsLocally: (graph: Graph) => boolean;
105
+ readonly drawsNodes: true;
97
106
  } | {
98
107
  readonly value: "samplerows";
99
108
  readonly label: "Sample rows";
@@ -103,6 +112,7 @@ export declare function layoutModeByValue(value: string): {
103
112
  readonly wholeWalks: false;
104
113
  readonly available: (graph: Graph) => boolean;
105
114
  readonly drawsLocally: (graph: Graph) => boolean;
115
+ readonly drawsNodes: true;
106
116
  } | {
107
117
  readonly value: "walkrows";
108
118
  readonly label: "Walk rows";
@@ -112,6 +122,7 @@ export declare function layoutModeByValue(value: string): {
112
122
  readonly wholeWalks: true;
113
123
  readonly available: (graph: Graph) => boolean;
114
124
  readonly drawsLocally: (graph: Graph) => boolean;
125
+ readonly drawsNodes: false;
115
126
  } | {
116
127
  readonly value: "ordered";
117
128
  readonly label: "Ordered";
@@ -121,6 +132,7 @@ export declare function layoutModeByValue(value: string): {
121
132
  readonly wholeWalks: false;
122
133
  readonly available: (graph: Graph) => boolean;
123
134
  readonly drawsLocally: (graph: Graph) => boolean;
135
+ readonly drawsNodes: true;
124
136
  } | {
125
137
  readonly value: "tubemap";
126
138
  readonly label: "Tube map";
@@ -130,6 +142,7 @@ export declare function layoutModeByValue(value: string): {
130
142
  readonly wholeWalks: false;
131
143
  readonly available: typeof hasTubeMapPaths;
132
144
  readonly drawsLocally: typeof hasTubeMapPaths;
145
+ readonly drawsNodes: false;
133
146
  } | {
134
147
  readonly value: "tubemapref";
135
148
  readonly label: "Tube map on reference";
@@ -139,6 +152,7 @@ export declare function layoutModeByValue(value: string): {
139
152
  readonly wholeWalks: false;
140
153
  readonly available: (graph: Graph) => boolean;
141
154
  readonly drawsLocally: (graph: Graph) => boolean;
155
+ readonly drawsNodes: false;
142
156
  } | {
143
157
  readonly value: "force";
144
158
  readonly label: "Force-directed layout";
@@ -148,4 +162,5 @@ export declare function layoutModeByValue(value: string): {
148
162
  readonly wholeWalks: false;
149
163
  readonly available: () => true;
150
164
  readonly drawsLocally: () => false;
165
+ readonly drawsNodes: true;
151
166
  };
@@ -1,4 +1,4 @@
1
- import type { Graph, GraphPath, PathOrigin, PathVisit } from './types.js';
1
+ import type { Graph, PathOrigin, PathVisit } from './types.js';
2
2
  export declare function pathOrigin(pathName: string): {
3
3
  name: string;
4
4
  start: number;
@@ -18,7 +18,7 @@ export declare function surveyPaths(paths: PathSteps[], lengthOf: (segmentId: st
18
18
  export declare function chooseReferencePath(anchorPaths: PathOrigin[], preferred: string | undefined): PathOrigin | undefined;
19
19
  export declare function anchorFromPaths(graph: Graph, preferred: string | undefined): Graph;
20
20
  export declare function anchorGraph(graph: Graph, preferred: string | undefined): Graph;
21
- export declare function trimOrigins(origins: PathOrigin[], paths: GraphPath[], stretches: Map<string, {
22
- dropped: number;
23
- bp: number;
24
- }>): PathOrigin[];
21
+ export declare function trimOrigins(graph: Graph, kept: Map<string, {
22
+ first: number;
23
+ nodeIds: string[];
24
+ }>): PathOrigin[] | undefined;
@@ -19,7 +19,8 @@ export declare function wellKnownSample(assemblyName: string): string | undefine
19
19
  export declare function graphBackbone(graph: Graph): Backbone | undefined;
20
20
  export declare function backboneAssembly<T extends AssemblyNames>(backbone: Backbone | undefined, assemblies: T[]): T | undefined;
21
21
  export declare function assemblyWalk(graph: Graph, assembly: AssemblyNames): PathOrigin | undefined;
22
- export declare function refNameBinding(refNames: Iterable<string>): (name: string) => string | undefined;
22
+ export declare function contigNames(contig: string): string[];
23
+ export declare function refNameBinding(refNames: Iterable<string>, aliases?: Record<string, string>): (name: string) => string | undefined;
23
24
  export declare function featuresOnBackbone<T extends {
24
25
  refName: string;
25
- }>(features: readonly T[], backbone: Backbone): T[];
26
+ }>(features: readonly T[], backbone: Backbone, aliases?: Record<string, string>): T[];
@@ -6,6 +6,7 @@ import type { RenderBatch } from './types.js';
6
6
  import type { AxisScale, BezierCurve } from '../util/geometry.js';
7
7
  export declare const LIFT_BACKDROP_COLOR: number;
8
8
  export declare const FADED_ALPHA = 0.18;
9
+ export declare const LIFT_BACKDROP_CSS: string;
9
10
  export interface BuildOptions {
10
11
  nodePositions: Record<string, NodeSegment[]>;
11
12
  graph: Graph;
@@ -31,6 +31,7 @@ type Command = {
31
31
  export declare function parsePath(d: string): Command[];
32
32
  interface Filled {
33
33
  color: string;
34
+ track?: number;
34
35
  alpha: number;
35
36
  x0: number;
36
37
  x1: number;
@@ -54,19 +55,16 @@ export interface TubeMapPicture {
54
55
  commands: Command[];
55
56
  x0: number;
56
57
  x1: number;
57
- color?: string;
58
58
  }[];
59
59
  mismatches: TubeMapMismatch[];
60
60
  }
61
- export interface TubeMapColors {
62
- tubes?: readonly string[];
63
- nodes?: ReadonlyMap<string, string>;
64
- }
65
- export declare function tubeMapPicture(layout: TubeMapLayout, colors?: TubeMapColors): TubeMapPicture;
61
+ export declare function tubeMapPicture(layout: TubeMapLayout): TubeMapPicture;
66
62
  export interface TubeMapFrame extends TubeMapTransform {
67
63
  width: number;
68
64
  highlightNode?: string | null;
69
65
  darkMode?: boolean;
66
+ tubeColors?: readonly string[];
67
+ nodeColors?: ReadonlyMap<string, string>;
70
68
  }
71
69
  export declare function drawTubeMap(ctx: CanvasRenderingContext2D, picture: TubeMapPicture, frame: TubeMapFrame): void;
72
70
  export declare function mismatchesLegible(yScale: number): boolean;
@@ -1 +1 @@
1
- export declare const version = "4.0.26";
1
+ export declare const version = "4.0.28";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/bandage-core",
3
- "version": "4.0.26",
3
+ "version": "4.0.28",
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": {