@jbrowse/bandage-core 0.1.6 → 0.1.8

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/README.md CHANGED
@@ -14,8 +14,9 @@ npm install @jbrowse/bandage-core
14
14
  - A Canvas2D renderer (`buildGeometry`, `Canvas2DRenderer`), hit testing and
15
15
  label placement
16
16
  - Bubbles, deletion edges, path colors, gbz-base windows cut to GFA
17
- - Which assembly a backbone lies on (`graphBackbone`, `backboneAssembly`), and
18
- the genes on it (`featuresOnBackbone`, `genePins`)
17
+ - Which assembly a backbone lies on (`graphBackbone`, `backboneAssembly`,
18
+ `assemblyWalk`), and the genes on it: `featuresOnBackbone` renames an
19
+ assembly's genes onto the backbone's refNames, and `genePins` pins only those
19
20
 
20
21
  Nothing here imports React, MobX or a JBrowse host. BandageJS's
21
22
  [`src/main.ts`](https://github.com/cmdcolin/BandageJS/blob/main/src/main.ts) is
package/dist/index.js CHANGED
@@ -971,13 +971,13 @@ var MAX_ZOOM = 100;
971
971
  function clampZoom(zoom) {
972
972
  return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, zoom));
973
973
  }
974
- function fittedTranslateY(bounds, usableHeight, yScale) {
974
+ function fittedTranslateY(bounds, usableHeight, yScale, padTop = FIT_PADDING) {
975
975
  const leftoverY = usableHeight - bounds.h * yScale;
976
- return FIT_PADDING - bounds.minY * yScale + Math.max(0, leftoverY) / 2;
976
+ return padTop - bounds.minY * yScale + Math.max(0, leftoverY) / 2;
977
977
  }
978
- function fitTransform(bounds, paneWidth, paneHeight, pixelRows, { minScale = 0, padLeft = FIT_PADDING } = {}) {
978
+ function fitTransform(bounds, paneWidth, paneHeight, pixelRows, { minScale = 0, padLeft = FIT_PADDING, padTop = FIT_PADDING } = {}) {
979
979
  const usableWidth = paneWidth - padLeft - FIT_PADDING;
980
- const usableHeight = paneHeight - FIT_PADDING * 2;
980
+ const usableHeight = paneHeight - padTop - FIT_PADDING;
981
981
  if (usableWidth <= 0 || usableHeight <= 0 || !(bounds.w > 0 || !pixelRows && bounds.h > 0)) {
982
982
  return void 0;
983
983
  }
@@ -990,7 +990,12 @@ function fitTransform(bounds, paneWidth, paneHeight, pixelRows, { minScale = 0,
990
990
  return {
991
991
  scale,
992
992
  translateX: padLeft - bounds.minX * scale + Math.max(0, leftoverX) / 2,
993
- translateY: fittedTranslateY(bounds, usableHeight, pixelRows ? 1 : scale)
993
+ translateY: fittedTranslateY(
994
+ bounds,
995
+ usableHeight,
996
+ pixelRows ? 1 : scale,
997
+ padTop
998
+ )
994
999
  };
995
1000
  }
996
1001
  function drawingBounds(layout, opts = {}) {
@@ -2065,6 +2070,7 @@ function walkRows(graph, region, unit) {
2065
2070
  name: path.name,
2066
2071
  label: labelOf(path),
2067
2072
  sample: sampleOf(path),
2073
+ haplotype: path.haplotype,
2068
2074
  bp,
2069
2075
  offReferenceBp,
2070
2076
  complete,
@@ -4748,9 +4754,9 @@ function tubeSpan(boxes, start, end) {
4748
4754
  const b = tubeX(boxes, end, true);
4749
4755
  return { x0: Math.min(a, b), x1: Math.max(a, b) };
4750
4756
  }
4751
- function rulerBoxes(byContig) {
4757
+ function rulerBoxes(byRefName) {
4752
4758
  let best;
4753
- for (const boxes of byContig.values()) {
4759
+ for (const boxes of byRefName.values()) {
4754
4760
  if (!best || boxes.length > best.length) {
4755
4761
  best = boxes;
4756
4762
  }
@@ -4762,6 +4768,9 @@ var LABEL_GAP_PX2 = 10;
4762
4768
  var TARGET_TICK_PX = 110;
4763
4769
  var ZIGZAG_PX = 4;
4764
4770
  var ZIGZAG_AMPLITUDE_PX = 2.5;
4771
+ function rulerInk(darkMode) {
4772
+ return darkMode ? "#b0b0b8" : "#55555c";
4773
+ }
4765
4774
  function niceStep(raw) {
4766
4775
  const pow = 10 ** Math.floor(Math.log10(raw));
4767
4776
  const m = raw / pow;
@@ -4844,7 +4853,7 @@ function drawTubeMapRuler(ctx, boxes, frame, top) {
4844
4853
  if (!marks) {
4845
4854
  return;
4846
4855
  }
4847
- const ink = darkMode ? "#b0b0b8" : "#55555c";
4856
+ const ink = rulerInk(darkMode);
4848
4857
  const y = top + 0.5;
4849
4858
  ctx.strokeStyle = ink;
4850
4859
  ctx.fillStyle = ink;
@@ -4868,79 +4877,11 @@ function drawTubeMapRuler(ctx, boxes, frame, top) {
4868
4877
  }
4869
4878
  }
4870
4879
 
4871
- // src/reference.ts
4872
- var WELL_KNOWN_SAMPLES = /* @__PURE__ */ new Map([
4873
- ["hg38", "GRCh38"],
4874
- ["hg19", "GRCh37"],
4875
- ["hs1", "CHM13"],
4876
- ["t2t-chm13", "CHM13"],
4877
- ["chm13v2", "CHM13"]
4878
- ]);
4879
- function wellKnownSample(assemblyName) {
4880
- return WELL_KNOWN_SAMPLES.get(assemblyName.toLowerCase());
4881
- }
4882
- function sharedPrefixes(refNames) {
4883
- return [panSNSample, panSNHaplotype].flatMap((prefixOf) => {
4884
- const prefixes = new Set(
4885
- refNames.map((n) => n.includes("#") ? prefixOf(n) : void 0)
4886
- );
4887
- const [only] = prefixes;
4888
- return prefixes.size === 1 && only ? [only] : [];
4889
- });
4890
- }
4891
- function graphBackbone(graph) {
4892
- const spans = /* @__PURE__ */ new Map();
4893
- for (const node of graph.nodes) {
4894
- if (isBackbone(node)) {
4895
- const { refName, start } = node.stable;
4896
- const end = start + node.length;
4897
- const span = spans.get(refName);
4898
- if (span) {
4899
- span.start = Math.min(span.start, start);
4900
- span.end = Math.max(span.end, end);
4901
- } else {
4902
- spans.set(refName, {
4903
- refName,
4904
- contig: panSNContig(refName),
4905
- start,
4906
- end
4907
- });
4908
- }
4909
- }
4910
- }
4911
- const contigs = [...spans.values()];
4912
- return contigs.length ? { contigs, prefixes: sharedPrefixes(contigs.map((c) => c.refName)) } : void 0;
4913
- }
4914
- function backboneAssembly(backbone, assemblies) {
4915
- const prefixes = new Set(backbone?.prefixes.map((p) => p.toLowerCase()));
4916
- const names = (a) => [a.name, ...a.aliases ?? []];
4917
- const named = (candidates) => candidates.some((n) => n !== void 0 && prefixes.has(n.toLowerCase()));
4918
- return assemblies.find((a) => named(names(a))) ?? assemblies.find((a) => named(names(a).map(wellKnownSample)));
4919
- }
4920
- function refNameBinding(refNames) {
4921
- const exact = new Set(refNames);
4922
- const byContig = /* @__PURE__ */ new Map();
4923
- for (const refName of exact) {
4924
- const contig = panSNContig(refName);
4925
- byContig.set(contig, byContig.has(contig) ? void 0 : refName);
4926
- }
4927
- return (name) => exact.has(name) ? name : byContig.get(name);
4928
- }
4929
- function featuresOnBackbone(features, backbone) {
4930
- const bind = refNameBinding(backbone.contigs.map((c) => c.refName));
4931
- return features.flatMap((f) => {
4932
- const refName = bind(f.refName);
4933
- return refName === void 0 ? [] : [refName === f.refName ? f : { ...f, refName }];
4934
- });
4935
- }
4936
-
4937
4880
  // src/tubeMap/genes.ts
4938
4881
  function tubeMapGenes(byRefName, genes) {
4939
4882
  const out = [];
4940
- const bind = refNameBinding(byRefName.keys());
4941
4883
  for (const gene of genes) {
4942
- const refName = bind(gene.refName);
4943
- const boxes = refName === void 0 ? void 0 : byRefName.get(refName);
4884
+ const boxes = byRefName.get(gene.refName);
4944
4885
  const first = boxes?.[0];
4945
4886
  const last = boxes?.at(-1);
4946
4887
  if (!boxes || !first || !last) {
@@ -4961,13 +4902,13 @@ function tubeMapGenes(byRefName, genes) {
4961
4902
  }
4962
4903
  return out;
4963
4904
  }
4964
- var ROW_PX = 22;
4905
+ var GENE_ROW_PX = 22;
4965
4906
  var EXON_PX = 8;
4966
4907
  var NAME_FONT = "11px sans-serif";
4967
4908
  var NAME_GAP_PX = 8;
4968
4909
  function drawTubeMapGenes(ctx, genes, frame, bottom, top = 0) {
4969
4910
  const { x, width, darkMode } = frame;
4970
- const rows = Math.max(1, Math.floor((bottom - top) / ROW_PX));
4911
+ const rows = Math.max(1, Math.floor((bottom - top) / GENE_ROW_PX));
4971
4912
  const rowEnds = [];
4972
4913
  const ink = darkMode ? "#e0e0e6" : "#1c1c22";
4973
4914
  ctx.font = NAME_FONT;
@@ -4989,7 +4930,7 @@ function drawTubeMapGenes(ctx, genes, frame, bottom, top = 0) {
4989
4930
  row = Math.min(rowEnds.length, rows - 1);
4990
4931
  }
4991
4932
  rowEnds[row] = Math.max(rowEnds[row] ?? -Infinity, right);
4992
- const glyphY = bottom - row * ROW_PX - EXON_PX / 2;
4933
+ const glyphY = bottom - row * GENE_ROW_PX - EXON_PX / 2;
4993
4934
  ctx.beginPath();
4994
4935
  ctx.moveTo(s0, glyphY + 0.5);
4995
4936
  ctx.lineTo(s1, glyphY + 0.5);
@@ -5644,11 +5585,9 @@ function layoutLabels(m) {
5644
5585
  // src/genes/genePins.ts
5645
5586
  function genePins(graph, genes, positions) {
5646
5587
  const byRefName = /* @__PURE__ */ new Map();
5647
- const refNames = /* @__PURE__ */ new Set();
5648
5588
  for (const node of graph.nodes) {
5649
5589
  if (isBackbone(node)) {
5650
5590
  const { refName } = node.stable;
5651
- refNames.add(refName);
5652
5591
  if (positions[node.id]?.length) {
5653
5592
  const entry = byRefName.get(refName) ?? byRefName.set(refName, { nodes: [], reach: 0 }).get(refName);
5654
5593
  entry.nodes.push(node);
@@ -5659,11 +5598,9 @@ function genePins(graph, genes, positions) {
5659
5598
  for (const { nodes } of byRefName.values()) {
5660
5599
  nodes.sort((a, b) => a.stable.start - b.stable.start);
5661
5600
  }
5662
- const bind = refNameBinding(refNames);
5663
5601
  const pins = [];
5664
5602
  for (const gene of genes) {
5665
- const refName = bind(gene.refName);
5666
- const backbone = refName === void 0 ? void 0 : byRefName.get(refName);
5603
+ const backbone = byRefName.get(gene.refName);
5667
5604
  if (!backbone) {
5668
5605
  continue;
5669
5606
  }
@@ -5722,6 +5659,135 @@ function genePins(graph, genes, positions) {
5722
5659
  return pins;
5723
5660
  }
5724
5661
 
5662
+ // src/reference.ts
5663
+ var WELL_KNOWN_SAMPLES = /* @__PURE__ */ new Map([
5664
+ ["hg38", "GRCh38"],
5665
+ ["hg19", "GRCh37"],
5666
+ ["hs1", "CHM13"],
5667
+ ["t2t-chm13", "CHM13"],
5668
+ ["chm13v2", "CHM13"]
5669
+ ]);
5670
+ function wellKnownSample(assemblyName) {
5671
+ return WELL_KNOWN_SAMPLES.get(assemblyName.toLowerCase());
5672
+ }
5673
+ var GENERIC_SAMPLES = /* @__PURE__ */ new Set(["_gbwt_ref"]);
5674
+ function sampleOf2(refName) {
5675
+ const sample = refName.includes("#") ? panSNSample(refName) : void 0;
5676
+ return sample === void 0 || GENERIC_SAMPLES.has(sample) ? void 0 : sample;
5677
+ }
5678
+ function haplotypeOf(refName) {
5679
+ return panSNHaplotype(refName) ?? panSNSample(refName);
5680
+ }
5681
+ function graphHaplotypes(graph) {
5682
+ const refNames = new Set((graph.anchorPaths ?? []).map((p) => p.name));
5683
+ for (const node of graph.nodes) {
5684
+ if (node.stable) {
5685
+ refNames.add(node.stable.refName);
5686
+ }
5687
+ }
5688
+ const bySample = /* @__PURE__ */ new Map();
5689
+ for (const refName of refNames) {
5690
+ const sample = sampleOf2(refName);
5691
+ if (sample !== void 0) {
5692
+ const haplotypes = bySample.get(sample) ?? bySample.set(sample, /* @__PURE__ */ new Set()).get(sample);
5693
+ haplotypes.add(haplotypeOf(refName));
5694
+ }
5695
+ }
5696
+ return bySample;
5697
+ }
5698
+ function backboneFrom(contigs, haplotypes) {
5699
+ const samples = new Set(contigs.map((c) => sampleOf2(c.refName)));
5700
+ const [sample] = samples;
5701
+ if (samples.size !== 1 || sample === void 0) {
5702
+ return { contigs, prefixes: [], named: false };
5703
+ }
5704
+ const own = new Set(contigs.map((c) => haplotypeOf(c.refName)));
5705
+ const unique = [...haplotypes.get(sample) ?? []].every((h) => own.has(h));
5706
+ const shared = new Set(contigs.map((c) => panSNHaplotype(c.refName)));
5707
+ const [haplotype] = shared;
5708
+ return {
5709
+ contigs,
5710
+ prefixes: [
5711
+ ...unique ? [sample] : [],
5712
+ ...shared.size === 1 && haplotype ? [haplotype] : []
5713
+ ],
5714
+ named: true
5715
+ };
5716
+ }
5717
+ function graphBackbone(graph) {
5718
+ const spans = /* @__PURE__ */ new Map();
5719
+ for (const node of graph.nodes) {
5720
+ if (isBackbone(node)) {
5721
+ const { refName, start } = node.stable;
5722
+ const end = start + node.length;
5723
+ const span = spans.get(refName);
5724
+ if (span) {
5725
+ span.start = Math.min(span.start, start);
5726
+ span.end = Math.max(span.end, end);
5727
+ } else {
5728
+ spans.set(refName, {
5729
+ refName,
5730
+ contig: panSNContig(refName),
5731
+ start,
5732
+ end
5733
+ });
5734
+ }
5735
+ }
5736
+ }
5737
+ const contigs = [...spans.values()];
5738
+ return contigs.length ? backboneFrom(contigs, graphHaplotypes(graph)) : void 0;
5739
+ }
5740
+ function backboneAssembly(backbone, assemblies) {
5741
+ const names = (a) => [a.name, ...a.aliases ?? []];
5742
+ const naming = (prefix) => (a) => names(a).some((n) => n.toLowerCase() === prefix.toLowerCase());
5743
+ const prefixes = [...backbone?.prefixes ?? []].reverse();
5744
+ const sample = backbone?.prefixes.find((p) => !p.includes("#"))?.toLowerCase();
5745
+ for (const prefix of prefixes) {
5746
+ const assembly = assemblies.find(naming(prefix));
5747
+ if (assembly) {
5748
+ return assembly;
5749
+ }
5750
+ }
5751
+ return sample === void 0 ? void 0 : assemblies.find(
5752
+ (a) => names(a).some((n) => wellKnownSample(n)?.toLowerCase() === sample)
5753
+ );
5754
+ }
5755
+ function assemblyWalk(graph, assembly) {
5756
+ const haplotypes = graphHaplotypes(graph);
5757
+ return graph.anchorPaths?.find(
5758
+ (walk) => backboneAssembly(
5759
+ backboneFrom(
5760
+ [
5761
+ {
5762
+ refName: walk.name,
5763
+ contig: panSNContig(walk.name),
5764
+ start: walk.start,
5765
+ end: walk.start + walk.length
5766
+ }
5767
+ ],
5768
+ haplotypes
5769
+ ),
5770
+ [assembly]
5771
+ )
5772
+ );
5773
+ }
5774
+ function refNameBinding(refNames) {
5775
+ const exact = new Set(refNames);
5776
+ const byContig = /* @__PURE__ */ new Map();
5777
+ for (const refName of exact) {
5778
+ const contig = panSNContig(refName);
5779
+ byContig.set(contig, byContig.has(contig) ? void 0 : refName);
5780
+ }
5781
+ return (name) => exact.has(name) ? name : byContig.get(name);
5782
+ }
5783
+ function featuresOnBackbone(features, backbone) {
5784
+ const bind = refNameBinding(backbone.contigs.map((c) => c.refName));
5785
+ return features.flatMap((f) => {
5786
+ const refName = bind(f.refName);
5787
+ return refName === void 0 ? [] : [refName === f.refName ? f : { ...f, refName }];
5788
+ });
5789
+ }
5790
+
5725
5791
  // src/gbzWindow.ts
5726
5792
  var NoReferenceSampleError = class extends Error {
5727
5793
  constructor(anchor, referenceSamples) {
@@ -5867,6 +5933,7 @@ export {
5867
5933
  REFERENCE_RAMP_MAX_HUE,
5868
5934
  ROW_HEIGHT_PX,
5869
5935
  WELL_KNOWN_SAMPLES,
5936
+ assemblyWalk,
5870
5937
  axisScaleOf,
5871
5938
  backboneAssembly,
5872
5939
  bubbleHalos,
@@ -29,5 +29,5 @@ export declare const COLOR_SCHEMES: readonly [{
29
29
  }];
30
30
  export type ColorScheme = (typeof COLOR_SCHEMES)[number]['value'];
31
31
  export type ResolvedColorScheme = Exclude<ColorScheme, 'auto'>;
32
- export declare const COLOR_SCHEME_VALUES: ("auto" | "uniform" | "random" | "rainbow" | "depth" | "node-length" | "stable-rank" | "reference-position" | "grey")[];
32
+ export declare const COLOR_SCHEME_VALUES: ("depth" | "auto" | "uniform" | "random" | "rainbow" | "node-length" | "stable-rank" | "reference-position" | "grey")[];
33
33
  export declare function resolveColorScheme(scheme: ColorScheme, graph: Graph | undefined): ResolvedColorScheme;
@@ -47,7 +47,7 @@ export type { BubbleGlyph, LabelLayout, LabelLayoutSource } from './labelLayout.
47
47
  export { formatBp } from './graphLabels.js';
48
48
  export { genePins } from './genes/genePins.js';
49
49
  export type { GeneModel, GenePin } from './genes/genePins.js';
50
- export { WELL_KNOWN_SAMPLES, backboneAssembly, featuresOnBackbone, graphBackbone, refNameBinding, wellKnownSample, } from './reference.js';
50
+ export { WELL_KNOWN_SAMPLES, assemblyWalk, backboneAssembly, featuresOnBackbone, graphBackbone, refNameBinding, wellKnownSample, } from './reference.js';
51
51
  export type { AssemblyNames, Backbone, BackboneContig } from './reference.js';
52
52
  export { LABEL_CHAR_PX, LABEL_PAD, LABEL_PX } from './overlayLabels.js';
53
53
  export type { Graph, GraphEdge, GraphNode, LayoutResult, NodeSegment, } from './types.js';
@@ -1,3 +1,4 @@
1
+ import type { Coarsened } from '../tubeMap/coarsen.js';
1
2
  import type { Graph, LayoutResult } from '../types.js';
2
3
  import type { InputTrack, TubeMapLayout } from '@gmod/tubemap-core';
3
4
  export interface TubeMapColumn {
@@ -11,7 +12,9 @@ export interface TubeMapDrawing {
11
12
  layout: TubeMapLayout;
12
13
  yOffset: number;
13
14
  columns?: TubeMapColumn[];
15
+ coarse?: Coarsened;
14
16
  }
17
+ export declare function visitStrands(graph: Graph): Map<string, ("+" | "-")[]>;
15
18
  export declare function tubeMapTracks(graph: Graph): InputTrack[];
16
19
  export declare function hasTubeMapPaths(graph: Graph): boolean;
17
20
  export declare function tubeWidth(trackCount: number): number;
@@ -10,6 +10,7 @@ export interface WalkRow {
10
10
  name: string;
11
11
  label: string;
12
12
  sample: string;
13
+ haplotype?: number;
13
14
  bp: number;
14
15
  offReferenceBp: number;
15
16
  complete: boolean;
@@ -10,7 +10,7 @@ export declare const NODE_WIDTHS: readonly [{
10
10
  readonly description: "Every node the same thickness.";
11
11
  }];
12
12
  export type NodeWidth = (typeof NODE_WIDTHS)[number]['value'];
13
- export declare const NODE_WIDTH_VALUES: ("uniform" | "depth")[];
13
+ export declare const NODE_WIDTH_VALUES: ("depth" | "uniform")[];
14
14
  export declare function meanDepth(graph: Graph): number;
15
15
  export declare function depthWidthFactor(node: GraphNode, mean: number): number;
16
16
  export declare function nodeWidthPx(node: GraphNode, contigThickness: number, nodeWidth: NodeWidth, mean: number): number;
@@ -54,15 +54,16 @@ export declare function clampZoom(zoom: number): number;
54
54
  export declare function fittedTranslateY(bounds: {
55
55
  minY: number;
56
56
  h: number;
57
- }, usableHeight: number, yScale: number): number;
57
+ }, usableHeight: number, yScale: number, padTop?: number): number;
58
58
  export declare function fitTransform(bounds: {
59
59
  minX: number;
60
60
  minY: number;
61
61
  w: number;
62
62
  h: number;
63
- }, paneWidth: number, paneHeight: number, pixelRows: boolean, { minScale, padLeft }?: {
63
+ }, paneWidth: number, paneHeight: number, pixelRows: boolean, { minScale, padLeft, padTop }?: {
64
64
  minScale?: number | undefined;
65
65
  padLeft?: number | undefined;
66
+ padTop?: number | undefined;
66
67
  }): {
67
68
  scale: number;
68
69
  translateX: number;
@@ -1,4 +1,4 @@
1
- import type { Graph } from './types.js';
1
+ import type { Graph, PathOrigin } from './types.js';
2
2
  export interface BackboneContig {
3
3
  refName: string;
4
4
  contig: string;
@@ -8,6 +8,7 @@ export interface BackboneContig {
8
8
  export interface Backbone {
9
9
  contigs: BackboneContig[];
10
10
  prefixes: string[];
11
+ named: boolean;
11
12
  }
12
13
  export interface AssemblyNames {
13
14
  name: string;
@@ -17,6 +18,7 @@ export declare const WELL_KNOWN_SAMPLES: ReadonlyMap<string, string>;
17
18
  export declare function wellKnownSample(assemblyName: string): string | undefined;
18
19
  export declare function graphBackbone(graph: Graph): Backbone | undefined;
19
20
  export declare function backboneAssembly<T extends AssemblyNames>(backbone: Backbone | undefined, assemblies: T[]): T | undefined;
21
+ export declare function assemblyWalk(graph: Graph, assembly: AssemblyNames): PathOrigin | undefined;
20
22
  export declare function refNameBinding(refNames: Iterable<string>): (name: string) => string | undefined;
21
23
  export declare function featuresOnBackbone<T extends {
22
24
  refName: string;
@@ -14,7 +14,10 @@ export declare function tubeSpan(boxes: readonly Box[], start: number, end: numb
14
14
  x0: number;
15
15
  x1: number;
16
16
  };
17
- export declare function rulerBoxes(byContig: ReferenceBoxes): Box[] | undefined;
17
+ export declare function rulerBoxes(byRefName: ReferenceBoxes): Box[] | undefined;
18
+ export declare const ZIGZAG_PX = 4;
19
+ export declare const ZIGZAG_AMPLITUDE_PX = 2.5;
20
+ export declare function rulerInk(darkMode?: boolean): "#b0b0b8" | "#55555c";
18
21
  export interface RulerMarks {
19
22
  from: number;
20
23
  to: number;
@@ -0,0 +1,16 @@
1
+ import type { Graph } from '../types.js';
2
+ export interface Deviation {
3
+ start: number;
4
+ end: number;
5
+ bp: number;
6
+ inverted?: true;
7
+ }
8
+ export type CutCause = 'variant' | 'backward' | 'inversion' | 'walk-end' | 'overlap' | 'reference-gap';
9
+ export interface Coarsened {
10
+ graph: Graph;
11
+ members: Map<string, string[]>;
12
+ coarseOf: Map<string, string>;
13
+ deviations: Map<string, Deviation[]>;
14
+ cuts: Map<number, CutCause>;
15
+ }
16
+ export declare function coarsenTubeMap(graph: Graph, sigma: number): Coarsened | undefined;
@@ -0,0 +1,13 @@
1
+ import type { Deviation } from './coarsen.js';
2
+ import type { TubeMapFrame } from './draw.js';
3
+ import type { Graph } from '../types.js';
4
+ import type { TubeMapLayout } from '@gmod/tubemap-core';
5
+ export interface DeviationMark {
6
+ x0: number;
7
+ x1: number;
8
+ y: number;
9
+ height: number;
10
+ }
11
+ export declare function deviationMarks(graph: Graph, layout: TubeMapLayout, deviations: Map<string, Deviation[]>): DeviationMark[];
12
+ export declare function deviationInk(darkMode?: boolean): "rgba(255,255,255,0.9)" | "rgba(0,0,0,0.8)";
13
+ export declare function drawDeviationMarks(ctx: CanvasRenderingContext2D, marks: readonly DeviationMark[], { x, y, width, darkMode }: TubeMapFrame): void;
@@ -11,4 +11,6 @@ export interface TubeMapGene {
11
11
  }[];
12
12
  }
13
13
  export declare function tubeMapGenes(byRefName: ReferenceBoxes, genes: readonly GeneModel[]): TubeMapGene[];
14
+ export declare const GENE_ROW_PX = 22;
15
+ export declare function tubeMapGeneRows(genes: readonly TubeMapGene[]): number;
14
16
  export declare function drawTubeMapGenes(ctx: CanvasRenderingContext2D, genes: readonly TubeMapGene[], frame: TubeMapFrame, bottom: number, top?: number): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/bandage-core",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
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": {