igv 3.0.3 → 3.0.5

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.esm.js CHANGED
@@ -25216,9 +25216,7 @@ class GFFHelper {
25216
25216
  } else {
25217
25217
  combinedFeatures = this.combineFeaturesByType(features);
25218
25218
  }
25219
- combinedFeatures.sort(function (a, b) {
25220
- return a.start - b.start
25221
- });
25219
+
25222
25220
  this.numberExons(combinedFeatures, genomicInterval);
25223
25221
  this.nameFeatures(combinedFeatures);
25224
25222
  return combinedFeatures
@@ -29775,20 +29773,30 @@ class FeatureFileReader {
29775
29773
  await this.readHeader();
29776
29774
  }
29777
29775
 
29776
+ let allFeatures;
29778
29777
  const index = await this.getIndex();
29779
29778
  if (index) {
29780
29779
  this.indexed = true;
29781
- return this.loadFeaturesWithIndex(chr, start, end)
29780
+ allFeatures = await this.loadFeaturesWithIndex(chr, start, end);
29782
29781
  } else if (this.dataURI) {
29783
29782
  this.indexed = false;
29784
- return this.loadFeaturesFromDataURI()
29783
+ allFeatures = await this.loadFeaturesFromDataURI();
29785
29784
  } else if ("service" === this.config.sourceType) {
29786
- return this.loadFeaturesFromService(chr, start, end)
29785
+ allFeatures = await this.loadFeaturesFromService(chr, start, end);
29787
29786
  } else {
29788
29787
  this.indexed = false;
29789
- return this.loadFeaturesNoIndex()
29788
+ allFeatures = await this.loadFeaturesNoIndex();
29790
29789
  }
29791
29790
 
29791
+ allFeatures.sort(function (a, b) {
29792
+ if (a.chr === b.chr) {
29793
+ return a.start - b.start
29794
+ } else {
29795
+ return a.chr.localeCompare(b.chr)
29796
+ }
29797
+ });
29798
+
29799
+ return allFeatures
29792
29800
  }
29793
29801
 
29794
29802
  async readHeader() {
@@ -29960,9 +29968,6 @@ class FeatureFileReader {
29960
29968
  await this._parse(allFeatures, dataWrapper, chr, end, start);
29961
29969
 
29962
29970
  }
29963
- allFeatures.sort(function (a, b) {
29964
- return a.start - b.start
29965
- });
29966
29971
 
29967
29972
  return allFeatures
29968
29973
  }
@@ -29992,8 +29997,13 @@ class FeatureFileReader {
29992
29997
 
29993
29998
  let features = await this.parser.parseFeatures(dataWrapper);
29994
29999
 
29995
- // Filter psuedo-features (e.g. created mates for VCF SV records) TODO why?
29996
- //slicedFeatures = slicedFeatures.filter(f => f._f === undefined)
30000
+ features.sort(function (a, b) {
30001
+ if (a.chr === b.chr) {
30002
+ return a.start - b.start
30003
+ } else {
30004
+ return a.chr.localeCompare(b.chr)
30005
+ }
30006
+ });
29997
30007
 
29998
30008
  // Filter features not in requested range.
29999
30009
  if (undefined === chr) {
@@ -30002,26 +30012,21 @@ class FeatureFileReader {
30002
30012
  let inInterval = false;
30003
30013
  for (let i = 0; i < features.length; i++) {
30004
30014
  const f = features[i];
30005
- if (f.chr !== chr) {
30006
- if (allFeatures.length === 0) {
30007
- continue //adjacent chr to the left
30008
- } else {
30009
- break //adjacent chr to the right
30015
+ if (f.chr === chr) {
30016
+ if (f.start > end) {
30017
+ allFeatures.push(f); // First feature beyond interval
30018
+ break
30010
30019
  }
30011
- }
30012
- if (f.start > end) {
30013
- allFeatures.push(f); // First feature beyond interval
30014
- break
30015
- }
30016
- if (f.end >= start && f.start <= end) {
30017
- // All this to grab first feature before start of interval. Needed for some track renderers, like line plot
30018
- if (!inInterval) {
30019
- inInterval = true;
30020
- if (i > 0) {
30021
- allFeatures.push(features[i - 1]);
30020
+ if (f.end >= start && f.start <= end) {
30021
+ // All this to grab first feature before start of interval. Needed for some track renderers, like line plot
30022
+ if (!inInterval) {
30023
+ inInterval = true;
30024
+ if (i > 0) {
30025
+ allFeatures.push(features[i - 1]);
30026
+ }
30022
30027
  }
30028
+ allFeatures.push(f);
30023
30029
  }
30024
- allFeatures.push(f);
30025
30030
  }
30026
30031
  }
30027
30032
  }
@@ -34495,7 +34500,11 @@ function renderFeatureLabel(ctx, feature, featureX, featureX1, featureY, referen
34495
34500
  if (name === undefined) name = feature.id || feature.ID;
34496
34501
  if (!name || name === '.') return
34497
34502
 
34498
- let centerX = (featureX + featureX1) / 2;
34503
+ let pixelXOffset = options.pixelXOffset || 0;
34504
+ const t1 = Math.max(featureX, -pixelXOffset);
34505
+ const t2 = Math.min(featureX1, -pixelXOffset + options.viewportWidth);
34506
+ let centerX = (t1 + t2) / 2;
34507
+ //let centerX = (featureX + featureX1) / 2
34499
34508
 
34500
34509
  let transform;
34501
34510
  if (this.displayMode === "COLLAPSED" && this.labelDisplayMode === "SLANT") {
@@ -34774,7 +34783,6 @@ class FeatureTrack extends TrackBase {
34774
34783
  displayMode: "EXPANDED", // COLLAPSED | EXPANDED | SQUISHED
34775
34784
  margin: 10,
34776
34785
  featureHeight: 14,
34777
- autoHeight: false,
34778
34786
  useScore: false
34779
34787
  }
34780
34788
 
@@ -35306,7 +35314,8 @@ function monitorTrackDrag(track) {
35306
35314
 
35307
35315
  function onDragEnd() {
35308
35316
  if (track.trackView && track.displayMode !== "SQUISHED") {
35309
- track.trackView.updateViews(); // TODO -- refine this to the viewport that was dragged after DOM refactor
35317
+ // Repaint views to adjust feature name if center is moved out of view
35318
+ track.trackView.repaintViews();
35310
35319
  }
35311
35320
  }
35312
35321
 
@@ -39596,6 +39605,10 @@ class DynamicFeatureSource {
39596
39605
  if (this.featureMap[chr]) {
39597
39606
  const match = `${chr}-${start}-${end}`;
39598
39607
  this.featureMap[chr] = this.featureMap[chr].filter(feature => match !== `${feature.chr}-${feature.start}-${feature.end}`);
39608
+ // Check if featureMap for a specific chromosome is empty now and delete it if yes
39609
+ if (this.featureMap[chr].length === 0) {
39610
+ delete this.featureMap[chr];
39611
+ }
39599
39612
  }
39600
39613
  }
39601
39614
  }
@@ -43043,7 +43056,7 @@ class TrackView {
43043
43056
  const viewportsToRepaint = visibleViewports.filter(vp => vp.needsRepaint()).filter(viewport => viewport.checkZoomIn());
43044
43057
 
43045
43058
  // Get viewports that require a data load
43046
- const viewportsToReload = viewportsToRepaint.filter(viewport => viewport.needsReload());
43059
+ const viewportsToReload = visibleViewports.filter(viewport => viewport.checkZoomIn()).filter(viewport => viewport.needsReload());
43047
43060
 
43048
43061
  // Trigger viewport to load features needed to cover current genomic range
43049
43062
  // NOTE: these must be loaded synchronously, do not user Promise.all, not all file readers are thread safe
@@ -67608,8 +67621,6 @@ class VariantTrack extends TrackBase {
67608
67621
  this.trackView.setTrackHeight(this.config.height || CNVPytorTrack.DEFAULT_TRACK_HEIGHT);
67609
67622
  this.trackView.checkContentHeight();
67610
67623
  this.trackView.updateViews();
67611
- this.trackView.track.autoHeight = false;
67612
-
67613
67624
 
67614
67625
  } finally {
67615
67626
  this.trackView.stopSpinner();
@@ -68030,13 +68041,8 @@ class QTLTrack extends TrackBase {
68030
68041
  this.divider = config.divider || "rgb(225,225,225)";
68031
68042
  this.dotSize = config.dotSize || 2;
68032
68043
  this.height = config.height || 100;
68033
- this.autoHeight = false;
68034
68044
  this.disableButtons = config.disableButtons;
68035
68045
 
68036
- // Limit visibility window to 2 mb, gtex server gets flaky beyond that
68037
- //this.visibilityWindow = config.visibilityWindow === undefined ?
68038
- // 2000000 : config.visibilityWindow >= 0 ? Math.min(2000000, config.visibilityWindow) : 2000000
68039
-
68040
68046
  this.featureSource = FeatureSource(config, this.browser.genome);
68041
68047
  }
68042
68048
 
@@ -70515,7 +70521,7 @@ function createReferenceFrameList(loci, genome, browserFlanking, minimumBases, v
70515
70521
  })
70516
70522
  }
70517
70523
 
70518
- const _version = "3.0.3";
70524
+ const _version = "3.0.5";
70519
70525
  function version() {
70520
70526
  return _version
70521
70527
  }
@@ -72065,9 +72071,16 @@ class ROIMenu {
72065
72071
  '<hr/>',
72066
72072
  {
72067
72073
  label: 'Delete',
72068
- click: () => {
72069
- this.browser.roiManager.deleteRegionWithKey(regionElement.dataset.region, this.browser.columnContainer);
72070
- this.browser.roiManager.repaintTable();
72074
+ click: async () => {
72075
+ roiSet.removeFeature(feature);
72076
+ const userDefinedFeatures = await roiSet.getAllFeatures();
72077
+
72078
+ // Delete user defined ROI Set if it is empty
72079
+ if (Object.keys(userDefinedFeatures).length === 0) {
72080
+ roiManager.deleteUserDefinedROISet();
72081
+ }
72082
+ roiManager.deleteRegionWithKey(regionElement.dataset.region, columnContainer);
72083
+ roiManager.repaintTable();
72071
72084
  }
72072
72085
  }
72073
72086
  );
@@ -72595,6 +72608,10 @@ class ROIManager {
72595
72608
  return this.roiSets.find(roiSet => true === roiSet.isUserDefined)
72596
72609
  }
72597
72610
 
72611
+ deleteUserDefinedROISet(){
72612
+ this.roiSets = this.roiSets.filter(roiSet => roiSet.isUserDefined !== true);
72613
+ }
72614
+
72598
72615
  initializeUserDefinedROISet() {
72599
72616
 
72600
72617
  const config =
@@ -72610,15 +72627,8 @@ class ROIManager {
72610
72627
  }
72611
72628
 
72612
72629
  async deleteRegionWithKey(regionKey, columnContainer) {
72613
-
72614
72630
  columnContainer.querySelectorAll(createSelector(regionKey)).forEach(node => node.remove());
72615
72631
 
72616
- const {feature, set} = await this.findRegionWithKey(regionKey);
72617
-
72618
- if (set) {
72619
- set.removeFeature(feature);
72620
- }
72621
-
72622
72632
  const records = await this.getTableRecords();
72623
72633
 
72624
72634
  if (0 === records.length) {
@@ -72628,23 +72638,6 @@ class ROIManager {
72628
72638
 
72629
72639
  }
72630
72640
 
72631
- async findRegionWithKey(regionKey) {
72632
-
72633
- const {chr, start, end} = parseRegionKey(regionKey);
72634
-
72635
- for (let set of this.roiSets) {
72636
- const features = await set.getFeatures(chr, start, end);
72637
-
72638
- for (let feature of features) {
72639
- if (feature.chr === chr && feature.start >= start && feature.end <= end) {
72640
- return {feature, set}
72641
- }
72642
- }
72643
- }
72644
-
72645
- return {feature: undefined, set: undefined}
72646
- }
72647
-
72648
72641
  toJSON() {
72649
72642
  return this.roiSets.map(roiSet => roiSet.toJSON())
72650
72643
  }
@@ -74619,7 +74612,7 @@ class Browser {
74619
74612
  */
74620
74613
  async loadGenome(idOrConfig) {
74621
74614
 
74622
- if(idOrConfig.genarkAccession) {
74615
+ if (idOrConfig.genarkAccession) {
74623
74616
  idOrConfig.url = convertToHubURL(idOrConfig.genarkAccession);
74624
74617
  }
74625
74618
 
@@ -75915,7 +75908,7 @@ class Browser {
75915
75908
 
75916
75909
  if (dragObject && dragObject.viewport.referenceFrame.start !== dragObject.start) {
75917
75910
  this.updateViews();
75918
- this.fireEvent('trackdragend');
75911
+ this.fireEvent('trackdragend', [dragObject.viewport]);
75919
75912
  }
75920
75913
  }
75921
75914