igv 2.12.0 → 2.12.1

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/igv.js CHANGED
@@ -19911,7 +19911,7 @@
19911
19911
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19912
19912
  * THE SOFTWARE.
19913
19913
  */
19914
- const knownFileExtensions = new Set(["narrowpeak", "broadpeak", "regionpeak", "peaks", "bedgraph", "wig", "gff3", "gff", "gtf", "fusionjuncspan", "refflat", "seg", "aed", "bed", "vcf", "bb", "bigbed", "biginteract", "bw", "bigwig", "bam", "tdf", "refgene", "genepred", "genepredext", "bedpe", "bp", "snp", "rmsk", "cram", "gwas", "maf", "mut"]);
19914
+ const knownFileExtensions = new Set(["narrowpeak", "broadpeak", "regionpeak", "peaks", "bedgraph", "wig", "gff3", "gff", "gtf", "fusionjuncspan", "refflat", "seg", "aed", "bed", "vcf", "bb", "bigbed", "biginteract", "biggenepred", "bignarrowpeak", "bw", "bigwig", "bam", "tdf", "refgene", "genepred", "genepredext", "bedpe", "bp", "snp", "rmsk", "cram", "gwas", "maf", "mut"]);
19915
19915
  /**
19916
19916
  * Return a custom format object with the given name.
19917
19917
  * @param name
@@ -20044,6 +20044,8 @@
20044
20044
  case "bed":
20045
20045
  case "bigbed":
20046
20046
  case "bb":
20047
+ case "biggenepred":
20048
+ case "bignarrowpeak":
20047
20049
  return "bedtype";
20048
20050
 
20049
20051
  default:
@@ -23091,7 +23093,7 @@
23091
23093
  }
23092
23094
  };
23093
23095
 
23094
- const _version = "2.12.0";
23096
+ const _version = "2.12.1";
23095
23097
 
23096
23098
  function version$1() {
23097
23099
  return _version;
@@ -23234,7 +23236,7 @@
23234
23236
  class Genome {
23235
23237
  constructor(config, sequence, ideograms, aliases) {
23236
23238
  this.config = config;
23237
- this.id = config.id;
23239
+ this.id = config.id || generateGenomeID(config);
23238
23240
  this.sequence = sequence;
23239
23241
  this.chromosomeNames = sequence.chromosomeNames;
23240
23242
  this.chromosomes = sequence.chromosomes; // An object (functions as a dictionary)
@@ -23550,6 +23552,18 @@
23550
23552
  }
23551
23553
  }
23552
23554
 
23555
+ function generateGenomeID(config) {
23556
+ if (config.id !== undefined) {
23557
+ return config.id;
23558
+ } else if (config.fastaURL && isString$3(config.fastaURL)) {
23559
+ return config.fastaURL;
23560
+ } else if (config.fastaURL && config.fastaURL.name) {
23561
+ return config.fastaURL.name;
23562
+ } else {
23563
+ return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4);
23564
+ }
23565
+ }
23566
+
23553
23567
  /**
23554
23568
  * Created by dat on 9/16/16.
23555
23569
  */
@@ -24116,7 +24130,7 @@
24116
24130
 
24117
24131
  addViewportClickHandler(viewport) {
24118
24132
  viewport.addEventListener('click', event => {
24119
- if (this.enableClick) {
24133
+ if (this.enableClick && this.canvas) {
24120
24134
  if (3 === event.which || event.ctrlKey) {
24121
24135
  return;
24122
24136
  } // Close any currently open popups
@@ -45417,6 +45431,10 @@
45417
45431
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45418
45432
  * THE SOFTWARE.
45419
45433
  */
45434
+
45435
+ const fixColor = colorString => {
45436
+ return colorString.indexOf(",") > 0 && !colorString.startsWith("rgb") ? `rgb(${colorString})` : colorString;
45437
+ };
45420
45438
  /**
45421
45439
  * A collection of properties and methods shared by all (or most) track types.
45422
45440
  *
@@ -45425,6 +45443,7 @@
45425
45443
  * @constructor
45426
45444
  */
45427
45445
 
45446
+
45428
45447
  class TrackBase {
45429
45448
  constructor(config, browser) {
45430
45449
  this.browser = browser;
@@ -45458,8 +45477,8 @@
45458
45477
 
45459
45478
  this.id = this.config.id === undefined ? this.name : this.config.id;
45460
45479
  this.order = config.order;
45461
- this.color = config.color;
45462
- this.altColor = config.altColor;
45480
+ if (config.color) this.color = fixColor(config.color);
45481
+ if (config.altColor) this.altColor = fixColor(config.altColor);
45463
45482
 
45464
45483
  if ("civic-ws" === config.sourceType) {
45465
45484
  // Ugly proxy for specialized track type
@@ -47663,7 +47682,7 @@
47663
47682
  return this.tracks.find(t => name === t.name);
47664
47683
  }
47665
47684
 
47666
- getChordset(name) {
47685
+ getChordSet(name) {
47667
47686
  return this.chordSets.find(cs => name === cs.name);
47668
47687
  }
47669
47688
 
@@ -47773,9 +47792,9 @@
47773
47792
  buttonContainer.appendChild(this.showControlsButton);
47774
47793
  this.showControlsButton.innerText = 'none' === this.controlPanel.style.display ? 'Show Controls' : 'Hide Controls';
47775
47794
  this.showControlsButton.addEventListener('click', event => {
47776
- const trackPanelRows = this.controlPanel.querySelectorAll('div');
47795
+ const panelRows = this.controlPanel.querySelectorAll('div');
47777
47796
 
47778
- if (trackPanelRows.length > 0) {
47797
+ if (panelRows.length > 0) {
47779
47798
  if ('none' === this.controlPanel.style.display) {
47780
47799
  this.controlPanel.style.display = 'flex';
47781
47800
  event.target.innerText = 'Hide Controls';
@@ -47855,10 +47874,10 @@
47855
47874
  hideShowButton.innerText = true === chordSet.visible ? 'Hide' : 'Show';
47856
47875
  hideShowButton.addEventListener('click', event => {
47857
47876
  if (true === chordSet.visible) {
47858
- this.hideTrack(chordSet.name);
47877
+ this.hideChordSet(chordSet.name);
47859
47878
  event.target.innerText = "Show";
47860
47879
  } else {
47861
- this.showTrack(chordSet.name);
47880
+ this.showChordSet(chordSet.name);
47862
47881
  event.target.innerText = "Hide";
47863
47882
  }
47864
47883
  }); // The alpha range slider. Create this here so we can reference it from the color picker
@@ -47885,7 +47904,7 @@
47885
47904
  rgbaString
47886
47905
  }) => {
47887
47906
  colorPickerButton.style.backgroundColor = setAlpha(rgbaString, 1);
47888
- this.setTrackColor(chordSet.name, rgbaString);
47907
+ this.setColor(chordSet.name, rgbaString);
47889
47908
  alphaSlider.value = alphaToValue(getAlpha(chordSet.color));
47890
47909
  }
47891
47910
  };
@@ -47903,7 +47922,7 @@
47903
47922
 
47904
47923
  alphaSlider.oninput = () => {
47905
47924
  const v = valueToAlpha(alphaSlider.value);
47906
- this.setTrackColor(chordSet.name, setAlpha(chordSet.color, v));
47925
+ this.setColor(chordSet.name, setAlpha(chordSet.color, v));
47907
47926
  picker.setColor(chordSet.color);
47908
47927
  };
47909
47928
 
@@ -47922,12 +47941,14 @@
47922
47941
 
47923
47942
 
47924
47943
  setAssembly(igvGenome) {
47925
- if (this.genomeId === igvGenome.id) {
47944
+ const id = this.genomeId || guid();
47945
+
47946
+ if (this.genomeId === id) {
47926
47947
  return;
47927
47948
  }
47928
47949
 
47929
47950
  this.chordManager.clearChords();
47930
- this.genomeId = igvGenome.id;
47951
+ this.genomeId = id;
47931
47952
  this.chrNames = new Set(igvGenome.chromosomes.map(chr => shortChrName$1(chr.name)));
47932
47953
  const regions = [];
47933
47954
  const colors = [];
@@ -47946,7 +47967,7 @@
47946
47967
  this.assembly = {
47947
47968
  name: igvGenome.name,
47948
47969
  sequence: {
47949
- trackId: igvGenome.id,
47970
+ trackId: id,
47950
47971
  type: 'ReferenceSequenceTrack',
47951
47972
  adapter: {
47952
47973
  type: 'FromConfigSequenceAdapter',
@@ -47984,7 +48005,7 @@
47984
48005
 
47985
48006
 
47986
48007
  addChords(newChords, options = {}) {
47987
- const tmp = options.track || options.name || "*";
48008
+ const tmp = options.name || options.track || "*";
47988
48009
  const trackName = tmp.split(' ')[0].replaceAll("%20", " ");
47989
48010
  const chordSetName = tmp.replaceAll("%20", " ");
47990
48011
  const chordSet = {
@@ -48034,20 +48055,6 @@
48034
48055
  clearSelection() {
48035
48056
  this.viewState.pluginManager.rootModel.session.clearSelection();
48036
48057
  }
48037
-
48038
- getFeature(featureId) {
48039
- // TODO -- broken
48040
- // const display = this.viewState.pluginManager.rootModel.session.view.tracks[0].displays[0]
48041
- // const feature = display.data.features.get(featureId)
48042
- // return feature;
48043
- const features = [...this.viewState.config.tracks[0].adapter.features.value];
48044
-
48045
- for (let f of features) {
48046
- if (featureId === f.uniqueId) {
48047
- return f;
48048
- }
48049
- }
48050
- }
48051
48058
  /**
48052
48059
  * Deprecated, use "visible" property
48053
48060
  */
@@ -48073,25 +48080,25 @@
48073
48080
  this.parent.style.display = isVisible ? 'block' : 'none';
48074
48081
  }
48075
48082
 
48076
- hideTrack(trackName) {
48077
- let track = this.getTrack(trackName);
48083
+ hideChordSet(trackName) {
48084
+ let cs = this.getChordSet(trackName);
48078
48085
 
48079
- if (track) {
48080
- track.visible = false;
48086
+ if (cs) {
48087
+ cs.visible = false;
48081
48088
  this.render();
48082
48089
  } else {
48083
48090
  console.warn(`No track with name: ${name}`);
48084
48091
  }
48085
48092
  }
48086
48093
 
48087
- showTrack(trackName) {
48088
- let track = this.getTrack(trackName);
48094
+ showChordSet(name) {
48095
+ let cs = this.getChordSet(name);
48089
48096
 
48090
- if (track) {
48091
- track.visible = true;
48097
+ if (cs) {
48098
+ cs.visible = true;
48092
48099
  this.render();
48093
48100
  } else {
48094
- console.warn(`No track with name: ${trackName}`);
48101
+ console.warn(`No track with name: ${name}`);
48095
48102
  }
48096
48103
  } // showTrack(trackID) {
48097
48104
  // let idx = this.tracks.findIndex(t => trackID === t.id)
@@ -48118,12 +48125,12 @@
48118
48125
  this.render();
48119
48126
  }
48120
48127
 
48121
- getTrack(name) {
48122
- return this.groupByTrack ? this.chordManager.getTrack(name) : this.chordManager.getChordset(name);
48128
+ getChordSet(name) {
48129
+ return this.groupByTrack ? this.chordManager.getTrack(name) : this.chordManager.getChordSet(name);
48123
48130
  }
48124
48131
 
48125
- setTrackColor(name, color) {
48126
- const t = this.getTrack(name);
48132
+ setColor(name, color) {
48133
+ const t = this.getChordSet(name);
48127
48134
 
48128
48135
  if (t) {
48129
48136
  t.color = color;
@@ -48224,7 +48231,7 @@
48224
48231
  }
48225
48232
 
48226
48233
  function embedCSS$1() {
48227
- const css = '.igv-circview-container {\n z-index: 2048;\n position: absolute;\n width: fit-content;\n height: fit-content;\n box-sizing: content-box;\n color: dimgray;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n background-color: white;\n border-color: dimgray;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-circview-toolbar {\n position: relative;\n width: 100%;\n height: 32px;\n background-color: lightgrey;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n\n.igv-circview-toolbar-button-container {\n height: 100%;\n width: fit-content;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-toolbar-button-container > div {\n margin: 4px;\n}\n\n.igv-circview-track-panel {\n z-index: 1024;\n position: absolute;\n top: 33px;\n left: 0;\n width: 100%;\n height: fit-content;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n.igv-circview-track-panel > div {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-track-panel > div > div {\n margin: 4px;\n}\n\n.igv-circview-swatch-button {\n cursor: pointer;\n padding: 5px;\n width: 8px;\n height: 8px;\n border: 1px solid #8d8b8b;\n border-radius: 16px;\n}\n\n.igv-circview-button {\n cursor: pointer;\n padding: 5px;\n color: #444;\n vertical-align: middle;\n text-align: center;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n border: 1px solid #8d8b8b;\n border-radius: 4px;\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2);\n}\n\n.igv-circview-button:hover {\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n.igv-circview-button:active {\n color: #007bff;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n/*# sourceMappingURL=circular-view.css.map */\n';
48234
+ const css = '.igv-circview-container {\n z-index: 2048;\n width: fit-content;\n height: fit-content;\n box-sizing: content-box;\n color: dimgray;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n background-color: white;\n border-color: dimgray;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-circview-toolbar {\n position: relative;\n width: 100%;\n height: 32px;\n background-color: lightgrey;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n\n.igv-circview-toolbar-button-container {\n height: 100%;\n width: fit-content;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-toolbar-button-container > div {\n margin: 4px;\n}\n\n.igv-circview-track-panel {\n z-index: 1024;\n position: absolute;\n top: 33px;\n left: 0;\n width: 100%;\n height: fit-content;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n.igv-circview-track-panel > div {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-track-panel > div > div {\n margin: 4px;\n}\n\n.igv-circview-swatch-button {\n cursor: pointer;\n padding: 5px;\n width: 8px;\n height: 8px;\n border: 1px solid #8d8b8b;\n border-radius: 16px;\n}\n\n.igv-circview-button {\n cursor: pointer;\n padding: 5px;\n color: #444;\n vertical-align: middle;\n text-align: center;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n border: 1px solid #8d8b8b;\n border-radius: 4px;\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2);\n}\n\n.igv-circview-button:hover {\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n.igv-circview-button:active {\n color: #007bff;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n/*# sourceMappingURL=circular-view.css.map */\n';
48228
48235
  const style = document.createElement('style');
48229
48236
  style.setAttribute('type', 'text/css');
48230
48237
  style.innerHTML = css;
@@ -49859,11 +49866,15 @@
49859
49866
  case "unexpectedPair":
49860
49867
  case "pairOrientation":
49861
49868
  if (this.pairOrientation && alignment.pairOrientation) {
49862
- var oTypes = orientationTypes[this.pairOrientation];
49869
+ const oTypes = orientationTypes[this.pairOrientation];
49863
49870
 
49864
49871
  if (oTypes) {
49865
- var pairColor = this.pairColors[oTypes[alignment.pairOrientation]];
49866
- if (pairColor) color = pairColor;
49872
+ const pairColor = this.pairColors[oTypes[alignment.pairOrientation]];
49873
+
49874
+ if (pairColor) {
49875
+ color = pairColor;
49876
+ break;
49877
+ }
49867
49878
  }
49868
49879
  }
49869
49880
 
@@ -52440,7 +52451,7 @@
52440
52451
  });
52441
52452
  }
52442
52453
 
52443
- findUTRs(exons, feature.cdStart, feature.cdEnd);
52454
+ findUTRs$1(exons, feature.cdStart, feature.cdEnd);
52444
52455
  feature.exons = exons;
52445
52456
  } // Optional extra columns
52446
52457
 
@@ -52545,7 +52556,7 @@
52545
52556
  });
52546
52557
  }
52547
52558
 
52548
- findUTRs(exons, cdStart, cdEnd);
52559
+ findUTRs$1(exons, cdStart, cdEnd);
52549
52560
  feature.exons = exons;
52550
52561
  return feature;
52551
52562
  }
@@ -52587,7 +52598,7 @@
52587
52598
  });
52588
52599
  }
52589
52600
 
52590
- findUTRs(exons, cdStart, cdEnd);
52601
+ findUTRs$1(exons, cdStart, cdEnd);
52591
52602
  feature.exons = exons;
52592
52603
  return feature;
52593
52604
  }
@@ -52628,12 +52639,12 @@
52628
52639
  });
52629
52640
  }
52630
52641
 
52631
- findUTRs(exons, cdStart, cdEnd);
52642
+ findUTRs$1(exons, cdStart, cdEnd);
52632
52643
  feature.exons = exons;
52633
52644
  return feature;
52634
52645
  }
52635
52646
 
52636
- function findUTRs(exons, cdStart, cdEnd) {
52647
+ function findUTRs$1(exons, cdStart, cdEnd) {
52637
52648
  for (let exon of exons) {
52638
52649
  const end = exon.end;
52639
52650
  const start = exon.start;
@@ -56192,7 +56203,7 @@
56192
56203
  this.genome = genome;
56193
56204
  this.sourceType = config.sourceType === undefined ? "file" : config.sourceType;
56194
56205
  this.maxWGCount = config.maxWGCount || DEFAULT_MAX_WG_COUNT;
56195
- const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "biginteract", "tdf"]);
56206
+ const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "biginteract", "biggenepred", "bignarrowpeak", "tdf"]);
56196
56207
 
56197
56208
  if (config.features && Array.isArray(config.features)) {
56198
56209
  // Explicit array of features
@@ -56603,10 +56614,8 @@
56603
56614
 
56604
56615
  }
56605
56616
 
56606
- //table chromatinInteract
56607
-
56608
56617
  function getDecoder(definedFieldCount, fieldCount, autoSql, format) {
56609
- if (autoSql && 'chromatinInteract' === autoSql.table || "biginteract" === format) {
56618
+ if ("biginteract" === format || autoSql && 'chromatinInteract' === autoSql.table || 'interact' === autoSql.table) {
56610
56619
  return decodeInteract;
56611
56620
  } else {
56612
56621
  const standardFieldCount = definedFieldCount - 3;
@@ -56653,6 +56662,7 @@
56653
56662
  });
56654
56663
  }
56655
56664
 
56665
+ findUTRs(exons, feature.cdStart, feature.cdEnd);
56656
56666
  feature.exons = exons;
56657
56667
  }
56658
56668
 
@@ -56669,7 +56679,29 @@
56669
56679
  }
56670
56680
  }
56671
56681
  };
56672
- }
56682
+ } //table chromatinInteract
56683
+ // "Chromatin interaction between two regions"
56684
+ // (
56685
+ // string chrom; "Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records"
56686
+ // uint chromStart; "Start position of lower region. For interchromosomal, set to chromStart of this region"
56687
+ // uint chromEnd; "End position of upper region. For interchromosomal, set to chromEnd of this region"
56688
+ // string name; "Name of item, for display"
56689
+ // uint score; "Score from 0-1000"
56690
+ // double value; "Strength of interaction or other data value. Typically basis for score"
56691
+ // string exp; "Experiment name (metadata for filtering). Use . if not applicable"
56692
+ // string color; "Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4."
56693
+ // string region1Chrom; "Chromosome of lower region. For non-directional interchromosomal, chrom of this region."
56694
+ // uint region1Start; "Start position of lower/this region"
56695
+ // uint region1End; "End position in chromosome of lower/this region"
56696
+ // string region1Name; "Identifier of lower/this region"
56697
+ // string region1Strand; "Orientation of lower/this region: + or -. Use . if not applicable"
56698
+ // string region2Chrom; "Chromosome of upper region. For non-directional interchromosomal, chrom of other region"
56699
+ // uint region2Start; "Start position in chromosome of upper/this region"
56700
+ // uint region2End; "End position in chromosome of upper/this region"
56701
+ // string region2Name; "Identifier of upper/this region"
56702
+ // string region2Strand; "Orientation of upper/this region: + or -. Use . if not applicable"
56703
+ // )
56704
+
56673
56705
 
56674
56706
  function decodeInteract(feature, tokens) {
56675
56707
  feature.chr1 = tokens[5];
@@ -56686,6 +56718,25 @@
56686
56718
  }
56687
56719
  }
56688
56720
 
56721
+ function findUTRs(exons, cdStart, cdEnd) {
56722
+ for (let exon of exons) {
56723
+ const end = exon.end;
56724
+ const start = exon.start;
56725
+
56726
+ if (end < cdStart || start > cdEnd) {
56727
+ exon.utr = true;
56728
+ } else {
56729
+ if (cdStart >= start && cdStart <= end) {
56730
+ exon.cdStart = cdStart;
56731
+ }
56732
+
56733
+ if (cdEnd >= start && cdEnd <= end) {
56734
+ exon.cdEnd = cdEnd;
56735
+ }
56736
+ }
56737
+ }
56738
+ }
56739
+
56689
56740
  function scoreShade(score, color) {
56690
56741
  const alpha = Math.min(1, 0.11 + 0.89 * (score / 779));
56691
56742
  return alpha.toString();
@@ -58236,11 +58287,12 @@
58236
58287
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58237
58288
  * THE SOFTWARE.
58238
58289
  */
58290
+ const bbFormats = new Set(['bigwig', 'bw', 'bigbed', 'bb', 'biginteract', 'biggenepred', 'bignarrowpeak']);
58239
58291
 
58240
58292
  function FeatureSource(config, genome) {
58241
58293
  const format = config.format ? config.format.toLowerCase() : undefined;
58242
58294
 
58243
- if ('bigwig' === format || 'bigbed' === format || 'bb' === format || "biginteract" === format) {
58295
+ if (bbFormats.has(format)) {
58244
58296
  return new BWSource(config, genome);
58245
58297
  } else if ("tdf" === format) {
58246
58298
  return new TDFSource(config, genome);
@@ -58489,8 +58541,8 @@
58489
58541
  const xleft = centerX - textBox.width / 2;
58490
58542
  const xright = centerX + textBox.width / 2;
58491
58543
 
58492
- if (options.labelAllFeatures || xleft > options.rowLastX[feature.row] || gtexSelection) {
58493
- options.rowLastX[feature.row] = xright;
58544
+ if (options.labelAllFeatures || xleft > options.rowLastLabelX[feature.row] || gtexSelection) {
58545
+ options.rowLastLabelX[feature.row] = xright;
58494
58546
  IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform);
58495
58547
  }
58496
58548
  } finally {
@@ -58830,27 +58882,31 @@
58830
58882
  if (featureList) {
58831
58883
  const rowFeatureCount = [];
58832
58884
  options.rowLastX = [];
58885
+ options.rowLastLabelX = [];
58833
58886
 
58834
58887
  for (let feature of featureList) {
58835
- const row = feature.row || 0;
58888
+ if (feature.start > bpStart && feature.end < bpEnd) {
58889
+ const row = this.displayMode === "COLLAPSED" ? 0 : feature.row || 0;
58836
58890
 
58837
- if (rowFeatureCount[row] === undefined) {
58838
- rowFeatureCount[row] = 1;
58839
- } else {
58840
- rowFeatureCount[row]++;
58841
- }
58891
+ if (rowFeatureCount[row] === undefined) {
58892
+ rowFeatureCount[row] = 1;
58893
+ } else {
58894
+ rowFeatureCount[row]++;
58895
+ }
58842
58896
 
58843
- options.rowLastX[row] = -Number.MAX_SAFE_INTEGER;
58897
+ options.rowLastX[row] = -Number.MAX_SAFE_INTEGER;
58898
+ options.rowLastLabelX[row] = -Number.MAX_SAFE_INTEGER;
58899
+ }
58844
58900
  }
58845
58901
 
58902
+ const pixelsPerFeature = pixelWidth / Math.max(...rowFeatureCount);
58846
58903
  let lastPxEnd = [];
58847
58904
 
58848
58905
  for (let feature of featureList) {
58849
58906
  if (feature.end < bpStart) continue;
58850
58907
  if (feature.start > bpEnd) break;
58851
58908
  const row = this.displayMode === 'COLLAPSED' ? 0 : feature.row;
58852
- const featureDensity = pixelWidth / rowFeatureCount[row];
58853
- options.drawLabel = options.labelAllFeatures || featureDensity > 10;
58909
+ options.drawLabel = options.labelAllFeatures || pixelsPerFeature > 10;
58854
58910
  const pxEnd = Math.ceil((feature.end - bpStart) / bpPerPixel);
58855
58911
  const last = lastPxEnd[row];
58856
58912
 
@@ -67714,6 +67770,8 @@
67714
67770
  }
67715
67771
 
67716
67772
  createCircularView(container, show) {
67773
+ show = show === true; // convert undefined to boolean
67774
+
67717
67775
  this.circularView = createCircularView(container, this);
67718
67776
  this.circularViewControl = new CircularViewControl(this.$toggle_button_container.get(0), this);
67719
67777
  this.circularView.setAssembly({
@@ -67722,6 +67780,7 @@
67722
67780
  chromosomes: makeCircViewChromosomes(this.genome)
67723
67781
  });
67724
67782
  this.circularViewVisible = show;
67783
+ return this.circularView;
67725
67784
  }
67726
67785
 
67727
67786
  get circularViewVisible() {