igv 3.0.8 → 3.0.9
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 +1303 -777
- package/dist/igv.esm.min.js +10 -10
- package/dist/igv.esm.min.js.map +1 -1
- package/dist/igv.js +1303 -777
- package/dist/igv.min.js +10 -10
- package/dist/igv.min.js.map +1 -1
- package/package.json +1 -1
package/dist/igv.js
CHANGED
|
@@ -18599,7 +18599,7 @@
|
|
|
18599
18599
|
|
|
18600
18600
|
}
|
|
18601
18601
|
|
|
18602
|
-
const colorPickerTrackTypeSet = new Set(['bedtype', 'alignment', 'annotation', 'variant', 'wig', 'interact']);
|
|
18602
|
+
const colorPickerTrackTypeSet = new Set(['bedtype', 'alignment', 'annotation', 'variant', 'wig', 'interact', 'shoebox']);
|
|
18603
18603
|
|
|
18604
18604
|
const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'qtl', 'snp', 'shoebox', 'wig']);
|
|
18605
18605
|
|
|
@@ -20942,125 +20942,6 @@
|
|
|
20942
20942
|
}
|
|
20943
20943
|
var purify = createDOMPurify();
|
|
20944
20944
|
|
|
20945
|
-
class SliderDialog {
|
|
20946
|
-
|
|
20947
|
-
constructor(parent) {
|
|
20948
|
-
|
|
20949
|
-
this.parent = parent;
|
|
20950
|
-
|
|
20951
|
-
// dialog container
|
|
20952
|
-
this.container = div({class: 'igv-ui-generic-dialog-container'});
|
|
20953
|
-
parent.appendChild(this.container);
|
|
20954
|
-
|
|
20955
|
-
// dialog header
|
|
20956
|
-
const header = div({class: 'igv-ui-generic-dialog-header'});
|
|
20957
|
-
this.container.appendChild(header);
|
|
20958
|
-
|
|
20959
|
-
// dialog label
|
|
20960
|
-
this.label = div({class: 'igv-ui-generic-dialog-one-liner'});
|
|
20961
|
-
this.container.appendChild(this.label);
|
|
20962
|
-
this.label.text = 'Unlabeled';
|
|
20963
|
-
|
|
20964
|
-
// input container
|
|
20965
|
-
this.input_container = div({class: 'igv-ui-generic-dialog-input'});
|
|
20966
|
-
this.container.appendChild(this.input_container);
|
|
20967
|
-
|
|
20968
|
-
// input element
|
|
20969
|
-
let html = `<input type="range" id="igv-slider-dialog-input" name="igv-slider-dialog-input" />`;
|
|
20970
|
-
this._input = document.createRange().createContextualFragment(html).firstChild;
|
|
20971
|
-
this.input_container.appendChild(this._input);
|
|
20972
|
-
|
|
20973
|
-
// output element
|
|
20974
|
-
html = `<output id="igv-slider-dialog-output" name="igv-slider-dialog-output" for="igv-slider-dialog-input"></output>`;
|
|
20975
|
-
this._output = document.createRange().createContextualFragment(html).firstChild;
|
|
20976
|
-
this.input_container.appendChild(this._output);
|
|
20977
|
-
|
|
20978
|
-
|
|
20979
|
-
// ok | cancel
|
|
20980
|
-
const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'});
|
|
20981
|
-
this.container.appendChild(buttons);
|
|
20982
|
-
|
|
20983
|
-
// ok
|
|
20984
|
-
this.ok = div();
|
|
20985
|
-
buttons.appendChild(this.ok);
|
|
20986
|
-
this.ok.textContent = 'OK';
|
|
20987
|
-
|
|
20988
|
-
// cancel
|
|
20989
|
-
this.cancel = div();
|
|
20990
|
-
buttons.appendChild(this.cancel);
|
|
20991
|
-
this.cancel.textContent = 'Cancel';
|
|
20992
|
-
|
|
20993
|
-
hide(this.container);
|
|
20994
|
-
|
|
20995
|
-
this._input.addEventListener('input', () => {
|
|
20996
|
-
const number = parseFloat(this._input.value)/this._scaleFactor;
|
|
20997
|
-
this.callback(number);
|
|
20998
|
-
this._output.value = `${number.toFixed(2)}`;
|
|
20999
|
-
}, false);
|
|
21000
|
-
|
|
21001
|
-
this.ok.addEventListener('click', () => {
|
|
21002
|
-
if (typeof this.callback === 'function') {
|
|
21003
|
-
const number = parseFloat(this._input.value)/this._scaleFactor;
|
|
21004
|
-
this.callback(number);
|
|
21005
|
-
this.callback = undefined;
|
|
21006
|
-
}
|
|
21007
|
-
this._input.value = undefined;
|
|
21008
|
-
hide(this.container);
|
|
21009
|
-
});
|
|
21010
|
-
|
|
21011
|
-
const cancel = () => {
|
|
21012
|
-
this._input.value = undefined;
|
|
21013
|
-
hide(this.container);
|
|
21014
|
-
};
|
|
21015
|
-
|
|
21016
|
-
this.cancel.addEventListener('click', cancel);
|
|
21017
|
-
|
|
21018
|
-
attachDialogCloseHandlerWithParent(header, cancel);
|
|
21019
|
-
makeDraggable(this.container, header);
|
|
21020
|
-
|
|
21021
|
-
}
|
|
21022
|
-
|
|
21023
|
-
get value() {
|
|
21024
|
-
return purify.sanitize(this._input.value)
|
|
21025
|
-
}
|
|
21026
|
-
|
|
21027
|
-
present(options, e) {
|
|
21028
|
-
|
|
21029
|
-
this.label.textContent = options.label;
|
|
21030
|
-
|
|
21031
|
-
this._scaleFactor = options.scaleFactor;
|
|
21032
|
-
const [ minS, maxS, valueS ] = [ options.min, options.max, options.value ].map(number => (Math.floor(this._scaleFactor * number)).toString());
|
|
21033
|
-
|
|
21034
|
-
this._input.min = minS;
|
|
21035
|
-
this._input.max = maxS;
|
|
21036
|
-
this._input.value = valueS;
|
|
21037
|
-
|
|
21038
|
-
const numer = parseFloat(valueS);
|
|
21039
|
-
const denom = this._scaleFactor;
|
|
21040
|
-
const number = numer/denom;
|
|
21041
|
-
this._output.value = `${number.toFixed(2)}`;
|
|
21042
|
-
|
|
21043
|
-
this.callback = options.callback || options.click;
|
|
21044
|
-
|
|
21045
|
-
show(this.container);
|
|
21046
|
-
this.clampLocation(e.clientX, e.clientY);
|
|
21047
|
-
|
|
21048
|
-
}
|
|
21049
|
-
|
|
21050
|
-
clampLocation(clientX, clientY) {
|
|
21051
|
-
|
|
21052
|
-
const {width: w, height: h} = this.container.getBoundingClientRect();
|
|
21053
|
-
const wh = window.innerHeight;
|
|
21054
|
-
const ww = window.innerWidth;
|
|
21055
|
-
|
|
21056
|
-
const y = Math.min(wh - h, clientY);
|
|
21057
|
-
const x = Math.min(ww - w, clientX);
|
|
21058
|
-
this.container.style.left = `${x}px`;
|
|
21059
|
-
this.container.style.top = `${y}px`;
|
|
21060
|
-
|
|
21061
|
-
}
|
|
21062
|
-
}
|
|
21063
|
-
|
|
21064
20945
|
class InputDialog {
|
|
21065
20946
|
|
|
21066
20947
|
constructor(parent) {
|
|
@@ -24514,6 +24395,29 @@
|
|
|
24514
24395
|
|
|
24515
24396
|
}
|
|
24516
24397
|
|
|
24398
|
+
function decodeShoebox(tokens, header, maxColumnCount = Number.MAX_SAFE_INTEGER) {
|
|
24399
|
+
|
|
24400
|
+
if (tokens.length < 4) return undefined
|
|
24401
|
+
|
|
24402
|
+
const chr = tokens[0];
|
|
24403
|
+
const start = parseInt(tokens[1]);
|
|
24404
|
+
const end = tokens.length > 2 ? parseInt(tokens[2]) : start + 1;
|
|
24405
|
+
if (isNaN(start) || isNaN(end)) {
|
|
24406
|
+
return new DecodeError(`Unparsable bed record.`)
|
|
24407
|
+
}
|
|
24408
|
+
const feature = new UCSCBedFeature({chr: chr, start: start, end: end, score: 1000});
|
|
24409
|
+
|
|
24410
|
+
const values = [];
|
|
24411
|
+
for(let i = 3; i< tokens.length; i++) {
|
|
24412
|
+
values.push(Number.parseInt(tokens[i]));
|
|
24413
|
+
}
|
|
24414
|
+
feature.values = values;
|
|
24415
|
+
|
|
24416
|
+
|
|
24417
|
+
return feature
|
|
24418
|
+
}
|
|
24419
|
+
|
|
24420
|
+
|
|
24517
24421
|
class UCSCBedFeature {
|
|
24518
24422
|
|
|
24519
24423
|
constructor(properties) {
|
|
@@ -25878,6 +25782,10 @@
|
|
|
25878
25782
|
this.decode = decodeGcnv;
|
|
25879
25783
|
this.delimiter = "\t";
|
|
25880
25784
|
break
|
|
25785
|
+
case "shoebox":
|
|
25786
|
+
this.decode = decodeShoebox;
|
|
25787
|
+
this.delimiter = "\t";
|
|
25788
|
+
break
|
|
25881
25789
|
default:
|
|
25882
25790
|
const customFormat = getFormat(format);
|
|
25883
25791
|
if (customFormat !== undefined) {
|
|
@@ -31964,14 +31872,25 @@
|
|
|
31964
31872
|
this.config = config;
|
|
31965
31873
|
this.bufferSize = BUFFER_SIZE;
|
|
31966
31874
|
this.loader = isDataURL(this.path) ?
|
|
31967
|
-
new DataBuffer(this.path) :
|
|
31875
|
+
new DataBuffer(decodeDataURI$1(this.path).buffer) :
|
|
31876
|
+
igvxhr;
|
|
31968
31877
|
|
|
31969
|
-
|
|
31970
|
-
|
|
31878
|
+
const trixURL = config.trixURL || config.searchTrix;
|
|
31879
|
+
if (trixURL) {
|
|
31880
|
+
this._trix = new Trix(`${trixURL}x`, trixURL);
|
|
31971
31881
|
}
|
|
31972
31882
|
|
|
31973
31883
|
}
|
|
31974
31884
|
|
|
31885
|
+
/**
|
|
31886
|
+
* Preload all the data for this bb file
|
|
31887
|
+
* @returns {Promise<void>}
|
|
31888
|
+
*/
|
|
31889
|
+
async preload() {
|
|
31890
|
+
const data = await igvxhr.loadArrayBuffer(this.path);
|
|
31891
|
+
this.loader = new DataBuffer(data);
|
|
31892
|
+
}
|
|
31893
|
+
|
|
31975
31894
|
async readWGFeatures(bpPerPixel, windowFunction) {
|
|
31976
31895
|
await this.loadHeader();
|
|
31977
31896
|
const chrIdx1 = 0;
|
|
@@ -32637,8 +32556,8 @@
|
|
|
32637
32556
|
|
|
32638
32557
|
class DataBuffer {
|
|
32639
32558
|
|
|
32640
|
-
constructor(
|
|
32641
|
-
this.data =
|
|
32559
|
+
constructor(data) {
|
|
32560
|
+
this.data = data;
|
|
32642
32561
|
}
|
|
32643
32562
|
|
|
32644
32563
|
/**
|
|
@@ -38025,6 +37944,16 @@
|
|
|
38025
37944
|
const groupsTxtURL = baseURL + genome.getProperty("groups");
|
|
38026
37945
|
groups = await loadStanzas(groupsTxtURL);
|
|
38027
37946
|
}
|
|
37947
|
+
|
|
37948
|
+
// If the genome has a chromSizes file, and it is not too large, set the chromSizesURL property. This will
|
|
37949
|
+
// enable whole genome view and the chromosome pulldown
|
|
37950
|
+
if (genome.hasProperty("chromSizes")) {
|
|
37951
|
+
const chromSizesURL = baseURL + genome.getProperty("chromSizes");
|
|
37952
|
+
const l = await getContentLength(chromSizesURL);
|
|
37953
|
+
if (l !== null && Number.parseInt(l) < 1000000) {
|
|
37954
|
+
genome.setProperty("chromSizesURL", chromSizesURL);
|
|
37955
|
+
}
|
|
37956
|
+
}
|
|
38028
37957
|
}
|
|
38029
37958
|
|
|
38030
37959
|
// TODO -- categorize extra "user" supplied and other tracks in some distinctive way before including them
|
|
@@ -38127,10 +38056,15 @@
|
|
|
38127
38056
|
name: name,
|
|
38128
38057
|
twoBitURL: this.baseURL + this.genomeStanza.getProperty("twoBitPath"),
|
|
38129
38058
|
nameSet: "ucsc",
|
|
38130
|
-
wholeGenomeView: false,
|
|
38131
|
-
showChromosomeWidget: false
|
|
38132
38059
|
};
|
|
38133
38060
|
|
|
38061
|
+
if (this.genomeStanza.hasProperty("chromSizesURL")) {
|
|
38062
|
+
config.chromSizesURL = this.genomeStanza.getProperty("chromSizesURL");
|
|
38063
|
+
} else {
|
|
38064
|
+
config.wholeGenomeView = false;
|
|
38065
|
+
config.showChromosomeWidget = false;
|
|
38066
|
+
}
|
|
38067
|
+
|
|
38134
38068
|
if (this.genomeStanza.hasProperty("defaultPos")) {
|
|
38135
38069
|
const hubLocus = this.genomeStanza.getProperty("defaultPos");
|
|
38136
38070
|
// Strip out coordinates => whole chromosome view
|
|
@@ -38331,7 +38265,7 @@
|
|
|
38331
38265
|
config.searchIndex = t.getProperty("searchIndex");
|
|
38332
38266
|
}
|
|
38333
38267
|
if (t.hasProperty("searchTrix")) {
|
|
38334
|
-
config.
|
|
38268
|
+
config.trixURL = this.baseURL + t.getProperty("searchTrix");
|
|
38335
38269
|
}
|
|
38336
38270
|
|
|
38337
38271
|
if (t.hasProperty("group")) {
|
|
@@ -38418,6 +38352,26 @@
|
|
|
38418
38352
|
}
|
|
38419
38353
|
}
|
|
38420
38354
|
|
|
38355
|
+
|
|
38356
|
+
/**
|
|
38357
|
+
* Return the content length of the resource. If the content length cannot be determined return null;
|
|
38358
|
+
* @param url
|
|
38359
|
+
* @returns {Promise<number|string>}
|
|
38360
|
+
*/
|
|
38361
|
+
async function getContentLength(url) {
|
|
38362
|
+
try {
|
|
38363
|
+
const response = await fetch(url, {method: 'HEAD'});
|
|
38364
|
+
const headers = response.headers;
|
|
38365
|
+
if (headers.has("content-length")) {
|
|
38366
|
+
return headers.get("content-length")
|
|
38367
|
+
} else {
|
|
38368
|
+
return null
|
|
38369
|
+
}
|
|
38370
|
+
} catch (e) {
|
|
38371
|
+
return null
|
|
38372
|
+
}
|
|
38373
|
+
}
|
|
38374
|
+
|
|
38421
38375
|
/**
|
|
38422
38376
|
* Parse a UCSC file
|
|
38423
38377
|
* @param url
|
|
@@ -41966,7 +41920,7 @@
|
|
|
41966
41920
|
|
|
41967
41921
|
class NavbarButton {
|
|
41968
41922
|
|
|
41969
|
-
constructor(
|
|
41923
|
+
constructor(parent, browser, title, buttonLabel, imageSVG, imageHoverSVG, initialButtonState) {
|
|
41970
41924
|
|
|
41971
41925
|
this.browser = browser;
|
|
41972
41926
|
|
|
@@ -42023,7 +41977,7 @@
|
|
|
42023
41977
|
}
|
|
42024
41978
|
|
|
42025
41979
|
configureTextButton(textContent) {
|
|
42026
|
-
|
|
41980
|
+
console.log(`text ${this.title}`);
|
|
42027
41981
|
this.button.classList.add('igv-navbar-text-button');
|
|
42028
41982
|
|
|
42029
41983
|
const tempDiv = document.createElement('div');
|
|
@@ -42038,6 +41992,7 @@
|
|
|
42038
41992
|
}
|
|
42039
41993
|
|
|
42040
41994
|
configureIconButton() {
|
|
41995
|
+
console.log(`icon ${this.title}`);
|
|
42041
41996
|
this.button.classList.add('igv-navbar-icon-button');
|
|
42042
41997
|
}
|
|
42043
41998
|
|
|
@@ -42077,11 +42032,6 @@
|
|
|
42077
42032
|
this.hide();
|
|
42078
42033
|
}
|
|
42079
42034
|
}
|
|
42080
|
-
|
|
42081
|
-
static currentNavbarButtonClass(browser) {
|
|
42082
|
-
const el = browser.$navigation.get(0).querySelector('.igv-navbar-text-button');
|
|
42083
|
-
return el ? 'igv-navbar-text-button' : 'igv-navbar-icon-button'
|
|
42084
|
-
}
|
|
42085
42035
|
}
|
|
42086
42036
|
|
|
42087
42037
|
const overlayTrackImage =
|
|
@@ -42290,6 +42240,19 @@
|
|
|
42290
42240
|
return this._autoscale
|
|
42291
42241
|
}
|
|
42292
42242
|
|
|
42243
|
+
set autoscaleGroup(g) {
|
|
42244
|
+
if(this.tracks) {
|
|
42245
|
+
for(let t of this.tracks) t.autoscaleGroup = g;
|
|
42246
|
+
}
|
|
42247
|
+
}
|
|
42248
|
+
|
|
42249
|
+
get autoscaleGroup() {
|
|
42250
|
+
if(this.tracks && this.tracks.length > 0) {
|
|
42251
|
+
const g = this.tracks[0].autoscaleGroup;
|
|
42252
|
+
return (this.tracks.some(t => g !== t.autoscaleGroup)) ? undefined : g
|
|
42253
|
+
}
|
|
42254
|
+
}
|
|
42255
|
+
|
|
42293
42256
|
/**
|
|
42294
42257
|
* Set the data range of all constitutive numeric tracks. This method is called from the menu item, i.e. an explicit
|
|
42295
42258
|
* setting, so it should disable autoscale as well.
|
|
@@ -42654,9 +42617,9 @@
|
|
|
42654
42617
|
};
|
|
42655
42618
|
|
|
42656
42619
|
class OverlayTrackButton extends NavbarButton {
|
|
42657
|
-
constructor(
|
|
42620
|
+
constructor(parent, browser) {
|
|
42658
42621
|
|
|
42659
|
-
super(
|
|
42622
|
+
super(parent, browser, 'Overlay Tracks', buttonLabel, overlayTrackImage, overlayTrackImageHover, false);
|
|
42660
42623
|
|
|
42661
42624
|
this.button.addEventListener('mouseenter', () => this.setState(true));
|
|
42662
42625
|
this.button.addEventListener('mouseleave', () => this.setState(false));
|
|
@@ -42679,15 +42642,15 @@
|
|
|
42679
42642
|
|
|
42680
42643
|
if (true === isOverlayTrackCriteriaMet(this.browser)) {
|
|
42681
42644
|
|
|
42682
|
-
const tracks = this.browser.getSelectedTrackViews().map(({
|
|
42645
|
+
const tracks = this.browser.getSelectedTrackViews().map(({track}) => track);
|
|
42683
42646
|
for (const track of tracks) {
|
|
42684
42647
|
track.selected = false;
|
|
42685
42648
|
}
|
|
42686
42649
|
|
|
42687
|
-
// Flatten any merged tracks. Must do this before
|
|
42650
|
+
// Flatten any merged tracks. Must do this before their removal
|
|
42688
42651
|
const flattenedTracks = [];
|
|
42689
|
-
for(let t of tracks) {
|
|
42690
|
-
if("merged" === t.type) {
|
|
42652
|
+
for (let t of tracks) {
|
|
42653
|
+
if ("merged" === t.type) {
|
|
42691
42654
|
flattenedTracks.push(...t.tracks);
|
|
42692
42655
|
} else {
|
|
42693
42656
|
flattenedTracks.push(t);
|
|
@@ -42700,17 +42663,20 @@
|
|
|
42700
42663
|
type: 'merged',
|
|
42701
42664
|
autoscale: false,
|
|
42702
42665
|
alpha: 0.5, //fudge * (1.0/tracks.length),
|
|
42703
|
-
height: Math.max(...tracks.map(({
|
|
42704
|
-
order: Math.min(...tracks.map(({
|
|
42666
|
+
height: Math.max(...tracks.map(({height}) => height)),
|
|
42667
|
+
order: Math.min(...tracks.map(({order}) => order)),
|
|
42705
42668
|
};
|
|
42706
42669
|
|
|
42707
42670
|
const mergedTrack = new MergedTrack(config, this.browser, flattenedTracks);
|
|
42708
42671
|
|
|
42709
42672
|
for (const track of tracks) {
|
|
42710
|
-
this.browser.
|
|
42673
|
+
const idx = this.browser.trackViews.indexOf(track.trackView);
|
|
42674
|
+
this.browser.trackViews.splice(idx, 1);
|
|
42675
|
+
track.trackView.dispose();
|
|
42711
42676
|
}
|
|
42712
42677
|
|
|
42713
42678
|
this.browser.addTrack(config, mergedTrack);
|
|
42679
|
+
mergedTrack.trackView.updateViews();
|
|
42714
42680
|
|
|
42715
42681
|
}
|
|
42716
42682
|
|
|
@@ -42722,9 +42688,9 @@
|
|
|
42722
42688
|
|
|
42723
42689
|
if (selected && selected.length > 1) {
|
|
42724
42690
|
|
|
42725
|
-
const criteriaSet = new Set([
|
|
42691
|
+
const criteriaSet = new Set(['wig', 'merged']);
|
|
42726
42692
|
|
|
42727
|
-
const list = selected.filter(({
|
|
42693
|
+
const list = selected.filter(({track}) => criteriaSet.has(track.type));
|
|
42728
42694
|
|
|
42729
42695
|
return list.length > 1
|
|
42730
42696
|
|
|
@@ -42839,6 +42805,8 @@
|
|
|
42839
42805
|
createAxis(browser, track) {
|
|
42840
42806
|
|
|
42841
42807
|
const axis = div();
|
|
42808
|
+
this.axis = axis;
|
|
42809
|
+
|
|
42842
42810
|
browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis);
|
|
42843
42811
|
|
|
42844
42812
|
axis.dataset.tracktype = track.type;
|
|
@@ -42856,12 +42824,12 @@
|
|
|
42856
42824
|
|
|
42857
42825
|
if (false === multiTrackSelectExclusionTypes.has(this.track.type)) {
|
|
42858
42826
|
|
|
42859
|
-
|
|
42860
|
-
axis.appendChild(trackSelectionContainer);
|
|
42827
|
+
this.trackSelectionContainer = div();
|
|
42828
|
+
axis.appendChild(this.trackSelectionContainer);
|
|
42861
42829
|
|
|
42862
42830
|
const html = `<input type="checkbox" name="track-select">`;
|
|
42863
42831
|
const input = document.createRange().createContextualFragment(html).firstChild;
|
|
42864
|
-
trackSelectionContainer.appendChild(input);
|
|
42832
|
+
this.trackSelectionContainer.appendChild(input);
|
|
42865
42833
|
input.checked = this.track.selected || false;
|
|
42866
42834
|
|
|
42867
42835
|
input.addEventListener('change', event => {
|
|
@@ -42869,10 +42837,10 @@
|
|
|
42869
42837
|
event.stopPropagation();
|
|
42870
42838
|
this.track.selected = event.target.checked;
|
|
42871
42839
|
this.setDragHandleSelectionState(event.target.checked);
|
|
42872
|
-
this.browser.overlayTrackButton.setVisibility(
|
|
42840
|
+
this.browser.overlayTrackButton.setVisibility(isOverlayTrackCriteriaMet(this.browser));
|
|
42873
42841
|
});
|
|
42874
42842
|
|
|
42875
|
-
this.
|
|
42843
|
+
this.enableTrackSelection(false);
|
|
42876
42844
|
|
|
42877
42845
|
}
|
|
42878
42846
|
|
|
@@ -43682,13 +43650,19 @@
|
|
|
43682
43650
|
return Math.max(...this.viewports.map(viewport => viewport.getContentHeight()))
|
|
43683
43651
|
}
|
|
43684
43652
|
|
|
43685
|
-
|
|
43653
|
+
enableTrackSelection(doEnableMultiSelection) {
|
|
43686
43654
|
|
|
43687
|
-
const container =
|
|
43655
|
+
const container = this.trackSelectionContainer;
|
|
43656
|
+
|
|
43657
|
+
if (!container || multiTrackSelectExclusionTypes.has(this.track.type)) {
|
|
43658
|
+
return
|
|
43659
|
+
}
|
|
43688
43660
|
|
|
43689
43661
|
if (false !== doEnableMultiSelection) {
|
|
43690
43662
|
container.style.display = 'grid';
|
|
43691
43663
|
} else {
|
|
43664
|
+
// If disabling selection set track selection state to false
|
|
43665
|
+
this.track.selected = false;
|
|
43692
43666
|
|
|
43693
43667
|
const trackSelectInput = container.querySelector('[name=track-select]');
|
|
43694
43668
|
trackSelectInput.checked = this.track.selected;
|
|
@@ -43714,13 +43688,11 @@
|
|
|
43714
43688
|
dragHandle.classList.remove('igv-track-drag-handle-selected-color');
|
|
43715
43689
|
dragHandle.classList.add('igv-track-drag-handle-color');
|
|
43716
43690
|
}
|
|
43717
|
-
|
|
43718
43691
|
}
|
|
43719
43692
|
|
|
43720
43693
|
}
|
|
43721
43694
|
|
|
43722
43695
|
|
|
43723
|
-
|
|
43724
43696
|
function renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) {
|
|
43725
43697
|
|
|
43726
43698
|
if (typeof track.paintAxis === 'function') {
|
|
@@ -43834,13 +43806,13 @@
|
|
|
43834
43806
|
*
|
|
43835
43807
|
*/
|
|
43836
43808
|
|
|
43837
|
-
const defaultColorScaleConfig = {threshold: 2000, r: 0, g: 0, b: 255};
|
|
43809
|
+
const defaultColorScaleConfig$1 = {threshold: 2000, r: 0, g: 0, b: 255};
|
|
43838
43810
|
|
|
43839
43811
|
class HicColorScale {
|
|
43840
43812
|
|
|
43841
43813
|
constructor(scale) {
|
|
43842
43814
|
|
|
43843
|
-
scale = scale || defaultColorScaleConfig;
|
|
43815
|
+
scale = scale || defaultColorScaleConfig$1;
|
|
43844
43816
|
this.threshold = scale.threshold;
|
|
43845
43817
|
this.r = scale.r;
|
|
43846
43818
|
this.g = scale.g;
|
|
@@ -54043,6 +54015,10 @@
|
|
|
54043
54015
|
if (firstLine.startsWith("##gff-version")) {
|
|
54044
54016
|
return "gff"
|
|
54045
54017
|
}
|
|
54018
|
+
if(firstLine.startsWith("##fileformat=")) {
|
|
54019
|
+
return firstLine.substring(13).toLowerCase(); // Non standard extension of VCF convention
|
|
54020
|
+
}
|
|
54021
|
+
|
|
54046
54022
|
|
|
54047
54023
|
// QTL test must preceed GWAS test as GWAS files will also pass the QTL test
|
|
54048
54024
|
if (QTLParser.isQTL(firstLine)) {
|
|
@@ -57279,10 +57255,6 @@
|
|
|
57279
57255
|
|
|
57280
57256
|
function clickHandler() {
|
|
57281
57257
|
this.alignmentTrack.colorBy = menuItem.key;
|
|
57282
|
-
if ('strand' !== this.alignmentTrack.groupBy) {
|
|
57283
|
-
this.alignmentTrack.groupBy = 'strand';
|
|
57284
|
-
this.alignmentTrack.repackAlignments();
|
|
57285
|
-
}
|
|
57286
57258
|
this.trackView.repaintViews();
|
|
57287
57259
|
}
|
|
57288
57260
|
|
|
@@ -67871,6 +67843,7 @@
|
|
|
67871
67843
|
const searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG;
|
|
67872
67844
|
let feature;
|
|
67873
67845
|
|
|
67846
|
+
name = name.toUpperCase();
|
|
67874
67847
|
const searchableTracks = browser.tracks.filter(t => t.searchable);
|
|
67875
67848
|
for (let track of searchableTracks) {
|
|
67876
67849
|
const feature = await track.search(name);
|
|
@@ -70209,6 +70182,343 @@
|
|
|
70209
70182
|
}
|
|
70210
70183
|
}
|
|
70211
70184
|
|
|
70185
|
+
/*
|
|
70186
|
+
* The MIT License (MIT)
|
|
70187
|
+
*
|
|
70188
|
+
* Copyright (c) 2016-2017 The Regents of the University of California
|
|
70189
|
+
*
|
|
70190
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
70191
|
+
* associated documentation files (the "Software"), to deal in the Software without restriction, including
|
|
70192
|
+
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
70193
|
+
* copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
|
70194
|
+
* following conditions:
|
|
70195
|
+
*
|
|
70196
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
70197
|
+
* portions of the Software.
|
|
70198
|
+
*
|
|
70199
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
70200
|
+
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
70201
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
70202
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
70203
|
+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
70204
|
+
* THE SOFTWARE.
|
|
70205
|
+
*
|
|
70206
|
+
*/
|
|
70207
|
+
|
|
70208
|
+
const defaultColorScaleConfig = {min: 0, max: 3000, color: "rgb(0,0,255)"};
|
|
70209
|
+
|
|
70210
|
+
class ShoeboxColorScale {
|
|
70211
|
+
|
|
70212
|
+
constructor(scale) {
|
|
70213
|
+
|
|
70214
|
+
scale = scale || defaultColorScaleConfig;
|
|
70215
|
+
this.max = scale.max;
|
|
70216
|
+
this.min = scale.min || 0;
|
|
70217
|
+
this.cache = [];
|
|
70218
|
+
this.nbins = 1000;
|
|
70219
|
+
this.binsize = (this.max - this.min) / this.nbins;
|
|
70220
|
+
this.updateColor(scale.color || "rgb(0,0,255)");
|
|
70221
|
+
|
|
70222
|
+
}
|
|
70223
|
+
|
|
70224
|
+
updateColor(color) {
|
|
70225
|
+
const comps = color.substring(4).replace(")", "").split(",");
|
|
70226
|
+
if (comps.length === 3) {
|
|
70227
|
+
this.r = Number.parseInt(comps[0].trim());
|
|
70228
|
+
this.g = Number.parseInt(comps[1].trim());
|
|
70229
|
+
this.b = Number.parseInt(comps[2].trim());
|
|
70230
|
+
}
|
|
70231
|
+
this.cache = [];
|
|
70232
|
+
}
|
|
70233
|
+
|
|
70234
|
+
setMinMax(min, max) {
|
|
70235
|
+
this.min = min;
|
|
70236
|
+
this.max = max;
|
|
70237
|
+
this.cache = [];
|
|
70238
|
+
this.binsize = (this.max - this.min) / this.nbins;
|
|
70239
|
+
}
|
|
70240
|
+
|
|
70241
|
+
getColor(value) {
|
|
70242
|
+
const low = 0;
|
|
70243
|
+
if (value < this.min) return "white"
|
|
70244
|
+
|
|
70245
|
+
const bin = Math.floor((Math.min(this.max, value) - this.min) / this.binsize);
|
|
70246
|
+
if (undefined === this.cache[bin]) {
|
|
70247
|
+
const alpha = (IGVMath.clamp(value, low, this.max) - low) / (this.max - low);
|
|
70248
|
+
this.cache[bin] = `rgba(${this.r},${this.g},${this.b}, ${alpha})`;
|
|
70249
|
+
}
|
|
70250
|
+
return this.cache[bin]
|
|
70251
|
+
}
|
|
70252
|
+
|
|
70253
|
+
/**
|
|
70254
|
+
*
|
|
70255
|
+
* @returns {{min: (*|number), color: string, max}}
|
|
70256
|
+
*/
|
|
70257
|
+
toJson() {
|
|
70258
|
+
return {
|
|
70259
|
+
min: this.min,
|
|
70260
|
+
max: this.max,
|
|
70261
|
+
color: `rgb(${this.r},${this.g},${this.b})`
|
|
70262
|
+
}
|
|
70263
|
+
}
|
|
70264
|
+
|
|
70265
|
+
// For short-term backward compatibility
|
|
70266
|
+
static parse(str) {
|
|
70267
|
+
|
|
70268
|
+
const tokens = str.split(",");
|
|
70269
|
+
|
|
70270
|
+
const cs = {
|
|
70271
|
+
min: Number.parseFloat(tokens[0]),
|
|
70272
|
+
max: Number.parseFloat(tokens[1]),
|
|
70273
|
+
color: `${tokens[2]},${tokens[3]},${tokens[4]}`
|
|
70274
|
+
};
|
|
70275
|
+
return new ShoeboxColorScale(cs)
|
|
70276
|
+
}
|
|
70277
|
+
|
|
70278
|
+
}
|
|
70279
|
+
|
|
70280
|
+
class ShoeboxTrack extends TrackBase {
|
|
70281
|
+
|
|
70282
|
+
static defaults = {
|
|
70283
|
+
height: 300,
|
|
70284
|
+
rowHeight: 3,
|
|
70285
|
+
max: 3000,
|
|
70286
|
+
visibilityWindow: 10000
|
|
70287
|
+
}
|
|
70288
|
+
|
|
70289
|
+
constructor(config, browser) {
|
|
70290
|
+
super(config, browser);
|
|
70291
|
+
}
|
|
70292
|
+
|
|
70293
|
+
init(config) {
|
|
70294
|
+
super.init(config);
|
|
70295
|
+
|
|
70296
|
+
this.type = "shoebox";
|
|
70297
|
+
this.height = config.height || 300;
|
|
70298
|
+
this.rowHeight = config.rowHeight || 3;
|
|
70299
|
+
this.max = config.max || 3000;
|
|
70300
|
+
|
|
70301
|
+
// Hardcoded -- todo get from track line
|
|
70302
|
+
this.sampleKeys = [];
|
|
70303
|
+
for (let i = 1; i <= 100; i++) {
|
|
70304
|
+
this.sampleKeys.push(i);
|
|
70305
|
+
}
|
|
70306
|
+
|
|
70307
|
+
// Create featureSource
|
|
70308
|
+
const configCopy = Object.assign({}, this.config);
|
|
70309
|
+
configCopy.format = 'shoebox'; // bit of a hack
|
|
70310
|
+
this.featureSource = FeatureSource(configCopy, this.browser.genome);
|
|
70311
|
+
}
|
|
70312
|
+
|
|
70313
|
+
async postInit() {
|
|
70314
|
+
if (typeof this.featureSource.getHeader === "function") {
|
|
70315
|
+
this.header = await this.featureSource.getHeader();
|
|
70316
|
+
if (this.disposed) return // This track was removed during async load
|
|
70317
|
+
}
|
|
70318
|
+
// Set properties from track line
|
|
70319
|
+
if (this.header) {
|
|
70320
|
+
this.setTrackProperties(this.header);
|
|
70321
|
+
}
|
|
70322
|
+
|
|
70323
|
+
// Must do the following after setting track properties as they can be overriden via a track line
|
|
70324
|
+
|
|
70325
|
+
// Color settings
|
|
70326
|
+
if (this.config.colorScale && this.config.colorScale.max && this.config.colorScale.color) { // Minimal validation
|
|
70327
|
+
this.colorScale = new ShoeboxColorScale(this.config.colorScale);
|
|
70328
|
+
|
|
70329
|
+
} else {
|
|
70330
|
+
const min = this.dataRange.min;
|
|
70331
|
+
const max = this.dataRange.max;
|
|
70332
|
+
this.colorScale = new ShoeboxColorScale({min, max, color: this.color});
|
|
70333
|
+
}
|
|
70334
|
+
}
|
|
70335
|
+
|
|
70336
|
+
get color() {
|
|
70337
|
+
return this._color || "rgb(0,0,255)"
|
|
70338
|
+
}
|
|
70339
|
+
|
|
70340
|
+
set color(color) {
|
|
70341
|
+
this._color = color;
|
|
70342
|
+
if (this.colorScale) {
|
|
70343
|
+
this.colorScale.updateColor(color);
|
|
70344
|
+
}
|
|
70345
|
+
}
|
|
70346
|
+
|
|
70347
|
+
menuItemList() {
|
|
70348
|
+
|
|
70349
|
+
const menuItems = [];
|
|
70350
|
+
|
|
70351
|
+
|
|
70352
|
+
menuItems.push('<hr/>');
|
|
70353
|
+
|
|
70354
|
+
// Data range
|
|
70355
|
+
let object = $$1('<div>');
|
|
70356
|
+
object.text('Set data range');
|
|
70357
|
+
|
|
70358
|
+
function dialogPresentationHandler() {
|
|
70359
|
+
|
|
70360
|
+
if (this.trackView.track.selected) {
|
|
70361
|
+
this.browser.dataRangeDialog.configure(this.trackView.browser.getSelectedTrackViews());
|
|
70362
|
+
} else {
|
|
70363
|
+
this.browser.dataRangeDialog.configure(this.trackView);
|
|
70364
|
+
}
|
|
70365
|
+
this.browser.dataRangeDialog.present($$1(this.browser.columnContainer));
|
|
70366
|
+
}
|
|
70367
|
+
|
|
70368
|
+
menuItems.push({object, dialog: dialogPresentationHandler});
|
|
70369
|
+
|
|
70370
|
+
return menuItems
|
|
70371
|
+
}
|
|
70372
|
+
|
|
70373
|
+
setDataRange({min, max}) {
|
|
70374
|
+
this.dataRange.min = min;
|
|
70375
|
+
this.dataRange.max = max;
|
|
70376
|
+
this.colorScale.min = min;
|
|
70377
|
+
this.colorScale.max = max;
|
|
70378
|
+
this.trackView.repaintViews();
|
|
70379
|
+
}
|
|
70380
|
+
|
|
70381
|
+
hasSamples() {
|
|
70382
|
+
return true // by definition
|
|
70383
|
+
}
|
|
70384
|
+
|
|
70385
|
+
getSamples() {
|
|
70386
|
+
return {
|
|
70387
|
+
names: this.sampleKeys,
|
|
70388
|
+
height: this.rowHeight,
|
|
70389
|
+
yOffset: 0
|
|
70390
|
+
}
|
|
70391
|
+
}
|
|
70392
|
+
|
|
70393
|
+
async getFeatures(chr, start, end, bpPerPixel) {
|
|
70394
|
+
const visibilityWindow = this.visibilityWindow;
|
|
70395
|
+
return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow})
|
|
70396
|
+
}
|
|
70397
|
+
|
|
70398
|
+
|
|
70399
|
+
draw({context, pixelTop, pixelWidth, pixelHeight, features, bpPerPixel, bpStart}) {
|
|
70400
|
+
|
|
70401
|
+
|
|
70402
|
+
IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
|
70403
|
+
|
|
70404
|
+
if (features && features.length > 0) {
|
|
70405
|
+
|
|
70406
|
+
const rowHeight = this.rowHeight;
|
|
70407
|
+
const pixelBottom = pixelTop + pixelHeight;
|
|
70408
|
+
const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
|
|
70409
|
+
|
|
70410
|
+
const h = rowHeight;
|
|
70411
|
+
|
|
70412
|
+
for (let f of features) {
|
|
70413
|
+
|
|
70414
|
+
// Test for overlap with in-view region
|
|
70415
|
+
if (f.end < bpStart || f.start > bpEnd) continue
|
|
70416
|
+
|
|
70417
|
+
// Pixel x values
|
|
70418
|
+
const xLeft = Math.round((f.start - bpStart) / bpPerPixel);
|
|
70419
|
+
const xRight = Math.round((f.end - bpStart) / bpPerPixel);
|
|
70420
|
+
const w = Math.max(1, xRight - xLeft);
|
|
70421
|
+
|
|
70422
|
+
// Loop through value array
|
|
70423
|
+
let row = 0;
|
|
70424
|
+
|
|
70425
|
+
for (let i = f.values.length - 1; i >= 0; i--) {
|
|
70426
|
+
|
|
70427
|
+
const v = f.values[i];
|
|
70428
|
+
|
|
70429
|
+
const y = row * rowHeight;
|
|
70430
|
+
|
|
70431
|
+
|
|
70432
|
+
const bottom = y + rowHeight;
|
|
70433
|
+
|
|
70434
|
+
if (bottom < pixelTop || y > pixelBottom) {
|
|
70435
|
+
continue
|
|
70436
|
+
}
|
|
70437
|
+
|
|
70438
|
+
const color = this.colorScale.getColor(v);
|
|
70439
|
+
|
|
70440
|
+
context.fillStyle = color;
|
|
70441
|
+
|
|
70442
|
+
context.fillRect(xLeft, y, w, h);
|
|
70443
|
+
|
|
70444
|
+
row++;
|
|
70445
|
+
}
|
|
70446
|
+
}
|
|
70447
|
+
}
|
|
70448
|
+
|
|
70449
|
+
}
|
|
70450
|
+
|
|
70451
|
+
/**
|
|
70452
|
+
* Optional method to compute pixel height to accomodate the list of features.
|
|
70453
|
+
*
|
|
70454
|
+
* @param features
|
|
70455
|
+
* @returns {number}
|
|
70456
|
+
*/
|
|
70457
|
+
computePixelHeight(features) {
|
|
70458
|
+
if (!features || features.length === 0) return 0
|
|
70459
|
+
return features[0].values.length * this.rowHeight
|
|
70460
|
+
}
|
|
70461
|
+
|
|
70462
|
+
|
|
70463
|
+
clickedFeatures(clickState) {
|
|
70464
|
+
|
|
70465
|
+
const allFeatures = super.clickedFeatures(clickState);
|
|
70466
|
+
const y = clickState.y;
|
|
70467
|
+
return allFeatures.filter(function (feature) {
|
|
70468
|
+
const rect = feature.pixelRect;
|
|
70469
|
+
return rect && y >= rect.y && y <= (rect.y + rect.h)
|
|
70470
|
+
})
|
|
70471
|
+
|
|
70472
|
+
}
|
|
70473
|
+
|
|
70474
|
+
hoverText(clickState) {
|
|
70475
|
+
const features = this.clickedFeatures(clickState);
|
|
70476
|
+
if (features && features.length > 0) {
|
|
70477
|
+
return `${features[0].sample}: ${features[0].value}`
|
|
70478
|
+
}
|
|
70479
|
+
}
|
|
70480
|
+
|
|
70481
|
+
popupData(clickState, featureList) {
|
|
70482
|
+
|
|
70483
|
+
if (featureList === undefined) featureList = this.clickedFeatures(clickState);
|
|
70484
|
+
|
|
70485
|
+
const items = [];
|
|
70486
|
+
|
|
70487
|
+
for (let feature of featureList) {
|
|
70488
|
+
|
|
70489
|
+
// Double line divider between features
|
|
70490
|
+
if (items.length > 0) {
|
|
70491
|
+
items.push('<hr/>');
|
|
70492
|
+
items.push('<hr/>');
|
|
70493
|
+
}
|
|
70494
|
+
|
|
70495
|
+
// hack for whole genome features, which save the original feature as "_f"
|
|
70496
|
+
const f = feature._f || feature;
|
|
70497
|
+
|
|
70498
|
+
const data = (typeof f.popupData === 'function') ?
|
|
70499
|
+
f.popupData(this.type, this.browser.genome.id) :
|
|
70500
|
+
this.extractPopupData(f);
|
|
70501
|
+
Array.prototype.push.apply(items, data);
|
|
70502
|
+
|
|
70503
|
+
}
|
|
70504
|
+
|
|
70505
|
+
return items
|
|
70506
|
+
}
|
|
70507
|
+
|
|
70508
|
+
get supportsWholeGenome() {
|
|
70509
|
+
return false
|
|
70510
|
+
}
|
|
70511
|
+
|
|
70512
|
+
getState() {
|
|
70513
|
+
|
|
70514
|
+
const config = super.getState();
|
|
70515
|
+
config.colorScale = this.colorScale.toJson();
|
|
70516
|
+
return config
|
|
70517
|
+
|
|
70518
|
+
}
|
|
70519
|
+
|
|
70520
|
+
}
|
|
70521
|
+
|
|
70212
70522
|
//import CNVPytorTrack from "./CNVpytor/cnvpytorTrack.js"
|
|
70213
70523
|
|
|
70214
70524
|
|
|
@@ -70220,7 +70530,7 @@
|
|
|
70220
70530
|
['seg', (config, browser) => new SegTrack(config, browser)],
|
|
70221
70531
|
['mut', (config, browser) => new SegTrack(config, browser)],
|
|
70222
70532
|
['maf', (config, browser) => new SegTrack(config, browser)],
|
|
70223
|
-
['shoebox', (config, browser) => new
|
|
70533
|
+
['shoebox', (config, browser) => new ShoeboxTrack(config, browser)],
|
|
70224
70534
|
['wig', (config, browser) => new WigTrack(config, browser)],
|
|
70225
70535
|
['merged', (config, browser) => new MergedTrack(config, browser)],
|
|
70226
70536
|
['alignment', (config, browser) => new BAMTrack(config, browser)],
|
|
@@ -70712,94 +71022,11 @@
|
|
|
70712
71022
|
})
|
|
70713
71023
|
}
|
|
70714
71024
|
|
|
70715
|
-
const _version = "3.0.
|
|
71025
|
+
const _version = "3.0.9";
|
|
70716
71026
|
function version() {
|
|
70717
71027
|
return _version
|
|
70718
71028
|
}
|
|
70719
71029
|
|
|
70720
|
-
/*
|
|
70721
|
-
* The MIT License (MIT)
|
|
70722
|
-
*
|
|
70723
|
-
* Copyright (c) 2014 Broad Institute
|
|
70724
|
-
*
|
|
70725
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
70726
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
70727
|
-
* in the Software without restriction, including without limitation the rights
|
|
70728
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
70729
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
70730
|
-
* furnished to do so, subject to the following conditions:
|
|
70731
|
-
*
|
|
70732
|
-
* The above copyright notice and this permission notice shall be included in
|
|
70733
|
-
* all copies or substantial portions of the Software.
|
|
70734
|
-
*
|
|
70735
|
-
*
|
|
70736
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
70737
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
70738
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
70739
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
70740
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
70741
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
70742
|
-
* THE SOFTWARE.
|
|
70743
|
-
*/
|
|
70744
|
-
|
|
70745
|
-
const navbarResponsiveClasses = {};
|
|
70746
|
-
|
|
70747
|
-
const responsiveThreshold = 8;
|
|
70748
|
-
let textButtonContainerWidth = undefined;
|
|
70749
|
-
|
|
70750
|
-
function navbarDidResize(browser, width) {
|
|
70751
|
-
|
|
70752
|
-
const currentClass = NavbarButton.currentNavbarButtonClass(browser);
|
|
70753
|
-
if ('igv-navbar-text-button' === currentClass) {
|
|
70754
|
-
textButtonContainerWidth = browser.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect().width;
|
|
70755
|
-
}
|
|
70756
|
-
|
|
70757
|
-
const responsiveClasses = getResponsiveClasses(browser, width);
|
|
70758
|
-
|
|
70759
|
-
$$1(browser.zoomWidget.zoomContainer).removeClass();
|
|
70760
|
-
$$1(browser.zoomWidget.zoomContainer).addClass(responsiveClasses.zoomContainer);
|
|
70761
|
-
|
|
70762
|
-
browser.fireEvent('navbar-resize', [ responsiveClasses.navbarButton ]);
|
|
70763
|
-
}
|
|
70764
|
-
|
|
70765
|
-
function getResponsiveClasses(browser, navbarWidth) {
|
|
70766
|
-
|
|
70767
|
-
const isWGV =
|
|
70768
|
-
(browser.isMultiLocusWholeGenomeView()) ||
|
|
70769
|
-
(browser.referenceFrameList && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr));
|
|
70770
|
-
|
|
70771
|
-
isWGV ? browser.windowSizePanel.hide() : browser.windowSizePanel.show();
|
|
70772
|
-
|
|
70773
|
-
const { x: leftContainerX, width: leftContainerWidth } = browser.$navigation.get(0).querySelector('.igv-navbar-left-container').getBoundingClientRect();
|
|
70774
|
-
const leftContainerExtent = leftContainerX + leftContainerWidth;
|
|
70775
|
-
const { x:rightContainerX} = browser.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect();
|
|
70776
|
-
|
|
70777
|
-
const delta = rightContainerX - leftContainerExtent;
|
|
70778
|
-
|
|
70779
|
-
const currentClass = NavbarButton.currentNavbarButtonClass(browser);
|
|
70780
|
-
|
|
70781
|
-
// console.log(`Current class ${ currentClass } Delta: ${ StringUtils.numberFormatter(Math.floor(delta))}`)
|
|
70782
|
-
|
|
70783
|
-
if ('igv-navbar-text-button' === currentClass && delta < responsiveThreshold) {
|
|
70784
|
-
navbarResponsiveClasses.navbarButton = 'igv-navbar-icon-button';
|
|
70785
|
-
} else if (textButtonContainerWidth && 'igv-navbar-icon-button' === currentClass) {
|
|
70786
|
-
const length = navbarWidth - leftContainerExtent;
|
|
70787
|
-
if (length - textButtonContainerWidth > responsiveThreshold) {
|
|
70788
|
-
navbarResponsiveClasses.navbarButton = 'igv-navbar-text-button';
|
|
70789
|
-
}
|
|
70790
|
-
|
|
70791
|
-
}
|
|
70792
|
-
|
|
70793
|
-
|
|
70794
|
-
if (isWGV) {
|
|
70795
|
-
navbarResponsiveClasses.zoomContainer = 'igv-zoom-widget-hidden';
|
|
70796
|
-
} else {
|
|
70797
|
-
navbarResponsiveClasses.zoomContainer = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900';
|
|
70798
|
-
}
|
|
70799
|
-
|
|
70800
|
-
return navbarResponsiveClasses
|
|
70801
|
-
}
|
|
70802
|
-
|
|
70803
71030
|
/*
|
|
70804
71031
|
* The MIT License (MIT)
|
|
70805
71032
|
*
|
|
@@ -70847,7 +71074,7 @@
|
|
|
70847
71074
|
});
|
|
70848
71075
|
|
|
70849
71076
|
this.showAllChromosomes = browser.config.showAllChromosomes !== false; // i.e. default to true
|
|
70850
|
-
|
|
71077
|
+
this.genome = browser.genome;
|
|
70851
71078
|
}
|
|
70852
71079
|
|
|
70853
71080
|
show() {
|
|
@@ -70858,10 +71085,16 @@
|
|
|
70858
71085
|
this.container.style.display = 'none';
|
|
70859
71086
|
}
|
|
70860
71087
|
|
|
71088
|
+
setValue(chrName) {
|
|
71089
|
+
this.select.value = this.genome.getChromosomeDisplayName(chrName);
|
|
71090
|
+
}
|
|
71091
|
+
|
|
70861
71092
|
update(genome) {
|
|
70862
71093
|
|
|
71094
|
+
this.genome = genome;
|
|
71095
|
+
|
|
70863
71096
|
// Start with explicit chromosome name list
|
|
70864
|
-
const list = genome.wgChromosomeNames || [];
|
|
71097
|
+
const list = genome.wgChromosomeNames.map(nm => genome.getChromosomeDisplayName(nm)) || [];
|
|
70865
71098
|
|
|
70866
71099
|
if (this.showAllChromosomes && genome.chromosomeNames.length > 1) {
|
|
70867
71100
|
const exclude = new Set(list);
|
|
@@ -70872,6 +71105,7 @@
|
|
|
70872
71105
|
break
|
|
70873
71106
|
}
|
|
70874
71107
|
if (!exclude.has(nm)) {
|
|
71108
|
+
nm = genome.getChromosomeDisplayName(nm);
|
|
70875
71109
|
list.push(nm);
|
|
70876
71110
|
}
|
|
70877
71111
|
}
|
|
@@ -70952,6 +71186,99 @@
|
|
|
70952
71186
|
}
|
|
70953
71187
|
}
|
|
70954
71188
|
|
|
71189
|
+
const multiSelectImage =
|
|
71190
|
+
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
71191
|
+
<title>multi select</title>
|
|
71192
|
+
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
71193
|
+
<g id="multi-select">
|
|
71194
|
+
<rect id="backdrop-copy-3" stroke="#737373" stroke-width="12" fill="#FFFFFF" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
71195
|
+
<g id="row-copy-3" transform="translate(81, 427)" fill="#737373">
|
|
71196
|
+
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
71197
|
+
<rect id="Rectangle-Copy-16" stroke="#737373" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
71198
|
+
</g>
|
|
71199
|
+
<g id="row-copy-2" transform="translate(82, 277)">
|
|
71200
|
+
<rect id="Rectangle" fill-opacity="0.33" fill="#CFCECE" x="133" y="0" width="329" height="70"></rect>
|
|
71201
|
+
<rect id="Rectangle-Copy-16" stroke-opacity="0.32659528" stroke="#CFCECE" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
71202
|
+
</g>
|
|
71203
|
+
<g id="row-copy" transform="translate(81, 119)" fill="#737373">
|
|
71204
|
+
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
71205
|
+
<rect id="Rectangle-Copy-17" stroke="#737373" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
71206
|
+
</g>
|
|
71207
|
+
</g>
|
|
71208
|
+
</g>
|
|
71209
|
+
</svg>`;
|
|
71210
|
+
|
|
71211
|
+
const multiSelectImageHover =
|
|
71212
|
+
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
71213
|
+
<title>multi select hover</title>
|
|
71214
|
+
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
71215
|
+
<g id="multi-select-hover">
|
|
71216
|
+
<rect id="backdrop-copy-4" stroke="#737373" stroke-width="12" fill="#737373" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
71217
|
+
<g id="row-copy-3" transform="translate(81, 427)" fill="#FFFFFF">
|
|
71218
|
+
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
71219
|
+
<rect id="Rectangle-Copy-16" stroke="#FFFFFF" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
71220
|
+
</g>
|
|
71221
|
+
<g id="row-copy-2" transform="translate(82, 277)">
|
|
71222
|
+
<rect id="Rectangle" fill-opacity="0.33" fill="#CFCECE" x="133" y="0" width="329" height="70"></rect>
|
|
71223
|
+
<rect id="Rectangle-Copy-16" stroke-opacity="0.33" stroke="#CFCECE" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
71224
|
+
</g>
|
|
71225
|
+
<g id="row-copy" transform="translate(81, 119)" fill="#FFFFFF">
|
|
71226
|
+
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
71227
|
+
<rect id="Rectangle-Copy-17" stroke="#FFFFFF" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
71228
|
+
</g>
|
|
71229
|
+
</g>
|
|
71230
|
+
</g>
|
|
71231
|
+
</svg>`;
|
|
71232
|
+
|
|
71233
|
+
class MultiTrackSelectButton extends NavbarButton {
|
|
71234
|
+
|
|
71235
|
+
constructor(parent, browser, navbar, enableMultiTrackSelection) {
|
|
71236
|
+
|
|
71237
|
+
super(parent, browser, 'Select Tracks', buttonLabel, multiSelectImage, multiSelectImageHover, false);
|
|
71238
|
+
|
|
71239
|
+
this.navbar = navbar;
|
|
71240
|
+
this.enableMultiTrackSelection = false; // Initial state
|
|
71241
|
+
this.button.addEventListener('mouseenter', event => {
|
|
71242
|
+
if (false === enableMultiTrackSelection) {
|
|
71243
|
+
this.setState(true);
|
|
71244
|
+
}
|
|
71245
|
+
});
|
|
71246
|
+
|
|
71247
|
+
this.button.addEventListener('mouseleave', event => {
|
|
71248
|
+
if (false === enableMultiTrackSelection) {
|
|
71249
|
+
this.setState(false);
|
|
71250
|
+
}
|
|
71251
|
+
});
|
|
71252
|
+
|
|
71253
|
+
const mouseClickHandler = () => {
|
|
71254
|
+
// Toggle the selection state
|
|
71255
|
+
this.setMultiTrackSelection(!this.enableMultiTrackSelection);
|
|
71256
|
+
};
|
|
71257
|
+
|
|
71258
|
+
this.boundMouseClickHandler = mouseClickHandler.bind(this);
|
|
71259
|
+
|
|
71260
|
+
this.button.addEventListener('click', this.boundMouseClickHandler);
|
|
71261
|
+
|
|
71262
|
+
}
|
|
71263
|
+
|
|
71264
|
+
setMultiTrackSelection(enableMultiTrackSelection) {
|
|
71265
|
+
|
|
71266
|
+
this.enableMultiTrackSelection = enableMultiTrackSelection;
|
|
71267
|
+
this.setState(this.enableMultiTrackSelection);
|
|
71268
|
+
|
|
71269
|
+
// If enableMultiTrackSelection is false hide the Overly button
|
|
71270
|
+
if (false === this.enableMultiTrackSelection) {
|
|
71271
|
+
this.navbar.overlayTrackButton.setVisibility(false);
|
|
71272
|
+
}
|
|
71273
|
+
|
|
71274
|
+
for (const trackView of this.browser.trackViews) {
|
|
71275
|
+
trackView.enableTrackSelection(enableMultiTrackSelection);
|
|
71276
|
+
}
|
|
71277
|
+
|
|
71278
|
+
}
|
|
71279
|
+
|
|
71280
|
+
}
|
|
71281
|
+
|
|
70955
71282
|
class CursorGuide {
|
|
70956
71283
|
|
|
70957
71284
|
constructor(columnContainer, browser) {
|
|
@@ -71133,9 +71460,9 @@
|
|
|
71133
71460
|
|
|
71134
71461
|
class CursorGuideButton extends NavbarButton {
|
|
71135
71462
|
|
|
71136
|
-
constructor(
|
|
71463
|
+
constructor(parent, browser) {
|
|
71137
71464
|
|
|
71138
|
-
super(
|
|
71465
|
+
super(parent, browser, 'Crosshairs', buttonLabel, cursorImage, cursorImageHover, browser.doShowCursorGuide);
|
|
71139
71466
|
|
|
71140
71467
|
this.button.addEventListener('mouseenter', () => {
|
|
71141
71468
|
if (false === browser.doShowCursorGuide) {
|
|
@@ -71221,9 +71548,9 @@
|
|
|
71221
71548
|
|
|
71222
71549
|
class CenterLineButton extends NavbarButton {
|
|
71223
71550
|
|
|
71224
|
-
constructor(
|
|
71551
|
+
constructor(parent, browser) {
|
|
71225
71552
|
|
|
71226
|
-
super(
|
|
71553
|
+
super(parent, browser, 'Center Line', buttonLabel, centerlineImage, centerlineImageHover, browser.config.showCenterGuide);
|
|
71227
71554
|
|
|
71228
71555
|
this.button.addEventListener('mouseenter', () => {
|
|
71229
71556
|
if (false === browser.doShowCenterLine) {
|
|
@@ -71312,7 +71639,7 @@
|
|
|
71312
71639
|
|
|
71313
71640
|
constructor(parent, browser) {
|
|
71314
71641
|
|
|
71315
|
-
super(
|
|
71642
|
+
super(parent, browser, 'Track Labels', buttonLabel, trackLabelsImage, trackLabelsImageHover, browser.config.showTrackLabels);
|
|
71316
71643
|
|
|
71317
71644
|
this.button.addEventListener('mouseenter', () => {
|
|
71318
71645
|
if (false === browser.doShowTrackLabels) {
|
|
@@ -71342,28 +71669,28 @@
|
|
|
71342
71669
|
|
|
71343
71670
|
}
|
|
71344
71671
|
|
|
71345
|
-
const
|
|
71672
|
+
const roiImage =
|
|
71346
71673
|
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
71347
|
-
<title>
|
|
71674
|
+
<title>roi</title>
|
|
71348
71675
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
71349
|
-
<g id="
|
|
71350
|
-
<rect id="Rectangle-Copy-
|
|
71351
|
-
<
|
|
71352
|
-
|
|
71353
|
-
|
|
71676
|
+
<g id="roi">
|
|
71677
|
+
<rect id="Rectangle-Copy-23" stroke="#737373" stroke-width="12" fill="#FFFFFF" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
71678
|
+
<text id="ROI" font-family="HelveticaNeue-Bold, Helvetica Neue" font-size="258" font-weight="bold" fill="#737373">
|
|
71679
|
+
<tspan x="81.445" y="389">ROI</tspan>
|
|
71680
|
+
</text>
|
|
71354
71681
|
</g>
|
|
71355
71682
|
</g>
|
|
71356
71683
|
</svg>`;
|
|
71357
71684
|
|
|
71358
|
-
const
|
|
71685
|
+
const roiImageHover =
|
|
71359
71686
|
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
71360
|
-
<title>
|
|
71687
|
+
<title>roi hover</title>
|
|
71361
71688
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
71362
|
-
<g id="
|
|
71363
|
-
<rect id="Rectangle-Copy-
|
|
71364
|
-
<
|
|
71365
|
-
|
|
71366
|
-
|
|
71689
|
+
<g id="roi-hover">
|
|
71690
|
+
<rect id="Rectangle-Copy-24" stroke="#737373" stroke-width="12" fill="#737373" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
71691
|
+
<text id="ROI" font-family="HelveticaNeue-Bold, Helvetica Neue" font-size="258" font-weight="bold" fill="#FFFFFF">
|
|
71692
|
+
<tspan x="81.445" y="389">ROI</tspan>
|
|
71693
|
+
</text>
|
|
71367
71694
|
</g>
|
|
71368
71695
|
</g>
|
|
71369
71696
|
</svg>`;
|
|
@@ -71394,49 +71721,34 @@
|
|
|
71394
71721
|
* THE SOFTWARE.
|
|
71395
71722
|
*/
|
|
71396
71723
|
|
|
71397
|
-
class
|
|
71724
|
+
class ROITableControl extends NavbarButton {
|
|
71398
71725
|
|
|
71399
|
-
constructor(parent, browser)
|
|
71726
|
+
constructor(parent, browser) {
|
|
71400
71727
|
|
|
71401
|
-
super(browser,
|
|
71728
|
+
super(parent, browser, ['ROI', 'Regions of Interest Table'], buttonLabel, roiImage, roiImageHover, false);
|
|
71402
71729
|
|
|
71403
71730
|
this.button.addEventListener('mouseenter', () => {
|
|
71404
|
-
if (false === browser.
|
|
71731
|
+
if (false === browser.doShowROITable) {
|
|
71405
71732
|
this.setState(true);
|
|
71406
71733
|
}
|
|
71407
71734
|
});
|
|
71408
71735
|
|
|
71409
71736
|
this.button.addEventListener('mouseleave', () => {
|
|
71410
|
-
if (false === browser.
|
|
71737
|
+
if (false === browser.doShowROITable) {
|
|
71411
71738
|
this.setState(false);
|
|
71412
71739
|
}
|
|
71413
71740
|
});
|
|
71414
71741
|
|
|
71415
|
-
this.button.addEventListener('click', () =>
|
|
71416
|
-
this.performClickWithState(browser, undefined);
|
|
71417
|
-
});
|
|
71742
|
+
this.button.addEventListener('click', () => this.buttonHandler(!browser.doShowROITable));
|
|
71418
71743
|
|
|
71419
|
-
if
|
|
71420
|
-
this.show();
|
|
71421
|
-
} else {
|
|
71422
|
-
this.hide();
|
|
71423
|
-
}
|
|
71744
|
+
this.setVisibility(false); // Hide initially, it will be un-hidden if ROIs are loaded
|
|
71424
71745
|
|
|
71425
71746
|
}
|
|
71426
71747
|
|
|
71427
|
-
|
|
71428
|
-
|
|
71429
|
-
|
|
71430
|
-
|
|
71431
|
-
const column = browser.columnContainer.querySelector('.igv-sample-name-column');
|
|
71432
|
-
column.style.display = false === browser.showSampleNames ? 'none' : 'flex';
|
|
71433
|
-
|
|
71434
|
-
this.setState(browser.showSampleNames);
|
|
71435
|
-
|
|
71436
|
-
browser.layoutChange();
|
|
71437
|
-
|
|
71748
|
+
buttonHandler(status) {
|
|
71749
|
+
this.setState(status);
|
|
71750
|
+
this.browser.setROITableVisibility(status);
|
|
71438
71751
|
}
|
|
71439
|
-
|
|
71440
71752
|
}
|
|
71441
71753
|
|
|
71442
71754
|
const sampleInfoImage =
|
|
@@ -71540,7 +71852,7 @@
|
|
|
71540
71852
|
|
|
71541
71853
|
constructor(parent, browser) {
|
|
71542
71854
|
|
|
71543
|
-
super(
|
|
71855
|
+
super(parent, browser, 'Sample Info', buttonLabel, sampleInfoImage, sampleInfoImageHover, false);
|
|
71544
71856
|
|
|
71545
71857
|
this.showSampleInfo = false;
|
|
71546
71858
|
|
|
@@ -71590,141 +71902,102 @@
|
|
|
71590
71902
|
|
|
71591
71903
|
}
|
|
71592
71904
|
|
|
71593
|
-
const
|
|
71594
|
-
|
|
71595
|
-
|
|
71596
|
-
|
|
71597
|
-
|
|
71598
|
-
|
|
71599
|
-
|
|
71600
|
-
|
|
71601
|
-
|
|
71602
|
-
|
|
71603
|
-
|
|
71604
|
-
|
|
71605
|
-
this.zoomOutButton = div();
|
|
71606
|
-
this.zoomContainer.appendChild(this.zoomOutButton);
|
|
71607
|
-
this.zoomOutButton.appendChild(createIcon('minus-circle'));
|
|
71608
|
-
this.zoomOutButton.addEventListener('click', () => {
|
|
71609
|
-
// browser.zoomWithScaleFactor(2.0)
|
|
71610
|
-
browser.zoomOut();
|
|
71611
|
-
});
|
|
71612
|
-
|
|
71613
|
-
// Range slider
|
|
71614
|
-
const el = div();
|
|
71615
|
-
this.zoomContainer.appendChild(el);
|
|
71616
|
-
this.slider = document.createElement('input');
|
|
71617
|
-
this.slider.type = 'range';
|
|
71618
|
-
|
|
71619
|
-
this.slider.min = `${sliderMin}`;
|
|
71620
|
-
this.slider.max = `${sliderMax}`;
|
|
71621
|
-
|
|
71622
|
-
el.appendChild(this.slider);
|
|
71623
|
-
|
|
71624
|
-
this.slider.addEventListener('change', e => {
|
|
71625
|
-
|
|
71626
|
-
e.preventDefault();
|
|
71627
|
-
e.stopPropagation();
|
|
71628
|
-
|
|
71629
|
-
const referenceFrame = browser.referenceFrameList[0];
|
|
71630
|
-
const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr);
|
|
71631
|
-
const {end, start} = referenceFrame;
|
|
71905
|
+
const sampleNameImage =
|
|
71906
|
+
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
71907
|
+
<title>sample names</title>
|
|
71908
|
+
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
71909
|
+
<g id="sample-names" stroke="#737373">
|
|
71910
|
+
<rect id="Rectangle-Copy-13" stroke-width="12" fill="#FFFFFF" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
71911
|
+
<line x1="80" y1="465" x2="541" y2="464.5" id="Line-3-Copy-3" stroke-width="32"></line>
|
|
71912
|
+
<line x1="80" y1="312.5" x2="542" y2="313" id="Line-3" stroke-width="32"></line>
|
|
71913
|
+
<line x1="80" y1="158" x2="541" y2="158" id="Line-3-Copy" stroke-width="32"></line>
|
|
71914
|
+
</g>
|
|
71915
|
+
</g>
|
|
71916
|
+
</svg>`;
|
|
71632
71917
|
|
|
71633
|
-
|
|
71918
|
+
const sampleNameImageHover =
|
|
71919
|
+
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
71920
|
+
<title>sample names hover</title>
|
|
71921
|
+
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
71922
|
+
<g id="sample-names-hover">
|
|
71923
|
+
<rect id="Rectangle-Copy-18" stroke="#737373" stroke-width="12" fill="#737373" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
71924
|
+
<line x1="80" y1="465" x2="541" y2="464.5" id="Line-3-Copy-3" stroke="#FFFFFF" stroke-width="32" fill="#FFFFFF"></line>
|
|
71925
|
+
<line x1="80" y1="312.5" x2="542" y2="313" id="Line-3" stroke="#FFFFFF" stroke-width="32" fill="#FFFFFF"></line>
|
|
71926
|
+
<line x1="80" y1="158" x2="541" y2="158" id="Line-3-Copy" stroke="#FFFFFF" stroke-width="32" fill="#FFFFFF"></line>
|
|
71927
|
+
</g>
|
|
71928
|
+
</g>
|
|
71929
|
+
</svg>`;
|
|
71634
71930
|
|
|
71635
|
-
|
|
71636
|
-
|
|
71931
|
+
/*
|
|
71932
|
+
* The MIT License (MIT)
|
|
71933
|
+
*
|
|
71934
|
+
* Copyright (c) 2016 University of California San Diego
|
|
71935
|
+
* Author: Jim Robinson
|
|
71936
|
+
*
|
|
71937
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
71938
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
71939
|
+
* in the Software without restriction, including without limitation the rights
|
|
71940
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
71941
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
71942
|
+
* furnished to do so, subject to the following conditions:
|
|
71943
|
+
*
|
|
71944
|
+
* The above copyright notice and this permission notice shall be included in
|
|
71945
|
+
* all copies or substantial portions of the Software.
|
|
71946
|
+
*
|
|
71947
|
+
*
|
|
71948
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
71949
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
71950
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
71951
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
71952
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
71953
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
71954
|
+
* THE SOFTWARE.
|
|
71955
|
+
*/
|
|
71637
71956
|
|
|
71638
|
-
|
|
71639
|
-
const zoomedExtent = bpLength / scaleFactor;
|
|
71957
|
+
class SampleNameControl extends NavbarButton {
|
|
71640
71958
|
|
|
71641
|
-
|
|
71959
|
+
constructor(parent, browser) {
|
|
71642
71960
|
|
|
71643
|
-
|
|
71961
|
+
super(parent, browser, 'Sample Names', sampleNameButtonLabel, sampleNameImage, sampleNameImageHover, browser.config.showSampleNames);
|
|
71644
71962
|
|
|
71645
|
-
|
|
71963
|
+
this.button.addEventListener('mouseenter', () => {
|
|
71964
|
+
if (false === browser.showSampleNames) {
|
|
71965
|
+
this.setState(true);
|
|
71966
|
+
}
|
|
71967
|
+
});
|
|
71646
71968
|
|
|
71647
|
-
|
|
71648
|
-
|
|
71649
|
-
|
|
71650
|
-
|
|
71651
|
-
|
|
71652
|
-
// browser.zoomWithScaleFactor(0.5)
|
|
71653
|
-
browser.zoomIn();
|
|
71654
|
-
});
|
|
71969
|
+
this.button.addEventListener('mouseleave', () => {
|
|
71970
|
+
if (false === browser.showSampleNames) {
|
|
71971
|
+
this.setState(false);
|
|
71972
|
+
}
|
|
71973
|
+
});
|
|
71655
71974
|
|
|
71656
|
-
|
|
71975
|
+
this.button.addEventListener('click', () => {
|
|
71976
|
+
this.performClickWithState(browser, undefined);
|
|
71977
|
+
});
|
|
71657
71978
|
|
|
71658
|
-
if (
|
|
71659
|
-
this.
|
|
71979
|
+
if (true === browser.config.showSampleNameButton) {
|
|
71980
|
+
this.show();
|
|
71660
71981
|
} else {
|
|
71661
|
-
this.
|
|
71662
|
-
this.update(referenceFrameList);
|
|
71982
|
+
this.hide();
|
|
71663
71983
|
}
|
|
71664
71984
|
|
|
71665
|
-
}
|
|
71666
|
-
|
|
71667
|
-
};
|
|
71668
|
-
|
|
71669
|
-
ZoomWidget.prototype.update = function (referenceFrameList) {
|
|
71670
|
-
|
|
71671
|
-
const referenceFrame = referenceFrameList[0];
|
|
71672
|
-
const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr);
|
|
71673
|
-
const {start, end} = referenceFrame;
|
|
71674
|
-
|
|
71675
|
-
sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases()));
|
|
71676
|
-
|
|
71677
|
-
this.slider.max = `${sliderMax}`;
|
|
71678
|
-
|
|
71679
|
-
const scaleFactor = bpLength / (end - start);
|
|
71680
|
-
sliderValueRaw = Math.log2(scaleFactor);
|
|
71681
|
-
this.slider.value = `${Math.round(sliderValueRaw)}`;
|
|
71682
|
-
|
|
71683
|
-
// referenceFrame.description('zoom.update')
|
|
71684
|
-
|
|
71685
|
-
// console.log(`${ Date.now() } update - slider ${ this.slider.value } scaleFactor ${ Math.round(scaleFactor) } extent ${ StringUtils.numberFormatter(Math.round(extent)) }`)
|
|
71686
|
-
|
|
71687
|
-
// console.log(`update - sliderMin ${ sliderMin } sliderValue ${ this.slider.value } sliderMax ${ sliderMax } scaleFactor ${ scaleFactor.toFixed(3) } derived-scaleFactor ${ derivedScalefactor.toFixed(3) }`)
|
|
71688
|
-
|
|
71689
|
-
};
|
|
71690
|
-
|
|
71691
|
-
ZoomWidget.prototype.enable = function () {
|
|
71692
|
-
|
|
71693
|
-
// this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ];
|
|
71694
|
-
// this.zoomInButton.style.pointerEvents = 'auto';
|
|
71695
|
-
//
|
|
71696
|
-
// this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ];
|
|
71697
|
-
// this.zoomOutButton.style.pointerEvents = 'auto';
|
|
71698
|
-
|
|
71699
|
-
this.slider.disabled = false;
|
|
71700
|
-
};
|
|
71985
|
+
}
|
|
71701
71986
|
|
|
71702
|
-
|
|
71987
|
+
performClickWithState(browser, doShowSampleNamesOrUndefined) {
|
|
71703
71988
|
|
|
71704
|
-
|
|
71705
|
-
// this.zoomInButton.style.pointerEvents = 'none';
|
|
71706
|
-
//
|
|
71707
|
-
// this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ];
|
|
71708
|
-
// this.zoomOutButton.style.pointerEvents = 'none';
|
|
71989
|
+
browser.showSampleNames = undefined === doShowSampleNamesOrUndefined ? !browser.showSampleNames : doShowSampleNamesOrUndefined;
|
|
71709
71990
|
|
|
71710
|
-
|
|
71711
|
-
|
|
71991
|
+
const column = browser.columnContainer.querySelector('.igv-sample-name-column');
|
|
71992
|
+
column.style.display = false === browser.showSampleNames ? 'none' : 'flex';
|
|
71712
71993
|
|
|
71713
|
-
|
|
71714
|
-
this.zoomContainer.style.display = 'none';
|
|
71715
|
-
};
|
|
71994
|
+
this.setState(browser.showSampleNames);
|
|
71716
71995
|
|
|
71717
|
-
|
|
71718
|
-
this.zoomContainer.style.display = 'block';
|
|
71719
|
-
};
|
|
71996
|
+
browser.layoutChange();
|
|
71720
71997
|
|
|
71721
|
-
|
|
71722
|
-
this.slider.style.display = 'none';
|
|
71723
|
-
};
|
|
71998
|
+
}
|
|
71724
71999
|
|
|
71725
|
-
|
|
71726
|
-
this.slider.style.display = 'block';
|
|
71727
|
-
};
|
|
72000
|
+
}
|
|
71728
72001
|
|
|
71729
72002
|
class Dropdown {
|
|
71730
72003
|
constructor(parent, shim) {
|
|
@@ -71867,7 +72140,7 @@
|
|
|
71867
72140
|
class SaveImageControl extends NavbarButton {
|
|
71868
72141
|
constructor(parent, browser) {
|
|
71869
72142
|
|
|
71870
|
-
super(
|
|
72143
|
+
super(parent, browser, 'Save Image', buttonLabel, imageSaveImageSVG, imageSaveImageHoverSVG, false);
|
|
71871
72144
|
|
|
71872
72145
|
this.button.addEventListener('mouseenter', () => this.setState(true));
|
|
71873
72146
|
|
|
@@ -71933,6 +72206,422 @@
|
|
|
71933
72206
|
|
|
71934
72207
|
}
|
|
71935
72208
|
|
|
72209
|
+
/**
|
|
72210
|
+
* User supplied button for the navbar
|
|
72211
|
+
*/
|
|
72212
|
+
|
|
72213
|
+
const CustomButton = function (parent, browser, b) {
|
|
72214
|
+
|
|
72215
|
+
const button = div({class: 'igv-navbar-button'});
|
|
72216
|
+
parent.append(button);
|
|
72217
|
+
button.textContent = b.label;
|
|
72218
|
+
button.addEventListener('click', () => b.callback(browser));
|
|
72219
|
+
};
|
|
72220
|
+
|
|
72221
|
+
const sliderMin = 0;
|
|
72222
|
+
let sliderMax = 23;
|
|
72223
|
+
let sliderValueRaw = 0;
|
|
72224
|
+
|
|
72225
|
+
class ZoomWidget {
|
|
72226
|
+
constructor(config, browser, parent) {
|
|
72227
|
+
|
|
72228
|
+
this.browser = browser;
|
|
72229
|
+
|
|
72230
|
+
this.zoomContainer = div({class: 'igv-zoom-widget'});
|
|
72231
|
+
parent.appendChild(this.zoomContainer);
|
|
72232
|
+
|
|
72233
|
+
// zoom out
|
|
72234
|
+
this.zoomOutButton = div();
|
|
72235
|
+
this.zoomContainer.appendChild(this.zoomOutButton);
|
|
72236
|
+
this.zoomOutButton.appendChild(createIcon('minus-circle'));
|
|
72237
|
+
this.zoomOutButton.addEventListener('click', () => {
|
|
72238
|
+
// browser.zoomWithScaleFactor(2.0)
|
|
72239
|
+
browser.zoomOut();
|
|
72240
|
+
});
|
|
72241
|
+
|
|
72242
|
+
// Range slider
|
|
72243
|
+
const el = div();
|
|
72244
|
+
this.zoomContainer.appendChild(el);
|
|
72245
|
+
this.slider = document.createElement('input');
|
|
72246
|
+
this.slider.type = 'range';
|
|
72247
|
+
|
|
72248
|
+
this.slider.min = `${sliderMin}`;
|
|
72249
|
+
this.slider.max = `${sliderMax}`;
|
|
72250
|
+
|
|
72251
|
+
el.appendChild(this.slider);
|
|
72252
|
+
|
|
72253
|
+
this.slider.addEventListener('change', e => {
|
|
72254
|
+
|
|
72255
|
+
e.preventDefault();
|
|
72256
|
+
e.stopPropagation();
|
|
72257
|
+
|
|
72258
|
+
const referenceFrame = browser.referenceFrameList[0];
|
|
72259
|
+
const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr);
|
|
72260
|
+
const {end, start} = referenceFrame;
|
|
72261
|
+
|
|
72262
|
+
const extent = end - start;
|
|
72263
|
+
|
|
72264
|
+
// bpLength/(end - start)
|
|
72265
|
+
const scaleFactor = Math.pow(2, e.target.valueAsNumber);
|
|
72266
|
+
|
|
72267
|
+
// (end - start) = bpLength/scaleFactor
|
|
72268
|
+
const zoomedExtent = bpLength / scaleFactor;
|
|
72269
|
+
|
|
72270
|
+
// console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`)
|
|
72271
|
+
|
|
72272
|
+
browser.zoomWithScaleFactor(zoomedExtent / extent);
|
|
72273
|
+
|
|
72274
|
+
});
|
|
72275
|
+
|
|
72276
|
+
// zoom in
|
|
72277
|
+
this.zoomInButton = div();
|
|
72278
|
+
this.zoomContainer.appendChild(this.zoomInButton);
|
|
72279
|
+
this.zoomInButton.appendChild(createIcon('plus-circle'));
|
|
72280
|
+
this.zoomInButton.addEventListener('click', () => {
|
|
72281
|
+
// browser.zoomWithScaleFactor(0.5)
|
|
72282
|
+
browser.zoomIn();
|
|
72283
|
+
});
|
|
72284
|
+
|
|
72285
|
+
browser.on('locuschange', (referenceFrameList) => {
|
|
72286
|
+
|
|
72287
|
+
if (this.browser.isMultiLocusMode()) {
|
|
72288
|
+
this.disable();
|
|
72289
|
+
} else {
|
|
72290
|
+
this.enable();
|
|
72291
|
+
this.update(referenceFrameList);
|
|
72292
|
+
}
|
|
72293
|
+
|
|
72294
|
+
});
|
|
72295
|
+
|
|
72296
|
+
}
|
|
72297
|
+
|
|
72298
|
+
update(referenceFrameList) {
|
|
72299
|
+
|
|
72300
|
+
if (this.slider) {
|
|
72301
|
+
const referenceFrame = referenceFrameList[0];
|
|
72302
|
+
const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr);
|
|
72303
|
+
const {start, end} = referenceFrame;
|
|
72304
|
+
|
|
72305
|
+
sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases()));
|
|
72306
|
+
this.slider.max = `${sliderMax}`;
|
|
72307
|
+
|
|
72308
|
+
const scaleFactor = bpLength / (end - start);
|
|
72309
|
+
sliderValueRaw = Math.log2(scaleFactor);
|
|
72310
|
+
this.slider.value = `${Math.round(sliderValueRaw)}`;
|
|
72311
|
+
}
|
|
72312
|
+
}
|
|
72313
|
+
|
|
72314
|
+
|
|
72315
|
+
enable() {
|
|
72316
|
+
|
|
72317
|
+
// this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ];
|
|
72318
|
+
// this.zoomInButton.style.pointerEvents = 'auto';
|
|
72319
|
+
//
|
|
72320
|
+
// this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ];
|
|
72321
|
+
// this.zoomOutButton.style.pointerEvents = 'auto';
|
|
72322
|
+
|
|
72323
|
+
if (this.slider) this.slider.disabled = false;
|
|
72324
|
+
}
|
|
72325
|
+
|
|
72326
|
+
disable() {
|
|
72327
|
+
|
|
72328
|
+
// this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ];
|
|
72329
|
+
// this.zoomInButton.style.pointerEvents = 'none';
|
|
72330
|
+
//
|
|
72331
|
+
// this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ];
|
|
72332
|
+
// this.zoomOutButton.style.pointerEvents = 'none';
|
|
72333
|
+
|
|
72334
|
+
if (this.slider) this.slider.disabled = true;
|
|
72335
|
+
}
|
|
72336
|
+
|
|
72337
|
+
hide() {
|
|
72338
|
+
this.zoomContainer.style.display = 'none';
|
|
72339
|
+
}
|
|
72340
|
+
|
|
72341
|
+
show() {
|
|
72342
|
+
this.zoomContainer.style.display = 'block';
|
|
72343
|
+
}
|
|
72344
|
+
|
|
72345
|
+
hideSlider() {
|
|
72346
|
+
if (this.slider) this.slider.style.display = 'none';
|
|
72347
|
+
}
|
|
72348
|
+
|
|
72349
|
+
showSlider() {
|
|
72350
|
+
if (this.slider) this.slider.style.display = 'block';
|
|
72351
|
+
}
|
|
72352
|
+
}
|
|
72353
|
+
|
|
72354
|
+
/*
|
|
72355
|
+
* The MIT License (MIT)
|
|
72356
|
+
*
|
|
72357
|
+
* Copyright (c) 2014 Broad Institute
|
|
72358
|
+
*
|
|
72359
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
72360
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
72361
|
+
* in the Software without restriction, including without limitation the rights
|
|
72362
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
72363
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
72364
|
+
* furnished to do so, subject to the following conditions:
|
|
72365
|
+
*
|
|
72366
|
+
* The above copyright notice and this permission notice shall be included in
|
|
72367
|
+
* all copies or substantial portions of the Software.
|
|
72368
|
+
*
|
|
72369
|
+
*
|
|
72370
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
72371
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
72372
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
72373
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
72374
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
72375
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
72376
|
+
* THE SOFTWARE.
|
|
72377
|
+
*/
|
|
72378
|
+
|
|
72379
|
+
class ResponsiveNavbar {
|
|
72380
|
+
constructor(config, browser) {
|
|
72381
|
+
|
|
72382
|
+
this.browser = browser;
|
|
72383
|
+
this.config = config;
|
|
72384
|
+
|
|
72385
|
+
this.currentClass = 'igv-navbar-text-button';
|
|
72386
|
+
|
|
72387
|
+
// DOM element for
|
|
72388
|
+
const $navBar = $$1('<div>', {class: 'igv-navbar'});
|
|
72389
|
+
this.$navigation = $navBar;
|
|
72390
|
+
|
|
72391
|
+
const $navbarLeftContainer = $$1('<div>', {class: 'igv-navbar-left-container'});
|
|
72392
|
+
$navBar.append($navbarLeftContainer);
|
|
72393
|
+
this.navbarLeftContainer = $navbarLeftContainer.get(0);
|
|
72394
|
+
|
|
72395
|
+
// IGV logo
|
|
72396
|
+
const $logo = $$1('<div>', {class: 'igv-logo'});
|
|
72397
|
+
$navbarLeftContainer.append($logo);
|
|
72398
|
+
|
|
72399
|
+
const logoSvg = logo();
|
|
72400
|
+
logoSvg.css("width", "34px");
|
|
72401
|
+
logoSvg.css("height", "32px");
|
|
72402
|
+
$logo.append(logoSvg);
|
|
72403
|
+
|
|
72404
|
+
this.$current_genome = $$1('<div>', {class: 'igv-current-genome'});
|
|
72405
|
+
$navbarLeftContainer.append(this.$current_genome);
|
|
72406
|
+
this.$current_genome.text('');
|
|
72407
|
+
|
|
72408
|
+
const $genomicLocation = $$1('<div>', {class: 'igv-navbar-genomic-location'});
|
|
72409
|
+
$navbarLeftContainer.append($genomicLocation);
|
|
72410
|
+
|
|
72411
|
+
// chromosome select widget
|
|
72412
|
+
this.chromosomeSelectWidget = new ChromosomeSelectWidget(browser, $genomicLocation.get(0));
|
|
72413
|
+
if (config.showChromosomeWidget !== false) {
|
|
72414
|
+
this.chromosomeSelectWidget.show();
|
|
72415
|
+
} else {
|
|
72416
|
+
this.chromosomeSelectWidget.hide();
|
|
72417
|
+
}
|
|
72418
|
+
|
|
72419
|
+
const $locusSizeGroup = $$1('<div>', {class: 'igv-locus-size-group'});
|
|
72420
|
+
$genomicLocation.append($locusSizeGroup);
|
|
72421
|
+
|
|
72422
|
+
const $searchContainer = $$1('<div>', {class: 'igv-search-container'});
|
|
72423
|
+
$locusSizeGroup.append($searchContainer);
|
|
72424
|
+
|
|
72425
|
+
// browser.$searchInput = $('<input type="text" placeholder="Locus Search">');
|
|
72426
|
+
this.$searchInput = $$1('<input>', {class: 'igv-search-input', type: 'text', placeholder: 'Locus Search'});
|
|
72427
|
+
$searchContainer.append(this.$searchInput);
|
|
72428
|
+
// Stop event propagation to prevent feature track keyboard navigation
|
|
72429
|
+
this.$searchInput[0].addEventListener('keyup', (event) => {
|
|
72430
|
+
event.stopImmediatePropagation();
|
|
72431
|
+
});
|
|
72432
|
+
|
|
72433
|
+
this.$searchInput.change(() => browser.doSearch(this.$searchInput.val()));
|
|
72434
|
+
|
|
72435
|
+
const searchIconContainer = div({class: 'igv-search-icon-container'});
|
|
72436
|
+
$searchContainer.append($$1(searchIconContainer));
|
|
72437
|
+
searchIconContainer.appendChild(createIcon("search"));
|
|
72438
|
+
searchIconContainer.addEventListener('click', () => browser.doSearch(this.$searchInput.val()));
|
|
72439
|
+
|
|
72440
|
+
this.windowSizePanel = new WindowSizePanel($locusSizeGroup.get(0), browser);
|
|
72441
|
+
|
|
72442
|
+
const $navbarRightContainer = $$1('<div>', {class: 'igv-navbar-right-container'});
|
|
72443
|
+
$navBar.append($navbarRightContainer);
|
|
72444
|
+
this.navbarRightContainer = $navbarRightContainer.get(0);
|
|
72445
|
+
|
|
72446
|
+
const $toggle_button_container = $$1('<div class="igv-navbar-toggle-button-container">');
|
|
72447
|
+
$navbarRightContainer.append($toggle_button_container);
|
|
72448
|
+
const toggleButtonContainer = $toggle_button_container.get(0);
|
|
72449
|
+
this.toggle_button_container = toggleButtonContainer; // TODO -- for circular view , refactor this
|
|
72450
|
+
|
|
72451
|
+
this.overlayTrackButton = new OverlayTrackButton(toggleButtonContainer, browser);
|
|
72452
|
+
this.overlayTrackButton.setVisibility(false);
|
|
72453
|
+
|
|
72454
|
+
const showMultiSelect = config.showMultiSelectButton !== false;
|
|
72455
|
+
this.multiTrackSelectButton = new MultiTrackSelectButton(toggleButtonContainer, browser, this, showMultiSelect);
|
|
72456
|
+
|
|
72457
|
+
this.cursorGuideButton = new CursorGuideButton(toggleButtonContainer, browser);
|
|
72458
|
+
|
|
72459
|
+
this.centerLineButton = new CenterLineButton(toggleButtonContainer, browser);
|
|
72460
|
+
|
|
72461
|
+
this.trackLabelControl = new TrackLabelControl(toggleButtonContainer, browser);
|
|
72462
|
+
|
|
72463
|
+
// ROI Control
|
|
72464
|
+
this.roiTableControl = new ROITableControl(toggleButtonContainer, browser);
|
|
72465
|
+
|
|
72466
|
+
this.sampleInfoControl = new SampleInfoControl(toggleButtonContainer, browser);
|
|
72467
|
+
|
|
72468
|
+
this.sampleNameControl = new SampleNameControl(toggleButtonContainer, browser);
|
|
72469
|
+
|
|
72470
|
+
if (true === config.showSVGButton) {
|
|
72471
|
+
this.saveImageControl = new SaveImageControl(toggleButtonContainer, browser);
|
|
72472
|
+
}
|
|
72473
|
+
|
|
72474
|
+
if (config.customButtons) {
|
|
72475
|
+
for (let b of config.customButtons) {
|
|
72476
|
+
new CustomButton(toggleButtonContainer, browser, b);
|
|
72477
|
+
}
|
|
72478
|
+
}
|
|
72479
|
+
|
|
72480
|
+
this.zoomWidget = new ZoomWidget(config, browser, $navbarRightContainer.get(0));
|
|
72481
|
+
|
|
72482
|
+
if (false === config.showNavigation) {
|
|
72483
|
+
this.$navigation.hide();
|
|
72484
|
+
}
|
|
72485
|
+
|
|
72486
|
+
|
|
72487
|
+
|
|
72488
|
+
}
|
|
72489
|
+
|
|
72490
|
+
navbarDidResize() {
|
|
72491
|
+
|
|
72492
|
+
|
|
72493
|
+
const navbarWidth = this.$navigation.width();
|
|
72494
|
+
const currentClass = this.currentNavbarButtonClass();
|
|
72495
|
+
if ('igv-navbar-text-button' === currentClass) {
|
|
72496
|
+
this.textButtonContainerWidth = this.navbarRightContainer.getBoundingClientRect().width;
|
|
72497
|
+
}
|
|
72498
|
+
const browser = this.browser;
|
|
72499
|
+
const isWGV =
|
|
72500
|
+
(browser.isMultiLocusWholeGenomeView()) ||
|
|
72501
|
+
(browser.referenceFrameList && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr));
|
|
72502
|
+
|
|
72503
|
+
isWGV ? this.windowSizePanel.hide() : this.windowSizePanel.show();
|
|
72504
|
+
|
|
72505
|
+
const {
|
|
72506
|
+
x: leftContainerX,
|
|
72507
|
+
width: leftContainerWidth
|
|
72508
|
+
} = this.navbarLeftContainer.getBoundingClientRect();
|
|
72509
|
+
const leftContainerExtent = leftContainerX + leftContainerWidth;
|
|
72510
|
+
const {x: rightContainerX} = this.navbarRightContainer.getBoundingClientRect();
|
|
72511
|
+
|
|
72512
|
+
const delta = rightContainerX - leftContainerExtent;
|
|
72513
|
+
|
|
72514
|
+
let navbarButtonClass;
|
|
72515
|
+
const threshold = 8;
|
|
72516
|
+
if ('igv-navbar-text-button' === currentClass && delta < threshold) {
|
|
72517
|
+
navbarButtonClass = 'igv-navbar-icon-button';
|
|
72518
|
+
} else if (this.textButtonContainerWidth && 'igv-navbar-icon-button' === currentClass) {
|
|
72519
|
+
const length = navbarWidth - leftContainerExtent;
|
|
72520
|
+
if (length - this.textButtonContainerWidth > threshold) {
|
|
72521
|
+
navbarButtonClass = 'igv-navbar-text-button';
|
|
72522
|
+
}
|
|
72523
|
+
}
|
|
72524
|
+
// Update all the buttons (buttons are listeners)
|
|
72525
|
+
if(navbarButtonClass && currentClass !== navbarButtonClass) {
|
|
72526
|
+
this.currentClass = navbarButtonClass;
|
|
72527
|
+
this.browser.fireEvent('navbar-resize', [navbarButtonClass]);
|
|
72528
|
+
}
|
|
72529
|
+
|
|
72530
|
+
let zoomContainerClass;
|
|
72531
|
+
if (isWGV) {
|
|
72532
|
+
zoomContainerClass = 'igv-zoom-widget-hidden';
|
|
72533
|
+
} else {
|
|
72534
|
+
zoomContainerClass = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900';
|
|
72535
|
+
}
|
|
72536
|
+
$$1(this.zoomWidget.zoomContainer).removeClass();
|
|
72537
|
+
$$1(this.zoomWidget.zoomContainer).addClass(zoomContainerClass);
|
|
72538
|
+
}
|
|
72539
|
+
|
|
72540
|
+
|
|
72541
|
+
setCenterLineButtonVisibility(isWholeGenomeView) {
|
|
72542
|
+
if (isWholeGenomeView) {
|
|
72543
|
+
this.centerLineButton.setVisibility(!isWholeGenomeView);
|
|
72544
|
+
} else {
|
|
72545
|
+
this.centerLineButton.setVisibility(this.config.showCenterGuideButton);
|
|
72546
|
+
}
|
|
72547
|
+
}
|
|
72548
|
+
|
|
72549
|
+
setCursorGuideVisibility(doShowCursorGuide) {
|
|
72550
|
+
if (doShowCursorGuide) {
|
|
72551
|
+
this.cursorGuide.show();
|
|
72552
|
+
} else {
|
|
72553
|
+
this.cursorGuide.hide();
|
|
72554
|
+
}
|
|
72555
|
+
}
|
|
72556
|
+
|
|
72557
|
+
updateGenome(genome) {
|
|
72558
|
+
|
|
72559
|
+
let genomeLabel = (genome.id && genome.id.length < 20 ? genome.id : `${genome.id.substring(0, 8)}...${genome.id.substring(genome.id.length - 8)}`);
|
|
72560
|
+
this.$current_genome.text(genomeLabel);
|
|
72561
|
+
this.$current_genome.attr('title', genome.description);
|
|
72562
|
+
|
|
72563
|
+
// chromosome select widget -- Show this IFF its not explicitly hidden AND the genome has pre-loaded chromosomes
|
|
72564
|
+
const showChromosomeWidget =
|
|
72565
|
+
this.config.showChromosomeWidget !== false &&
|
|
72566
|
+
genome.showChromosomeWidget !== false &&
|
|
72567
|
+
genome.chromosomeNames &&
|
|
72568
|
+
genome.chromosomeNames.length > 1;
|
|
72569
|
+
|
|
72570
|
+
if (showChromosomeWidget) {
|
|
72571
|
+
this.chromosomeSelectWidget.update(genome);
|
|
72572
|
+
this.chromosomeSelectWidget.show();
|
|
72573
|
+
} else {
|
|
72574
|
+
this.chromosomeSelectWidget.hide();
|
|
72575
|
+
}
|
|
72576
|
+
}
|
|
72577
|
+
|
|
72578
|
+
updateLocus(loc, chrName) {
|
|
72579
|
+
if(this.$searchInput) {
|
|
72580
|
+
this.$searchInput.val(loc);
|
|
72581
|
+
}
|
|
72582
|
+
if (this.chromosomeSelectWidget) {
|
|
72583
|
+
this.chromosomeSelectWidget.select.value = chrName;
|
|
72584
|
+
}
|
|
72585
|
+
}
|
|
72586
|
+
|
|
72587
|
+
currentNavbarButtonClass() {
|
|
72588
|
+
return this.currentClass
|
|
72589
|
+
//const el = this.$navigation.get(0).querySelector('.igv-navbar-text-button')
|
|
72590
|
+
//return el ? 'igv-navbar-text-button' : 'igv-navbar-icon-button'
|
|
72591
|
+
}
|
|
72592
|
+
|
|
72593
|
+
setEnableTrackSelection(b) {
|
|
72594
|
+
this.multiTrackSelectButton.setMultiTrackSelection(b);
|
|
72595
|
+
}
|
|
72596
|
+
getEnableTrackSelection() {
|
|
72597
|
+
return this.multiTrackSelectButton.enableMultiTrackSelection
|
|
72598
|
+
}
|
|
72599
|
+
|
|
72600
|
+
hide() {
|
|
72601
|
+
this.$navigation.hide();
|
|
72602
|
+
}
|
|
72603
|
+
|
|
72604
|
+
show() {
|
|
72605
|
+
this.$navigation.show();
|
|
72606
|
+
}
|
|
72607
|
+
|
|
72608
|
+
}
|
|
72609
|
+
|
|
72610
|
+
|
|
72611
|
+
function logo() {
|
|
72612
|
+
|
|
72613
|
+
return $$1(
|
|
72614
|
+
'<svg width="690px" height="324px" viewBox="0 0 690 324" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
|
|
72615
|
+
'<title>IGV</title>' +
|
|
72616
|
+
'<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">' +
|
|
72617
|
+
'<g id="IGV" fill="#666666">' +
|
|
72618
|
+
'<polygon id="Path" points="379.54574 8.00169252 455.581247 8.00169252 515.564813 188.87244 532.884012 253.529506 537.108207 253.529506 554.849825 188.87244 614.833392 8.00169252 689.60164 8.00169252 582.729511 320.722144 486.840288 320.722144"></polygon>' +
|
|
72619
|
+
'<path d="M261.482414,323.793286 C207.975678,323.793286 168.339046,310.552102 142.571329,284.069337 C116.803612,257.586572 103.919946,217.158702 103.919946,162.784513 C103.919946,108.410325 117.437235,67.8415913 144.472217,41.0770945 C171.507199,14.3125977 212.903894,0.930550071 268.663545,0.930550071 C283.025879,0.930550071 298.232828,1.84616386 314.284849,3.6774189 C330.33687,5.50867394 344.839793,7.97378798 357.794056,11.072835 L357.794056,68.968378 C339.48912,65.869331 323.578145,63.5450806 310.060654,61.9955571 C296.543163,60.4460336 284.574731,59.6712835 274.154998,59.6712835 C255.850062,59.6712835 240.502308,61.4320792 228.111274,64.9537236 C215.720241,68.4753679 205.793482,74.2507779 198.330701,82.2801269 C190.867919,90.309476 185.587729,100.87425 182.48997,113.974767 C179.392212,127.075284 177.843356,143.345037 177.843356,162.784513 C177.843356,181.942258 179.251407,198.000716 182.067551,210.960367 C184.883695,223.920018 189.671068,234.41436 196.429813,242.443709 C203.188559,250.473058 212.059279,256.178037 223.042241,259.558815 C234.025202,262.939594 247.683295,264.629958 264.01693,264.629958 C268.241146,264.629958 273.098922,264.489094 278.590403,264.207362 C284.081883,263.925631 289.643684,263.50304 295.275972,262.939577 L295.275972,159.826347 L361.595831,159.826347 L361.595831,308.579859 C344.698967,313.087564 327.239137,316.750019 309.215815,319.567334 C291.192494,322.38465 275.281519,323.793286 261.482414,323.793286 L261.482414,323.793286 L261.482414,323.793286 Z" id="Path"></path>;' +
|
|
72620
|
+
'<polygon id="Path" points="0.81355666 5.00169252 73.0472883 5.00169252 73.0472883 317.722144 0.81355666 317.722144"></polygon>' +
|
|
72621
|
+
'</g> </g> </svg>'
|
|
72622
|
+
)
|
|
72623
|
+
}
|
|
72624
|
+
|
|
71936
72625
|
const viewportColumnManager =
|
|
71937
72626
|
{
|
|
71938
72627
|
createColumns: (columnContainer, count) => {
|
|
@@ -72144,18 +72833,6 @@
|
|
|
72144
72833
|
this.button.style.display = 'none';
|
|
72145
72834
|
};
|
|
72146
72835
|
|
|
72147
|
-
/**
|
|
72148
|
-
* User supplied button for the navbar
|
|
72149
|
-
*/
|
|
72150
|
-
|
|
72151
|
-
const CustomButton = function (parent, browser, b) {
|
|
72152
|
-
|
|
72153
|
-
const button = div({class: 'igv-navbar-button'});
|
|
72154
|
-
parent.append(button);
|
|
72155
|
-
button.textContent = b.label;
|
|
72156
|
-
button.addEventListener('click', () => b.callback(browser));
|
|
72157
|
-
};
|
|
72158
|
-
|
|
72159
72836
|
const maxSequenceSize = 1000000;
|
|
72160
72837
|
const maxBlatSize = 25000;
|
|
72161
72838
|
|
|
@@ -72920,88 +73597,6 @@
|
|
|
72920
73597
|
}
|
|
72921
73598
|
}
|
|
72922
73599
|
|
|
72923
|
-
const roiImage =
|
|
72924
|
-
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
72925
|
-
<title>roi</title>
|
|
72926
|
-
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
72927
|
-
<g id="roi">
|
|
72928
|
-
<rect id="Rectangle-Copy-23" stroke="#737373" stroke-width="12" fill="#FFFFFF" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
72929
|
-
<text id="ROI" font-family="HelveticaNeue-Bold, Helvetica Neue" font-size="258" font-weight="bold" fill="#737373">
|
|
72930
|
-
<tspan x="81.445" y="389">ROI</tspan>
|
|
72931
|
-
</text>
|
|
72932
|
-
</g>
|
|
72933
|
-
</g>
|
|
72934
|
-
</svg>`;
|
|
72935
|
-
|
|
72936
|
-
const roiImageHover =
|
|
72937
|
-
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
72938
|
-
<title>roi hover</title>
|
|
72939
|
-
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
72940
|
-
<g id="roi-hover">
|
|
72941
|
-
<rect id="Rectangle-Copy-24" stroke="#737373" stroke-width="12" fill="#737373" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
72942
|
-
<text id="ROI" font-family="HelveticaNeue-Bold, Helvetica Neue" font-size="258" font-weight="bold" fill="#FFFFFF">
|
|
72943
|
-
<tspan x="81.445" y="389">ROI</tspan>
|
|
72944
|
-
</text>
|
|
72945
|
-
</g>
|
|
72946
|
-
</g>
|
|
72947
|
-
</svg>`;
|
|
72948
|
-
|
|
72949
|
-
/*
|
|
72950
|
-
* The MIT License (MIT)
|
|
72951
|
-
*
|
|
72952
|
-
* Copyright (c) 2016 University of California San Diego
|
|
72953
|
-
* Author: Jim Robinson
|
|
72954
|
-
*
|
|
72955
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
72956
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
72957
|
-
* in the Software without restriction, including without limitation the rights
|
|
72958
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
72959
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
72960
|
-
* furnished to do so, subject to the following conditions:
|
|
72961
|
-
*
|
|
72962
|
-
* The above copyright notice and this permission notice shall be included in
|
|
72963
|
-
* all copies or substantial portions of the Software.
|
|
72964
|
-
*
|
|
72965
|
-
*
|
|
72966
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
72967
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
72968
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
72969
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
72970
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
72971
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
72972
|
-
* THE SOFTWARE.
|
|
72973
|
-
*/
|
|
72974
|
-
|
|
72975
|
-
class ROITableControl extends NavbarButton {
|
|
72976
|
-
|
|
72977
|
-
constructor(parent, browser) {
|
|
72978
|
-
|
|
72979
|
-
super(browser, parent, [ 'ROI', 'Regions of Interest Table' ], buttonLabel, roiImage, roiImageHover, false);
|
|
72980
|
-
|
|
72981
|
-
this.button.addEventListener('mouseenter', () => {
|
|
72982
|
-
if (false === browser.doShowROITable) {
|
|
72983
|
-
this.setState(true);
|
|
72984
|
-
}
|
|
72985
|
-
});
|
|
72986
|
-
|
|
72987
|
-
this.button.addEventListener('mouseleave', () => {
|
|
72988
|
-
if (false === browser.doShowROITable) {
|
|
72989
|
-
this.setState(false);
|
|
72990
|
-
}
|
|
72991
|
-
});
|
|
72992
|
-
|
|
72993
|
-
this.button.addEventListener('click', () => this.buttonHandler(!browser.doShowROITable));
|
|
72994
|
-
|
|
72995
|
-
this.setVisibility(false); // Hide initially, it will be un-hidden if ROIs are loaded
|
|
72996
|
-
|
|
72997
|
-
}
|
|
72998
|
-
|
|
72999
|
-
buttonHandler(status) {
|
|
73000
|
-
this.setState(status);
|
|
73001
|
-
this.browser.setROITableVisibility(status);
|
|
73002
|
-
}
|
|
73003
|
-
}
|
|
73004
|
-
|
|
73005
73600
|
async function translateSession(juiceboxSession) {
|
|
73006
73601
|
|
|
73007
73602
|
const jbBrowser = juiceboxSession.browsers[0];
|
|
@@ -73038,101 +73633,6 @@
|
|
|
73038
73633
|
|
|
73039
73634
|
}
|
|
73040
73635
|
|
|
73041
|
-
const multiSelectImage =
|
|
73042
|
-
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
73043
|
-
<title>multi select</title>
|
|
73044
|
-
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
73045
|
-
<g id="multi-select">
|
|
73046
|
-
<rect id="backdrop-copy-3" stroke="#737373" stroke-width="12" fill="#FFFFFF" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
73047
|
-
<g id="row-copy-3" transform="translate(81, 427)" fill="#737373">
|
|
73048
|
-
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
73049
|
-
<rect id="Rectangle-Copy-16" stroke="#737373" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
73050
|
-
</g>
|
|
73051
|
-
<g id="row-copy-2" transform="translate(82, 277)">
|
|
73052
|
-
<rect id="Rectangle" fill-opacity="0.33" fill="#CFCECE" x="133" y="0" width="329" height="70"></rect>
|
|
73053
|
-
<rect id="Rectangle-Copy-16" stroke-opacity="0.32659528" stroke="#CFCECE" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
73054
|
-
</g>
|
|
73055
|
-
<g id="row-copy" transform="translate(81, 119)" fill="#737373">
|
|
73056
|
-
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
73057
|
-
<rect id="Rectangle-Copy-17" stroke="#737373" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
73058
|
-
</g>
|
|
73059
|
-
</g>
|
|
73060
|
-
</g>
|
|
73061
|
-
</svg>`;
|
|
73062
|
-
|
|
73063
|
-
const multiSelectImageHover =
|
|
73064
|
-
`<svg width="625px" height="625px" viewBox="0 0 625 625" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
73065
|
-
<title>multi select hover</title>
|
|
73066
|
-
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
73067
|
-
<g id="multi-select-hover">
|
|
73068
|
-
<rect id="backdrop-copy-4" stroke="#737373" stroke-width="12" fill="#737373" x="6" y="6" width="613" height="613" rx="135"></rect>
|
|
73069
|
-
<g id="row-copy-3" transform="translate(81, 427)" fill="#FFFFFF">
|
|
73070
|
-
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
73071
|
-
<rect id="Rectangle-Copy-16" stroke="#FFFFFF" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
73072
|
-
</g>
|
|
73073
|
-
<g id="row-copy-2" transform="translate(82, 277)">
|
|
73074
|
-
<rect id="Rectangle" fill-opacity="0.33" fill="#CFCECE" x="133" y="0" width="329" height="70"></rect>
|
|
73075
|
-
<rect id="Rectangle-Copy-16" stroke-opacity="0.33" stroke="#CFCECE" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
73076
|
-
</g>
|
|
73077
|
-
<g id="row-copy" transform="translate(81, 119)" fill="#FFFFFF">
|
|
73078
|
-
<rect id="Rectangle" x="134" y="0" width="329" height="70"></rect>
|
|
73079
|
-
<rect id="Rectangle-Copy-17" stroke="#FFFFFF" stroke-width="12" x="6" y="6" width="58" height="58"></rect>
|
|
73080
|
-
</g>
|
|
73081
|
-
</g>
|
|
73082
|
-
</g>
|
|
73083
|
-
</svg>`;
|
|
73084
|
-
|
|
73085
|
-
class MultiTrackSelectButton extends NavbarButton {
|
|
73086
|
-
|
|
73087
|
-
constructor(browser, parent, enableMultiTrackSelection) {
|
|
73088
|
-
|
|
73089
|
-
super(browser, parent, 'Select Tracks', buttonLabel, multiSelectImage, multiSelectImageHover, enableMultiTrackSelection = false);
|
|
73090
|
-
this.enableMultiTrackSelection = enableMultiTrackSelection;
|
|
73091
|
-
this.button.addEventListener('mouseenter', event => {
|
|
73092
|
-
if (false === enableMultiTrackSelection) {
|
|
73093
|
-
this.setState(true);
|
|
73094
|
-
}
|
|
73095
|
-
});
|
|
73096
|
-
|
|
73097
|
-
this.button.addEventListener('mouseleave', event => {
|
|
73098
|
-
if (false === enableMultiTrackSelection) {
|
|
73099
|
-
this.setState(false);
|
|
73100
|
-
}
|
|
73101
|
-
});
|
|
73102
|
-
|
|
73103
|
-
const mouseClickHandler = () => {
|
|
73104
|
-
this.setMultiTrackSelection(!this.enableMultiTrackSelection);
|
|
73105
|
-
};
|
|
73106
|
-
|
|
73107
|
-
this.boundMouseClickHandler = mouseClickHandler.bind(this);
|
|
73108
|
-
|
|
73109
|
-
this.button.addEventListener('click', this.boundMouseClickHandler);
|
|
73110
|
-
|
|
73111
|
-
this.setVisibility(true);
|
|
73112
|
-
|
|
73113
|
-
}
|
|
73114
|
-
|
|
73115
|
-
setMultiTrackSelection(enableMultiTrackSelection) {
|
|
73116
|
-
this.enableMultiTrackSelection = enableMultiTrackSelection;
|
|
73117
|
-
for (const trackView of this.browser.trackViews) {
|
|
73118
|
-
if (false === multiTrackSelectExclusionTypes.has(trackView.track.type)) {
|
|
73119
|
-
trackView.setTrackSelectionState(trackView.axis, this.enableMultiTrackSelection);
|
|
73120
|
-
|
|
73121
|
-
// If closing the selection boxes set track selected property to false
|
|
73122
|
-
if (!this.enableMultiTrackSelection) {
|
|
73123
|
-
trackView.track.selected = false;
|
|
73124
|
-
}
|
|
73125
|
-
}
|
|
73126
|
-
}
|
|
73127
|
-
this.setState(this.enableMultiTrackSelection);
|
|
73128
|
-
|
|
73129
|
-
// If enableMultiTrackSelection is false hide Overlay button
|
|
73130
|
-
if (false === this.enableMultiTrackSelection) {
|
|
73131
|
-
this.browser.overlayTrackButton.setVisibility(false);
|
|
73132
|
-
}
|
|
73133
|
-
}
|
|
73134
|
-
}
|
|
73135
|
-
|
|
73136
73636
|
/**
|
|
73137
73637
|
* Chromosome alias source backed by a UCSC bigbed file
|
|
73138
73638
|
*
|
|
@@ -73152,6 +73652,13 @@
|
|
|
73152
73652
|
this.reader = new BWReader(config, genome);
|
|
73153
73653
|
}
|
|
73154
73654
|
|
|
73655
|
+
async preload(chrNames) {
|
|
73656
|
+
await this.reader.preload();
|
|
73657
|
+
for(let nm of chrNames) {
|
|
73658
|
+
await this.search(nm);
|
|
73659
|
+
}
|
|
73660
|
+
}
|
|
73661
|
+
|
|
73155
73662
|
/**
|
|
73156
73663
|
* Return the cached canonical chromosome name for the alias. If none found return the alias.
|
|
73157
73664
|
*
|
|
@@ -73227,6 +73734,10 @@
|
|
|
73227
73734
|
this.genome = genome;
|
|
73228
73735
|
}
|
|
73229
73736
|
|
|
73737
|
+
async preload() {
|
|
73738
|
+
return this.loadAliases();
|
|
73739
|
+
}
|
|
73740
|
+
|
|
73230
73741
|
/**
|
|
73231
73742
|
* Return the canonical chromosome name for the alias. If none found return the alias
|
|
73232
73743
|
*
|
|
@@ -73279,6 +73790,9 @@
|
|
|
73279
73790
|
aliasRecord[key] = tokens[i];
|
|
73280
73791
|
this.aliasRecordCache.set(tokens[i], aliasRecord);
|
|
73281
73792
|
}
|
|
73793
|
+
|
|
73794
|
+
this.aliasRecordCache.set(chr.toLowerCase(), aliasRecord);
|
|
73795
|
+
this.aliasRecordCache.set(chr.toUpperCase(), aliasRecord);
|
|
73282
73796
|
}
|
|
73283
73797
|
}
|
|
73284
73798
|
}
|
|
@@ -73450,6 +73964,9 @@
|
|
|
73450
73964
|
this.update(id, chromosomeNames);
|
|
73451
73965
|
}
|
|
73452
73966
|
|
|
73967
|
+
async preload() {
|
|
73968
|
+
// no-op
|
|
73969
|
+
}
|
|
73453
73970
|
|
|
73454
73971
|
/**
|
|
73455
73972
|
* Return the canonical chromosome name for the alias. If none found return the alias
|
|
@@ -73551,6 +74068,8 @@
|
|
|
73551
74068
|
} else if (Number.isInteger(Number(name))) {
|
|
73552
74069
|
record["ucsc"] = "chr" + name;
|
|
73553
74070
|
}
|
|
74071
|
+
|
|
74072
|
+
|
|
73554
74073
|
}
|
|
73555
74074
|
}
|
|
73556
74075
|
|
|
@@ -73558,7 +74077,10 @@
|
|
|
73558
74077
|
for (let a of Object.values(rec)) {
|
|
73559
74078
|
this.aliasRecordCache.set(a, rec);
|
|
73560
74079
|
}
|
|
74080
|
+
this.aliasRecordCache.set(rec.chr.toLowerCase(), rec);
|
|
74081
|
+
this.aliasRecordCache.set(rec.chr.toUpperCase(), rec);
|
|
73561
74082
|
}
|
|
74083
|
+
|
|
73562
74084
|
}
|
|
73563
74085
|
}
|
|
73564
74086
|
|
|
@@ -73626,7 +74148,7 @@
|
|
|
73626
74148
|
|
|
73627
74149
|
if (config.chromAliasBbURL) {
|
|
73628
74150
|
this.chromAlias = new ChromAliasBB(config.chromAliasBbURL, Object.assign({}, config), this);
|
|
73629
|
-
if(!this.chromosomeNames) {
|
|
74151
|
+
if (!this.chromosomeNames) {
|
|
73630
74152
|
this.chromosomeNames = await this.chromAlias.getChromosomeNames();
|
|
73631
74153
|
}
|
|
73632
74154
|
} else if (config.aliasURL) {
|
|
@@ -73637,17 +74159,17 @@
|
|
|
73637
74159
|
|
|
73638
74160
|
if (config.cytobandBbURL) {
|
|
73639
74161
|
this.cytobandSource = new CytobandFileBB(config.cytobandBbURL, Object.assign({}, config), this);
|
|
73640
|
-
if(!this.chromosomeNames) {
|
|
74162
|
+
if (!this.chromosomeNames) {
|
|
73641
74163
|
this.chromosomeNames = await this.cytobandSource.getChromosomeNames();
|
|
73642
74164
|
}
|
|
73643
74165
|
} else if (config.cytobandURL) {
|
|
73644
74166
|
this.cytobandSource = new CytobandFile(config.cytobandURL, Object.assign({}, config));
|
|
73645
|
-
if(!this.chromosomeNames) {
|
|
74167
|
+
if (!this.chromosomeNames) {
|
|
73646
74168
|
this.chromosomeNames = await this.cytobandSource.getChromosomeNames();
|
|
73647
74169
|
}
|
|
73648
|
-
if(this.chromosomes.size === 0) {
|
|
74170
|
+
if (this.chromosomes.size === 0) {
|
|
73649
74171
|
const c = await this.cytobandSource.getChromosomes();
|
|
73650
|
-
for(let chromosome of c) {
|
|
74172
|
+
for (let chromosome of c) {
|
|
73651
74173
|
this.chromosomes.set(c.name, c);
|
|
73652
74174
|
}
|
|
73653
74175
|
}
|
|
@@ -73665,6 +74187,7 @@
|
|
|
73665
74187
|
} else {
|
|
73666
74188
|
this.#wgChromosomeNames = trimSmallChromosomes(this.chromosomes);
|
|
73667
74189
|
}
|
|
74190
|
+
await this.chromAlias.preload(this.#wgChromosomeNames);
|
|
73668
74191
|
}
|
|
73669
74192
|
|
|
73670
74193
|
// Optionally create the psuedo chromosome "all" to support whole genome view
|
|
@@ -73731,15 +74254,15 @@
|
|
|
73731
74254
|
async loadChromosome(chr) {
|
|
73732
74255
|
|
|
73733
74256
|
if (this.chromAlias) {
|
|
73734
|
-
|
|
73735
|
-
if(chromAliasRecord) {
|
|
74257
|
+
const chromAliasRecord = await this.chromAlias.search(chr);
|
|
74258
|
+
if (chromAliasRecord) {
|
|
73736
74259
|
chr = chromAliasRecord.chr;
|
|
73737
74260
|
}
|
|
73738
74261
|
}
|
|
73739
74262
|
|
|
73740
74263
|
if (!this.chromosomes.has(chr)) {
|
|
73741
74264
|
let chromosome;
|
|
73742
|
-
const
|
|
74265
|
+
const sequenceRecord = await this.sequence.getSequenceRecord(chr);
|
|
73743
74266
|
if (sequenceRecord) {
|
|
73744
74267
|
chromosome = new Chromosome(chr, 0, sequenceRecord.bpLength);
|
|
73745
74268
|
}
|
|
@@ -73749,6 +74272,7 @@
|
|
|
73749
74272
|
|
|
73750
74273
|
return this.chromosomes.get(chr)
|
|
73751
74274
|
}
|
|
74275
|
+
|
|
73752
74276
|
async getAliasRecord(chr) {
|
|
73753
74277
|
if (this.chromAlias) {
|
|
73754
74278
|
return this.chromAlias.search(chr)
|
|
@@ -73768,7 +74292,7 @@
|
|
|
73768
74292
|
}
|
|
73769
74293
|
|
|
73770
74294
|
get wgChromosomeNames() {
|
|
73771
|
-
return this.#wgChromosomeNames ?
|
|
74295
|
+
return this.#wgChromosomeNames ? this.#wgChromosomeNames.slice() : undefined
|
|
73772
74296
|
}
|
|
73773
74297
|
|
|
73774
74298
|
get showChromosomeWidget() {
|
|
@@ -73872,7 +74396,7 @@
|
|
|
73872
74396
|
* @param end
|
|
73873
74397
|
*/
|
|
73874
74398
|
getSequenceInterval(chr, start, end) {
|
|
73875
|
-
if(typeof this.sequence.getSequenceInterval === 'function') {
|
|
74399
|
+
if (typeof this.sequence.getSequenceInterval === 'function') {
|
|
73876
74400
|
return this.sequence.getSequenceInterval(chr, start, end)
|
|
73877
74401
|
} else {
|
|
73878
74402
|
return undefined
|
|
@@ -74041,6 +74565,125 @@
|
|
|
74041
74565
|
brewer.push("rgb(204, 235, 197)");
|
|
74042
74566
|
brewer.push("rgb(255, 237, 111)");
|
|
74043
74567
|
|
|
74568
|
+
class SliderDialog {
|
|
74569
|
+
|
|
74570
|
+
constructor(parent) {
|
|
74571
|
+
|
|
74572
|
+
this.parent = parent;
|
|
74573
|
+
|
|
74574
|
+
// dialog container
|
|
74575
|
+
this.container = div({class: 'igv-ui-generic-dialog-container'});
|
|
74576
|
+
parent.appendChild(this.container);
|
|
74577
|
+
|
|
74578
|
+
// dialog header
|
|
74579
|
+
const header = div({class: 'igv-ui-generic-dialog-header'});
|
|
74580
|
+
this.container.appendChild(header);
|
|
74581
|
+
|
|
74582
|
+
// dialog label
|
|
74583
|
+
this.label = div({class: 'igv-ui-generic-dialog-one-liner'});
|
|
74584
|
+
this.container.appendChild(this.label);
|
|
74585
|
+
this.label.text = 'Unlabeled';
|
|
74586
|
+
|
|
74587
|
+
// input container
|
|
74588
|
+
this.input_container = div({class: 'igv-ui-generic-dialog-input'});
|
|
74589
|
+
this.container.appendChild(this.input_container);
|
|
74590
|
+
|
|
74591
|
+
// input element
|
|
74592
|
+
let html = `<input type="range" id="igv-slider-dialog-input" name="igv-slider-dialog-input" />`;
|
|
74593
|
+
this._input = document.createRange().createContextualFragment(html).firstChild;
|
|
74594
|
+
this.input_container.appendChild(this._input);
|
|
74595
|
+
|
|
74596
|
+
// output element
|
|
74597
|
+
html = `<output id="igv-slider-dialog-output" name="igv-slider-dialog-output" for="igv-slider-dialog-input"></output>`;
|
|
74598
|
+
this._output = document.createRange().createContextualFragment(html).firstChild;
|
|
74599
|
+
this.input_container.appendChild(this._output);
|
|
74600
|
+
|
|
74601
|
+
|
|
74602
|
+
// ok | cancel
|
|
74603
|
+
const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'});
|
|
74604
|
+
this.container.appendChild(buttons);
|
|
74605
|
+
|
|
74606
|
+
// ok
|
|
74607
|
+
this.ok = div();
|
|
74608
|
+
buttons.appendChild(this.ok);
|
|
74609
|
+
this.ok.textContent = 'OK';
|
|
74610
|
+
|
|
74611
|
+
// cancel
|
|
74612
|
+
this.cancel = div();
|
|
74613
|
+
buttons.appendChild(this.cancel);
|
|
74614
|
+
this.cancel.textContent = 'Cancel';
|
|
74615
|
+
|
|
74616
|
+
hide(this.container);
|
|
74617
|
+
|
|
74618
|
+
this._input.addEventListener('input', () => {
|
|
74619
|
+
const number = parseFloat(this._input.value)/this._scaleFactor;
|
|
74620
|
+
this.callback(number);
|
|
74621
|
+
this._output.value = `${number.toFixed(2)}`;
|
|
74622
|
+
}, false);
|
|
74623
|
+
|
|
74624
|
+
this.ok.addEventListener('click', () => {
|
|
74625
|
+
if (typeof this.callback === 'function') {
|
|
74626
|
+
const number = parseFloat(this._input.value)/this._scaleFactor;
|
|
74627
|
+
this.callback(number);
|
|
74628
|
+
this.callback = undefined;
|
|
74629
|
+
}
|
|
74630
|
+
this._input.value = undefined;
|
|
74631
|
+
hide(this.container);
|
|
74632
|
+
});
|
|
74633
|
+
|
|
74634
|
+
const cancel = () => {
|
|
74635
|
+
this._input.value = undefined;
|
|
74636
|
+
hide(this.container);
|
|
74637
|
+
};
|
|
74638
|
+
|
|
74639
|
+
this.cancel.addEventListener('click', cancel);
|
|
74640
|
+
|
|
74641
|
+
attachDialogCloseHandlerWithParent(header, cancel);
|
|
74642
|
+
makeDraggable(this.container, header);
|
|
74643
|
+
|
|
74644
|
+
}
|
|
74645
|
+
|
|
74646
|
+
get value() {
|
|
74647
|
+
return purify.sanitize(this._input.value)
|
|
74648
|
+
}
|
|
74649
|
+
|
|
74650
|
+
present(options, e) {
|
|
74651
|
+
|
|
74652
|
+
this.label.textContent = options.label;
|
|
74653
|
+
|
|
74654
|
+
this._scaleFactor = options.scaleFactor;
|
|
74655
|
+
const [ minS, maxS, valueS ] = [ options.min, options.max, options.value ].map(number => (Math.floor(this._scaleFactor * number)).toString());
|
|
74656
|
+
|
|
74657
|
+
this._input.min = minS;
|
|
74658
|
+
this._input.max = maxS;
|
|
74659
|
+
this._input.value = valueS;
|
|
74660
|
+
|
|
74661
|
+
const numer = parseFloat(valueS);
|
|
74662
|
+
const denom = this._scaleFactor;
|
|
74663
|
+
const number = numer/denom;
|
|
74664
|
+
this._output.value = `${number.toFixed(2)}`;
|
|
74665
|
+
|
|
74666
|
+
this.callback = options.callback || options.click;
|
|
74667
|
+
|
|
74668
|
+
show(this.container);
|
|
74669
|
+
this.clampLocation(e.clientX, e.clientY);
|
|
74670
|
+
|
|
74671
|
+
}
|
|
74672
|
+
|
|
74673
|
+
clampLocation(clientX, clientY) {
|
|
74674
|
+
|
|
74675
|
+
const {width: w, height: h} = this.container.getBoundingClientRect();
|
|
74676
|
+
const wh = window.innerHeight;
|
|
74677
|
+
const ww = window.innerWidth;
|
|
74678
|
+
|
|
74679
|
+
const y = Math.min(wh - h, clientY);
|
|
74680
|
+
const x = Math.min(ww - w, clientX);
|
|
74681
|
+
this.container.style.left = `${x}px`;
|
|
74682
|
+
this.container.style.top = `${y}px`;
|
|
74683
|
+
|
|
74684
|
+
}
|
|
74685
|
+
}
|
|
74686
|
+
|
|
74044
74687
|
// css - $igv-scrollbar-outer-width: 14px;
|
|
74045
74688
|
const igv_scrollbar_outer_width = 14;
|
|
74046
74689
|
|
|
@@ -74130,7 +74773,6 @@
|
|
|
74130
74773
|
this.sampleNameControl.setState(this.showSampleNames);
|
|
74131
74774
|
this.sampleNameControl.hide();
|
|
74132
74775
|
|
|
74133
|
-
|
|
74134
74776
|
this.layoutChange();
|
|
74135
74777
|
}
|
|
74136
74778
|
});
|
|
@@ -74149,7 +74791,7 @@
|
|
|
74149
74791
|
|
|
74150
74792
|
this.sampleInfo = new SampleInfo(this);
|
|
74151
74793
|
|
|
74152
|
-
this.
|
|
74794
|
+
this.createStandardControls(config);
|
|
74153
74795
|
|
|
74154
74796
|
// Region of interest
|
|
74155
74797
|
this.roiManager = new ROIManager(this);
|
|
@@ -74207,121 +74849,18 @@
|
|
|
74207
74849
|
}
|
|
74208
74850
|
}
|
|
74209
74851
|
|
|
74210
|
-
setControls(config) {
|
|
74211
|
-
|
|
74212
|
-
const $navBar = this.createStandardControls(config);
|
|
74213
|
-
$navBar.insertBefore($$1(this.columnContainer));
|
|
74214
|
-
this.$navigation = $navBar;
|
|
74215
|
-
|
|
74216
|
-
if (false === config.showControls) {
|
|
74217
|
-
$navBar.hide();
|
|
74218
|
-
}
|
|
74219
|
-
|
|
74220
|
-
}
|
|
74221
|
-
|
|
74222
74852
|
createStandardControls(config) {
|
|
74223
74853
|
|
|
74224
|
-
const $navBar = $$1('<div>', {class: 'igv-navbar'});
|
|
74225
|
-
this.$navigation = $navBar;
|
|
74226
|
-
|
|
74227
|
-
const $navbarLeftContainer = $$1('<div>', {class: 'igv-navbar-left-container'});
|
|
74228
|
-
$navBar.append($navbarLeftContainer);
|
|
74229
|
-
|
|
74230
|
-
// IGV logo
|
|
74231
|
-
const $logo = $$1('<div>', {class: 'igv-logo'});
|
|
74232
|
-
$navbarLeftContainer.append($logo);
|
|
74233
|
-
|
|
74234
|
-
const logoSvg = logo();
|
|
74235
|
-
logoSvg.css("width", "34px");
|
|
74236
|
-
logoSvg.css("height", "32px");
|
|
74237
|
-
$logo.append(logoSvg);
|
|
74238
|
-
|
|
74239
|
-
this.$current_genome = $$1('<div>', {class: 'igv-current-genome'});
|
|
74240
|
-
$navbarLeftContainer.append(this.$current_genome);
|
|
74241
|
-
this.$current_genome.text('');
|
|
74242
|
-
|
|
74243
|
-
const $genomicLocation = $$1('<div>', {class: 'igv-navbar-genomic-location'});
|
|
74244
|
-
$navbarLeftContainer.append($genomicLocation);
|
|
74245
|
-
|
|
74246
|
-
// chromosome select widget
|
|
74247
|
-
this.chromosomeSelectWidget = new ChromosomeSelectWidget(this, $genomicLocation.get(0));
|
|
74248
|
-
if (config.showChromosomeWidget !== false) {
|
|
74249
|
-
this.chromosomeSelectWidget.show();
|
|
74250
|
-
} else {
|
|
74251
|
-
this.chromosomeSelectWidget.hide();
|
|
74252
|
-
}
|
|
74253
|
-
|
|
74254
|
-
const $locusSizeGroup = $$1('<div>', {class: 'igv-locus-size-group'});
|
|
74255
|
-
$genomicLocation.append($locusSizeGroup);
|
|
74256
|
-
|
|
74257
|
-
const $searchContainer = $$1('<div>', {class: 'igv-search-container'});
|
|
74258
|
-
$locusSizeGroup.append($searchContainer);
|
|
74259
|
-
|
|
74260
|
-
// browser.$searchInput = $('<input type="text" placeholder="Locus Search">');
|
|
74261
|
-
this.$searchInput = $$1('<input>', {class: 'igv-search-input', type: 'text', placeholder: 'Locus Search'});
|
|
74262
|
-
$searchContainer.append(this.$searchInput);
|
|
74263
|
-
// Stop event propagation to prevent feature track keyboard navigation
|
|
74264
|
-
this.$searchInput[0].addEventListener('keyup', (event) => {
|
|
74265
|
-
event.stopImmediatePropagation();
|
|
74266
|
-
});
|
|
74267
|
-
|
|
74268
|
-
this.$searchInput.change(() => this.doSearch(this.$searchInput.val()));
|
|
74269
|
-
|
|
74270
|
-
const searchIconContainer = div({class: 'igv-search-icon-container'});
|
|
74271
|
-
$searchContainer.append($$1(searchIconContainer));
|
|
74272
|
-
|
|
74273
|
-
searchIconContainer.appendChild(createIcon("search"));
|
|
74274
|
-
|
|
74275
|
-
searchIconContainer.addEventListener('click', () => this.doSearch(this.$searchInput.val()));
|
|
74276
|
-
|
|
74277
|
-
this.windowSizePanel = new WindowSizePanel($locusSizeGroup.get(0), this);
|
|
74278
|
-
|
|
74279
|
-
const $navbarRightContainer = $$1('<div>', {class: 'igv-navbar-right-container'});
|
|
74280
|
-
$navBar.append($navbarRightContainer);
|
|
74281
|
-
|
|
74282
|
-
const $toggle_button_container = $$1('<div class="igv-navbar-toggle-button-container">');
|
|
74283
|
-
$navbarRightContainer.append($toggle_button_container);
|
|
74284
|
-
this.$toggle_button_container = $toggle_button_container;
|
|
74285
|
-
|
|
74286
|
-
this.overlayTrackButton = new OverlayTrackButton(this, $toggle_button_container.get(0));
|
|
74287
|
-
this.overlayTrackButton.setVisibility(false);
|
|
74288
|
-
|
|
74289
|
-
this.multiTrackSelectButton = new MultiTrackSelectButton(this, $toggle_button_container.get(0));
|
|
74290
|
-
|
|
74291
|
-
this.cursorGuide = new CursorGuide(this.columnContainer, this);
|
|
74292
|
-
|
|
74293
|
-
this.cursorGuideButton = new CursorGuideButton(this, $toggle_button_container.get(0));
|
|
74294
|
-
|
|
74295
|
-
this.centerLineButton = new CenterLineButton(this, $toggle_button_container.get(0));
|
|
74296
|
-
|
|
74297
74854
|
this.setTrackLabelVisibility(config.showTrackLabels);
|
|
74298
|
-
this.trackLabelControl = new TrackLabelControl($toggle_button_container.get(0), this);
|
|
74299
74855
|
|
|
74300
|
-
|
|
74301
|
-
this.roiTableControl = new ROITableControl($toggle_button_container.get(0), this);
|
|
74302
|
-
|
|
74303
|
-
this.sampleInfoControl = new SampleInfoControl($toggle_button_container.get(0), this);
|
|
74856
|
+
this.navbar = new ResponsiveNavbar(config, this);
|
|
74304
74857
|
|
|
74305
|
-
this.
|
|
74306
|
-
|
|
74307
|
-
if (true === config.showSVGButton) {
|
|
74308
|
-
this.saveImageControl = new SaveImageControl($toggle_button_container.get(0), this);
|
|
74309
|
-
}
|
|
74858
|
+
this.navbar.$navigation.insertBefore($$1(this.columnContainer));
|
|
74310
74859
|
|
|
74311
|
-
if (config.
|
|
74312
|
-
|
|
74313
|
-
new CustomButton($toggle_button_container.get(0), this, b);
|
|
74314
|
-
}
|
|
74315
|
-
}
|
|
74316
|
-
|
|
74317
|
-
this.zoomWidget = new ZoomWidget(this, $navbarRightContainer.get(0));
|
|
74318
|
-
|
|
74319
|
-
if (false === config.showNavigation) {
|
|
74320
|
-
this.$navigation.hide();
|
|
74860
|
+
if (false === config.showControls) {
|
|
74861
|
+
this.navbar.hide();
|
|
74321
74862
|
}
|
|
74322
|
-
|
|
74323
|
-
this.sliderDialog = new SliderDialog(this.root);
|
|
74324
|
-
this.sliderDialog.container.id = `igv-slider-dialog-${guid$2()}`;
|
|
74863
|
+
this.cursorGuide = new CursorGuide(this.columnContainer, this);
|
|
74325
74864
|
|
|
74326
74865
|
this.inputDialog = new InputDialog(this.root);
|
|
74327
74866
|
this.inputDialog.container.id = `igv-input-dialog-${guid$2()}`;
|
|
@@ -74332,7 +74871,8 @@
|
|
|
74332
74871
|
this.genericColorPicker = new GenericColorPicker({parent: this.columnContainer, width: 432});
|
|
74333
74872
|
this.genericColorPicker.container.id = `igv-track-color-picker-${guid$2()}`;
|
|
74334
74873
|
|
|
74335
|
-
|
|
74874
|
+
this.sliderDialog = new SliderDialog(this.root);
|
|
74875
|
+
this.sliderDialog.container.id = `igv-slider-dialog-${guid$2()}`;
|
|
74336
74876
|
|
|
74337
74877
|
}
|
|
74338
74878
|
|
|
@@ -74563,10 +75103,10 @@
|
|
|
74563
75103
|
session = await translateSession(session);
|
|
74564
75104
|
}
|
|
74565
75105
|
|
|
74566
|
-
this.sampleInfoControl.setButtonVisibility(false);
|
|
75106
|
+
this.navbar.sampleInfoControl.setButtonVisibility(false);
|
|
74567
75107
|
|
|
74568
75108
|
this.showSampleNames = session.showSampleNames || false;
|
|
74569
|
-
this.sampleNameControl.setState(this.showSampleNames === true);
|
|
75109
|
+
this.navbar.sampleNameControl.setState(this.showSampleNames === true);
|
|
74570
75110
|
|
|
74571
75111
|
if (session.sampleNameViewportWidth) {
|
|
74572
75112
|
this.sampleNameViewportWidth = session.sampleNameViewportWidth;
|
|
@@ -74686,9 +75226,9 @@
|
|
|
74686
75226
|
await rtv.updateViews();
|
|
74687
75227
|
}
|
|
74688
75228
|
|
|
74689
|
-
// If any tracks are selected show the
|
|
75229
|
+
// If any tracks are selected show the selection buttons
|
|
74690
75230
|
if (this.trackViews.some(tv => tv.track.selected)) {
|
|
74691
|
-
this.
|
|
75231
|
+
this.navbar.setEnableTrackSelection(true);
|
|
74692
75232
|
}
|
|
74693
75233
|
|
|
74694
75234
|
this.updateUIWithReferenceFrameList();
|
|
@@ -74729,7 +75269,8 @@
|
|
|
74729
75269
|
|
|
74730
75270
|
this.removeAllTracks(); // Do this first, before new genome is set
|
|
74731
75271
|
this.roiManager.clearROIs();
|
|
74732
|
-
|
|
75272
|
+
|
|
75273
|
+
this.navbar.setEnableTrackSelection(false);
|
|
74733
75274
|
|
|
74734
75275
|
let genome;
|
|
74735
75276
|
if (genomeConfig.gbkURL) {
|
|
@@ -74742,8 +75283,7 @@
|
|
|
74742
75283
|
|
|
74743
75284
|
this.genome = genome;
|
|
74744
75285
|
|
|
74745
|
-
this.
|
|
74746
|
-
|
|
75286
|
+
this.navbar.updateGenome(genome);
|
|
74747
75287
|
|
|
74748
75288
|
let locus = initialLocus || genome.initialLocus;
|
|
74749
75289
|
if (Array.isArray(locus)) {
|
|
@@ -74774,26 +75314,6 @@
|
|
|
74774
75314
|
}
|
|
74775
75315
|
}
|
|
74776
75316
|
|
|
74777
|
-
updateNavbarDOMWithGenome(genome) {
|
|
74778
|
-
let genomeLabel = (genome.id && genome.id.length < 20 ? genome.id : `${genome.id.substring(0, 8)}...${genome.id.substring(genome.id.length - 8)}`);
|
|
74779
|
-
this.$current_genome.text(genomeLabel);
|
|
74780
|
-
this.$current_genome.attr('title', genome.description);
|
|
74781
|
-
|
|
74782
|
-
// chromosome select widget -- Show this IFF its not explicitly hidden AND the genome has pre-loaded chromosomes
|
|
74783
|
-
const showChromosomeWidget =
|
|
74784
|
-
this.config.showChromosomeWidget !== false &&
|
|
74785
|
-
this.genome.showChromosomeWidget !== false &&
|
|
74786
|
-
genome.chromosomeNames &&
|
|
74787
|
-
genome.chromosomeNames.length > 1;
|
|
74788
|
-
|
|
74789
|
-
if (showChromosomeWidget) {
|
|
74790
|
-
this.chromosomeSelectWidget.update(genome);
|
|
74791
|
-
this.chromosomeSelectWidget.show();
|
|
74792
|
-
} else {
|
|
74793
|
-
this.chromosomeSelectWidget.hide();
|
|
74794
|
-
}
|
|
74795
|
-
}
|
|
74796
|
-
|
|
74797
75317
|
/**
|
|
74798
75318
|
* Load a genome, defined by a string ID or a json-like configuration object. This includes a fasta reference
|
|
74799
75319
|
* as well as optional cytoband and annotation tracks.
|
|
@@ -74878,16 +75398,16 @@
|
|
|
74878
75398
|
|
|
74879
75399
|
(this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr));
|
|
74880
75400
|
|
|
74881
|
-
|
|
75401
|
+
this.navbar.navbarDidResize();
|
|
74882
75402
|
|
|
74883
75403
|
toggleTrackLabels(this.trackViews, this.doShowTrackLabels);
|
|
74884
75404
|
|
|
74885
75405
|
if (this.doShowCenterLine && GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)) {
|
|
74886
|
-
this.centerLineButton.boundMouseClickHandler();
|
|
75406
|
+
this.navbar.centerLineButton.boundMouseClickHandler();
|
|
74887
75407
|
}
|
|
74888
75408
|
|
|
74889
75409
|
if (this.doShowCursorGuide && GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)) {
|
|
74890
|
-
this.cursorGuideButton.boundMouseClickHandler();
|
|
75410
|
+
this.navbar.cursorGuideButton.boundMouseClickHandler();
|
|
74891
75411
|
}
|
|
74892
75412
|
|
|
74893
75413
|
this.setCenterLineAndCenterLineButtonVisibility(GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr));
|
|
@@ -74897,9 +75417,9 @@
|
|
|
74897
75417
|
setCenterLineAndCenterLineButtonVisibility(isWholeGenomeView) {
|
|
74898
75418
|
|
|
74899
75419
|
if (isWholeGenomeView) {
|
|
74900
|
-
this.centerLineButton.setVisibility(
|
|
75420
|
+
this.navbar.centerLineButton.setVisibility(false);
|
|
74901
75421
|
} else {
|
|
74902
|
-
this.centerLineButton.setVisibility(this.config.showCenterGuideButton);
|
|
75422
|
+
this.navbar.centerLineButton.setVisibility(this.config.showCenterGuideButton);
|
|
74903
75423
|
}
|
|
74904
75424
|
|
|
74905
75425
|
for (let centerLine of this.centerLineList) {
|
|
@@ -75105,7 +75625,7 @@
|
|
|
75105
75625
|
this.reorderTracks();
|
|
75106
75626
|
this.fireEvent('trackorderchanged', [this.getTrackOrder()]);
|
|
75107
75627
|
|
|
75108
|
-
|
|
75628
|
+
newTrack.trackView.enableTrackSelection(this.navbar.getEnableTrackSelection());
|
|
75109
75629
|
|
|
75110
75630
|
return newTrack
|
|
75111
75631
|
|
|
@@ -75473,8 +75993,7 @@
|
|
|
75473
75993
|
}
|
|
75474
75994
|
|
|
75475
75995
|
if (this.referenceFrameList) {
|
|
75476
|
-
this.
|
|
75477
|
-
navbarDidResize(this, this.$navigation.width());
|
|
75996
|
+
this.navbar.navbarDidResize();
|
|
75478
75997
|
}
|
|
75479
75998
|
|
|
75480
75999
|
resize.call(this);
|
|
@@ -75556,13 +76075,11 @@
|
|
|
75556
76075
|
referenceFrame.end = referenceFrame.start + referenceFrame.bpPerPixel * width;
|
|
75557
76076
|
}
|
|
75558
76077
|
|
|
75559
|
-
|
|
75560
|
-
this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : '';
|
|
75561
|
-
}
|
|
76078
|
+
const chrName = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : '';
|
|
75562
76079
|
|
|
75563
76080
|
const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' ');
|
|
75564
76081
|
|
|
75565
|
-
this
|
|
76082
|
+
this.navbar.updateLocus(loc, chrName);
|
|
75566
76083
|
|
|
75567
76084
|
this.fireEvent('locuschange', [this.referenceFrameList]);
|
|
75568
76085
|
}
|
|
@@ -75837,7 +76354,7 @@
|
|
|
75837
76354
|
async loadSampleInfo(config) {
|
|
75838
76355
|
|
|
75839
76356
|
await this.sampleInfo.loadSampleInfoFile(config.url);
|
|
75840
|
-
|
|
76357
|
+
|
|
75841
76358
|
for (const {sampleInfoViewport} of this.trackViews) {
|
|
75842
76359
|
sampleInfoViewport.setWidth(this.getSampleInfoColumnWidth());
|
|
75843
76360
|
}
|
|
@@ -76293,7 +76810,7 @@
|
|
|
76293
76810
|
createCircularView(container, show) {
|
|
76294
76811
|
show = show === true; // convert undefined to boolean
|
|
76295
76812
|
this.circularView = createCircularView(container, this);
|
|
76296
|
-
this.circularViewControl = new CircularViewControl(this
|
|
76813
|
+
this.circularViewControl = new CircularViewControl(this.navbar.toggle_button_container, this);
|
|
76297
76814
|
this.circularView.setAssembly({
|
|
76298
76815
|
name: this.genome.id,
|
|
76299
76816
|
id: this.genome.id,
|
|
@@ -76313,6 +76830,30 @@
|
|
|
76313
76830
|
this.circularViewControl.setState(isVisible);
|
|
76314
76831
|
}
|
|
76315
76832
|
}
|
|
76833
|
+
|
|
76834
|
+
|
|
76835
|
+
|
|
76836
|
+
// Navbar delegates
|
|
76837
|
+
get sampleInfoControl() {
|
|
76838
|
+
return this.navbar.sampleInfoControl
|
|
76839
|
+
}
|
|
76840
|
+
|
|
76841
|
+
get overlayTrackButton() {
|
|
76842
|
+
return this.navbar.overlayTrackButton
|
|
76843
|
+
}
|
|
76844
|
+
|
|
76845
|
+
get roiTableControl() {
|
|
76846
|
+
return this.navbar.roiTableControl
|
|
76847
|
+
}
|
|
76848
|
+
|
|
76849
|
+
get sampleInfoControl() {
|
|
76850
|
+
return this.navbar.sampleInfoControl
|
|
76851
|
+
}
|
|
76852
|
+
|
|
76853
|
+
get sampleNameControl() {
|
|
76854
|
+
return this.navbar.sampleNameControl
|
|
76855
|
+
}
|
|
76856
|
+
|
|
76316
76857
|
}
|
|
76317
76858
|
|
|
76318
76859
|
function getFileExtension(input) {
|
|
@@ -76522,21 +77063,6 @@
|
|
|
76522
77063
|
}
|
|
76523
77064
|
}
|
|
76524
77065
|
|
|
76525
|
-
|
|
76526
|
-
function logo() {
|
|
76527
|
-
|
|
76528
|
-
return $$1(
|
|
76529
|
-
'<svg width="690px" height="324px" viewBox="0 0 690 324" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
|
|
76530
|
-
'<title>IGV</title>' +
|
|
76531
|
-
'<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">' +
|
|
76532
|
-
'<g id="IGV" fill="#666666">' +
|
|
76533
|
-
'<polygon id="Path" points="379.54574 8.00169252 455.581247 8.00169252 515.564813 188.87244 532.884012 253.529506 537.108207 253.529506 554.849825 188.87244 614.833392 8.00169252 689.60164 8.00169252 582.729511 320.722144 486.840288 320.722144"></polygon>' +
|
|
76534
|
-
'<path d="M261.482414,323.793286 C207.975678,323.793286 168.339046,310.552102 142.571329,284.069337 C116.803612,257.586572 103.919946,217.158702 103.919946,162.784513 C103.919946,108.410325 117.437235,67.8415913 144.472217,41.0770945 C171.507199,14.3125977 212.903894,0.930550071 268.663545,0.930550071 C283.025879,0.930550071 298.232828,1.84616386 314.284849,3.6774189 C330.33687,5.50867394 344.839793,7.97378798 357.794056,11.072835 L357.794056,68.968378 C339.48912,65.869331 323.578145,63.5450806 310.060654,61.9955571 C296.543163,60.4460336 284.574731,59.6712835 274.154998,59.6712835 C255.850062,59.6712835 240.502308,61.4320792 228.111274,64.9537236 C215.720241,68.4753679 205.793482,74.2507779 198.330701,82.2801269 C190.867919,90.309476 185.587729,100.87425 182.48997,113.974767 C179.392212,127.075284 177.843356,143.345037 177.843356,162.784513 C177.843356,181.942258 179.251407,198.000716 182.067551,210.960367 C184.883695,223.920018 189.671068,234.41436 196.429813,242.443709 C203.188559,250.473058 212.059279,256.178037 223.042241,259.558815 C234.025202,262.939594 247.683295,264.629958 264.01693,264.629958 C268.241146,264.629958 273.098922,264.489094 278.590403,264.207362 C284.081883,263.925631 289.643684,263.50304 295.275972,262.939577 L295.275972,159.826347 L361.595831,159.826347 L361.595831,308.579859 C344.698967,313.087564 327.239137,316.750019 309.215815,319.567334 C291.192494,322.38465 275.281519,323.793286 261.482414,323.793286 L261.482414,323.793286 L261.482414,323.793286 Z" id="Path"></path>;' +
|
|
76535
|
-
'<polygon id="Path" points="0.81355666 5.00169252 73.0472883 5.00169252 73.0472883 317.722144 0.81355666 317.722144"></polygon>' +
|
|
76536
|
-
'</g> </g> </svg>'
|
|
76537
|
-
)
|
|
76538
|
-
}
|
|
76539
|
-
|
|
76540
77066
|
function toggleTrackLabels(trackViews, isVisible) {
|
|
76541
77067
|
|
|
76542
77068
|
for (let {viewports} of trackViews) {
|
|
@@ -76631,7 +77157,7 @@
|
|
|
76631
77157
|
}
|
|
76632
77158
|
|
|
76633
77159
|
browser.stopSpinner();
|
|
76634
|
-
|
|
77160
|
+
browser.navbar.navbarDidResize();
|
|
76635
77161
|
|
|
76636
77162
|
return browser
|
|
76637
77163
|
|