igv 3.0.1 → 3.0.2
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 +10 -10
- package/dist/igv.esm.js +220 -179
- package/dist/igv.esm.min.js +9 -9
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +220 -179
- package/dist/igv.min.js +9 -9
- package/dist/igv.min.js.map +1 -1
- package/package.json +1 -1
package/dist/igv.esm.js
CHANGED
|
@@ -19015,13 +19015,13 @@ class DataRangeDialog {
|
|
|
19015
19015
|
if (Array.isArray(trackViewOrTrackViewList)) {
|
|
19016
19016
|
dataRange = { min: Number.MAX_SAFE_INTEGER, max:-Number.MAX_SAFE_INTEGER };
|
|
19017
19017
|
for (const trackView of trackViewOrTrackViewList) {
|
|
19018
|
-
if (trackView.dataRange) {
|
|
19019
|
-
dataRange.min = Math.min(trackView.dataRange.min, dataRange.min);
|
|
19020
|
-
dataRange.max = Math.max(trackView.dataRange.max, dataRange.max);
|
|
19018
|
+
if (trackView.track.dataRange) {
|
|
19019
|
+
dataRange.min = Math.min(trackView.track.dataRange.min, dataRange.min);
|
|
19020
|
+
dataRange.max = Math.max(trackView.track.dataRange.max, dataRange.max);
|
|
19021
19021
|
}
|
|
19022
19022
|
}
|
|
19023
19023
|
} else {
|
|
19024
|
-
dataRange = trackViewOrTrackViewList.dataRange;
|
|
19024
|
+
dataRange = trackViewOrTrackViewList.track.dataRange;
|
|
19025
19025
|
}
|
|
19026
19026
|
|
|
19027
19027
|
if (dataRange) {
|
|
@@ -19063,7 +19063,7 @@ class DataRangeDialog {
|
|
|
19063
19063
|
} else {
|
|
19064
19064
|
const list = Array.isArray(trackViewOfTrackViewList) ? trackViewOfTrackViewList : [ trackViewOfTrackViewList ];
|
|
19065
19065
|
for (const trackView of list) {
|
|
19066
|
-
trackView.
|
|
19066
|
+
trackView.track.setDataRange({ min, max });
|
|
19067
19067
|
}
|
|
19068
19068
|
|
|
19069
19069
|
}
|
|
@@ -26696,6 +26696,14 @@ class TrackBase {
|
|
|
26696
26696
|
return menuItems
|
|
26697
26697
|
}
|
|
26698
26698
|
|
|
26699
|
+
setDataRange({ min, max }) {
|
|
26700
|
+
|
|
26701
|
+
this.dataRange = { min, max };
|
|
26702
|
+
this.autoscale = false;
|
|
26703
|
+
this.autoscaleGroup = undefined;
|
|
26704
|
+
this.trackView.repaintViews();
|
|
26705
|
+
}
|
|
26706
|
+
|
|
26699
26707
|
/**
|
|
26700
26708
|
* Return the first feature in this track whose start position is > position
|
|
26701
26709
|
* @param chr
|
|
@@ -27063,7 +27071,7 @@ class Variant {
|
|
|
27063
27071
|
this.filter = tokens[6];
|
|
27064
27072
|
this.info = {};
|
|
27065
27073
|
const infoStr = tokens[7];
|
|
27066
|
-
if (infoStr) {
|
|
27074
|
+
if (infoStr && infoStr !== '.') {
|
|
27067
27075
|
for (let elem of infoStr.split(';')) {
|
|
27068
27076
|
var element = elem.split('=');
|
|
27069
27077
|
this.info[element[0]] = element[1];
|
|
@@ -27222,9 +27230,10 @@ class Variant {
|
|
|
27222
27230
|
}
|
|
27223
27231
|
}
|
|
27224
27232
|
|
|
27225
|
-
|
|
27233
|
+
const infoKeys = Object.keys(this.info);
|
|
27234
|
+
if (this.info && infoKeys.length > 0) {
|
|
27226
27235
|
fields.push({html: '<hr style="border-top: dotted 1px;border-color: #c9c3ba" />'});
|
|
27227
|
-
for (let key of
|
|
27236
|
+
for (let key of infoKeys) {
|
|
27228
27237
|
fields.push({name: key, value: arrayToString(decodeURIComponent(this.info[key]))});
|
|
27229
27238
|
}
|
|
27230
27239
|
}
|
|
@@ -27291,7 +27300,7 @@ class SVComplement {
|
|
|
27291
27300
|
}
|
|
27292
27301
|
|
|
27293
27302
|
getAttributeValue(key) {
|
|
27294
|
-
|
|
27303
|
+
return this.mate.getAttributeValue(key)
|
|
27295
27304
|
}
|
|
27296
27305
|
|
|
27297
27306
|
getInfo(tag) {
|
|
@@ -27314,7 +27323,7 @@ class SVComplement {
|
|
|
27314
27323
|
popupData.push({name: 'Pos', value: `${numberFormatter$1(this.pos)}`});
|
|
27315
27324
|
popupData.push({html: '<hr style="border-top: dotted 1px;border-color: #c9c3ba" />'});
|
|
27316
27325
|
popupData.push("SV");
|
|
27317
|
-
popupData.push(...
|
|
27326
|
+
popupData.push(...this.mate.popupData(genomicLocation, genomeId));
|
|
27318
27327
|
|
|
27319
27328
|
return popupData
|
|
27320
27329
|
}
|
|
@@ -31210,7 +31219,7 @@ function overlaps(item, chrIdx1, startBase, chrIdx2, endBase) {
|
|
|
31210
31219
|
|
|
31211
31220
|
function getDecoder(definedFieldCount, fieldCount, autoSql, format) {
|
|
31212
31221
|
|
|
31213
|
-
if ("biginteract" === format || (autoSql && ('chromatinInteract' === autoSql.table
|
|
31222
|
+
if ("biginteract" === format || (autoSql && ('chromatinInteract' === autoSql.table || 'interact' === autoSql.table))) {
|
|
31214
31223
|
return decodeInteract
|
|
31215
31224
|
} else {
|
|
31216
31225
|
const standardFieldCount = definedFieldCount - 3;
|
|
@@ -34416,7 +34425,7 @@ class FeatureTrack extends TrackBase {
|
|
|
34416
34425
|
}
|
|
34417
34426
|
|
|
34418
34427
|
|
|
34419
|
-
if (!this.
|
|
34428
|
+
if (!this.isMergedTrack) {
|
|
34420
34429
|
IGVGraphics.fillRect(context, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
|
34421
34430
|
}
|
|
34422
34431
|
|
|
@@ -41605,39 +41614,36 @@ function paintAxis(ctx, width, height, colorOrUndefined) {
|
|
|
41605
41614
|
* THE SOFTWARE.
|
|
41606
41615
|
*/
|
|
41607
41616
|
|
|
41608
|
-
|
|
41609
41617
|
/**
|
|
41610
|
-
* Represents 2 or more
|
|
41618
|
+
* Represents 2 or more tracks overlaid on a common viewport.
|
|
41611
41619
|
*/
|
|
41612
41620
|
class MergedTrack extends TrackBase {
|
|
41613
41621
|
|
|
41614
41622
|
static defaults = {
|
|
41623
|
+
autoscale: undefined,
|
|
41615
41624
|
alpha: 0.5,
|
|
41616
41625
|
height: 50
|
|
41617
41626
|
}
|
|
41618
41627
|
|
|
41619
|
-
constructor(config, browser) {
|
|
41628
|
+
constructor(config, browser, tracks) {
|
|
41620
41629
|
super(config, browser);
|
|
41621
41630
|
this.type = "merged";
|
|
41622
|
-
this.featureType = "numeric";
|
|
41623
41631
|
this.paintAxis = paintAxis;
|
|
41624
41632
|
this.graphType = config.graphType;
|
|
41625
|
-
|
|
41626
|
-
|
|
41627
|
-
|
|
41628
|
-
|
|
41629
|
-
throw Error("Error: no tracks defined for merged track" + config)
|
|
41633
|
+
if (tracks) {
|
|
41634
|
+
this.tracks = tracks; // Dynamic creation, actual track objects (not configurations)
|
|
41635
|
+
} else {
|
|
41636
|
+
this.tracks = [];
|
|
41630
41637
|
}
|
|
41631
|
-
super.init(config);
|
|
41632
41638
|
}
|
|
41633
41639
|
|
|
41640
|
+
|
|
41634
41641
|
async postInit() {
|
|
41635
41642
|
|
|
41636
|
-
this.tracks = [];
|
|
41637
41643
|
if (this.config.tracks) {
|
|
41638
|
-
//
|
|
41644
|
+
// Track configurations, this indicates a configured merged track as opposed to dynamic merge through the UI
|
|
41645
|
+
// Actual track objects need to be created.
|
|
41639
41646
|
for (let tconf of this.config.tracks) {
|
|
41640
|
-
tconf.isMergedTrack = true;
|
|
41641
41647
|
const t = await this.browser.createTrack(tconf);
|
|
41642
41648
|
if (t) {
|
|
41643
41649
|
this.tracks.push(t);
|
|
@@ -41648,24 +41654,27 @@ class MergedTrack extends TrackBase {
|
|
|
41648
41654
|
await t.postInit();
|
|
41649
41655
|
}
|
|
41650
41656
|
}
|
|
41651
|
-
//
|
|
41652
|
-
|
|
41653
|
-
|
|
41654
|
-
|
|
41655
|
-
this.dataRange = {
|
|
41656
|
-
min: this.config.min || 0,
|
|
41657
|
-
max: this.config.max
|
|
41658
|
-
};
|
|
41659
|
-
} else {
|
|
41660
|
-
this.autoscale = !this.tracks.every(t => t.config.autoscale || t.config.max !== undefined);
|
|
41657
|
+
// Default to autoscale unless scale if range or autoscale is not otherwise defined
|
|
41658
|
+
const allTracksSpecified = this.config.tracks.every(config => config.autoscale !== undefined || config.max !== undefined);
|
|
41659
|
+
if (!allTracksSpecified) {
|
|
41660
|
+
this.config.autoscale = this.config.max === undefined;
|
|
41661
41661
|
}
|
|
41662
|
-
} else {
|
|
41663
|
-
// Dynamic merged track
|
|
41664
|
-
this.tracks = this.config._tracks;
|
|
41665
|
-
this.autoscale = false;
|
|
41666
|
-
delete this.config._tracks;
|
|
41667
41662
|
}
|
|
41668
41663
|
|
|
41664
|
+
// Mark constitutive tracks as merged.
|
|
41665
|
+
for (let t of this.tracks) t.isMergedTrack = true;
|
|
41666
|
+
|
|
41667
|
+
// Explicit settings -- these will override any individual track settings
|
|
41668
|
+
if(this.config.autoscale) {
|
|
41669
|
+
this.autoscale = this.config.autoscale;
|
|
41670
|
+
} else if (this.config.max !== undefined) {
|
|
41671
|
+
this.setDataRange ({
|
|
41672
|
+
min: this.config.min || 0,
|
|
41673
|
+
max: this.config.max
|
|
41674
|
+
});
|
|
41675
|
+
}
|
|
41676
|
+
|
|
41677
|
+
|
|
41669
41678
|
if (this.config.flipAxis !== undefined) {
|
|
41670
41679
|
for (let t of this.tracks) t.flipAxis = this.config.flipAxis;
|
|
41671
41680
|
}
|
|
@@ -41675,25 +41684,28 @@ class MergedTrack extends TrackBase {
|
|
|
41675
41684
|
}
|
|
41676
41685
|
|
|
41677
41686
|
this.resolutionAware = this.tracks.some(t => t.resolutionAware);
|
|
41678
|
-
|
|
41679
41687
|
}
|
|
41680
41688
|
|
|
41681
41689
|
set flipAxis(b) {
|
|
41682
41690
|
this.config.flipAxis = b;
|
|
41683
|
-
for (let t of this.tracks)
|
|
41691
|
+
for (let t of numericTracks(this.tracks)) {
|
|
41692
|
+
t.flipAxis = b;
|
|
41693
|
+
}
|
|
41684
41694
|
}
|
|
41685
41695
|
|
|
41686
41696
|
get flipAxis() {
|
|
41687
|
-
return this.tracks.every(t => t.flipAxis)
|
|
41697
|
+
return numericTracks(this.tracks).every(t => t.flipAxis)
|
|
41688
41698
|
}
|
|
41689
41699
|
|
|
41690
41700
|
set logScale(b) {
|
|
41691
41701
|
this.config.logScale = b;
|
|
41692
|
-
for (let t of this.tracks)
|
|
41702
|
+
for (let t of numericTracks(this.tracks)) {
|
|
41703
|
+
t.logScale = b;
|
|
41704
|
+
}
|
|
41693
41705
|
}
|
|
41694
41706
|
|
|
41695
41707
|
get logScale() {
|
|
41696
|
-
return this.tracks.every(t => t.logScale)
|
|
41708
|
+
return numericTracks(this.tracks).every(t => t.logScale)
|
|
41697
41709
|
}
|
|
41698
41710
|
|
|
41699
41711
|
get height() {
|
|
@@ -41711,49 +41723,76 @@ class MergedTrack extends TrackBase {
|
|
|
41711
41723
|
}
|
|
41712
41724
|
}
|
|
41713
41725
|
|
|
41714
|
-
|
|
41715
|
-
|
|
41716
|
-
if
|
|
41717
|
-
|
|
41726
|
+
set autoscale(b) {
|
|
41727
|
+
this._autoscale = b;
|
|
41728
|
+
if(b === false && this.tracks) {
|
|
41729
|
+
for(let t of this.tracks) t.autoscale = false;
|
|
41718
41730
|
}
|
|
41731
|
+
}
|
|
41719
41732
|
|
|
41720
|
-
|
|
41721
|
-
|
|
41722
|
-
|
|
41723
|
-
}
|
|
41733
|
+
get autoscale() {
|
|
41734
|
+
return this._autoscale
|
|
41735
|
+
}
|
|
41724
41736
|
|
|
41725
|
-
|
|
41726
|
-
|
|
41727
|
-
|
|
41728
|
-
|
|
41737
|
+
/**
|
|
41738
|
+
* Set the data range of all constitutive numeric tracks. This method is called from the menu item, i.e. an explicit
|
|
41739
|
+
* setting, so it should disable autoscale as well.
|
|
41740
|
+
*
|
|
41741
|
+
* @param min
|
|
41742
|
+
* @param max
|
|
41743
|
+
*/
|
|
41729
41744
|
|
|
41730
|
-
|
|
41731
|
-
|
|
41732
|
-
|
|
41745
|
+
setDataRange({min, max}) {
|
|
41746
|
+
this.autoscale = false;
|
|
41747
|
+
for (const track of numericTracks(this.tracks)) {
|
|
41748
|
+
track.dataRange = {min, max};
|
|
41749
|
+
track.autoscale = false;
|
|
41750
|
+
track.autoscaleGroup = false;
|
|
41733
41751
|
}
|
|
41752
|
+
}
|
|
41734
41753
|
|
|
41735
|
-
|
|
41754
|
+
set dataRange({min, max}) {
|
|
41755
|
+
for (const track of numericTracks(this.tracks)) {
|
|
41756
|
+
track.dataRange = {min, max};
|
|
41757
|
+
}
|
|
41736
41758
|
}
|
|
41737
41759
|
|
|
41738
|
-
|
|
41739
|
-
|
|
41740
|
-
|
|
41760
|
+
/**
|
|
41761
|
+
* Return a DataRang {min, max} if all constitutive numeric tracks have identical range. A numeric track is defined
|
|
41762
|
+
* as a track with a data range. Otherwise return undefined.
|
|
41763
|
+
*
|
|
41764
|
+
* @returns {{min: any, max: any}|undefined}
|
|
41765
|
+
*/
|
|
41766
|
+
get dataRange() {
|
|
41767
|
+
if(this.tracks) {
|
|
41768
|
+
const num = numericTracks(this.tracks);
|
|
41769
|
+
if (num.length > 0) {
|
|
41770
|
+
const firstRange = num[0].dataRange;
|
|
41771
|
+
if (num.every(t => t.dataRange && t.dataRange.min === firstRange.min && t.dataRange.max === firstRange.max)) {
|
|
41772
|
+
return firstRange
|
|
41773
|
+
}
|
|
41774
|
+
}
|
|
41741
41775
|
}
|
|
41776
|
+
return undefined
|
|
41742
41777
|
}
|
|
41743
41778
|
|
|
41779
|
+
|
|
41744
41780
|
menuItemList() {
|
|
41745
41781
|
const items = [];
|
|
41746
|
-
if (this.
|
|
41747
|
-
items.push({
|
|
41748
|
-
label: "Flip y-axis",
|
|
41749
|
-
click: function flipYAxisHandler() {
|
|
41750
|
-
this.flipAxis = !this.flipAxis;
|
|
41751
|
-
this.trackView.repaintViews();
|
|
41752
|
-
}
|
|
41753
|
-
});
|
|
41754
|
-
}
|
|
41782
|
+
if (numericTracks(this.tracks).length > 0) {
|
|
41755
41783
|
|
|
41756
|
-
|
|
41784
|
+
if (this.flipAxis !== undefined) {
|
|
41785
|
+
items.push({
|
|
41786
|
+
label: "Flip y-axis",
|
|
41787
|
+
click: function flipYAxisHandler() {
|
|
41788
|
+
this.flipAxis = !this.flipAxis;
|
|
41789
|
+
this.trackView.repaintViews();
|
|
41790
|
+
}
|
|
41791
|
+
});
|
|
41792
|
+
}
|
|
41793
|
+
|
|
41794
|
+
items.push(...this.numericDataMenuItems());
|
|
41795
|
+
}
|
|
41757
41796
|
|
|
41758
41797
|
items.push('<hr/>');
|
|
41759
41798
|
items.push(this.overlayTrackAlphaAdjustmentMenuItem());
|
|
@@ -41770,7 +41809,14 @@ class MergedTrack extends TrackBase {
|
|
|
41770
41809
|
|
|
41771
41810
|
const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel));
|
|
41772
41811
|
const featureArrays = await Promise.all(promises);
|
|
41773
|
-
|
|
41812
|
+
|
|
41813
|
+
if (featureArrays.every((arr) => arr.length === 0)){
|
|
41814
|
+
return new MergedFeatureCollection([], [])
|
|
41815
|
+
}
|
|
41816
|
+
else {
|
|
41817
|
+
const trackNames = this.tracks.map((t) => t.name);
|
|
41818
|
+
return new MergedFeatureCollection(featureArrays, trackNames)
|
|
41819
|
+
}
|
|
41774
41820
|
}
|
|
41775
41821
|
|
|
41776
41822
|
draw(options) {
|
|
@@ -41782,11 +41828,6 @@ class MergedTrack extends TrackBase {
|
|
|
41782
41828
|
trackOptions.features = mergedFeatures.featureArrays[i];
|
|
41783
41829
|
trackOptions.alpha = this.alpha;
|
|
41784
41830
|
|
|
41785
|
-
if (this.dataRange) {
|
|
41786
|
-
// Single data scale for all tracks
|
|
41787
|
-
this.tracks[i].dataRange = this.dataRange;
|
|
41788
|
-
}
|
|
41789
|
-
|
|
41790
41831
|
if (this.graphType) {
|
|
41791
41832
|
this.tracks[i].graphType = this.graphType;
|
|
41792
41833
|
}
|
|
@@ -41880,6 +41921,7 @@ class MergedTrack extends TrackBase {
|
|
|
41880
41921
|
let scaleChange;
|
|
41881
41922
|
|
|
41882
41923
|
if (this.autoscale) {
|
|
41924
|
+
// Overrides any specific track scale settings
|
|
41883
41925
|
scaleChange = true;
|
|
41884
41926
|
let allFeatures = [];
|
|
41885
41927
|
for (let visibleViewport of visibleViewports) {
|
|
@@ -41894,7 +41936,12 @@ class MergedTrack extends TrackBase {
|
|
|
41894
41936
|
allFeatures.push({value: mergedFeatureCollection.getMin(start, end)});
|
|
41895
41937
|
}
|
|
41896
41938
|
}
|
|
41897
|
-
|
|
41939
|
+
const dataRange = doAutoscale(allFeatures);
|
|
41940
|
+
for (const track of numericTracks(this.tracks)) {
|
|
41941
|
+
// Do not use this.dataRange, as that has side effects
|
|
41942
|
+
track.dataRange = dataRange;
|
|
41943
|
+
}
|
|
41944
|
+
|
|
41898
41945
|
}
|
|
41899
41946
|
} else {
|
|
41900
41947
|
// Individual track scaling
|
|
@@ -41974,6 +42021,7 @@ class MergedTrack extends TrackBase {
|
|
|
41974
42021
|
if (groupAutoscale) {
|
|
41975
42022
|
track.autoscaleGroup = name;
|
|
41976
42023
|
}
|
|
42024
|
+
track.isMergedTrack = false;
|
|
41977
42025
|
browser.addTrack(track.config, track);
|
|
41978
42026
|
}
|
|
41979
42027
|
browser.updateViews();
|
|
@@ -41987,25 +42035,30 @@ class MergedTrack extends TrackBase {
|
|
|
41987
42035
|
|
|
41988
42036
|
class MergedFeatureCollection {
|
|
41989
42037
|
|
|
41990
|
-
constructor(featureArrays) {
|
|
42038
|
+
constructor(featureArrays,trackNames) {
|
|
41991
42039
|
this.featureArrays = featureArrays;
|
|
42040
|
+
//trackNames is needed for the popup data to populate track names
|
|
42041
|
+
//preserving the order of the actual tracks
|
|
42042
|
+
this.trackNames = trackNames;
|
|
41992
42043
|
}
|
|
41993
42044
|
|
|
41994
42045
|
getMax(start, end) {
|
|
41995
42046
|
let max = -Number.MAX_VALUE;
|
|
41996
42047
|
|
|
41997
42048
|
for (let a of this.featureArrays) {
|
|
41998
|
-
|
|
41999
|
-
|
|
42000
|
-
|
|
42001
|
-
|
|
42002
|
-
|
|
42003
|
-
|
|
42004
|
-
|
|
42005
|
-
|
|
42006
|
-
|
|
42049
|
+
if (Array.isArray(a)) {
|
|
42050
|
+
for (let f of a) {
|
|
42051
|
+
if (typeof f.value === 'undefined' || Number.isNaN(f.value)) {
|
|
42052
|
+
continue
|
|
42053
|
+
}
|
|
42054
|
+
if (f.end < start) {
|
|
42055
|
+
continue
|
|
42056
|
+
}
|
|
42057
|
+
if (f.start > end) {
|
|
42058
|
+
break
|
|
42059
|
+
}
|
|
42060
|
+
max = Math.max(max, f.value);
|
|
42007
42061
|
}
|
|
42008
|
-
max = Math.max(max, f.value);
|
|
42009
42062
|
}
|
|
42010
42063
|
}
|
|
42011
42064
|
|
|
@@ -42016,15 +42069,17 @@ class MergedFeatureCollection {
|
|
|
42016
42069
|
getMin(start, end) {
|
|
42017
42070
|
let min = 0;
|
|
42018
42071
|
for (let a of this.featureArrays) {
|
|
42019
|
-
|
|
42020
|
-
|
|
42021
|
-
if (f.
|
|
42022
|
-
|
|
42023
|
-
|
|
42024
|
-
|
|
42025
|
-
|
|
42072
|
+
if (Array.isArray(a)) {
|
|
42073
|
+
for (let f of a) {
|
|
42074
|
+
if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {
|
|
42075
|
+
if (f.end < start) {
|
|
42076
|
+
continue
|
|
42077
|
+
}
|
|
42078
|
+
if (f.start > end) {
|
|
42079
|
+
break
|
|
42080
|
+
}
|
|
42081
|
+
min = Math.min(min, f.value);
|
|
42026
42082
|
}
|
|
42027
|
-
min = Math.min(min, f.value);
|
|
42028
42083
|
}
|
|
42029
42084
|
}
|
|
42030
42085
|
}
|
|
@@ -42032,6 +42087,16 @@ class MergedFeatureCollection {
|
|
|
42032
42087
|
}
|
|
42033
42088
|
}
|
|
42034
42089
|
|
|
42090
|
+
/**
|
|
42091
|
+
* Heuristic for finding numeric tracks.
|
|
42092
|
+
*
|
|
42093
|
+
* @param tracks
|
|
42094
|
+
* @returns {*}
|
|
42095
|
+
*/
|
|
42096
|
+
const numericTracks = (tracks) => {
|
|
42097
|
+
return tracks ? tracks.filter(track => undefined !== track.dataRange || undefined !== track.autoscale || undefined !== track.autoscaleGroup) : []
|
|
42098
|
+
};
|
|
42099
|
+
|
|
42035
42100
|
class OverlayTrackButton extends NavbarButton {
|
|
42036
42101
|
constructor(browser, parent) {
|
|
42037
42102
|
|
|
@@ -42077,13 +42142,13 @@ function trackOverlayClickHandler(e) {
|
|
|
42077
42142
|
{
|
|
42078
42143
|
name: 'Overlay',
|
|
42079
42144
|
type: 'merged',
|
|
42145
|
+
autoscale: false,
|
|
42080
42146
|
alpha: 0.5, //fudge * (1.0/tracks.length),
|
|
42081
42147
|
height: Math.max(...tracks.map(({ height }) => height)),
|
|
42082
42148
|
order: Math.min(...tracks.map(({ order }) => order)),
|
|
42083
|
-
_tracks: flattenedTracks
|
|
42084
42149
|
};
|
|
42085
42150
|
|
|
42086
|
-
const mergedTrack = new MergedTrack(config, this.browser);
|
|
42151
|
+
const mergedTrack = new MergedTrack(config, this.browser, flattenedTracks);
|
|
42087
42152
|
|
|
42088
42153
|
for (const track of tracks) {
|
|
42089
42154
|
this.browser.removeTrack(track);
|
|
@@ -42303,27 +42368,6 @@ class TrackView {
|
|
|
42303
42368
|
}
|
|
42304
42369
|
}
|
|
42305
42370
|
|
|
42306
|
-
get dataRange() {
|
|
42307
|
-
return this.track.dataRange ? this.track.dataRange : undefined
|
|
42308
|
-
}
|
|
42309
|
-
|
|
42310
|
-
set dataRange({ min, max }) {
|
|
42311
|
-
|
|
42312
|
-
this.track.dataRange = { min, max };
|
|
42313
|
-
|
|
42314
|
-
this.track.autoscale = false;
|
|
42315
|
-
this.track.autoscaleGroup = undefined;
|
|
42316
|
-
|
|
42317
|
-
const list = this.browser.trackViews.filter(({track}) => track.autoscaleGroup);
|
|
42318
|
-
if (1 === list.length) {
|
|
42319
|
-
list[0].track.autoscale = false;
|
|
42320
|
-
list[0].track.autoscaleGroup = undefined;
|
|
42321
|
-
list[0].repaintViews();
|
|
42322
|
-
}
|
|
42323
|
-
|
|
42324
|
-
this.repaintViews();
|
|
42325
|
-
|
|
42326
|
-
}
|
|
42327
42371
|
|
|
42328
42372
|
presentColorPicker(key) {
|
|
42329
42373
|
|
|
@@ -49772,46 +49816,41 @@ const BamUtils = {
|
|
|
49772
49816
|
},
|
|
49773
49817
|
|
|
49774
49818
|
/**
|
|
49819
|
+
* @param ba - UInt8Array bytes to decode
|
|
49775
49820
|
*
|
|
49776
|
-
* @
|
|
49777
|
-
* @param genome optional igv genome object
|
|
49778
|
-
* @returns {{ magicNumer: number, size: number, chrNames: Array, chrToIndex: ({}|*), chrAliasTable: ({}|*) }}
|
|
49821
|
+
* @returns {{size: *, chrNames: *[], magicNumber: *, chrToIndex: {}}}
|
|
49779
49822
|
*/
|
|
49780
|
-
decodeBamHeader: function (ba
|
|
49823
|
+
decodeBamHeader: function (ba) {
|
|
49781
49824
|
|
|
49782
|
-
var magic, samHeaderLen, samHeader, chrToIndex, chrNames;
|
|
49783
49825
|
|
|
49784
|
-
magic = readInt(ba, 0);
|
|
49826
|
+
const magic = readInt(ba, 0);
|
|
49785
49827
|
if (magic !== BAM1_MAGIC_NUMBER) {
|
|
49786
49828
|
throw new Error('BAM header errror: bad magic number. This could be caused by either a corrupt or missing file.')
|
|
49787
49829
|
}
|
|
49788
49830
|
|
|
49789
|
-
samHeaderLen = readInt(ba, 4);
|
|
49790
|
-
samHeader = '';
|
|
49791
|
-
|
|
49831
|
+
const samHeaderLen = readInt(ba, 4);
|
|
49832
|
+
let samHeader = '';
|
|
49792
49833
|
for (var i = 0; i < samHeaderLen; ++i) {
|
|
49793
49834
|
samHeader += String.fromCharCode(ba[i + 8]);
|
|
49794
49835
|
}
|
|
49795
49836
|
|
|
49796
|
-
|
|
49797
|
-
|
|
49837
|
+
const nRef = readInt(ba, samHeaderLen + 8);
|
|
49838
|
+
let p = samHeaderLen + 12;
|
|
49798
49839
|
|
|
49799
|
-
chrToIndex = {};
|
|
49800
|
-
chrNames = [];
|
|
49840
|
+
const chrToIndex = {};
|
|
49841
|
+
const chrNames = [];
|
|
49801
49842
|
|
|
49802
49843
|
for (i = 0; i < nRef; ++i) {
|
|
49803
|
-
|
|
49804
|
-
|
|
49805
|
-
for (var j = 0; j <
|
|
49844
|
+
const len = readInt(ba, p);
|
|
49845
|
+
let name = '';
|
|
49846
|
+
for (var j = 0; j < len - 1; ++j) {
|
|
49806
49847
|
name += String.fromCharCode(ba[p + 4 + j]);
|
|
49807
49848
|
}
|
|
49808
|
-
readInt(ba, p + lName + 4);
|
|
49809
|
-
//dlog(name + ': ' + lRef);
|
|
49810
49849
|
|
|
49811
49850
|
chrToIndex[name] = i;
|
|
49812
49851
|
chrNames[i] = name;
|
|
49813
49852
|
|
|
49814
|
-
p = p + 8 +
|
|
49853
|
+
p = p + 8 + len;
|
|
49815
49854
|
}
|
|
49816
49855
|
|
|
49817
49856
|
return {
|
|
@@ -50801,8 +50840,8 @@ class HtsgetBamReader extends HtsgetReader {
|
|
|
50801
50840
|
const ba = unbgzf(compressedData.buffer);
|
|
50802
50841
|
this.header = BamUtils.decodeBamHeader(ba, this.genome);
|
|
50803
50842
|
this.chrAliasTable = new Map();
|
|
50804
|
-
for (let
|
|
50805
|
-
this.chrAliasTable.set(
|
|
50843
|
+
for (let name of this.header.chrNames) {
|
|
50844
|
+
this.chrAliasTable.set(name, this.genome.getChromosomeName(name));
|
|
50806
50845
|
}
|
|
50807
50846
|
}
|
|
50808
50847
|
|
|
@@ -50812,6 +50851,7 @@ class HtsgetBamReader extends HtsgetReader {
|
|
|
50812
50851
|
|
|
50813
50852
|
// BAM decoding
|
|
50814
50853
|
const ba = unbgzf(compressedData.buffer);
|
|
50854
|
+
this.header = BamUtils.decodeBamHeader(ba, this.genome);
|
|
50815
50855
|
|
|
50816
50856
|
const chrIdx = this.header.chrToIndex[chr];
|
|
50817
50857
|
const alignmentContainer = new AlignmentContainer(chr, start, end, this.config);
|
|
@@ -57656,6 +57696,7 @@ class CoverageTrack {
|
|
|
57656
57696
|
|
|
57657
57697
|
|
|
57658
57698
|
constructor(config, parent) {
|
|
57699
|
+
this.featureType = 'numeric';
|
|
57659
57700
|
this.parent = parent;
|
|
57660
57701
|
this.featureSource = parent.featureSource;
|
|
57661
57702
|
|
|
@@ -66134,12 +66175,12 @@ class CNVPytorTrack extends TrackBase {
|
|
|
66134
66175
|
if (this.signals.includes(signal_name)) {
|
|
66135
66176
|
let tconf = {};
|
|
66136
66177
|
tconf.type = "wig";
|
|
66137
|
-
tconf.isMergedTrack = true;
|
|
66138
66178
|
tconf.features = wig;
|
|
66139
66179
|
tconf.name = signal_name;
|
|
66140
66180
|
tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color);
|
|
66141
66181
|
const t = await this.browser.createTrack(tconf);
|
|
66142
66182
|
if (t) {
|
|
66183
|
+
t.isMergedTrack = true;
|
|
66143
66184
|
t.autoscale = false; // Scaling done from merged track
|
|
66144
66185
|
this.tracks.push(t);
|
|
66145
66186
|
} else {
|
|
@@ -66318,12 +66359,12 @@ class CNVPytorTrack extends TrackBase {
|
|
|
66318
66359
|
if (this.signals.includes(signal_name)) {
|
|
66319
66360
|
let tconf = {};
|
|
66320
66361
|
tconf.type = "wig";
|
|
66321
|
-
tconf.isMergedTrack = true;
|
|
66322
66362
|
tconf.features = wig;
|
|
66323
66363
|
tconf.name = signal_name;
|
|
66324
66364
|
tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color);
|
|
66325
66365
|
const t = await this.browser.createTrack(tconf);
|
|
66326
66366
|
if (t) {
|
|
66367
|
+
t.isMergedTrack = true;
|
|
66327
66368
|
t.autoscale = false; // Scaling done from merged track
|
|
66328
66369
|
this.tracks.push(t);
|
|
66329
66370
|
} else {
|
|
@@ -66716,23 +66757,26 @@ class VariantTrack extends TrackBase {
|
|
|
66716
66757
|
this.header = await this.getHeader();
|
|
66717
66758
|
|
|
66718
66759
|
// Set colorBy, if not explicitly set default to allele frequency, if available, otherwise default to none (undefined)
|
|
66719
|
-
|
|
66720
|
-
|
|
66721
|
-
|
|
66722
|
-
|
|
66723
|
-
this.
|
|
66724
|
-
|
|
66760
|
+
if(this.header.INFO) {
|
|
66761
|
+
const infoFields = new Set(Object.keys(this.header.INFO));
|
|
66762
|
+
if (this.config.colorBy) {
|
|
66763
|
+
this.colorBy = this.config.colorBy;
|
|
66764
|
+
} else if (!this.config.color && infoFields.has('AF')) {
|
|
66765
|
+
this.colorBy = 'AF';
|
|
66766
|
+
}
|
|
66725
66767
|
|
|
66726
|
-
|
|
66727
|
-
|
|
66728
|
-
|
|
66729
|
-
|
|
66730
|
-
|
|
66731
|
-
|
|
66732
|
-
|
|
66733
|
-
|
|
66734
|
-
|
|
66768
|
+
// Configure menu items based on info available
|
|
66769
|
+
if (infoFields.has('AF')) {
|
|
66770
|
+
this._colorByItems.set('AF', 'Allele frequency');
|
|
66771
|
+
}
|
|
66772
|
+
if (infoFields.has('VT')) {
|
|
66773
|
+
this._colorByItems.set('VT', 'Variant Type');
|
|
66774
|
+
}
|
|
66775
|
+
if (infoFields.has('SVTYPE')) {
|
|
66776
|
+
this._colorByItems.set('SVTYPE', 'SV Type');
|
|
66777
|
+
}
|
|
66735
66778
|
}
|
|
66779
|
+
|
|
66736
66780
|
if (this.config.colorBy && !this._colorByItems.has(this.config.colorBy)) {
|
|
66737
66781
|
this._colorByItems.set(this.config.colorBy, this.config.colorBy);
|
|
66738
66782
|
}
|
|
@@ -69577,11 +69621,15 @@ someMotifValues.forEach(motif => {
|
|
|
69577
69621
|
JUNCTION_MOTIF_PALETTE.getColor(motif);
|
|
69578
69622
|
});
|
|
69579
69623
|
|
|
69580
|
-
// rendering context with values that only need to be computed once per render, rather than for each splice junction
|
|
69581
|
-
const junctionRenderingContext = {};
|
|
69582
69624
|
|
|
69583
69625
|
class SpliceJunctionTrack extends TrackBase {
|
|
69584
69626
|
|
|
69627
|
+
static defaults = {
|
|
69628
|
+
margin: 10,
|
|
69629
|
+
colorByNumReadsThreshold: 5,
|
|
69630
|
+
height: 100
|
|
69631
|
+
}
|
|
69632
|
+
|
|
69585
69633
|
constructor(config, browser) {
|
|
69586
69634
|
super(config, browser);
|
|
69587
69635
|
}
|
|
@@ -69602,16 +69650,6 @@ class SpliceJunctionTrack extends TrackBase {
|
|
|
69602
69650
|
FeatureSource(config, this.browser.genome);
|
|
69603
69651
|
}
|
|
69604
69652
|
|
|
69605
|
-
this.margin = config.margin === undefined ? 10 : config.margin;
|
|
69606
|
-
|
|
69607
|
-
if (!this.height) {
|
|
69608
|
-
this.height = 100;
|
|
69609
|
-
}
|
|
69610
|
-
|
|
69611
|
-
//set defaults
|
|
69612
|
-
if (config.colorByNumReadsThreshold === undefined) {
|
|
69613
|
-
config.colorByNumReadsThreshold = 5;
|
|
69614
|
-
}
|
|
69615
69653
|
}
|
|
69616
69654
|
|
|
69617
69655
|
async postInit() {
|
|
@@ -69666,13 +69704,16 @@ class SpliceJunctionTrack extends TrackBase {
|
|
|
69666
69704
|
const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
|
|
69667
69705
|
|
|
69668
69706
|
|
|
69669
|
-
if (!this.
|
|
69707
|
+
if (!this.isMergedTrack) {
|
|
69670
69708
|
IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
|
69671
69709
|
}
|
|
69672
69710
|
|
|
69673
69711
|
if (featureList) {
|
|
69674
69712
|
|
|
69675
69713
|
|
|
69714
|
+
// rendering context with values that only need to be computed once per render, rather than for each splice junction
|
|
69715
|
+
const junctionRenderingContext = {};
|
|
69716
|
+
|
|
69676
69717
|
junctionRenderingContext.referenceFrame = options.viewport.referenceFrame;
|
|
69677
69718
|
junctionRenderingContext.referenceFrameStart = junctionRenderingContext.referenceFrame.start;
|
|
69678
69719
|
junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart +
|
|
@@ -69685,7 +69726,7 @@ class SpliceJunctionTrack extends TrackBase {
|
|
|
69685
69726
|
for (let feature of featureList) {
|
|
69686
69727
|
if (feature.end < bpStart) continue
|
|
69687
69728
|
if (feature.start > bpEnd) break
|
|
69688
|
-
this.renderJunction(feature, bpStart, bpPerPixel, pixelHeight, ctx);
|
|
69729
|
+
this.renderJunction(feature, bpStart, bpPerPixel, pixelHeight, ctx, junctionRenderingContext);
|
|
69689
69730
|
}
|
|
69690
69731
|
|
|
69691
69732
|
} else {
|
|
@@ -69702,7 +69743,7 @@ class SpliceJunctionTrack extends TrackBase {
|
|
|
69702
69743
|
* @param pixelHeight pixel height of the current canvas
|
|
69703
69744
|
* @param ctx the canvas 2d context
|
|
69704
69745
|
*/
|
|
69705
|
-
renderJunction(feature, bpStart, xScale, pixelHeight, ctx) {
|
|
69746
|
+
renderJunction(feature, bpStart, xScale, pixelHeight, ctx, junctionRenderingContext) {
|
|
69706
69747
|
// cache whether this junction is rendered or filtered out. Use later to exclude non-rendered junctions from click detection.
|
|
69707
69748
|
feature.isVisible = false;
|
|
69708
69749
|
|
|
@@ -69786,7 +69827,7 @@ class SpliceJunctionTrack extends TrackBase {
|
|
|
69786
69827
|
}
|
|
69787
69828
|
|
|
69788
69829
|
const py = this.margin;
|
|
69789
|
-
const rowHeight =
|
|
69830
|
+
const rowHeight = pixelHeight;
|
|
69790
69831
|
|
|
69791
69832
|
const cy = py + 0.5 * rowHeight;
|
|
69792
69833
|
let topY = py;
|
|
@@ -70471,7 +70512,7 @@ function createReferenceFrameList(loci, genome, browserFlanking, minimumBases, v
|
|
|
70471
70512
|
})
|
|
70472
70513
|
}
|
|
70473
70514
|
|
|
70474
|
-
const _version = "3.0.
|
|
70515
|
+
const _version = "3.0.2";
|
|
70475
70516
|
function version() {
|
|
70476
70517
|
return _version
|
|
70477
70518
|
}
|
|
@@ -72922,7 +72963,7 @@ class ChromAliasBB {
|
|
|
72922
72963
|
}
|
|
72923
72964
|
|
|
72924
72965
|
/**
|
|
72925
|
-
* Return the canonical chromosome name for the alias. If none found return the alias.
|
|
72966
|
+
* Return the cached canonical chromosome name for the alias. If none found return the alias.
|
|
72926
72967
|
*
|
|
72927
72968
|
* Note this will only work if a "search" for ths chromosome has been performed previously.
|
|
72928
72969
|
*
|