igv-rails 1.0.1.1 → 1.0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/igv/rails/version.rb +1 -1
- data/vendor/assets/javascripts/igv.js +1944 -968
- data/vendor/assets/stylesheets/igv.css +88 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76161467f05802730c2f1f2076a7d6de438fc135
|
4
|
+
data.tar.gz: 6bf22fd3d74470c663a0c9b9b7bae0c56a1f7955
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b4e7cec64c16cc4dfa1e8cd7c39a322217b374e0d8dfd19723226db3d465db1297bb28be0b42b246f99f4b573ba340702cbc9c8e8fbe558063cb13100ce85dc
|
7
|
+
data.tar.gz: 0590b833c50d84ab96b00e8dbec3ce6382b4c6c1c96301485688d8fb509a9f0cc465ef9edd620d6b0bafba6567fc69da7631e04687afd952100aa786d33cd64a
|
data/README.md
CHANGED
@@ -89,9 +89,9 @@ This is [igv-web](https://www.broadinstitute.org/software/igv/home) GEMified for
|
|
89
89
|
bundle gem igv-rails
|
90
90
|
cd igv-rails
|
91
91
|
mkdir -p vendor/assets/javascripts
|
92
|
-
curl http://igv.org/web/release/1.0.
|
92
|
+
curl http://igv.org/web/release/1.0.9/igv-1.0.9.js -o vendor/assets/javascripts/igv.js
|
93
93
|
mkdir -p vendor/assets/stylesheets
|
94
|
-
curl http://igv.org/web/release/1.0.
|
94
|
+
curl http://igv.org/web/release/1.0.9/igv-1.0.9.css -o vendor/assets/stylesheets/igv.css
|
95
95
|
echo "" >> README.md; echo "# igv appended README #" >> README.md; echo "" >> README.md
|
96
96
|
curl https://github.com/broadinstitute/igv-web/blob/master/README.md >> README.md
|
97
97
|
echo "" >> LICENSE; echo "# igv appended LICENSE #" >> LICENSE; echo "" >> LICENSE
|
@@ -102,7 +102,7 @@ This is [igv-web](https://www.broadinstitute.org/software/igv/home) GEMified for
|
|
102
102
|
|
103
103
|
* modify **lib/igv/rails/version.rb** to match igv-all.js version
|
104
104
|
|
105
|
-
VERSION = "1.0.
|
105
|
+
VERSION = "1.0.9.*"
|
106
106
|
|
107
107
|
* modify **lib/igv/rails.rb** to subclass Rails::Engine
|
108
108
|
|
data/lib/igv/rails/version.rb
CHANGED
@@ -25,8 +25,7 @@
|
|
25
25
|
*/
|
26
26
|
|
27
27
|
var igv = (function (igv) {
|
28
|
-
|
29
|
-
var downSample = true;
|
28
|
+
|
30
29
|
|
31
30
|
function canBePaired(alignment) {
|
32
31
|
return alignment.isPaired() &&
|
@@ -49,9 +48,7 @@ var igv = (function (igv) {
|
|
49
48
|
this.downsampledIntervals = [];
|
50
49
|
|
51
50
|
this.samplingWindowSize = samplingWindowSize === undefined ? 100 : samplingWindowSize;
|
52
|
-
this.samplingDepth =
|
53
|
-
samplingDepth === undefined ? 50 : samplingDepth :
|
54
|
-
Number.MAX_VALUE;
|
51
|
+
this.samplingDepth = samplingDepth === undefined ? 50 : samplingDepth;
|
55
52
|
|
56
53
|
this.pairsSupported = pairsSupported;
|
57
54
|
this.paired = false; // false until proven otherwise
|
@@ -59,9 +56,7 @@ var igv = (function (igv) {
|
|
59
56
|
|
60
57
|
this.downsampledReads = new Set();
|
61
58
|
|
62
|
-
this.currentBucket =
|
63
|
-
new DownsampleBucket(this.start, this.start + this.samplingWindowSize, this) :
|
64
|
-
new DownsampleBucket(this.start, Number.MAX_VALUE, this);
|
59
|
+
this.currentBucket = new DownsampleBucket(this.start, this.start + this.samplingWindowSize, this);
|
65
60
|
|
66
61
|
this.filter = function filter(alignment) { // TODO -- pass this in
|
67
62
|
return alignment.isMapped() && !alignment.isFailsVendorQualityCheck();
|
@@ -213,6 +208,7 @@ var igv = (function (igv) {
|
|
213
208
|
}
|
214
209
|
|
215
210
|
|
211
|
+
// TODO -- refactor this to use an object, rather than an array, if end-start is > some threshold
|
216
212
|
function CoverageMap(chr, start, end) {
|
217
213
|
|
218
214
|
this.chr = chr;
|
@@ -547,7 +543,7 @@ var igv = (function (igv) {
|
|
547
543
|
nameValues.push("<hr>");
|
548
544
|
nameValues.push({ name: 'First in Pair', value: !this.isSecondOfPair(), borderTop: true });
|
549
545
|
nameValues.push({ name: 'Mate is Mapped', value: yesNo(this.isMateMapped()) });
|
550
|
-
if (this.
|
546
|
+
if (this.isMateMapped()) {
|
551
547
|
nameValues.push({ name: 'Mate Chromosome', value: this.mate.chr });
|
552
548
|
nameValues.push({ name: 'Mate Start', value: (this.mate.position + 1)});
|
553
549
|
nameValues.push({ name: 'Mate Strand', value: (true === this.mate.strand ? '(+)' : '(-)')});
|
@@ -813,64 +809,75 @@ var igv = (function (igv) {
|
|
813
809
|
withCredentials: config.withCredentials
|
814
810
|
}).then(function (arrayBuffer) {
|
815
811
|
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
if (!arrayBuffer) {
|
823
|
-
fulfill(null);
|
824
|
-
return;
|
825
|
-
}
|
812
|
+
var indices = [],
|
813
|
+
magic, nbin, nintv, nref, parser,
|
814
|
+
blockMin = Number.MAX_VALUE,
|
815
|
+
blockMax = 0,
|
816
|
+
binIndex, linearIndex, binNumber, cs, ce, b, i, ref, sequenceIndexMap;
|
826
817
|
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
818
|
+
if (!arrayBuffer) {
|
819
|
+
fulfill(null);
|
820
|
+
return;
|
821
|
+
}
|
831
822
|
|
832
|
-
|
823
|
+
if (tabix) {
|
824
|
+
var inflate = new Zlib.Gunzip(new Uint8Array(arrayBuffer));
|
825
|
+
arrayBuffer = inflate.decompress().buffer;
|
826
|
+
}
|
833
827
|
|
834
|
-
|
828
|
+
parser = new igv.BinaryParser(new DataView(arrayBuffer));
|
835
829
|
|
836
|
-
|
830
|
+
magic = parser.getInt();
|
837
831
|
|
838
|
-
|
832
|
+
if (magic === BAI_MAGIC || (tabix && magic === TABIX_MAGIC)) {
|
839
833
|
|
834
|
+
nref = parser.getInt();
|
840
835
|
|
841
|
-
if (tabix) {
|
842
|
-
// Tabix header parameters aren't used, but they must be read to advance the pointer
|
843
|
-
var format = parser.getInt();
|
844
|
-
var col_seq = parser.getInt();
|
845
|
-
var col_beg = parser.getInt();
|
846
|
-
var col_end = parser.getInt();
|
847
|
-
var meta = parser.getInt();
|
848
|
-
var skip = parser.getInt();
|
849
|
-
var l_nm = parser.getInt();
|
850
836
|
|
851
|
-
|
852
|
-
|
853
|
-
|
837
|
+
if (tabix) {
|
838
|
+
// Tabix header parameters aren't used, but they must be read to advance the pointer
|
839
|
+
var format = parser.getInt();
|
840
|
+
var col_seq = parser.getInt();
|
841
|
+
var col_beg = parser.getInt();
|
842
|
+
var col_end = parser.getInt();
|
843
|
+
var meta = parser.getInt();
|
844
|
+
var skip = parser.getInt();
|
845
|
+
var l_nm = parser.getInt();
|
846
|
+
|
847
|
+
sequenceIndexMap = {};
|
848
|
+
for (i = 0; i < nref; i++) {
|
849
|
+
var seq_name = parser.getString();
|
850
|
+
|
851
|
+
// Translate to "official" chr name.
|
852
|
+
if (genome) seq_name = genome.getChromosomeName(seq_name);
|
853
|
+
|
854
|
+
sequenceIndexMap[seq_name] = i;
|
855
|
+
}
|
856
|
+
}
|
854
857
|
|
855
|
-
|
856
|
-
if (genome) seq_name = genome.getChromosomeName(seq_name);
|
858
|
+
for (ref = 0; ref < nref; ++ref) {
|
857
859
|
|
858
|
-
|
859
|
-
|
860
|
-
}
|
860
|
+
binIndex = {};
|
861
|
+
linearIndex = [];
|
861
862
|
|
862
|
-
|
863
|
+
nbin = parser.getInt();
|
863
864
|
|
864
|
-
|
865
|
-
linearIndex = [];
|
865
|
+
for (b = 0; b < nbin; ++b) {
|
866
866
|
|
867
|
-
|
867
|
+
binNumber = parser.getInt();
|
868
868
|
|
869
|
-
|
869
|
+
if (binNumber == 37450) {
|
870
|
+
// This is a psuedo bin, not used but we have to consume the bytes
|
871
|
+
nchnk = parser.getInt(); // # of chunks for this bin
|
872
|
+
cs = parser.getVPointer(); // unmapped beg
|
873
|
+
ce = parser.getVPointer(); // unmapped end
|
874
|
+
var n_maped = parser.getLong();
|
875
|
+
var nUnmapped = parser.getLong();
|
870
876
|
|
871
|
-
|
877
|
+
}
|
878
|
+
else {
|
879
|
+
|
872
880
|
binIndex[binNumber] = [];
|
873
|
-
|
874
881
|
var nchnk = parser.getInt(); // # of chunks for this bin
|
875
882
|
|
876
883
|
for (i = 0; i < nchnk; i++) {
|
@@ -887,37 +894,37 @@ var igv = (function (igv) {
|
|
887
894
|
}
|
888
895
|
}
|
889
896
|
}
|
897
|
+
}
|
890
898
|
|
891
899
|
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
900
|
+
nintv = parser.getInt();
|
901
|
+
for (i = 0; i < nintv; i++) {
|
902
|
+
cs = parser.getVPointer();
|
903
|
+
linearIndex.push(cs); // Might be null
|
904
|
+
}
|
897
905
|
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
}
|
906
|
+
if (nbin > 0) {
|
907
|
+
indices[ref] = {
|
908
|
+
binIndex: binIndex,
|
909
|
+
linearIndex: linearIndex
|
903
910
|
}
|
904
911
|
}
|
905
|
-
|
906
|
-
} else {
|
907
|
-
throw new Error(indexURL + " is not a " + (tabix ? "tabix" : "bai") + " file");
|
908
912
|
}
|
909
|
-
|
910
|
-
}
|
913
|
+
|
914
|
+
} else {
|
915
|
+
throw new Error(indexURL + " is not a " + (tabix ? "tabix" : "bai") + " file");
|
916
|
+
}
|
917
|
+
fulfill(new igv.BamIndex(indices, blockMin, sequenceIndexMap, tabix));
|
918
|
+
}).catch(reject);
|
911
919
|
})
|
912
920
|
}
|
913
921
|
|
914
922
|
|
915
|
-
igv.BamIndex = function (indices,
|
916
|
-
this.
|
923
|
+
igv.BamIndex = function (indices, blockMin, sequenceIndexMap, tabix) {
|
924
|
+
this.firstAlignmentBlock = blockMin;
|
917
925
|
this.indices = indices;
|
918
926
|
this.sequenceIndexMap = sequenceIndexMap;
|
919
927
|
this.tabix = tabix;
|
920
|
-
this.blockMax = blockMax;
|
921
928
|
|
922
929
|
}
|
923
930
|
|
@@ -972,7 +979,7 @@ var igv = (function (igv) {
|
|
972
979
|
}
|
973
980
|
});
|
974
981
|
|
975
|
-
// Use the linear index to find the lowest
|
982
|
+
// Use the linear index to find the lowest chunk that could contain alignments in the region
|
976
983
|
nintv = ba.linearIndex.length;
|
977
984
|
lowest = null;
|
978
985
|
minLin = Math.min(min >> 14, nintv - 1), maxLin = Math.min(max >> 14, nintv - 1);
|
@@ -986,12 +993,12 @@ var igv = (function (igv) {
|
|
986
993
|
}
|
987
994
|
}
|
988
995
|
|
989
|
-
// Prune chunks that end before the lowest
|
996
|
+
// Prune chunks that end before the lowest chunk
|
990
997
|
prunedOtherChunks = [];
|
991
998
|
if (lowest != null) {
|
992
999
|
for (i = 0; i < otherChunks.length; ++i) {
|
993
1000
|
chnk = otherChunks[i];
|
994
|
-
if (chnk.maxv.block
|
1001
|
+
if (chnk.maxv.block > lowest.block || (chnk.maxv.block == lowest.block && chnk.maxv.offset >= lowest.offset)) {
|
995
1002
|
prunedOtherChunks.push(chnk);
|
996
1003
|
}
|
997
1004
|
}
|
@@ -1066,12 +1073,6 @@ var igv = (function (igv) {
|
|
1066
1073
|
var CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?'];
|
1067
1074
|
var READ_STRAND_FLAG = 0x10;
|
1068
1075
|
var MATE_STRAND_FLAG = 0x20;
|
1069
|
-
var READ_PAIRED_FLAG = 0x1;
|
1070
|
-
var PROPER_PAIR_FLAG = 0x2;
|
1071
|
-
var READ_UNMAPPED_FLAG = 0x4;
|
1072
|
-
var MATE_UNMAPPED_FLAG = 0x8;
|
1073
|
-
var READ_STRAND_FLAG = 0x10;
|
1074
|
-
var MATE_STRAND_FLAG = 0x20;
|
1075
1076
|
var FIRST_OF_PAIR_FLAG = 0x40;
|
1076
1077
|
var SECOND_OF_PAIR_FLAG = 0x80;
|
1077
1078
|
var NOT_PRIMARY_ALIGNMENT_FLAG = 0x100;
|
@@ -1079,8 +1080,10 @@ var igv = (function (igv) {
|
|
1079
1080
|
var DUPLICATE_READ_FLAG = 0x400;
|
1080
1081
|
var SUPPLEMENTARY_FLAG = 0x800;
|
1081
1082
|
|
1082
|
-
const MAX_GZIP_BLOCK_SIZE =
|
1083
|
-
|
1083
|
+
const MAX_GZIP_BLOCK_SIZE = 65536; // APPARENTLY. Where is this documented???
|
1084
|
+
const DEFAULT_SAMPLING_WINDOW_SIZE = 100;
|
1085
|
+
const DEFAULT_SAMPLING_DEPTH = 50;
|
1086
|
+
const MAXIMUM_SAMPLING_DEPTH = 2500;
|
1084
1087
|
|
1085
1088
|
/**
|
1086
1089
|
* Class for reading a bam file
|
@@ -1094,17 +1097,18 @@ var igv = (function (igv) {
|
|
1094
1097
|
|
1095
1098
|
this.filter = config.filter || new igv.BamFilter();
|
1096
1099
|
|
1097
|
-
this.bamPath =
|
1098
|
-
|
1099
|
-
|
1100
|
-
this.baiPath = 'gcs' === config.sourceType ?
|
1101
|
-
igv.translateGoogleCloudURL(config.url + ".bai") :
|
1102
|
-
config.url + ".bai"; // Todo - deal with Picard convention. WHY DOES THERE HAVE TO BE 2?
|
1103
|
-
this.baiPath = config.indexURL || this.baiPath; // If there is an indexURL provided, use it!
|
1100
|
+
this.bamPath = config.url;
|
1101
|
+
// Todo - deal with Picard convention. WHY DOES THERE HAVE TO BE 2?
|
1102
|
+
this.baiPath = config.indexURL || this.bamPath + ".bai"; // If there is an indexURL provided, use it!
|
1104
1103
|
this.headPath = config.headURL || this.bamPath;
|
1105
1104
|
|
1106
|
-
|
1107
|
-
this.
|
1105
|
+
|
1106
|
+
this.samplingWindowSize = config.samplingWindowSize === undefined ? DEFAULT_SAMPLING_WINDOW_SIZE : config.samplingWindowSize;
|
1107
|
+
this.samplingDepth = config.samplingDepth === undefined ? DEFAULT_SAMPLING_DEPTH : config.samplingDepth;
|
1108
|
+
if(this.samplingDepth > MAXIMUM_SAMPLING_DEPTH) {
|
1109
|
+
igv.log("Warning: attempt to set sampling depth > maximum value of 2500");
|
1110
|
+
this.samplingDepth = MAXIMUM_SAMPLING_DEPTH;
|
1111
|
+
}
|
1108
1112
|
|
1109
1113
|
if (config.viewAsPairs) {
|
1110
1114
|
this.pairsSupported = true;
|
@@ -1147,17 +1151,14 @@ var igv = (function (igv) {
|
|
1147
1151
|
fulfill(alignmentContainer);
|
1148
1152
|
return;
|
1149
1153
|
}
|
1150
|
-
|
1154
|
+
|
1151
1155
|
chunks.forEach(function (c) {
|
1152
1156
|
|
1153
1157
|
promises.push(new Promise(function (fulfill, reject) {
|
1154
1158
|
|
1155
1159
|
var fetchMin = c.minv.block,
|
1156
|
-
fetchMax = c.maxv.block +
|
1157
|
-
range =
|
1158
|
-
(self.contentLength > 0 && fetchMax > self.contentLength) ?
|
1159
|
-
{start: fetchMin} :
|
1160
|
-
{start: fetchMin, size: fetchMax - fetchMin + 1};
|
1160
|
+
fetchMax = c.maxv.block + MAX_GZIP_BLOCK_SIZE, // Make sure we get the whole block.
|
1161
|
+
range = {start: fetchMin, size: fetchMax - fetchMin + 1};
|
1161
1162
|
|
1162
1163
|
igvxhr.loadArrayBuffer(self.bamPath,
|
1163
1164
|
{
|
@@ -1166,30 +1167,20 @@ var igv = (function (igv) {
|
|
1166
1167
|
withCredentials: self.config.withCredentials
|
1167
1168
|
}).then(function (compressed) {
|
1168
1169
|
|
1169
|
-
|
1170
|
-
|
1170
|
+
var ba = new Uint8Array(igv.unbgzf(compressed)); //new Uint8Array(igv.unbgzf(compressed)); //, c.maxv.block - c.minv.block + 1));
|
1171
|
+
decodeBamRecords(ba, c.minv.offset, alignmentContainer, bpStart, bpEnd, chrId, self.filter);
|
1171
1172
|
|
1172
|
-
|
1173
|
+
fulfill(alignmentContainer);
|
1173
1174
|
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1175
|
+
}).catch(function (obj) {
|
1176
|
+
reject(obj);
|
1177
|
+
});
|
1177
1178
|
|
1178
1179
|
}))
|
1179
1180
|
});
|
1180
1181
|
|
1181
1182
|
|
1182
1183
|
Promise.all(promises).then(function (ignored) {
|
1183
|
-
|
1184
|
-
//if (chunks.length > 1) {
|
1185
|
-
// alignments.sort(function (a, b) {
|
1186
|
-
// return a.start - b.start;
|
1187
|
-
// });
|
1188
|
-
//}
|
1189
|
-
//var alignmentContainer = new igv.AlignmentContainer(chr, bpStart, bpEnd, self.samplingWindowSize, self.samplingDepth);
|
1190
|
-
//alignments.forEach(function (a) {
|
1191
|
-
// alignmentContainer.push(a);
|
1192
|
-
//})
|
1193
1184
|
alignmentContainer.finish();
|
1194
1185
|
fulfill(alignmentContainer);
|
1195
1186
|
}).catch(function (obj) {
|
@@ -1201,7 +1192,7 @@ var igv = (function (igv) {
|
|
1201
1192
|
});
|
1202
1193
|
|
1203
1194
|
|
1204
|
-
function decodeBamRecords(ba, offset,
|
1195
|
+
function decodeBamRecords(ba, offset, alignmentContainer, min, max, chrId, filter) {
|
1205
1196
|
|
1206
1197
|
var blockSize,
|
1207
1198
|
blockEnd,
|
@@ -1234,7 +1225,7 @@ var igv = (function (igv) {
|
|
1234
1225
|
blockSize = readInt(ba, offset);
|
1235
1226
|
blockEnd = offset + blockSize + 4;
|
1236
1227
|
|
1237
|
-
if (blockEnd
|
1228
|
+
if (blockEnd > ba.length) {
|
1238
1229
|
return;
|
1239
1230
|
}
|
1240
1231
|
|
@@ -1243,8 +1234,15 @@ var igv = (function (igv) {
|
|
1243
1234
|
refID = readInt(ba, offset + 4);
|
1244
1235
|
pos = readInt(ba, offset + 8);
|
1245
1236
|
|
1246
|
-
if
|
1247
|
-
|
1237
|
+
if(refID < 0) {
|
1238
|
+
return; // unmapped reads
|
1239
|
+
}
|
1240
|
+
else if (refID > chrId || pos > max) {
|
1241
|
+
return; // off right edge, we're done
|
1242
|
+
}
|
1243
|
+
else if (refID < chrId) {
|
1244
|
+
continue; // to left of start, not sure this is possible
|
1245
|
+
}
|
1248
1246
|
|
1249
1247
|
bmn = readInt(ba, offset + 12);
|
1250
1248
|
bin = (bmn & 0xffff0000) >> 16;
|
@@ -1342,7 +1340,7 @@ var igv = (function (igv) {
|
|
1342
1340
|
blocks = makeBlocks(alignment, cigarArray);
|
1343
1341
|
alignment.blocks = blocks.blocks;
|
1344
1342
|
alignment.insertions = blocks.insertions;
|
1345
|
-
|
1343
|
+
alignmentContainer.push(alignment);
|
1346
1344
|
}
|
1347
1345
|
}
|
1348
1346
|
offset = blockEnd;
|
@@ -1434,14 +1432,7 @@ var igv = (function (igv) {
|
|
1434
1432
|
|
1435
1433
|
getIndex(self).then(function (index) {
|
1436
1434
|
|
1437
|
-
var
|
1438
|
-
len = index.headerSize + MAX_GZIP_BLOCK_SIZE + 100; // Insure we get the complete compressed block containing the header
|
1439
|
-
|
1440
|
-
if (contentLength <= 0) contentLength = index.blockMax; // Approximate
|
1441
|
-
|
1442
|
-
self.contentLength = contentLength;
|
1443
|
-
|
1444
|
-
if (contentLength > 0) len = Math.min(contentLength, len);
|
1435
|
+
var len = index.firstAlignmentBlock + MAX_GZIP_BLOCK_SIZE; // Insure we get the complete compressed block containing the header
|
1445
1436
|
|
1446
1437
|
igvxhr.loadArrayBuffer(self.bamPath,
|
1447
1438
|
{
|
@@ -1452,49 +1443,49 @@ var igv = (function (igv) {
|
|
1452
1443
|
withCredentials: self.config.withCredentials
|
1453
1444
|
}).then(function (compressedBuffer) {
|
1454
1445
|
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1446
|
+
var unc = igv.unbgzf(compressedBuffer, len),
|
1447
|
+
uncba = new Uint8Array(unc),
|
1448
|
+
magic = readInt(uncba, 0),
|
1449
|
+
samHeaderLen = readInt(uncba, 4),
|
1450
|
+
samHeader = '',
|
1451
|
+
genome = igv.browser ? igv.browser.genome : null;
|
1461
1452
|
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1453
|
+
for (var i = 0; i < samHeaderLen; ++i) {
|
1454
|
+
samHeader += String.fromCharCode(uncba[i + 8]);
|
1455
|
+
}
|
1465
1456
|
|
1466
|
-
|
1467
|
-
|
1457
|
+
var nRef = readInt(uncba, samHeaderLen + 8);
|
1458
|
+
var p = samHeaderLen + 12;
|
1468
1459
|
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1460
|
+
self.chrToIndex = {};
|
1461
|
+
self.indexToChr = [];
|
1462
|
+
for (var i = 0; i < nRef; ++i) {
|
1463
|
+
var lName = readInt(uncba, p);
|
1464
|
+
var name = '';
|
1465
|
+
for (var j = 0; j < lName - 1; ++j) {
|
1466
|
+
name += String.fromCharCode(uncba[p + 4 + j]);
|
1467
|
+
}
|
1468
|
+
var lRef = readInt(uncba, p + lName + 4);
|
1469
|
+
//dlog(name + ': ' + lRef);
|
1479
1470
|
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1471
|
+
if (genome && genome.getChromosomeName) {
|
1472
|
+
name = genome.getChromosomeName(name);
|
1473
|
+
}
|
1483
1474
|
|
1484
|
-
|
1485
|
-
|
1475
|
+
self.chrToIndex[name] = i;
|
1476
|
+
self.indexToChr.push(name);
|
1486
1477
|
|
1487
|
-
|
1488
|
-
|
1478
|
+
p = p + 8 + lName;
|
1479
|
+
}
|
1489
1480
|
|
1490
|
-
|
1481
|
+
fulfill();
|
1491
1482
|
|
1492
|
-
|
1483
|
+
}).catch(reject);
|
1493
1484
|
}).catch(reject);
|
1494
1485
|
});
|
1495
1486
|
}
|
1496
1487
|
|
1497
|
-
|
1488
|
+
//
|
1498
1489
|
function getIndex(bam) {
|
1499
1490
|
|
1500
1491
|
return new Promise(function (fulfill, reject) {
|
@@ -1506,9 +1497,6 @@ var igv = (function (igv) {
|
|
1506
1497
|
igv.loadBamIndex(bam.baiPath, bam.config).then(function (index) {
|
1507
1498
|
bam.index = index;
|
1508
1499
|
|
1509
|
-
// Content length TODO -- is this exact or approximate?
|
1510
|
-
bam.contentLength = index.blockMax;
|
1511
|
-
|
1512
1500
|
fulfill(bam.index);
|
1513
1501
|
}).catch(reject);
|
1514
1502
|
}
|
@@ -1833,7 +1821,7 @@ var igv = (function (igv) {
|
|
1833
1821
|
var alignmentRowYInset = 0;
|
1834
1822
|
var alignmentStartGap = 5;
|
1835
1823
|
var downsampleRowHeight = 5;
|
1836
|
-
|
1824
|
+
const DEFAULT_COVERAGE_TRACK_HEIGHT = 50;
|
1837
1825
|
|
1838
1826
|
igv.BAMTrack = function (config) {
|
1839
1827
|
|
@@ -1841,6 +1829,10 @@ var igv = (function (igv) {
|
|
1841
1829
|
|
1842
1830
|
igv.configTrack(this, config);
|
1843
1831
|
|
1832
|
+
if(config.coverageTrackHeight === undefined) {
|
1833
|
+
config.coverageTrackHeight = DEFAULT_COVERAGE_TRACK_HEIGHT;
|
1834
|
+
}
|
1835
|
+
|
1844
1836
|
this.coverageTrack = new CoverageTrack(config, this);
|
1845
1837
|
|
1846
1838
|
this.alignmentTrack = new AlignmentTrack(config, this);
|
@@ -1925,7 +1917,9 @@ var igv = (function (igv) {
|
|
1925
1917
|
|
1926
1918
|
igv.BAMTrack.prototype.draw = function (options) {
|
1927
1919
|
|
1928
|
-
this.coverageTrack.
|
1920
|
+
if(this.coverageTrack.height > 0) {
|
1921
|
+
this.coverageTrack.draw(options);
|
1922
|
+
}
|
1929
1923
|
|
1930
1924
|
this.alignmentTrack.draw(options);
|
1931
1925
|
};
|
@@ -2112,7 +2106,9 @@ var igv = (function (igv) {
|
|
2112
2106
|
this.parent = parent;
|
2113
2107
|
this.featureSource = parent.featureSource;
|
2114
2108
|
this.top = 0;
|
2115
|
-
|
2109
|
+
|
2110
|
+
|
2111
|
+
this.height = config.coverageTrackHeight;
|
2116
2112
|
this.dataRange = {min: 0}; // Leav max undefined
|
2117
2113
|
this.paintAxis = igv.paintAxis;
|
2118
2114
|
}
|
@@ -2270,7 +2266,7 @@ var igv = (function (igv) {
|
|
2270
2266
|
|
2271
2267
|
this.parent = parent;
|
2272
2268
|
this.featureSource = parent.featureSource;
|
2273
|
-
this.top = config.coverageTrackHeight + 5
|
2269
|
+
this.top = config.coverageTrackHeight == 0 ? 0 : config.coverageTrackHeight + 5;
|
2274
2270
|
this.alignmentRowHeight = config.alignmentRowHeight || 14;
|
2275
2271
|
|
2276
2272
|
this.negStrandColor = config.negStrandColor || "rgba(150, 150, 230, 0.75)";
|
@@ -2709,26 +2705,21 @@ var igv = (function (igv) {
|
|
2709
2705
|
})
|
2710
2706
|
(igv || {});
|
2711
2707
|
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
2708
|
var igv = (function (igv) {
|
2716
2709
|
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2710
|
+
var BLOCK_HEADER_LENGTH = 18;
|
2711
|
+
var BLOCK_LENGTH_OFFSET = 16; // Location in the gzip block of the total block size (actually total block size - 1)
|
2712
|
+
var BLOCK_FOOTER_LENGTH = 8; // Number of bytes that follow the deflated data
|
2713
|
+
var MAX_COMPRESSED_BLOCK_SIZE = 64 * 1024; // We require that a compressed block (including header and footer, be <= this)
|
2714
|
+
var GZIP_OVERHEAD = BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH + 2; // Gzip overhead is the header, the footer, and the block size (encoded as a short).
|
2715
|
+
var GZIP_ID1 = 31; // Magic number
|
2716
|
+
var GZIP_ID2 = 139; // Magic number
|
2717
|
+
var GZIP_FLG = 4; // FEXTRA flag means there are optional fields
|
2726
2718
|
|
2727
2719
|
|
2728
|
-
|
2729
|
-
//
|
2730
|
-
|
2731
|
-
igv.unbgzf = function(data, lim) {
|
2720
|
+
// Uncompress data, assumed to be series of bgzipped blocks
|
2721
|
+
// Code is based heavily on bam.js, part of the Dalliance Genome Explorer, (c) Thomas Down 2006-2001.
|
2722
|
+
igv.unbgzf = function (data, lim) {
|
2732
2723
|
|
2733
2724
|
var oBlockList = [],
|
2734
2725
|
ptr = [0],
|
@@ -2775,6 +2766,57 @@ var igv = (function (igv) {
|
|
2775
2766
|
}
|
2776
2767
|
|
2777
2768
|
|
2769
|
+
|
2770
|
+
igv.BGZFile = function (config) {
|
2771
|
+
this.filePosition = 0;
|
2772
|
+
this.config = config;
|
2773
|
+
}
|
2774
|
+
|
2775
|
+
igv.BGZFile.prototype.nextBlock = function () {
|
2776
|
+
|
2777
|
+
var self = this;
|
2778
|
+
|
2779
|
+
return new Promise(function (fulfill, reject) {
|
2780
|
+
|
2781
|
+
igvxhr.loadArrayBuffer(self.path,
|
2782
|
+
{
|
2783
|
+
headers: self.config.headers,
|
2784
|
+
range: {start: self.filePosition, size: BLOCK_HEADER_LENGTH},
|
2785
|
+
withCredentials: self.config.withCredentials
|
2786
|
+
|
2787
|
+
}).then(function (arrayBuffer) {
|
2788
|
+
|
2789
|
+
var ba = new Uint8Array(arrayBuffer);
|
2790
|
+
var xlen = (ba[11] << 8) | (ba[10]);
|
2791
|
+
var si1 = ba[12];
|
2792
|
+
var si2 = ba[13];
|
2793
|
+
var slen = (ba[15] << 8) | (ba[14]);
|
2794
|
+
var bsize = (ba[17] << 8) | (ba[16]) + 1;
|
2795
|
+
|
2796
|
+
self.filePosition += BLOCK_HEADER_LENGTH;
|
2797
|
+
|
2798
|
+
igvxhr.loadArrayBuffer(self.path, {
|
2799
|
+
headers: self.config.headers,
|
2800
|
+
range: {start: self.filePosition, size: bsize},
|
2801
|
+
withCredentials: self.config.withCredentials
|
2802
|
+
|
2803
|
+
}).then(function (arrayBuffer) {
|
2804
|
+
|
2805
|
+
var unc = jszlib_inflate_buffer(arrayBuffer);
|
2806
|
+
|
2807
|
+
self.filePosition += (bsize + 8); // "8" for CRC-32 and size of uncompressed data
|
2808
|
+
|
2809
|
+
fulfill(unc);
|
2810
|
+
|
2811
|
+
}).catch(reject)
|
2812
|
+
}).catch(reject);
|
2813
|
+
})
|
2814
|
+
|
2815
|
+
}
|
2816
|
+
|
2817
|
+
|
2818
|
+
|
2819
|
+
|
2778
2820
|
return igv;
|
2779
2821
|
|
2780
2822
|
})(igv || {});
|
@@ -3015,243 +3057,6 @@ var igv = (function (igv) {
|
|
3015
3057
|
}
|
3016
3058
|
|
3017
3059
|
|
3018
|
-
return igv;
|
3019
|
-
|
3020
|
-
})(igv || {});
|
3021
|
-
/*
|
3022
|
-
* The MIT License (MIT)
|
3023
|
-
*
|
3024
|
-
* Copyright (c) 2016 University of California San Diego
|
3025
|
-
* Author: Jim Robinson
|
3026
|
-
*
|
3027
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
3028
|
-
* of this software and associated documentation files (the "Software"), to deal
|
3029
|
-
* in the Software without restriction, including without limitation the rights
|
3030
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
3031
|
-
* copies of the Software, and to permit persons to whom the Software is
|
3032
|
-
* furnished to do so, subject to the following conditions:
|
3033
|
-
*
|
3034
|
-
* The above copyright notice and this permission notice shall be included in
|
3035
|
-
* all copies or substantial portions of the Software.
|
3036
|
-
*
|
3037
|
-
*
|
3038
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
3039
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
3040
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
3041
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
3042
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
3043
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
3044
|
-
* THE SOFTWARE.
|
3045
|
-
*/
|
3046
|
-
|
3047
|
-
var igv = (function (igv) {
|
3048
|
-
|
3049
|
-
|
3050
|
-
igv.BigQueryFeatureReader = function (config) {
|
3051
|
-
|
3052
|
-
// Harcoded for seg features for now
|
3053
|
-
this.projectId = 'isb-cgc-03-0001';
|
3054
|
-
this.decode = decodeSeg;
|
3055
|
-
this.cohort = config.cohort
|
3056
|
-
|
3057
|
-
}
|
3058
|
-
|
3059
|
-
//SELECT ParticipantBarcode FROM [isb-cgc:tcga_201510_alpha.Clinical_data] WHERE Study = \"" + this.study + "\")
|
3060
|
-
|
3061
|
-
igv.BigQueryFeatureReader.prototype.allSamples = function () {
|
3062
|
-
|
3063
|
-
var q = "SELECT UNIQUE(AliquotBarcode) FROM [isb-cgc:tcga_201510_alpha.Copy_Number_segments] WHERE " +
|
3064
|
-
" ParticipantBarcode IN (" + this.cohort + ")";
|
3065
|
-
|
3066
|
-
return igv.bigQuery(
|
3067
|
-
{
|
3068
|
-
projectId: this.projectId,
|
3069
|
-
queryString: q,
|
3070
|
-
decode: decodeSample
|
3071
|
-
});
|
3072
|
-
|
3073
|
-
}
|
3074
|
-
|
3075
|
-
igv.BigQueryFeatureReader.prototype.readFeatures = function (chr, bpStart, bpEnd) {
|
3076
|
-
|
3077
|
-
var c = chr.startsWith("chr") ? chr.substring(3) : chr,
|
3078
|
-
q = "SELECT * FROM [isb-cgc:tcga_201510_alpha.Copy_Number_segments]" +
|
3079
|
-
" WHERE " +
|
3080
|
-
" ParticipantBarcode IN (" + this.cohort + ") " +
|
3081
|
-
" AND Chromosome = \"" + c + "\" " +
|
3082
|
-
" AND Start >= " + bpStart + " AND End <= " + bpEnd;
|
3083
|
-
|
3084
|
-
return igv.bigQuery(
|
3085
|
-
{
|
3086
|
-
projectId: this.projectId,
|
3087
|
-
queryString: q,
|
3088
|
-
decode: decodeSeg
|
3089
|
-
});
|
3090
|
-
|
3091
|
-
}
|
3092
|
-
|
3093
|
-
|
3094
|
-
igv.bigQuery = function (options) {
|
3095
|
-
|
3096
|
-
return new Promise(function (fulfill, reject) {
|
3097
|
-
|
3098
|
-
if (!options.projectId) {
|
3099
|
-
//todo throw error
|
3100
|
-
}
|
3101
|
-
|
3102
|
-
var baseURL = options.baseURL || "https://www.googleapis.com/bigquery/v2/",
|
3103
|
-
url = baseURL + "projects/" + options.projectId + "/queries",
|
3104
|
-
body = {
|
3105
|
-
"kind": "bigquery#queryRequest",
|
3106
|
-
"query": options.queryString,
|
3107
|
-
"maxResults": 1000,
|
3108
|
-
"timeoutMs": 5000,
|
3109
|
-
"dryRun": false,
|
3110
|
-
"preserveNulls": true,
|
3111
|
-
"useQueryCache": true
|
3112
|
-
},
|
3113
|
-
decode = options.decode,
|
3114
|
-
apiKey = oauth.google.apiKey,
|
3115
|
-
jobId,
|
3116
|
-
paramSeparator = "&";
|
3117
|
-
|
3118
|
-
url = url + "?alt=json";
|
3119
|
-
|
3120
|
-
if (apiKey) {
|
3121
|
-
url = url + paramSeparator + "key=" + apiKey;
|
3122
|
-
}
|
3123
|
-
|
3124
|
-
var sendData = JSON.stringify(body);
|
3125
|
-
|
3126
|
-
igvxhr.loadJson(url,
|
3127
|
-
{
|
3128
|
-
sendData: sendData,
|
3129
|
-
contentType: "application/json"
|
3130
|
-
}).then(function (response) {
|
3131
|
-
|
3132
|
-
var results = [],
|
3133
|
-
totalRows,
|
3134
|
-
jobId = response.jobReference.jobId;
|
3135
|
-
|
3136
|
-
|
3137
|
-
if (response.jobComplete === true) {
|
3138
|
-
|
3139
|
-
totalRows = parseInt(response.totalRows); // Google convention is to use strings for "long" types
|
3140
|
-
|
3141
|
-
if (totalRows === 0) {
|
3142
|
-
fulfill(results);
|
3143
|
-
}
|
3144
|
-
else {
|
3145
|
-
|
3146
|
-
response.rows.forEach(function (row) {
|
3147
|
-
results.push(decode(row));
|
3148
|
-
});
|
3149
|
-
|
3150
|
-
if (results.length < totalRows) {
|
3151
|
-
getQueryResults(options);
|
3152
|
-
}
|
3153
|
-
else {
|
3154
|
-
fulfill(results);
|
3155
|
-
}
|
3156
|
-
}
|
3157
|
-
}
|
3158
|
-
else {
|
3159
|
-
setTimeout(function () {
|
3160
|
-
getQueryResults(options);
|
3161
|
-
}, 1000);
|
3162
|
-
}
|
3163
|
-
|
3164
|
-
|
3165
|
-
function getQueryResults(options) {
|
3166
|
-
|
3167
|
-
var url = "https://clients6.google.com/bigquery/v2/projects/" + options.projectId + "/queries/" + jobId,
|
3168
|
-
decode = options.decode,
|
3169
|
-
success = options.success,
|
3170
|
-
apiKey = oauth.google.apiKey,
|
3171
|
-
paramSeparator = "&";
|
3172
|
-
|
3173
|
-
url = url + "?alt=json"
|
3174
|
-
|
3175
|
-
if (apiKey) {
|
3176
|
-
url = url + paramSeparator + "key=" + apiKey;
|
3177
|
-
}
|
3178
|
-
|
3179
|
-
if (options.maxResults) {
|
3180
|
-
url = url + "&maxResults=" + options.maxResults;
|
3181
|
-
}
|
3182
|
-
|
3183
|
-
if (results.length > 0) {
|
3184
|
-
url = url + ("&startIndex=" + results.length);
|
3185
|
-
}
|
3186
|
-
|
3187
|
-
igvxhr.loadJson(url,
|
3188
|
-
{
|
3189
|
-
contentType: "application/json"
|
3190
|
-
}).then(function (response) {
|
3191
|
-
|
3192
|
-
if (response.jobComplete === true) {
|
3193
|
-
|
3194
|
-
totalRows = response.totalRows;
|
3195
|
-
|
3196
|
-
response.rows.forEach(function (row) {
|
3197
|
-
results.push(decode(row));
|
3198
|
-
});
|
3199
|
-
|
3200
|
-
if (results.length < totalRows) {
|
3201
|
-
getQueryResults(options);
|
3202
|
-
}
|
3203
|
-
else {
|
3204
|
-
fulfill(results);
|
3205
|
-
}
|
3206
|
-
|
3207
|
-
}
|
3208
|
-
else {
|
3209
|
-
setTimeout(function () {
|
3210
|
-
getQueryResults(options);
|
3211
|
-
}, 1000);
|
3212
|
-
}
|
3213
|
-
|
3214
|
-
});
|
3215
|
-
|
3216
|
-
}
|
3217
|
-
|
3218
|
-
}).catch(reject);
|
3219
|
-
});
|
3220
|
-
}
|
3221
|
-
|
3222
|
-
|
3223
|
-
/*
|
3224
|
-
sample: tokens[sampleColumn],
|
3225
|
-
chr: tokens[chrColumn],
|
3226
|
-
start: parseInt(tokens[startColumn]),
|
3227
|
-
end: parseInt(tokens[endColumn]),
|
3228
|
-
value: parseFloat(tokens[dataColumn])
|
3229
|
-
*/
|
3230
|
-
|
3231
|
-
function decodeSeg(row) {
|
3232
|
-
|
3233
|
-
var seg = {};
|
3234
|
-
seg["sample"] = row.f[3].v;
|
3235
|
-
seg["Study"] = row.f[4].v;
|
3236
|
-
seg["chr"] = row.f[6].v;
|
3237
|
-
seg["start"] = row.f[7].v - 1;
|
3238
|
-
seg["end"] = row.f[8].v;
|
3239
|
-
seg["Num_Probes"] = row.f[9].v;
|
3240
|
-
seg["value"] = row.f[10].v;
|
3241
|
-
return seg;
|
3242
|
-
}
|
3243
|
-
|
3244
|
-
|
3245
|
-
function decodeStudy(row) {
|
3246
|
-
|
3247
|
-
return row.f[0].v;
|
3248
|
-
}
|
3249
|
-
|
3250
|
-
function decodeSample(row) {
|
3251
|
-
return row.f[0].v;
|
3252
|
-
}
|
3253
|
-
|
3254
|
-
|
3255
3060
|
return igv;
|
3256
3061
|
|
3257
3062
|
})(igv || {});
|
@@ -3388,14 +3193,8 @@ var igv = (function (igv) {
|
|
3388
3193
|
loadRange = {start: requestedRange.start, size: bufferSize};
|
3389
3194
|
}
|
3390
3195
|
|
3391
|
-
igvxhr.loadArrayBuffer(self.path,
|
3392
|
-
{
|
3393
|
-
headers: self.config.headers,
|
3394
|
-
range: loadRange,
|
3395
|
-
withCredentials: self.config.withCredentials
|
3396
|
-
}).then(function (arrayBuffer) {
|
3397
|
-
// TODO -- handle error
|
3398
|
-
|
3196
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {range: loadRange}))
|
3197
|
+
.then(function (arrayBuffer) {
|
3399
3198
|
self.data = arrayBuffer;
|
3400
3199
|
self.range = loadRange;
|
3401
3200
|
subbuffer(self, requestedRange, asUint8);
|
@@ -3421,6 +3220,7 @@ var igv = (function (igv) {
|
|
3421
3220
|
return igv;
|
3422
3221
|
|
3423
3222
|
})(igv || {});
|
3223
|
+
|
3424
3224
|
/*
|
3425
3225
|
* The MIT License (MIT)
|
3426
3226
|
*
|
@@ -3458,11 +3258,11 @@ var igv = (function (igv) {
|
|
3458
3258
|
var BPTREE_HEADER_SIZE = 32;
|
3459
3259
|
|
3460
3260
|
|
3461
|
-
igv.BPTree = function (binaryParser,
|
3261
|
+
igv.BPTree = function (binaryParser, startOffset) {
|
3462
3262
|
|
3463
|
-
var
|
3263
|
+
var self = this,
|
3264
|
+
genome = igv.browser ? igv.browser.genome : null;
|
3464
3265
|
|
3465
|
-
this.treeOffset = treeOffset; // File offset to beginning of tree
|
3466
3266
|
this.header = {};
|
3467
3267
|
this.header.magic = binaryParser.getInt();
|
3468
3268
|
this.header.blockSize = binaryParser.getInt();
|
@@ -3476,6 +3276,8 @@ var igv = (function (igv) {
|
|
3476
3276
|
// Recursively walk tree to populate dictionary
|
3477
3277
|
readTreeNode(binaryParser, -1, this.header.keySize, this.dictionary);
|
3478
3278
|
|
3279
|
+
var itemSize = 8 + this.header.keySize;
|
3280
|
+
var minSize = 4 + itemSize; // Bytes for a node with 1 item
|
3479
3281
|
|
3480
3282
|
function readTreeNode(byteBuffer, offset, keySize, dictionary) {
|
3481
3283
|
|
@@ -3483,34 +3285,42 @@ var igv = (function (igv) {
|
|
3483
3285
|
|
3484
3286
|
var type = byteBuffer.getByte(),
|
3485
3287
|
reserved = byteBuffer.getByte(),
|
3486
|
-
count = byteBuffer.
|
3288
|
+
count = byteBuffer.getUShort(),
|
3487
3289
|
i,
|
3488
3290
|
key,
|
3489
3291
|
chromId,
|
3490
3292
|
chromSize,
|
3491
3293
|
childOffset,
|
3492
|
-
bufferOffset
|
3294
|
+
bufferOffset,
|
3295
|
+
currOffset;
|
3493
3296
|
|
3494
3297
|
|
3495
3298
|
if (type == 1) {
|
3496
|
-
for (i = 0; i < count; i++) {
|
3497
|
-
key = byteBuffer.getFixedLengthString(keySize).trim();
|
3498
3299
|
|
3499
|
-
|
3300
|
+
for (i = 0; i < count; i++) {
|
3500
3301
|
|
3302
|
+
key = byteBuffer.getFixedLengthTrimmedString(keySize);
|
3501
3303
|
chromId = byteBuffer.getInt();
|
3502
3304
|
chromSize = byteBuffer.getInt();
|
3305
|
+
|
3306
|
+
if(genome) key = genome.getChromosomeName(key); // Translate to canonical chr name
|
3503
3307
|
dictionary[key] = chromId;
|
3504
3308
|
|
3505
3309
|
}
|
3506
3310
|
}
|
3507
3311
|
else { // non-leaf
|
3312
|
+
|
3508
3313
|
for (i = 0; i < count; i++) {
|
3509
|
-
|
3510
|
-
|
3511
|
-
|
3314
|
+
|
3315
|
+
key = byteBuffer.getFixedLengthTrimmedString(keySize);
|
3316
|
+
childOffset = byteBuffer.getLong();
|
3317
|
+
bufferOffset = childOffset - startOffset;
|
3318
|
+
currOffset = byteBuffer.position;
|
3319
|
+
readTreeNode(byteBuffer, bufferOffset, keySize, dictionary);
|
3320
|
+
byteBuffer.position = currOffset;
|
3512
3321
|
}
|
3513
3322
|
}
|
3323
|
+
|
3514
3324
|
}
|
3515
3325
|
}
|
3516
3326
|
|
@@ -3518,6 +3328,7 @@ var igv = (function (igv) {
|
|
3518
3328
|
return igv;
|
3519
3329
|
|
3520
3330
|
})(igv || {});
|
3331
|
+
|
3521
3332
|
/*
|
3522
3333
|
* The MIT License (MIT)
|
3523
3334
|
*
|
@@ -3595,7 +3406,7 @@ var igv = (function (igv) {
|
|
3595
3406
|
var type = binaryParser.getByte();
|
3596
3407
|
var isLeaf = (type === 1) ? true : false;
|
3597
3408
|
var reserved = binaryParser.getByte();
|
3598
|
-
var count = binaryParser.
|
3409
|
+
var count = binaryParser.getUShort();
|
3599
3410
|
|
3600
3411
|
filePosition += 4;
|
3601
3412
|
|
@@ -3753,6 +3564,7 @@ var igv = (function (igv) {
|
|
3753
3564
|
|
3754
3565
|
|
3755
3566
|
})(igv || {});
|
3567
|
+
|
3756
3568
|
/*
|
3757
3569
|
* The MIT License (MIT)
|
3758
3570
|
*
|
@@ -3822,12 +3634,8 @@ var igv = (function (igv) {
|
|
3822
3634
|
var self = this;
|
3823
3635
|
|
3824
3636
|
return new Promise(function (fulfill, reject) {
|
3825
|
-
igvxhr.loadArrayBuffer(self.path,
|
3826
|
-
{
|
3827
|
-
headers: self.config.headers,
|
3828
|
-
range: {start: 0, size: BBFILE_HEADER_SIZE},
|
3829
|
-
withCredentials: self.config.withCredentials
|
3830
|
-
}).then(function (data) {
|
3637
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {range: {start: 0, size: BBFILE_HEADER_SIZE}}))
|
3638
|
+
.then(function (data) {
|
3831
3639
|
|
3832
3640
|
if (!data) return;
|
3833
3641
|
|
@@ -3865,13 +3673,13 @@ var igv = (function (igv) {
|
|
3865
3673
|
}
|
3866
3674
|
// Table 5 "Common header for BigWig and BigBed files"
|
3867
3675
|
self.header = {};
|
3868
|
-
self.header.bwVersion = binaryParser.
|
3869
|
-
self.header.nZoomLevels = binaryParser.
|
3676
|
+
self.header.bwVersion = binaryParser.getUShort();
|
3677
|
+
self.header.nZoomLevels = binaryParser.getUShort();
|
3870
3678
|
self.header.chromTreeOffset = binaryParser.getLong();
|
3871
3679
|
self.header.fullDataOffset = binaryParser.getLong();
|
3872
3680
|
self.header.fullIndexOffset = binaryParser.getLong();
|
3873
|
-
self.header.fieldCount = binaryParser.
|
3874
|
-
self.header.definedFieldCount = binaryParser.
|
3681
|
+
self.header.fieldCount = binaryParser.getUShort();
|
3682
|
+
self.header.definedFieldCount = binaryParser.getUShort();
|
3875
3683
|
self.header.autoSqlOffset = binaryParser.getLong();
|
3876
3684
|
self.header.totalSummaryOffset = binaryParser.getLong();
|
3877
3685
|
self.header.uncompressBuffSize = binaryParser.getInt();
|
@@ -3893,13 +3701,11 @@ var igv = (function (igv) {
|
|
3893
3701
|
self = this;
|
3894
3702
|
|
3895
3703
|
return new Promise(function (fulfill, reject) {
|
3704
|
+
|
3705
|
+
var range = {start: startOffset, size: (self.header.fullDataOffset - startOffset + 5)};
|
3896
3706
|
|
3897
|
-
igvxhr.loadArrayBuffer(self.path,
|
3898
|
-
{
|
3899
|
-
headers: self.config.headers,
|
3900
|
-
range: {start: startOffset, size: (self.header.fullDataOffset - startOffset + 5)},
|
3901
|
-
withCredentials: self.config.withCredentials
|
3902
|
-
}).then(function (data) {
|
3707
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {range: range}))
|
3708
|
+
.then(function (data) {
|
3903
3709
|
|
3904
3710
|
var nZooms = self.header.nZoomLevels,
|
3905
3711
|
binaryParser = new igv.BinaryParser(new DataView(data)),
|
@@ -3933,7 +3739,7 @@ var igv = (function (igv) {
|
|
3933
3739
|
// Chrom data index
|
3934
3740
|
if (self.header.chromTreeOffset > 0) {
|
3935
3741
|
binaryParser.position = self.header.chromTreeOffset - startOffset;
|
3936
|
-
self.chromTree = new igv.BPTree(binaryParser,
|
3742
|
+
self.chromTree = new igv.BPTree(binaryParser, startOffset);
|
3937
3743
|
}
|
3938
3744
|
else {
|
3939
3745
|
// TODO -- this is an error, not expected
|
@@ -3983,6 +3789,7 @@ var igv = (function (igv) {
|
|
3983
3789
|
|
3984
3790
|
})
|
3985
3791
|
(igv || {});
|
3792
|
+
|
3986
3793
|
/*
|
3987
3794
|
* The MIT License (MIT)
|
3988
3795
|
*
|
@@ -4088,13 +3895,13 @@ var igv = (function (igv) {
|
|
4088
3895
|
|
4089
3896
|
var i, allFeatures = featureArrays[0];
|
4090
3897
|
if(featureArrays.length > 1) {
|
4091
|
-
for(i=
|
3898
|
+
for(i=1; i<featureArrays.length; i++) {
|
4092
3899
|
allFeatures = allFeatures.concat(featureArrays[i]);
|
4093
3900
|
}
|
4094
|
-
|
4095
|
-
|
4096
|
-
|
4097
|
-
}
|
3901
|
+
}
|
3902
|
+
allFeatures.sort(function (a, b) {
|
3903
|
+
return a.start - b.start;
|
3904
|
+
})
|
4098
3905
|
|
4099
3906
|
fulfill(allFeatures)
|
4100
3907
|
}).catch(reject);
|
@@ -4107,6 +3914,18 @@ var igv = (function (igv) {
|
|
4107
3914
|
|
4108
3915
|
});
|
4109
3916
|
}
|
3917
|
+
|
3918
|
+
|
3919
|
+
igv.BWSource.prototype.getDefaultRange = function () {
|
3920
|
+
|
3921
|
+
if(this.reader.totalSummary != undefined) {
|
3922
|
+
return this.reader.totalSummary.defaultRange;
|
3923
|
+
}
|
3924
|
+
else {
|
3925
|
+
return undefined;
|
3926
|
+
}
|
3927
|
+
|
3928
|
+
}
|
4110
3929
|
|
4111
3930
|
|
4112
3931
|
function zoomLevelForScale(bpPerPixel, zoomLevelHeaders) {
|
@@ -4141,7 +3960,7 @@ var igv = (function (igv) {
|
|
4141
3960
|
itemSpan = binaryParser.getInt(),
|
4142
3961
|
type = binaryParser.getByte(),
|
4143
3962
|
reserved = binaryParser.getByte(),
|
4144
|
-
itemCount = binaryParser.
|
3963
|
+
itemCount = binaryParser.getUShort(),
|
4145
3964
|
value;
|
4146
3965
|
|
4147
3966
|
if (chromId === chrIdx) {
|
@@ -4155,7 +3974,6 @@ var igv = (function (igv) {
|
|
4155
3974
|
value = binaryParser.getFloat();
|
4156
3975
|
break;
|
4157
3976
|
case 2:
|
4158
|
-
|
4159
3977
|
chromStart = binaryParser.getInt();
|
4160
3978
|
value = binaryParser.getFloat();
|
4161
3979
|
chromEnd = chromStart + itemSpan;
|
@@ -4170,7 +3988,7 @@ var igv = (function (igv) {
|
|
4170
3988
|
|
4171
3989
|
if (chromStart >= bpEnd) {
|
4172
3990
|
break; // Out of interval
|
4173
|
-
} else if (chromEnd > bpStart) {
|
3991
|
+
} else if (chromEnd > bpStart && Number.isFinite(value)) {
|
4174
3992
|
featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value});
|
4175
3993
|
}
|
4176
3994
|
|
@@ -4210,7 +4028,7 @@ var igv = (function (igv) {
|
|
4210
4028
|
if (chromStart >= bpEnd) {
|
4211
4029
|
break; // Out of interval
|
4212
4030
|
|
4213
|
-
} else if (chromEnd > bpStart) {
|
4031
|
+
} else if (chromEnd > bpStart && Number.isFinite(value)) {
|
4214
4032
|
featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value});
|
4215
4033
|
}
|
4216
4034
|
|
@@ -4355,7 +4173,15 @@ var igv = (function (igv) {
|
|
4355
4173
|
var n = this.basesCovered;
|
4356
4174
|
if (n > 0) {
|
4357
4175
|
this.mean = this.sumData / n;
|
4358
|
-
this.stddev = Math.sqrt(
|
4176
|
+
this.stddev = Math.sqrt(this.sumSquares / (n - 1));
|
4177
|
+
|
4178
|
+
var min = this.minVal < 0 ? this.mean - 2 * this.stddev : 0,
|
4179
|
+
max = this.maxVal > 0 ? this.mean + 2 * this.stddev : 0;
|
4180
|
+
|
4181
|
+
this.defaultRange = {
|
4182
|
+
min: 0,
|
4183
|
+
max: this.mean + 3 * this.stddev
|
4184
|
+
}
|
4359
4185
|
}
|
4360
4186
|
}
|
4361
4187
|
|
@@ -4375,6 +4201,7 @@ var igv = (function (igv) {
|
|
4375
4201
|
return igv;
|
4376
4202
|
|
4377
4203
|
})(igv || {});
|
4204
|
+
|
4378
4205
|
/*
|
4379
4206
|
* The MIT License (MIT)
|
4380
4207
|
*
|
@@ -4412,7 +4239,11 @@ var igv = (function (igv) {
|
|
4412
4239
|
this.length = dataView.byteLength;
|
4413
4240
|
}
|
4414
4241
|
|
4415
|
-
igv.BinaryParser.prototype.
|
4242
|
+
igv.BinaryParser.prototype.available = function() {
|
4243
|
+
return this.length - this.position;
|
4244
|
+
}
|
4245
|
+
|
4246
|
+
igv.BinaryParser.prototype.remLength = function () {
|
4416
4247
|
return this.length - this.position;
|
4417
4248
|
}
|
4418
4249
|
|
@@ -4433,6 +4264,19 @@ var igv = (function (igv) {
|
|
4433
4264
|
return retValue;
|
4434
4265
|
}
|
4435
4266
|
|
4267
|
+
igv.BinaryParser.prototype.getUShort = function () {
|
4268
|
+
|
4269
|
+
// var byte1 = this.getByte(),
|
4270
|
+
// byte2 = this.getByte(),
|
4271
|
+
// retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24));
|
4272
|
+
// return retValue;
|
4273
|
+
|
4274
|
+
//
|
4275
|
+
var retValue = this.view.getUint16 (this.position, this.littleEndian);
|
4276
|
+
this.position += 2
|
4277
|
+
return retValue;
|
4278
|
+
}
|
4279
|
+
|
4436
4280
|
|
4437
4281
|
igv.BinaryParser.prototype.getInt = function () {
|
4438
4282
|
|
@@ -4450,23 +4294,32 @@ var igv = (function (igv) {
|
|
4450
4294
|
|
4451
4295
|
igv.BinaryParser.prototype.getLong = function () {
|
4452
4296
|
|
4453
|
-
//
|
4454
|
-
|
4455
|
-
var
|
4456
|
-
|
4457
|
-
|
4458
|
-
|
4459
|
-
|
4460
|
-
|
4461
|
-
|
4462
|
-
|
4463
|
-
|
4464
|
-
|
4465
|
-
|
4466
|
-
|
4467
|
-
|
4468
|
-
|
4469
|
-
|
4297
|
+
// DataView doesn't support long. So we'll try manually
|
4298
|
+
|
4299
|
+
var b = [];
|
4300
|
+
b[0] = this.view.getUint8(this.position);
|
4301
|
+
b[1] = this.view.getUint8(this.position + 1);
|
4302
|
+
b[2] = this.view.getUint8(this.position + 2);
|
4303
|
+
b[3] = this.view.getUint8(this.position + 3);
|
4304
|
+
b[4] = this.view.getUint8(this.position + 4);
|
4305
|
+
b[5] = this.view.getUint8(this.position + 5);
|
4306
|
+
b[6] = this.view.getUint8(this.position + 6);
|
4307
|
+
b[7] = this.view.getUint8(this.position + 7);
|
4308
|
+
|
4309
|
+
var value = 0;
|
4310
|
+
if (this.littleEndian) {
|
4311
|
+
for (var i = b.length - 1; i >= 0; i--) {
|
4312
|
+
value = (value * 256) + b[i];
|
4313
|
+
}
|
4314
|
+
} else {
|
4315
|
+
for (var i = 0; i < b.length; i++) {
|
4316
|
+
value = (value * 256) + b[i];
|
4317
|
+
}
|
4318
|
+
}
|
4319
|
+
|
4320
|
+
|
4321
|
+
this.position += 8;
|
4322
|
+
return value;
|
4470
4323
|
}
|
4471
4324
|
|
4472
4325
|
igv.BinaryParser.prototype.getString = function (len) {
|
@@ -4485,15 +4338,28 @@ var igv = (function (igv) {
|
|
4485
4338
|
var s = "";
|
4486
4339
|
var i;
|
4487
4340
|
var c;
|
4488
|
-
for (i=0; i<len; i++) {
|
4341
|
+
for (i = 0; i < len; i++) {
|
4489
4342
|
c = this.view.getUint8(this.position++);
|
4490
|
-
if(c > 0) {
|
4343
|
+
if (c > 0) {
|
4491
4344
|
s += String.fromCharCode(c);
|
4492
4345
|
}
|
4493
4346
|
}
|
4494
4347
|
return s;
|
4495
4348
|
}
|
4496
4349
|
|
4350
|
+
igv.BinaryParser.prototype.getFixedLengthTrimmedString = function (len) {
|
4351
|
+
|
4352
|
+
var s = "";
|
4353
|
+
var i;
|
4354
|
+
var c;
|
4355
|
+
for (i = 0; i < len; i++) {
|
4356
|
+
c = this.view.getUint8(this.position++);
|
4357
|
+
if (c > 32) {
|
4358
|
+
s += String.fromCharCode(c);
|
4359
|
+
}
|
4360
|
+
}
|
4361
|
+
return s;
|
4362
|
+
}
|
4497
4363
|
|
4498
4364
|
igv.BinaryParser.prototype.getFloat = function () {
|
4499
4365
|
|
@@ -4523,7 +4389,7 @@ var igv = (function (igv) {
|
|
4523
4389
|
* TODO -- why isn't 8th byte used ?
|
4524
4390
|
* @returns {*}
|
4525
4391
|
*/
|
4526
|
-
igv.BinaryParser.prototype.
|
4392
|
+
igv.BinaryParser.prototype.getVPointer = function () {
|
4527
4393
|
|
4528
4394
|
var position = this.position,
|
4529
4395
|
offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)),
|
@@ -4535,11 +4401,11 @@ var igv = (function (igv) {
|
|
4535
4401
|
block = byte6 + byte5 + byte4 + byte3 + byte2;
|
4536
4402
|
this.position += 8;
|
4537
4403
|
|
4538
|
-
if (block == 0 && offset == 0) {
|
4539
|
-
|
4540
|
-
} else {
|
4541
|
-
|
4542
|
-
}
|
4404
|
+
// if (block == 0 && offset == 0) {
|
4405
|
+
// return null;
|
4406
|
+
// } else {
|
4407
|
+
return new VPointer(block, offset);
|
4408
|
+
// }
|
4543
4409
|
}
|
4544
4410
|
|
4545
4411
|
|
@@ -4548,7 +4414,17 @@ var igv = (function (igv) {
|
|
4548
4414
|
this.offset = offset;
|
4549
4415
|
}
|
4550
4416
|
|
4551
|
-
VPointer.prototype.
|
4417
|
+
VPointer.prototype.isLessThan = function (vp) {
|
4418
|
+
return this.block < vp.block ||
|
4419
|
+
(this.block === vp.block && this.offset < vp.offset);
|
4420
|
+
}
|
4421
|
+
|
4422
|
+
VPointer.prototype.isGreaterThan = function (vp) {
|
4423
|
+
return this.block > vp.block ||
|
4424
|
+
(this.block === vp.block && this.offset > vp.offset);
|
4425
|
+
}
|
4426
|
+
|
4427
|
+
VPointer.prototype.print = function () {
|
4552
4428
|
return "" + this.block + ":" + this.offset;
|
4553
4429
|
}
|
4554
4430
|
|
@@ -4556,6 +4432,7 @@ var igv = (function (igv) {
|
|
4556
4432
|
return igv;
|
4557
4433
|
|
4558
4434
|
})(igv || {});
|
4435
|
+
|
4559
4436
|
/*
|
4560
4437
|
* The MIT License (MIT)
|
4561
4438
|
*
|
@@ -4583,6 +4460,9 @@ var igv = (function (igv) {
|
|
4583
4460
|
|
4584
4461
|
var igv = (function (igv) {
|
4585
4462
|
|
4463
|
+
var knownFileTypes = new Set(["narrowpeak", "broadpeak", "peaks", "bedgraph", "wig", "gff3", "gff",
|
4464
|
+
"gtf", "aneu", "fusionjuncspan", "refflat", "seg", "bed", "vcf", "bb", "bigbed", "bw", "bigwig", "bam", "tdf"]);
|
4465
|
+
|
4586
4466
|
igv.Browser = function (options, trackContainer) {
|
4587
4467
|
|
4588
4468
|
igv.browser = this; // Make globally visible (for use in html markup).
|
@@ -4655,7 +4535,7 @@ var igv = (function (igv) {
|
|
4655
4535
|
this.searchConfig = {
|
4656
4536
|
// Legacy support -- deprecated
|
4657
4537
|
type: "plain",
|
4658
|
-
url: "
|
4538
|
+
url: "https://portals.broadinstitute.org/webservices/igv/locus?genome=" + genomeId + "&name=$FEATURE$",
|
4659
4539
|
coords: 0,
|
4660
4540
|
chromosomeField: "chromosome",
|
4661
4541
|
startField: "start",
|
@@ -4672,19 +4552,23 @@ var igv = (function (igv) {
|
|
4672
4552
|
|
4673
4553
|
igv.Browser.prototype.loadTracksWithConfigList = function (configList) {
|
4674
4554
|
|
4675
|
-
var self = this
|
4555
|
+
var self = this,
|
4556
|
+
loadedTracks = [];
|
4557
|
+
|
4676
4558
|
|
4677
4559
|
configList.forEach(function (config) {
|
4678
|
-
self.loadTrack(config);
|
4560
|
+
loadedTracks.push(self.loadTrack(config));
|
4679
4561
|
});
|
4680
4562
|
|
4681
4563
|
// Really we should just resize the new trackViews, but currently there is no way to get a handle on those
|
4682
4564
|
this.trackViews.forEach(function (trackView) {
|
4683
4565
|
trackView.resize();
|
4684
|
-
})
|
4566
|
+
});
|
4685
4567
|
|
4568
|
+
return loadedTracks;
|
4686
4569
|
};
|
4687
4570
|
|
4571
|
+
|
4688
4572
|
igv.Browser.prototype.loadTrack = function (config) {
|
4689
4573
|
|
4690
4574
|
var self = this,
|
@@ -4708,13 +4592,14 @@ var igv = (function (igv) {
|
|
4708
4592
|
}
|
4709
4593
|
}
|
4710
4594
|
|
4711
|
-
|
4595
|
+
var typeLowerCase = config.type === undefined ? "" : config.type.toLowerCase();
|
4596
|
+
switch (typeLowerCase) {
|
4712
4597
|
case "gwas":
|
4713
4598
|
newTrack = new igv.GWASTrack(config);
|
4714
4599
|
break;
|
4715
4600
|
case "annotation":
|
4716
4601
|
case "genes":
|
4717
|
-
case "
|
4602
|
+
case "fusionjuncspan":
|
4718
4603
|
newTrack = new igv.FeatureTrack(config);
|
4719
4604
|
break;
|
4720
4605
|
case "variant":
|
@@ -4745,7 +4630,7 @@ var igv = (function (igv) {
|
|
4745
4630
|
default:
|
4746
4631
|
|
4747
4632
|
//alert("Unknown file type: " + config.url);
|
4748
|
-
igv.presentAlert("Unknown file type: " +
|
4633
|
+
igv.presentAlert("Unknown file type: " + config.url);
|
4749
4634
|
|
4750
4635
|
return null;
|
4751
4636
|
}
|
@@ -4769,8 +4654,9 @@ var igv = (function (igv) {
|
|
4769
4654
|
self.addTrack(newTrack);
|
4770
4655
|
}
|
4771
4656
|
|
4772
|
-
|
4657
|
+
return newTrack;
|
4773
4658
|
|
4659
|
+
};
|
4774
4660
|
|
4775
4661
|
/**
|
4776
4662
|
* Add a new track. Each track is associated with the following DOM elements
|
@@ -4816,7 +4702,7 @@ var igv = (function (igv) {
|
|
4816
4702
|
});
|
4817
4703
|
|
4818
4704
|
// Reattach the divs to the dom in the correct order
|
4819
|
-
$(this.trackContainerDiv).children().detach();
|
4705
|
+
$(this.trackContainerDiv).children("igv-track-div").detach();
|
4820
4706
|
|
4821
4707
|
this.trackViews.forEach(function (trackView, index, trackViews) {
|
4822
4708
|
|
@@ -4947,6 +4833,10 @@ var igv = (function (igv) {
|
|
4947
4833
|
|
4948
4834
|
this.updateLocusSearch(this.referenceFrame);
|
4949
4835
|
|
4836
|
+
if (this.centerGuide) {
|
4837
|
+
this.centerGuide.repaint();
|
4838
|
+
}
|
4839
|
+
|
4950
4840
|
if (this.ideoPanel) {
|
4951
4841
|
this.ideoPanel.repaint();
|
4952
4842
|
}
|
@@ -5021,14 +4911,14 @@ var igv = (function (igv) {
|
|
5021
4911
|
|
5022
4912
|
};
|
5023
4913
|
|
5024
|
-
igv.Browser.prototype.pixelPerBasepairThreshold = function () {
|
5025
|
-
return 14.0;
|
5026
|
-
};
|
5027
|
-
|
5028
4914
|
igv.Browser.prototype.trackViewportWidthBP = function () {
|
5029
4915
|
return this.referenceFrame.bpPerPixel * this.trackViewportWidth();
|
5030
4916
|
};
|
5031
4917
|
|
4918
|
+
igv.Browser.prototype.minimumBasesExtent = function () {
|
4919
|
+
return 40;
|
4920
|
+
};
|
4921
|
+
|
5032
4922
|
igv.Browser.prototype.removeAllTracks = function () {
|
5033
4923
|
var tracks = this.trackViews;
|
5034
4924
|
|
@@ -5100,7 +4990,7 @@ var igv = (function (igv) {
|
|
5100
4990
|
|
5101
4991
|
};
|
5102
4992
|
|
5103
|
-
// Zoom in by a factor of 2, keeping the same center location
|
4993
|
+
// Zoom in by a factor of 2, keeping the same center location
|
5104
4994
|
igv.Browser.prototype.zoomIn = function () {
|
5105
4995
|
|
5106
4996
|
if (this.loadInProgress()) {
|
@@ -5108,25 +4998,36 @@ var igv = (function (igv) {
|
|
5108
4998
|
return;
|
5109
4999
|
}
|
5110
5000
|
|
5111
|
-
var
|
5112
|
-
center,
|
5113
|
-
viewportWidth;
|
5001
|
+
var centerBP;
|
5114
5002
|
|
5115
|
-
|
5003
|
+
console.log('browser.zoomIn - src extent ' + basesExtent(this.trackViewportWidth(), this.referenceFrame.bpPerPixel));
|
5116
5004
|
|
5117
|
-
|
5118
|
-
if (
|
5119
|
-
|
5005
|
+
// Have we reached the zoom-in threshold yet? If so, bail.
|
5006
|
+
if (this.minimumBasesExtent() > basesExtent(this.trackViewportWidth(), this.referenceFrame.bpPerPixel / 2.0)) {
|
5007
|
+
console.log('browser.zoomIn - dst extent ' + basesExtent(this.trackViewportWidth(), this.referenceFrame.bpPerPixel / 2.0) + ' bailing ...');
|
5120
5008
|
return;
|
5009
|
+
} else {
|
5010
|
+
console.log('browser.zoomIn - dst extent ' + basesExtent(this.trackViewportWidth(), this.referenceFrame.bpPerPixel / 2.0));
|
5121
5011
|
}
|
5122
5012
|
|
5123
|
-
|
5124
|
-
this.referenceFrame.start
|
5125
|
-
|
5013
|
+
// window center (base-pair units)
|
5014
|
+
centerBP = this.referenceFrame.start + this.referenceFrame.bpPerPixel * (this.trackViewportWidth() / 2);
|
5015
|
+
|
5016
|
+
// derive scaled (zoomed in) start location (base-pair units) by multiplying half-width by halve'd bases-per-pixel
|
5017
|
+
// which results in base-pair units
|
5018
|
+
this.referenceFrame.start = centerBP - (this.trackViewportWidth() / 2) * (this.referenceFrame.bpPerPixel / 2.0);
|
5019
|
+
|
5020
|
+
// halve the bases-per-pixel
|
5021
|
+
this.referenceFrame.bpPerPixel /= 2.0;
|
5022
|
+
|
5126
5023
|
this.update();
|
5024
|
+
|
5025
|
+
function basesExtent(width, bpp) {
|
5026
|
+
return Math.floor(width * bpp);
|
5027
|
+
}
|
5127
5028
|
};
|
5128
5029
|
|
5129
|
-
// Zoom out by a factor of 2, keeping the same center location if possible
|
5030
|
+
// Zoom out by a factor of 2, keeping the same center location if possible
|
5130
5031
|
igv.Browser.prototype.zoomOut = function () {
|
5131
5032
|
|
5132
5033
|
if (this.loadInProgress()) {
|
@@ -5160,67 +5061,46 @@ var igv = (function (igv) {
|
|
5160
5061
|
this.update();
|
5161
5062
|
};
|
5162
5063
|
|
5163
|
-
|
5164
5064
|
/**
|
5165
5065
|
*
|
5166
5066
|
* @param feature
|
5167
5067
|
* @param callback - function to call
|
5168
5068
|
*/
|
5169
|
-
igv.Browser.prototype.search = function (feature, callback) {
|
5170
|
-
|
5171
|
-
// See if we're ready to respond to a search, if not just queue it up and return
|
5172
|
-
if (igv.browser === undefined || igv.browser.genome === undefined) {
|
5173
|
-
igv.browser.initialLocus = feature;
|
5174
|
-
if (callback) callback();
|
5175
|
-
return;
|
5176
|
-
}
|
5177
|
-
|
5178
|
-
|
5069
|
+
igv.Browser.prototype.search = function (feature, callback, force) {
|
5179
5070
|
var type,
|
5180
5071
|
chr,
|
5181
|
-
posTokens,
|
5182
5072
|
start,
|
5183
5073
|
end,
|
5184
5074
|
searchConfig,
|
5185
|
-
tokens,
|
5186
5075
|
url,
|
5187
|
-
chromosome,
|
5188
5076
|
result;
|
5189
5077
|
|
5190
|
-
if
|
5078
|
+
// See if we're ready to respond to a search, if not just queue it up and return
|
5079
|
+
if (igv.browser === undefined || igv.browser.genome === undefined) {
|
5080
|
+
igv.browser.initialLocus = feature;
|
5081
|
+
if (callback) {
|
5082
|
+
callback();
|
5083
|
+
}
|
5084
|
+
return;
|
5085
|
+
}
|
5191
5086
|
|
5192
|
-
|
5193
|
-
tokens = feature.split(":");
|
5194
|
-
chr = this.genome.getChromosomeName(tokens[0]);
|
5087
|
+
if (isLocusFeature(feature, this.genome, force)) {
|
5195
5088
|
|
5196
|
-
|
5197
|
-
chromosome = this.genome.getChromosome(feature);
|
5198
|
-
start = 0;
|
5199
|
-
end = chromosome.bpLength;
|
5200
|
-
}
|
5201
|
-
else {
|
5202
|
-
posTokens = tokens[1].split("-");
|
5203
|
-
start = parseInt(posTokens[0].replace(/,/g, "")) - 1;
|
5204
|
-
end = parseInt(posTokens[1].replace(/,/g, ""));
|
5205
|
-
}
|
5089
|
+
var success = gotoLocusFeature(feature, this.genome, this);
|
5206
5090
|
|
5207
|
-
if (
|
5208
|
-
|
5209
|
-
fireOnsearch.call(igv.browser, feature, type);
|
5091
|
+
if ((force || true === success) && callback) {
|
5092
|
+
callback();
|
5210
5093
|
}
|
5211
5094
|
|
5212
|
-
|
5213
|
-
|
5214
|
-
}
|
5215
|
-
else {
|
5095
|
+
} else {
|
5216
5096
|
|
5217
5097
|
// Try local feature cache first
|
5218
5098
|
result = this.featureDB[feature.toUpperCase()];
|
5219
5099
|
if (result) {
|
5100
|
+
|
5220
5101
|
handleSearchResult(result.name, result.chr, result.start, result.end, "");
|
5221
|
-
}
|
5222
5102
|
|
5223
|
-
else if (this.searchConfig) {
|
5103
|
+
} else if (this.searchConfig) {
|
5224
5104
|
url = this.searchConfig.url.replace("$FEATURE$", feature);
|
5225
5105
|
searchConfig = this.searchConfig;
|
5226
5106
|
|
@@ -5245,7 +5125,7 @@ var igv = (function (igv) {
|
|
5245
5125
|
//alert('No feature found with name "' + feature + '"');
|
5246
5126
|
igv.presentAlert('No feature found with name "' + feature + '"');
|
5247
5127
|
}
|
5248
|
-
else
|
5128
|
+
else {
|
5249
5129
|
|
5250
5130
|
// Just take the first result for now
|
5251
5131
|
// TODO - merge results, or ask user to choose
|
@@ -5257,18 +5137,124 @@ var igv = (function (igv) {
|
|
5257
5137
|
type = r["featureType"] || r["type"];
|
5258
5138
|
handleSearchResult(feature, chr, start, end, type);
|
5259
5139
|
}
|
5260
|
-
else {
|
5261
|
-
|
5262
|
-
}
|
5140
|
+
//else {
|
5141
|
+
// presentSearchResults(results, searchConfig, feature);
|
5142
|
+
//}
|
5263
5143
|
|
5264
5144
|
if (callback) callback();
|
5265
5145
|
});
|
5266
5146
|
}
|
5267
5147
|
}
|
5268
5148
|
|
5149
|
+
function isLocusFeature(f, genome) {
|
5150
|
+
|
5151
|
+
if (2 === f.split(':').length) {
|
5152
|
+
return true;
|
5153
|
+
}
|
5154
|
+
|
5155
|
+
if (genome.getChromosome(f)) {
|
5156
|
+
return true;
|
5157
|
+
}
|
5269
5158
|
|
5159
|
+
return false;
|
5160
|
+
}
|
5270
5161
|
};
|
5271
5162
|
|
5163
|
+
function gotoLocusFeature(locusFeature, genome, browser) {
|
5164
|
+
|
5165
|
+
var type,
|
5166
|
+
tokens,
|
5167
|
+
chr,
|
5168
|
+
start,
|
5169
|
+
end,
|
5170
|
+
chrName,
|
5171
|
+
startEnd,
|
5172
|
+
center,
|
5173
|
+
obj;
|
5174
|
+
|
5175
|
+
|
5176
|
+
type = 'locus';
|
5177
|
+
tokens = locusFeature.split(":");
|
5178
|
+
chrName = genome.getChromosomeName(tokens[0]);
|
5179
|
+
if (chrName) {
|
5180
|
+
chr = genome.getChromosome(chrName);
|
5181
|
+
}
|
5182
|
+
|
5183
|
+
if (chr) {
|
5184
|
+
|
5185
|
+
// returning undefined indicates locus is a chromosome name.
|
5186
|
+
start = end = undefined;
|
5187
|
+
if (1 === tokens.length) {
|
5188
|
+
start = 0;
|
5189
|
+
end = chr.bpLength;
|
5190
|
+
} else {
|
5191
|
+
startEnd = tokens[1].split("-");
|
5192
|
+
start = Math.max(0, parseInt(startEnd[0].replace(/,/g, "")) - 1);
|
5193
|
+
if (2 === startEnd.length) {
|
5194
|
+
end = Math.min(chr.bpLength, parseInt(startEnd[1].replace(/,/g, "")));
|
5195
|
+
if (end < 0) {
|
5196
|
+
// This can happen from integer overflow
|
5197
|
+
end = chr.bpLength;
|
5198
|
+
}
|
5199
|
+
}
|
5200
|
+
}
|
5201
|
+
|
5202
|
+
obj = {start: start, end: end};
|
5203
|
+
validateLocusExtent(igv.browser, chr, obj);
|
5204
|
+
start = obj.start;
|
5205
|
+
end = obj.end;
|
5206
|
+
|
5207
|
+
}
|
5208
|
+
|
5209
|
+
if (undefined === chr || isNaN(start) || (start > end)) {
|
5210
|
+
igv.presentAlert("Unrecognized feature or locus: " + locusFeature);
|
5211
|
+
return false;
|
5212
|
+
}
|
5213
|
+
|
5214
|
+
browser.goto(chrName, start, end);
|
5215
|
+
fireOnsearch.call(igv.browser, locusFeature, type);
|
5216
|
+
|
5217
|
+
function validateLocusExtent(browser, chromosome, extent) {
|
5218
|
+
|
5219
|
+
var ss = extent.start,
|
5220
|
+
ee = extent.end,
|
5221
|
+
locusExtent = ee - ss;
|
5222
|
+
|
5223
|
+
if (undefined === ee) {
|
5224
|
+
|
5225
|
+
ss -= igv.browser.minimumBasesExtent() / 2;
|
5226
|
+
ee = ss + igv.browser.minimumBasesExtent();
|
5227
|
+
|
5228
|
+
if (ee > chromosome.bpLength) {
|
5229
|
+
ee = chromosome.bpLength;
|
5230
|
+
ss = ee - igv.browser.minimumBasesExtent();
|
5231
|
+
} else if (ss < 0) {
|
5232
|
+
ss = 0;
|
5233
|
+
ee = igv.browser.minimumBasesExtent();
|
5234
|
+
}
|
5235
|
+
|
5236
|
+
} else if (ee - ss < igv.browser.minimumBasesExtent()) {
|
5237
|
+
|
5238
|
+
center = (ee + ss) / 2;
|
5239
|
+
if (center - igv.browser.minimumBasesExtent() / 2 < 0) {
|
5240
|
+
ss = 0;
|
5241
|
+
ee = ss + igv.browser.minimumBasesExtent();
|
5242
|
+
} else if (center + igv.browser.minimumBasesExtent() / 2 > chromosome.bpLength) {
|
5243
|
+
ee = chromosome.bpLength;
|
5244
|
+
ss = ee - igv.browser.minimumBasesExtent();
|
5245
|
+
} else {
|
5246
|
+
ss = center - igv.browser.minimumBasesExtent() / 2;
|
5247
|
+
ee = ss + igv.browser.minimumBasesExtent();
|
5248
|
+
}
|
5249
|
+
}
|
5250
|
+
|
5251
|
+
extent.start = Math.ceil(ss);
|
5252
|
+
extent.end = Math.floor(ee);
|
5253
|
+
}
|
5254
|
+
|
5255
|
+
return true;
|
5256
|
+
}
|
5257
|
+
|
5272
5258
|
function presentSearchResults(loci, config, feature) {
|
5273
5259
|
|
5274
5260
|
igv.browser.$searchResultsTable.empty();
|
@@ -5402,6 +5388,20 @@ var igv = (function (igv) {
|
|
5402
5388
|
mouseDownX = lastMouseX;
|
5403
5389
|
});
|
5404
5390
|
|
5391
|
+
// Guide line is bound within track area, and offset by 5 pixels so as not to interfere mouse clicks.
|
5392
|
+
$(trackContainerDiv).mousemove(function (e) {
|
5393
|
+
var xy,
|
5394
|
+
_left,
|
5395
|
+
$element = igv.browser.$cursorTrackingGuide;
|
5396
|
+
|
5397
|
+
xy = igv.translateMouseCoordinates(e, trackContainerDiv);
|
5398
|
+
_left = Math.max(50, xy.x - 5);
|
5399
|
+
|
5400
|
+
_left = Math.min(igv.browser.trackContainerDiv.clientWidth - 65, _left);
|
5401
|
+
$element.css({left: _left + 'px'});
|
5402
|
+
});
|
5403
|
+
|
5404
|
+
|
5405
5405
|
$(trackContainerDiv).mousemove(igv.throttle(function (e) {
|
5406
5406
|
|
5407
5407
|
var coords = igv.translateMouseCoordinates(e, trackContainerDiv),
|
@@ -5430,14 +5430,10 @@ var igv = (function (igv) {
|
|
5430
5430
|
|
5431
5431
|
referenceFrame.shiftPixels(lastMouseX - coords.x);
|
5432
5432
|
|
5433
|
-
// TODO -- clamping code below is broken for regular IGV => disabled for now, needs fixed
|
5434
|
-
|
5435
|
-
|
5436
5433
|
// clamp left
|
5437
5434
|
referenceFrame.start = Math.max(0, referenceFrame.start);
|
5438
5435
|
|
5439
5436
|
// clamp right
|
5440
|
-
|
5441
5437
|
var chromosome = igv.browser.genome.getChromosome(referenceFrame.chr);
|
5442
5438
|
maxEnd = chromosome.bpLength;
|
5443
5439
|
maxStart = maxEnd - igv.browser.trackViewportWidth() * referenceFrame.bpPerPixel;
|
@@ -5462,12 +5458,19 @@ var igv = (function (igv) {
|
|
5462
5458
|
|
5463
5459
|
$(trackContainerDiv).mouseleave(mouseUpOrOut);
|
5464
5460
|
|
5465
|
-
function mouseUpOrOut() {
|
5461
|
+
function mouseUpOrOut(e) {
|
5462
|
+
|
5463
|
+
var element = igv.browser.$cursorTrackingGuide.get(0);
|
5466
5464
|
|
5467
5465
|
if (isRulerTrack) {
|
5468
5466
|
return;
|
5469
5467
|
}
|
5470
5468
|
|
5469
|
+
// Don't let vertical line interfere with dragging
|
5470
|
+
if (igv.browser.$cursorTrackingGuide && e.toElement === igv.browser.$cursorTrackingGuide.get(0) && e.type === 'mouseleave') {
|
5471
|
+
return;
|
5472
|
+
}
|
5473
|
+
|
5471
5474
|
if (isDragging) {
|
5472
5475
|
igv.browser.fireEvent('trackdragend');
|
5473
5476
|
isDragging = false;
|
@@ -5486,6 +5489,8 @@ var igv = (function (igv) {
|
|
5486
5489
|
*
|
5487
5490
|
* @param config
|
5488
5491
|
*/
|
5492
|
+
|
5493
|
+
|
5489
5494
|
function inferTypes(config) {
|
5490
5495
|
|
5491
5496
|
function translateDeprecatedTypes(config) {
|
@@ -5496,32 +5501,36 @@ var igv = (function (igv) {
|
|
5496
5501
|
}
|
5497
5502
|
|
5498
5503
|
if ("bed" === config.type) {
|
5499
|
-
config.type =
|
5504
|
+
config.type = "annotation";
|
5500
5505
|
config.format = config.format || "bed";
|
5506
|
+
|
5501
5507
|
}
|
5502
5508
|
|
5503
|
-
if ("bam" === config.type) {
|
5509
|
+
else if ("bam" === config.type) {
|
5504
5510
|
config.type = "alignment";
|
5505
5511
|
config.format = "bam"
|
5506
5512
|
}
|
5507
5513
|
|
5508
|
-
if ("vcf" === config.type) {
|
5514
|
+
else if ("vcf" === config.type) {
|
5509
5515
|
config.type = "variant";
|
5510
5516
|
config.format = "vcf"
|
5511
5517
|
}
|
5512
5518
|
|
5513
|
-
if ("t2d" === config.type) {
|
5519
|
+
else if ("t2d" === config.type) {
|
5514
5520
|
config.type = "gwas";
|
5515
5521
|
}
|
5516
5522
|
|
5517
|
-
if ("FusionJuncSpan" === config.type) {
|
5518
|
-
config.format = "
|
5523
|
+
else if ("FusionJuncSpan" === config.type) {
|
5524
|
+
config.format = "fusionjuncspan";
|
5519
5525
|
}
|
5520
5526
|
}
|
5521
5527
|
|
5522
5528
|
function inferFileFormat(config) {
|
5523
5529
|
|
5524
|
-
if (config.format)
|
5530
|
+
if (config.format) {
|
5531
|
+
config.format = config.format.toLowerCase();
|
5532
|
+
return;
|
5533
|
+
}
|
5525
5534
|
|
5526
5535
|
var path = config.url || config.localFile.name,
|
5527
5536
|
fn = path.toLowerCase(),
|
@@ -5543,18 +5552,20 @@ var igv = (function (igv) {
|
|
5543
5552
|
|
5544
5553
|
|
5545
5554
|
idx = fn.lastIndexOf(".");
|
5546
|
-
ext = idx < 0 ? fn : fn.substr(idx);
|
5555
|
+
ext = idx < 0 ? fn : fn.substr(idx + 1);
|
5547
5556
|
|
5548
|
-
switch (ext) {
|
5557
|
+
switch (ext.toLowerCase()) {
|
5549
5558
|
|
5550
|
-
case "
|
5559
|
+
case "bw":
|
5551
5560
|
config.format = "bigwig";
|
5552
5561
|
break;
|
5553
|
-
case "
|
5562
|
+
case "bb":
|
5554
5563
|
config.format = "bigbed";
|
5555
5564
|
|
5556
5565
|
default:
|
5557
|
-
|
5566
|
+
if (knownFileTypes.has(ext)) {
|
5567
|
+
config.format = ext;
|
5568
|
+
}
|
5558
5569
|
}
|
5559
5570
|
}
|
5560
5571
|
|
@@ -5562,25 +5573,27 @@ var igv = (function (igv) {
|
|
5562
5573
|
|
5563
5574
|
if (config.type) return;
|
5564
5575
|
|
5565
|
-
|
5566
|
-
|
5567
|
-
|
5568
|
-
|
5569
|
-
|
5570
|
-
|
5571
|
-
|
5572
|
-
|
5573
|
-
|
5574
|
-
|
5575
|
-
|
5576
|
-
|
5577
|
-
|
5578
|
-
|
5579
|
-
|
5580
|
-
|
5581
|
-
|
5582
|
-
|
5583
|
-
|
5576
|
+
if (config.format !== undefined) {
|
5577
|
+
switch (config.format.toLowerCase()) {
|
5578
|
+
case "bw":
|
5579
|
+
case "bigwig":
|
5580
|
+
case "wig":
|
5581
|
+
case "bedgraph":
|
5582
|
+
case "tdf":
|
5583
|
+
config.type = "wig";
|
5584
|
+
break;
|
5585
|
+
case "vcf":
|
5586
|
+
config.type = "variant";
|
5587
|
+
break;
|
5588
|
+
case "seg":
|
5589
|
+
config.type = "seg";
|
5590
|
+
break;
|
5591
|
+
case "bam":
|
5592
|
+
config.type = "alignment";
|
5593
|
+
break;
|
5594
|
+
default:
|
5595
|
+
config.type = "annotation";
|
5596
|
+
}
|
5584
5597
|
}
|
5585
5598
|
}
|
5586
5599
|
|
@@ -7492,7 +7505,7 @@ var igv = (function (igv) {
|
|
7492
7505
|
var self = this;
|
7493
7506
|
|
7494
7507
|
return new Promise(function (fulfill, reject) {
|
7495
|
-
parser = self.parser,
|
7508
|
+
var parser = self.parser,
|
7496
7509
|
options = {
|
7497
7510
|
headers: self.config.headers, // http headers, not file header
|
7498
7511
|
withCredentials: self.config.withCredentials
|
@@ -7543,7 +7556,7 @@ var igv = (function (igv) {
|
|
7543
7556
|
|
7544
7557
|
var startPos = block.minv.block,
|
7545
7558
|
startOffset = block.minv.offset,
|
7546
|
-
endPos = block.maxv.block + (index.tabix ? MAX_GZIP_BLOCK_SIZE
|
7559
|
+
endPos = block.maxv.block + (index.tabix ? MAX_GZIP_BLOCK_SIZE : 0),
|
7547
7560
|
options = {
|
7548
7561
|
headers: self.config.headers, // http headers, not file header
|
7549
7562
|
range: {start: startPos, size: endPos - startPos + 1},
|
@@ -7643,7 +7656,7 @@ var igv = (function (igv) {
|
|
7643
7656
|
return new Promise(function (fulfill, reject) {
|
7644
7657
|
|
7645
7658
|
|
7646
|
-
if(self.header) {
|
7659
|
+
if (self.header) {
|
7647
7660
|
fulfill(self.header);
|
7648
7661
|
}
|
7649
7662
|
|
@@ -7776,8 +7789,8 @@ var igv = (function (igv) {
|
|
7776
7789
|
|
7777
7790
|
|
7778
7791
|
switch (format) {
|
7779
|
-
case "
|
7780
|
-
case "
|
7792
|
+
case "narrowpeak":
|
7793
|
+
case "broadpeak":
|
7781
7794
|
case "peaks":
|
7782
7795
|
this.decode = decodePeak;
|
7783
7796
|
this.delimiter = /\s+/;
|
@@ -7800,12 +7813,12 @@ var igv = (function (igv) {
|
|
7800
7813
|
this.decode = decodeAneu;
|
7801
7814
|
this.delimiter = "\t";
|
7802
7815
|
break;
|
7803
|
-
case "
|
7816
|
+
case "fusionjuncspan":
|
7804
7817
|
// bhaas, needed for FusionInspector view
|
7805
7818
|
this.decode = decodeFusionJuncSpan;
|
7806
7819
|
this.delimiter = /\s+/;
|
7807
7820
|
break;
|
7808
|
-
case "
|
7821
|
+
case "gtexgwas":
|
7809
7822
|
this.skipRows = 1;
|
7810
7823
|
this.decode = decodeGtexGWAS;
|
7811
7824
|
this.delimiter = "\t";
|
@@ -8073,8 +8086,8 @@ var igv = (function (igv) {
|
|
8073
8086
|
chr: tokens[2],
|
8074
8087
|
start: parseInt(tokens[4]),
|
8075
8088
|
end: parseInt(tokens[5]),
|
8076
|
-
id: tokens[
|
8077
|
-
name: tokens[
|
8089
|
+
id: tokens[1],
|
8090
|
+
name: tokens[0],
|
8078
8091
|
strand: tokens[3],
|
8079
8092
|
cdStart: parseInt(tokens[6]),
|
8080
8093
|
cdEnd: parseInt(tokens[7])
|
@@ -8523,7 +8536,13 @@ var igv = (function (igv) {
|
|
8523
8536
|
if(header) {
|
8524
8537
|
var features = header.features;
|
8525
8538
|
if (features) {
|
8539
|
+
|
8540
|
+
if ("gtf" === self.config.format || "gff3" === self.config.format || "gff" === self.config.format) {
|
8541
|
+
features = (new igv.GFFHelper(self.config.format)).combineFeatures(features);
|
8542
|
+
}
|
8543
|
+
|
8526
8544
|
// Assign overlapping features to rows
|
8545
|
+
|
8527
8546
|
packFeatures(features, maxRows);
|
8528
8547
|
self.featureCache = new igv.FeatureCache(features);
|
8529
8548
|
|
@@ -8586,7 +8605,8 @@ var igv = (function (igv) {
|
|
8586
8605
|
if (self.sourceType === 'file' && (self.visibilityWindow === undefined || self.visibilityWindow <= 0)) {
|
8587
8606
|
// Expand genomic interval to grab entire chromosome
|
8588
8607
|
genomicInterval.start = 0;
|
8589
|
-
|
8608
|
+
var chromosome = igv.browser.genome.getChromosome(chr);
|
8609
|
+
genomicInterval.end = (chromosome === undefined ? Number.MAX_VALUE : chromosome.bpLength);
|
8590
8610
|
}
|
8591
8611
|
|
8592
8612
|
self.reader.readFeatures(chr, genomicInterval.start, genomicInterval.end).then(
|
@@ -10321,21 +10341,19 @@ var igv = (function (igv) {
|
|
10321
10341
|
this.config = config;
|
10322
10342
|
this.url = config.url;
|
10323
10343
|
|
10344
|
+
if (config.color === undefined) config.color = "rgb(150,150,150)"; // Hack -- should set a default color per track type
|
10345
|
+
|
10346
|
+
igv.configTrack(this, config);
|
10347
|
+
|
10324
10348
|
if ("bigwig" === config.format) {
|
10325
10349
|
this.featureSource = new igv.BWSource(config);
|
10350
|
+
} else if("tdf" === config.format) {
|
10351
|
+
this.featureSource = new igv.TDFSource(config);
|
10326
10352
|
}
|
10327
10353
|
else {
|
10328
10354
|
this.featureSource = new igv.FeatureSource(config);
|
10329
10355
|
}
|
10330
10356
|
|
10331
|
-
this.name = config.name;
|
10332
|
-
this.color = config.color || "rgb(150,150,150)";
|
10333
|
-
this.autoScale = config.autoScale !== undefined ? config.autoScale :
|
10334
|
-
(config.max === undefined ? true : false);
|
10335
|
-
|
10336
|
-
this.height = 100;
|
10337
|
-
this.order = config.order;
|
10338
|
-
|
10339
10357
|
// Min and max values. No defaults for these, if they aren't set track will autoscale.
|
10340
10358
|
this.dataRange = {
|
10341
10359
|
min: config.min,
|
@@ -10508,7 +10526,6 @@ var igv = (function (igv) {
|
|
10508
10526
|
}
|
10509
10527
|
|
10510
10528
|
|
10511
|
-
|
10512
10529
|
return igv;
|
10513
10530
|
|
10514
10531
|
})(igv || {});
|
@@ -11324,15 +11341,7 @@ var igv = (function (igv) {
|
|
11324
11341
|
*/
|
11325
11342
|
igv.ga4ghGet = function (options) {
|
11326
11343
|
|
11327
|
-
var url = options.url + "/" + options.entity + "/" + options.entityId
|
11328
|
-
apiKey = oauth.google.apiKey,
|
11329
|
-
paramSeparator = "?";
|
11330
|
-
|
11331
|
-
if (apiKey) {
|
11332
|
-
url = url + paramSeparator + "key=" + apiKey;
|
11333
|
-
}
|
11334
|
-
|
11335
|
-
options.headers = ga4ghHeaders();
|
11344
|
+
var url = options.url + "/" + options.entity + "/" + options.entityId;
|
11336
11345
|
|
11337
11346
|
return igvxhr.loadJson(url, options); // Returns a promise
|
11338
11347
|
}
|
@@ -11776,24 +11785,55 @@ var igv = (function (igv) {
|
|
11776
11785
|
|
11777
11786
|
var igv = (function (igv) {
|
11778
11787
|
|
11788
|
+
igv.Google = {
|
11789
|
+
|
11790
|
+
// Crude test, this is conservative, nothing bad happens for a false positive
|
11791
|
+
isGoogleURL: function (url) {
|
11792
|
+
return url.contains("googleapis");
|
11793
|
+
},
|
11779
11794
|
|
11780
|
-
|
11795
|
+
translateGoogleCloudURL: function (gsUrl) {
|
11781
11796
|
|
11782
|
-
|
11783
|
-
|
11784
|
-
|
11785
|
-
|
11786
|
-
|
11797
|
+
var i = gsUrl.indexOf('/', 5);
|
11798
|
+
if (i < 0) {
|
11799
|
+
console.log("Invalid gs url: " + gsUrl);
|
11800
|
+
return gsUrl;
|
11801
|
+
}
|
11787
11802
|
|
11788
|
-
|
11789
|
-
|
11803
|
+
var bucket = gsUrl.substring(5, i);
|
11804
|
+
var object = encodeURIComponent(gsUrl.substring(i + 1));
|
11790
11805
|
|
11791
|
-
|
11806
|
+
return "https://www.googleapis.com/storage/v1/b/" + bucket + "/o/" + object + "?alt=media";
|
11792
11807
|
|
11808
|
+
},
|
11793
11809
|
|
11810
|
+
addGoogleHeaders: function (headers) {
|
11811
|
+
{
|
11812
|
+
headers["Cache-Control"] = "no-cache";
|
11794
11813
|
|
11795
|
-
|
11814
|
+
var acToken = oauth.google.access_token;
|
11815
|
+
if (acToken && !headers.hasOwnProperty("Authorization")) {
|
11816
|
+
headers["Authorization"] = "Bearer " + acToken;
|
11817
|
+
}
|
11818
|
+
|
11819
|
+
return headers;
|
11820
|
+
|
11821
|
+
}
|
11822
|
+
},
|
11823
|
+
|
11824
|
+
addApiKey: function (url) {
|
11796
11825
|
|
11826
|
+
var apiKey = oauth.google.apiKey,
|
11827
|
+
paramSeparator = url.contains("?") ? "&" : "?";
|
11828
|
+
|
11829
|
+
if (apiKey !== undefined && !url.contains("key=")) {
|
11830
|
+
if (apiKey) {
|
11831
|
+
url = url + paramSeparator + "key=" + apiKey;
|
11832
|
+
}
|
11833
|
+
}
|
11834
|
+
return url;
|
11835
|
+
}
|
11836
|
+
}
|
11797
11837
|
|
11798
11838
|
return igv;
|
11799
11839
|
|
@@ -14127,7 +14167,7 @@ var igv = (function (igv) {
|
|
14127
14167
|
|
14128
14168
|
|
14129
14169
|
igv.createColorString = function (token) {
|
14130
|
-
if (token.
|
14170
|
+
if (token.includes(",")) {
|
14131
14171
|
return token.startsWith("rgb") ? token : "rgb(" + token + ")";
|
14132
14172
|
}
|
14133
14173
|
else {
|
@@ -14336,7 +14376,8 @@ var igv = (function (igv) {
|
|
14336
14376
|
|
14337
14377
|
var igv = (function (igv) {
|
14338
14378
|
|
14339
|
-
var igvjs_version = "
|
14379
|
+
var igvjs_version = "beta";
|
14380
|
+
igv.version = igvjs_version;
|
14340
14381
|
|
14341
14382
|
/**
|
14342
14383
|
* Create an igv.browser instance. This object defines the public API for interacting with the genome browser.
|
@@ -14436,9 +14477,7 @@ var igv = (function (igv) {
|
|
14436
14477
|
// controls
|
14437
14478
|
|
14438
14479
|
if (config.showCommandBar !== false && config.showControls !== false) {
|
14439
|
-
controlDiv = config.createControls ?
|
14440
|
-
config.createControls(browser, config) :
|
14441
|
-
createStandardControls(browser, config);
|
14480
|
+
controlDiv = config.createControls ? config.createControls(browser, config) : createStandardControls(browser, config);
|
14442
14481
|
$(rootDiv).append($(controlDiv));
|
14443
14482
|
}
|
14444
14483
|
|
@@ -14462,7 +14501,7 @@ var igv = (function (igv) {
|
|
14462
14501
|
igv.colorPicker.hide();
|
14463
14502
|
|
14464
14503
|
// alert object -- singleton shared by all components
|
14465
|
-
igv.alert = new igv.
|
14504
|
+
igv.alert = new igv.AlertDialog($(rootDiv), "igv-alert");
|
14466
14505
|
igv.alert.hide();
|
14467
14506
|
|
14468
14507
|
// Dialog object -- singleton shared by all components
|
@@ -14479,8 +14518,12 @@ var igv = (function (igv) {
|
|
14479
14518
|
}
|
14480
14519
|
|
14481
14520
|
// ideogram
|
14482
|
-
|
14483
|
-
|
14521
|
+
if (config.hideIdeogram && true === config.hideIdeogram) {
|
14522
|
+
// do nothing
|
14523
|
+
} else {
|
14524
|
+
browser.ideoPanel = new igv.IdeoPanel(headerDiv);
|
14525
|
+
browser.ideoPanel.resize();
|
14526
|
+
}
|
14484
14527
|
|
14485
14528
|
// phone home -- counts launches. Count is anonymous, needed for our continued funding. Please don't delete
|
14486
14529
|
phoneHome();
|
@@ -14535,7 +14578,7 @@ var igv = (function (igv) {
|
|
14535
14578
|
|
14536
14579
|
}
|
14537
14580
|
|
14538
|
-
});
|
14581
|
+
}, true);
|
14539
14582
|
|
14540
14583
|
} else if (config.tracks) {
|
14541
14584
|
|
@@ -14562,9 +14605,12 @@ var igv = (function (igv) {
|
|
14562
14605
|
$searchContainer,
|
14563
14606
|
$faZoom,
|
14564
14607
|
$trackLabelToggle,
|
14608
|
+
$cursorTrackingGuideToggle,
|
14565
14609
|
$zoomContainer,
|
14566
14610
|
$faZoomIn,
|
14567
|
-
$faZoomOut
|
14611
|
+
$faZoomOut,
|
14612
|
+
$karyoPanelToggle,
|
14613
|
+
display;
|
14568
14614
|
|
14569
14615
|
$controls = $('<div id="igvControlDiv">');
|
14570
14616
|
|
@@ -14627,25 +14673,50 @@ var igv = (function (igv) {
|
|
14627
14673
|
$zoomContainer.append($faZoomIn[0]);
|
14628
14674
|
$navigation.append($zoomContainer[0]);
|
14629
14675
|
|
14630
|
-
//
|
14676
|
+
// toggle track labels
|
14631
14677
|
$trackLabelToggle = $('<div class="igv-toggle-track-labels">');
|
14632
14678
|
$trackLabelToggle.text("hide labels");
|
14633
|
-
|
14634
14679
|
$trackLabelToggle.click(function () {
|
14635
|
-
|
14636
14680
|
browser.trackLabelsVisible = !browser.trackLabelsVisible;
|
14637
14681
|
$(this).text(true === browser.trackLabelsVisible ? "hide labels" : "show labels");
|
14638
|
-
|
14639
14682
|
$(browser.trackContainerDiv).find('.igv-track-label').toggle();
|
14640
|
-
|
14641
14683
|
});
|
14642
14684
|
|
14643
|
-
|
14685
|
+
// one base wide center guide
|
14686
|
+
browser.centerGuide = new igv.CenterGuide($(browser.trackContainerDiv), config);
|
14644
14687
|
|
14645
|
-
|
14688
|
+
// cursor tracking guide
|
14689
|
+
browser.$cursorTrackingGuide = $('<div class="igv-cursor-tracking-guide">');
|
14690
|
+
$(browser.trackContainerDiv).append(browser.$cursorTrackingGuide);
|
14691
|
+
browser.$cursorTrackingGuide.css("display", (config.showCursorTrackingGuide && true == config.showCursorTrackingGuide) ? "block" : "none");
|
14646
14692
|
|
14647
|
-
|
14648
|
-
|
14693
|
+
$cursorTrackingGuideToggle = $('<div class="igv-toggle-track-labels">');
|
14694
|
+
display = browser.$cursorTrackingGuide.css("display");
|
14695
|
+
$cursorTrackingGuideToggle.text("none" === display ? "show cursor guide" : "hide cursor guide");
|
14696
|
+
|
14697
|
+
$cursorTrackingGuideToggle.click(function () {
|
14698
|
+
display = browser.$cursorTrackingGuide.css("display");
|
14699
|
+
if ("none" === display) {
|
14700
|
+
browser.$cursorTrackingGuide.css("display", "block");
|
14701
|
+
$cursorTrackingGuideToggle.text("hide cursor guide");
|
14702
|
+
} else {
|
14703
|
+
browser.$cursorTrackingGuide.css("display", "none");
|
14704
|
+
$cursorTrackingGuideToggle.text("show cursor guide");
|
14705
|
+
}
|
14706
|
+
});
|
14707
|
+
|
14708
|
+
if(undefined === config.showCursorTrackingGuide || false == config.showCursorTrackingGuide) {
|
14709
|
+
$cursorTrackingGuideToggle.css("display", "none");
|
14710
|
+
}
|
14711
|
+
|
14712
|
+
$navigation.append($cursorTrackingGuideToggle);
|
14713
|
+
$navigation.append(browser.centerGuide.$centerGuideToggle);
|
14714
|
+
$navigation.append($trackLabelToggle);
|
14715
|
+
|
14716
|
+
}
|
14717
|
+
|
14718
|
+
if (config.showKaryo) {
|
14719
|
+
contentKaryo = $('#igvKaryoDiv')[0];
|
14649
14720
|
// if a karyo div already exists in the page, use that one.
|
14650
14721
|
// this allows the placement of the karyo view on the side, for instance
|
14651
14722
|
if (!contentKaryo) {
|
@@ -14653,8 +14724,29 @@ var igv = (function (igv) {
|
|
14653
14724
|
$controls.append(contentKaryo);
|
14654
14725
|
}
|
14655
14726
|
browser.karyoPanel = new igv.KaryoPanel(contentKaryo);
|
14656
|
-
}
|
14657
14727
|
|
14728
|
+
$karyoPanelToggle = $('<div class="igv-toggle-track-labels">');
|
14729
|
+
|
14730
|
+
if (config.showKaryo === "hide") {
|
14731
|
+
$karyoPanelToggle.text("Show Karyotype");
|
14732
|
+
$(contentKaryo).addClass("igv-karyo-hide");
|
14733
|
+
} else {
|
14734
|
+
$karyoPanelToggle.text("Hide Karyotype");
|
14735
|
+
}
|
14736
|
+
|
14737
|
+
$karyoPanelToggle.click(function () {
|
14738
|
+
var hidden = $(".igv-karyo-div").hasClass("igv-karyo-hide");
|
14739
|
+
if (hidden) {
|
14740
|
+
$karyoPanelToggle.text("Hide Karyotype");
|
14741
|
+
$(".igv-karyo-div").removeClass("igv-karyo-hide");
|
14742
|
+
} else {
|
14743
|
+
$karyoPanelToggle.text("Show Karyotype");
|
14744
|
+
$(".igv-karyo-div").addClass("igv-karyo-hide");
|
14745
|
+
}
|
14746
|
+
});
|
14747
|
+
|
14748
|
+
$navigation.append($karyoPanelToggle[0]);
|
14749
|
+
}
|
14658
14750
|
|
14659
14751
|
return $controls[0];
|
14660
14752
|
}
|
@@ -14672,15 +14764,15 @@ var igv = (function (igv) {
|
|
14672
14764
|
switch (genomeId) {
|
14673
14765
|
|
14674
14766
|
case "hg18":
|
14675
|
-
reference.fastaURL = "
|
14676
|
-
reference.cytobandURL = "
|
14767
|
+
reference.fastaURL = "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg18/hg18.fasta";
|
14768
|
+
reference.cytobandURL = "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg18/cytoBand.txt.gz";
|
14677
14769
|
break;
|
14678
14770
|
case "hg19":
|
14679
14771
|
case "GRCh37":
|
14680
14772
|
default:
|
14681
14773
|
{
|
14682
|
-
reference.fastaURL = "
|
14683
|
-
reference.cytobandURL = "
|
14774
|
+
reference.fastaURL = "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta";
|
14775
|
+
reference.cytobandURL = "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/cytoBand.txt";
|
14684
14776
|
}
|
14685
14777
|
}
|
14686
14778
|
return reference;
|
@@ -14896,75 +14988,20 @@ if (typeof String.prototype.contains === "undefined") {
|
|
14896
14988
|
};
|
14897
14989
|
}
|
14898
14990
|
|
14899
|
-
if (typeof String.prototype.
|
14900
|
-
String.prototype.
|
14901
|
-
return this.
|
14902
|
-
}
|
14903
|
-
}
|
14904
|
-
|
14905
|
-
if (typeof Array.prototype.shuffle === "undefined") {
|
14906
|
-
// Randomly shuffle contents of an array
|
14907
|
-
Array.prototype.shuffle = function () {
|
14908
|
-
for (var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x);
|
14909
|
-
return this;
|
14991
|
+
if (typeof String.prototype.includes === "undefined") {
|
14992
|
+
String.prototype.includes = function (it) {
|
14993
|
+
return this.indexOf(it) != -1;
|
14910
14994
|
};
|
14911
14995
|
}
|
14912
14996
|
|
14913
|
-
if (typeof Array.prototype.swap === "undefined") {
|
14914
|
-
Array.prototype.swap = function (a, b) {
|
14915
|
-
var tmp = this[a];
|
14916
|
-
this[a] = this[b];
|
14917
|
-
this[b] = tmp;
|
14918
|
-
}
|
14919
|
-
}
|
14920
|
-
|
14921
14997
|
|
14922
|
-
if (typeof
|
14923
|
-
|
14924
|
-
|
14925
|
-
|
14926
|
-
var array = this,
|
14927
|
-
size = this.length,
|
14928
|
-
temp;
|
14929
|
-
buildMaxHeap(array);
|
14930
|
-
for (var i = size - 1; i > 0; i -= 1) {
|
14931
|
-
temp = array[0];
|
14932
|
-
array[0] = array[i];
|
14933
|
-
array[i] = temp;
|
14934
|
-
size -= 1;
|
14935
|
-
heapify(array, 0, size);
|
14936
|
-
}
|
14937
|
-
return array;
|
14938
|
-
|
14939
|
-
function heapify(array, index, heapSize) {
|
14940
|
-
|
14941
|
-
var left = 2 * index + 1,
|
14942
|
-
right = 2 * index + 2,
|
14943
|
-
largest = index;
|
14944
|
-
|
14945
|
-
if (left < heapSize && compare(array[left], array[index]) > 0)
|
14946
|
-
largest = left;
|
14947
|
-
|
14948
|
-
if (right < heapSize && compare(array[right], array[largest]) > 0)
|
14949
|
-
largest = right;
|
14950
|
-
|
14951
|
-
if (largest !== index) {
|
14952
|
-
var temp = array[index];
|
14953
|
-
array[index] = array[largest];
|
14954
|
-
array[largest] = temp;
|
14955
|
-
heapify(array, largest, heapSize);
|
14956
|
-
}
|
14957
|
-
}
|
14958
|
-
|
14959
|
-
function buildMaxHeap(array) {
|
14960
|
-
for (var i = Math.floor(array.length / 2); i >= 0; i -= 1) {
|
14961
|
-
heapify(array, i, array.length);
|
14962
|
-
}
|
14963
|
-
return array;
|
14964
|
-
}
|
14998
|
+
if (typeof String.prototype.splitLines === "undefined") {
|
14999
|
+
String.prototype.splitLines = function () {
|
15000
|
+
return this.split(/\r\n|\n|\r/gm);
|
14965
15001
|
}
|
14966
15002
|
}
|
14967
15003
|
|
15004
|
+
|
14968
15005
|
if (typeof Uint8Array.prototype.toText === "undefined") {
|
14969
15006
|
|
14970
15007
|
Uint8Array.prototype.toText = function () {
|
@@ -15092,10 +15129,9 @@ var igv = (function (igv) {
|
|
15092
15129
|
|
15093
15130
|
igv.presentAlert = function (string) {
|
15094
15131
|
|
15095
|
-
igv.alert.
|
15096
|
-
return string;
|
15097
|
-
}, undefined, undefined);
|
15132
|
+
igv.alert.$dialogLabel.text(string);
|
15098
15133
|
igv.alert.show(undefined);
|
15134
|
+
|
15099
15135
|
igv.popover.hide();
|
15100
15136
|
|
15101
15137
|
};
|
@@ -15248,44 +15284,44 @@ var igv = (function (igv) {
|
|
15248
15284
|
return {
|
15249
15285
|
object: $('<div class="igv-track-menu-item">' + "Set track color" + '</div>'),
|
15250
15286
|
click: function () {
|
15251
|
-
igv.colorPicker.trackView
|
15287
|
+
igv.colorPicker.configure(trackView);
|
15252
15288
|
igv.colorPicker.show();
|
15253
15289
|
popover.hide();
|
15254
15290
|
}
|
15255
15291
|
}
|
15256
15292
|
};
|
15257
15293
|
|
15258
|
-
igv.
|
15294
|
+
igv.attachDialogCloseHandlerWithParent = function ($parent, closeHandler) {
|
15259
15295
|
|
15260
|
-
var
|
15261
|
-
|
15296
|
+
var $container = $('<div class="igv-dialog-close-container">'),
|
15297
|
+
$fa = $('<i class="fa fa-times igv-dialog-close-fa">');
|
15262
15298
|
|
15263
|
-
|
15264
|
-
|
15299
|
+
$container.append($fa[0]);
|
15300
|
+
$parent.append($container[0]);
|
15265
15301
|
|
15266
|
-
|
15302
|
+
$fa.hover(
|
15267
15303
|
function () {
|
15268
|
-
|
15269
|
-
|
15304
|
+
$fa.removeClass("fa-times");
|
15305
|
+
$fa.addClass("fa-times-circle");
|
15270
15306
|
|
15271
|
-
|
15307
|
+
$fa.css({
|
15272
15308
|
"color": "#222"
|
15273
15309
|
});
|
15274
15310
|
},
|
15275
15311
|
|
15276
15312
|
function () {
|
15277
|
-
|
15278
|
-
|
15279
|
-
|
15313
|
+
$fa.removeClass("fa-times-circle");
|
15314
|
+
//$fa.removeClass("fa-times-circle fa-lg");
|
15315
|
+
$fa.addClass("fa-times");
|
15280
15316
|
|
15281
|
-
|
15317
|
+
$fa.css({
|
15282
15318
|
"color": "#444"
|
15283
15319
|
});
|
15284
15320
|
|
15285
15321
|
}
|
15286
15322
|
);
|
15287
15323
|
|
15288
|
-
|
15324
|
+
$fa.click(closeHandler);
|
15289
15325
|
|
15290
15326
|
};
|
15291
15327
|
|
@@ -15651,7 +15687,7 @@ var igvxhr = (function (igvxhr) {
|
|
15651
15687
|
|
15652
15688
|
igvxhr.load = function (url, options) {
|
15653
15689
|
|
15654
|
-
if(!options) options = {};
|
15690
|
+
if (!options) options = {};
|
15655
15691
|
|
15656
15692
|
return new Promise(function (fulfill, reject) {
|
15657
15693
|
|
@@ -15667,11 +15703,22 @@ var igvxhr = (function (igvxhr) {
|
|
15667
15703
|
withCredentials = options.withCredentials,
|
15668
15704
|
header_keys, key, value, i;
|
15669
15705
|
|
15706
|
+
// Support for GCS paths.
|
15707
|
+
url = url.startsWith("gs://") ? igv.Google.translateGoogleCloudURL(url) : url;
|
15708
|
+
|
15709
|
+
if (igv.Google.isGoogleURL(url)) {
|
15670
15710
|
|
15671
|
-
|
15672
|
-
|
15673
|
-
|
15674
|
-
|
15711
|
+
url = igv.Google.addApiKey(url);
|
15712
|
+
|
15713
|
+
// Add google headers (e.g. oAuth)
|
15714
|
+
headers = headers || {};
|
15715
|
+
igv.Google.addGoogleHeaders(headers);
|
15716
|
+
|
15717
|
+
// Hack to prevent caching for google storage files. Get weird net:err-cache errors otherwise
|
15718
|
+
if (range) {
|
15719
|
+
url += url.includes("?") ? "&" : "?";
|
15720
|
+
url += "someRandomSeed=" + Math.random().toString(36);
|
15721
|
+
}
|
15675
15722
|
}
|
15676
15723
|
|
15677
15724
|
xhr.open(method, url);
|
@@ -15699,7 +15746,6 @@ var igvxhr = (function (igvxhr) {
|
|
15699
15746
|
}
|
15700
15747
|
}
|
15701
15748
|
|
15702
|
-
// let cookies go along to get files from any website we are logged in to
|
15703
15749
|
// NOTE: using withCredentials with servers that return "*" for access-allowed-origin will fail
|
15704
15750
|
if (withCredentials === true) {
|
15705
15751
|
xhr.withCredentials = true;
|
@@ -16511,9 +16557,12 @@ var igv = (function (igv) {
|
|
16511
16557
|
var g = igv.guichromosomes[i];
|
16512
16558
|
if (g.x < mouseX && g.right > mouseX && g.y < mouseY && g.bottom > mouseY) {
|
16513
16559
|
var dy = mouseY - g.y;
|
16514
|
-
var
|
16515
|
-
log("Going to position " +
|
16516
|
-
|
16560
|
+
var center = Math.round(g.size * dy / g.h);
|
16561
|
+
log("Going to position " + center);
|
16562
|
+
|
16563
|
+
// the goto() signature is chr, start, end. We leave end undefined changing
|
16564
|
+
// the interpretation of start to the center of the locus extent.
|
16565
|
+
igv.browser.goto(g.name, center, undefined);
|
16517
16566
|
break;
|
16518
16567
|
}
|
16519
16568
|
}
|
@@ -18160,7 +18209,8 @@ var igv = (function (igv) {
|
|
18160
18209
|
/*
|
18161
18210
|
* The MIT License (MIT)
|
18162
18211
|
*
|
18163
|
-
* Copyright (c)
|
18212
|
+
* Copyright (c) 2016 University of California San Diego
|
18213
|
+
* Author: Jim Robinson
|
18164
18214
|
*
|
18165
18215
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
18166
18216
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -18182,220 +18232,907 @@ var igv = (function (igv) {
|
|
18182
18232
|
* THE SOFTWARE.
|
18183
18233
|
*/
|
18184
18234
|
|
18235
|
+
/**
|
18236
|
+
* Created by jrobinso on 11/22/2016.
|
18237
|
+
*/
|
18185
18238
|
|
18186
|
-
// Generic functions applicable to all track types
|
18187
18239
|
|
18188
18240
|
var igv = (function (igv) {
|
18189
18241
|
|
18190
|
-
/**
|
18191
|
-
* Set defaults for properties applicable to all tracks.
|
18192
|
-
* Insure required "config" properties are set.
|
18193
|
-
* @param track
|
18194
|
-
* @param config
|
18195
|
-
*/
|
18196
|
-
igv.configTrack = function (track, config) {
|
18197
18242
|
|
18198
|
-
|
18199
|
-
track.url = config.url;
|
18243
|
+
var GZIP_FLAG = 0x1;
|
18200
18244
|
|
18201
|
-
config.name = config.name || config.label; // synonym for name, label is deprecated
|
18202
|
-
if (config.name) {
|
18203
|
-
track.name = config.name;
|
18204
|
-
}
|
18205
|
-
else {
|
18206
|
-
if (config.localFile) track.name = config.localFile.name;
|
18207
|
-
else track.name = config.url;
|
18208
18245
|
|
18209
|
-
}
|
18210
18246
|
|
18211
|
-
|
18247
|
+
igv.TDFReader = function (config) {
|
18248
|
+
this.config = config || {};
|
18249
|
+
this.path = config.url;
|
18250
|
+
this.groupCache = {};
|
18251
|
+
};
|
18212
18252
|
|
18213
|
-
track.order = config.order;
|
18214
|
-
track.color = config.color || igv.browser.constants.defaultColor;
|
18215
18253
|
|
18216
|
-
|
18254
|
+
igv.TDFReader.prototype.readHeader = function () {
|
18217
18255
|
|
18218
|
-
|
18219
|
-
track.autoHeight = config.autoHeight === undefined ? true : config.autoHeight;
|
18220
|
-
track.minHeight = config.minHeight || Math.min(50, track.height);
|
18221
|
-
track.maxHeight = config.maxHeight || Math.max(500, track.height);
|
18256
|
+
var self = this;
|
18222
18257
|
|
18223
|
-
if (
|
18224
|
-
|
18258
|
+
if (this.magic !== undefined) {
|
18259
|
+
return Promise.resolve(this); // Already read
|
18225
18260
|
}
|
18226
|
-
};
|
18227
18261
|
|
18262
|
+
return new Promise(function (fulfill, reject) {
|
18228
18263
|
|
18229
|
-
|
18230
|
-
|
18231
|
-
track.name = label;
|
18232
|
-
|
18233
|
-
$(track.trackView.viewportDiv).find('.igv-track-label').text(track.name);
|
18264
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {range: {start: 0, size: 64000}}))
|
18265
|
+
.then(function (data) {
|
18234
18266
|
|
18235
|
-
|
18236
|
-
|
18237
|
-
|
18238
|
-
|
18267
|
+
if (!data) {
|
18268
|
+
reject("no data");
|
18269
|
+
return;
|
18270
|
+
}
|
18239
18271
|
|
18240
|
-
|
18272
|
+
var binaryParser = new igv.BinaryParser(new DataView(data));
|
18241
18273
|
|
18242
|
-
|
18274
|
+
self.magic = binaryParser.getInt();
|
18275
|
+
self.version = binaryParser.getInt();
|
18276
|
+
self.indexPos = binaryParser.getLong();
|
18277
|
+
self.indexSize = binaryParser.getInt();
|
18278
|
+
var headerSize = binaryParser.getInt();
|
18243
18279
|
|
18244
|
-
if (track.trackView) {
|
18245
18280
|
|
18246
|
-
|
18281
|
+
if (self.version >= 2) {
|
18282
|
+
var nWindowFunctions = binaryParser.getInt();
|
18283
|
+
self.windowFunctions = [];
|
18284
|
+
while (nWindowFunctions-- > 0) {
|
18285
|
+
self.windowFunctions.push(binaryParser.getString());
|
18286
|
+
}
|
18287
|
+
}
|
18247
18288
|
|
18248
|
-
|
18289
|
+
self.trackType = binaryParser.getString();
|
18290
|
+
self.trackLine = binaryParser.getString();
|
18249
18291
|
|
18250
|
-
|
18292
|
+
var nTracks = binaryParser.getInt();
|
18293
|
+
self.trackNames = [];
|
18294
|
+
while (nTracks-- > 0) {
|
18295
|
+
self.trackNames.push(binaryParser.getString());
|
18296
|
+
}
|
18251
18297
|
|
18252
|
-
|
18298
|
+
self.genomeID = binaryParser.getString();
|
18299
|
+
self.flags = binaryParser.getInt();
|
18253
18300
|
|
18254
|
-
|
18255
|
-
x2,
|
18256
|
-
y1,
|
18257
|
-
y2,
|
18258
|
-
a,
|
18259
|
-
b,
|
18260
|
-
reference,
|
18261
|
-
shim,
|
18262
|
-
font = {
|
18263
|
-
'font': 'normal 10px Arial',
|
18264
|
-
'textAlign': 'right',
|
18265
|
-
'strokeStyle': "black"
|
18266
|
-
};
|
18301
|
+
self.compressed = (self.flags & GZIP_FLAG) != 0;
|
18267
18302
|
|
18268
|
-
|
18269
|
-
|
18270
|
-
|
18303
|
+
// Now read index
|
18304
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {
|
18305
|
+
range: {
|
18306
|
+
start: self.indexPos,
|
18307
|
+
size: self.indexSize
|
18308
|
+
}
|
18309
|
+
}))
|
18310
|
+
.then(function (data) {
|
18271
18311
|
|
18272
|
-
igv.graphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
18273
18312
|
|
18274
|
-
|
18275
|
-
|
18276
|
-
|
18313
|
+
if (!data) {
|
18314
|
+
reject("no data");
|
18315
|
+
return;
|
18316
|
+
}
|
18277
18317
|
|
18278
|
-
|
18279
|
-
shim = .01;
|
18280
|
-
y1 = y2 = shim * pixelHeight;
|
18318
|
+
binaryParser = new igv.BinaryParser(new DataView(data));
|
18281
18319
|
|
18282
|
-
|
18320
|
+
self.datasetIndex = {};
|
18321
|
+
var nEntries = binaryParser.getInt();
|
18322
|
+
while (nEntries-- > 0) {
|
18323
|
+
var name = binaryParser.getString();
|
18324
|
+
var pos = binaryParser.getLong();
|
18325
|
+
var size = binaryParser.getInt();
|
18326
|
+
self.datasetIndex[name] = {position: pos, size: size};
|
18327
|
+
}
|
18283
18328
|
|
18284
|
-
|
18285
|
-
|
18286
|
-
|
18329
|
+
self.groupIndex = {};
|
18330
|
+
nEntries = binaryParser.getInt();
|
18331
|
+
while (nEntries-- > 0) {
|
18332
|
+
name = binaryParser.getString();
|
18333
|
+
pos = binaryParser.getLong();
|
18334
|
+
size = binaryParser.getInt();
|
18335
|
+
self.groupIndex[name] = {position: pos, size: size};
|
18336
|
+
}
|
18287
18337
|
|
18288
|
-
|
18289
|
-
y1 = y2 = (1.0 - shim) * pixelHeight;
|
18338
|
+
fulfill(self);
|
18290
18339
|
|
18291
|
-
|
18340
|
+
}).catch(reject);
|
18292
18341
|
|
18293
|
-
|
18294
|
-
igv.graphics.strokeLine(ctx, x1, y1, x2, y2, font);
|
18295
|
-
igv.graphics.fillText(ctx, prettyPrint(this.dataRange.min), x1 + 4, y1 - 4, font);
|
18342
|
+
}).catch(reject)
|
18296
18343
|
|
18297
|
-
|
18344
|
+
});
|
18345
|
+
}
|
18298
18346
|
|
18299
|
-
|
18300
|
-
// if number >= 100, show whole number
|
18301
|
-
// if >= 1 show 1 significant digits
|
18302
|
-
// if < 1 show 2 significant digits
|
18347
|
+
igv.TDFReader.prototype.readDataset = function (chr, windowFunction, zoom) {
|
18303
18348
|
|
18304
|
-
|
18305
|
-
return "0";
|
18306
|
-
} else if (Math.abs(number) >= 10) {
|
18307
|
-
return number.toFixed();
|
18308
|
-
} else if (Math.abs(number) >= 1) {
|
18309
|
-
return number.toFixed(1);
|
18310
|
-
} else {
|
18311
|
-
return number.toFixed(2);
|
18312
|
-
}
|
18313
|
-
}
|
18349
|
+
var self = this;
|
18314
18350
|
|
18315
|
-
|
18351
|
+
return new Promise(function (fulfill, reject) {
|
18316
18352
|
|
18317
18353
|
|
18318
|
-
|
18319
|
-
})(igv || {});
|
18320
|
-
/*
|
18321
|
-
* The MIT License (MIT)
|
18322
|
-
*
|
18323
|
-
* Copyright (c) 2014 Broad Institute
|
18324
|
-
*
|
18325
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
18326
|
-
* of this software and associated documentation files (the "Software"), to deal
|
18327
|
-
* in the Software without restriction, including without limitation the rights
|
18328
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18329
|
-
* copies of the Software, and to permit persons to whom the Software is
|
18330
|
-
* furnished to do so, subject to the following conditions:
|
18331
|
-
*
|
18332
|
-
* The above copyright notice and this permission notice shall be included in
|
18333
|
-
* all copies or substantial portions of the Software.
|
18334
|
-
*
|
18335
|
-
*
|
18336
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18337
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18338
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18339
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18340
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18341
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
18342
|
-
* THE SOFTWARE.
|
18343
|
-
*/
|
18354
|
+
self.readHeader().then(function (reader) {
|
18344
18355
|
|
18356
|
+
var wf = (self.version < 2) ? "" : "/" + windowFunction,
|
18357
|
+
zoomString = (chr === "all" || zoom === undefined) ? "0" : zoom.toString(),
|
18358
|
+
dsName,
|
18359
|
+
indexEntry;
|
18345
18360
|
|
18346
|
-
|
18361
|
+
if (windowFunction === "raw") {
|
18362
|
+
dsName = "/" + chr + "/raw";
|
18363
|
+
}
|
18364
|
+
else {
|
18365
|
+
dsName = "/" + chr + "/z" + zoomString + wf;
|
18366
|
+
}
|
18367
|
+
indexEntry = self.datasetIndex[dsName];
|
18347
18368
|
|
18348
|
-
|
18369
|
+
if (indexEntry === undefined) {
|
18370
|
+
fulfill(null);
|
18371
|
+
}
|
18372
|
+
else {
|
18349
18373
|
|
18350
|
-
var self = this,
|
18351
|
-
element;
|
18352
18374
|
|
18353
|
-
|
18354
|
-
|
18375
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {
|
18376
|
+
range: {
|
18377
|
+
start: indexEntry.position,
|
18378
|
+
size: indexEntry.size
|
18379
|
+
}
|
18380
|
+
}))
|
18381
|
+
.then(function (data) {
|
18355
18382
|
|
18356
|
-
|
18357
|
-
|
18383
|
+
if (!data) {
|
18384
|
+
reject("no data");
|
18385
|
+
return;
|
18386
|
+
}
|
18358
18387
|
|
18359
|
-
|
18360
|
-
if (track.height) { // Explicit height set, perhaps track.config.height?
|
18361
|
-
this.trackDiv.style.height = track.height + "px";
|
18362
|
-
}
|
18388
|
+
var binaryParser = new igv.BinaryParser(new DataView(data));
|
18363
18389
|
|
18364
|
-
|
18365
|
-
|
18390
|
+
var nAttributes = binaryParser.getInt();
|
18391
|
+
var attributes = {};
|
18392
|
+
while (nAttributes-- > 0) {
|
18393
|
+
attributes[binaryParser.getString()] = binaryParser.getString();
|
18394
|
+
}
|
18366
18395
|
|
18367
|
-
|
18368
|
-
|
18369
|
-
$(this.trackDiv).append(element);
|
18370
|
-
}
|
18396
|
+
var dataType = binaryParser.getString();
|
18397
|
+
var tileWidth = binaryParser.getFloat();
|
18371
18398
|
|
18372
|
-
|
18399
|
+
var nTiles = binaryParser.getInt();
|
18400
|
+
var tiles = [];
|
18401
|
+
while (nTiles-- > 0) {
|
18402
|
+
tiles.push({position: binaryParser.getLong(), size: binaryParser.getInt()});
|
18403
|
+
}
|
18373
18404
|
|
18374
|
-
|
18375
|
-
|
18405
|
+
var dataset = {
|
18406
|
+
name: dsName,
|
18407
|
+
attributes: attributes,
|
18408
|
+
dataType: dataType,
|
18409
|
+
tileWidth: tileWidth,
|
18410
|
+
tiles: tiles
|
18411
|
+
};
|
18376
18412
|
|
18377
|
-
|
18413
|
+
fulfill(dataset);
|
18378
18414
|
|
18379
|
-
|
18415
|
+
}).catch(reject);
|
18416
|
+
}
|
18417
|
+
}).catch(reject);
|
18418
|
+
});
|
18419
|
+
}
|
18380
18420
|
|
18381
|
-
|
18382
|
-
this.rulerSweeper = $('<div class="igv-ruler-sweeper-div">');
|
18383
|
-
$(this.contentDiv).append(this.rulerSweeper[0]);
|
18421
|
+
igv.TDFReader.prototype.readRootGroup = function () {
|
18384
18422
|
|
18385
|
-
|
18423
|
+
var self = this,
|
18424
|
+
rootGroup = this.groupCache["/"];
|
18386
18425
|
|
18387
|
-
|
18388
|
-
|
18426
|
+
if (rootGroup) {
|
18427
|
+
return Promise.resolve(rootGroup);
|
18389
18428
|
}
|
18429
|
+
else {
|
18430
|
+
return new Promise(function (fulfill, reject) {
|
18390
18431
|
|
18391
|
-
|
18392
|
-
$('.igv-viewport-div').addClass('igv-gutter-shim');
|
18432
|
+
self.readGroup("/").then(function (group) {
|
18393
18433
|
|
18394
|
-
|
18434
|
+
var genome = igv.browser.genome,
|
18435
|
+
names = group["chromosomes"],
|
18436
|
+
maxZoomString = group["maxZoom"];
|
18395
18437
|
|
18396
|
-
|
18397
|
-
|
18398
|
-
|
18438
|
+
// Now parse out interesting attributes. This is a side effect, and bad bad bad, but the alternative is messy as well.
|
18439
|
+
if (maxZoomString) {
|
18440
|
+
self.maxZoom = Number(maxZoomString);
|
18441
|
+
}
|
18442
|
+
|
18443
|
+
// Chromosome names
|
18444
|
+
self.chrNameMap = {};
|
18445
|
+
if (names) {
|
18446
|
+
names.split(",").forEach( function (chr) {
|
18447
|
+
var canonicalName = genome.getChromosomeName(chr);
|
18448
|
+
self.chrNameMap[canonicalName] = chr;
|
18449
|
+
})
|
18450
|
+
}
|
18451
|
+
|
18452
|
+
fulfill(group);
|
18453
|
+
|
18454
|
+
|
18455
|
+
}).catch(reject);
|
18456
|
+
});
|
18457
|
+
|
18458
|
+
}
|
18459
|
+
}
|
18460
|
+
|
18461
|
+
igv.TDFReader.prototype.readGroup = function (name) {
|
18462
|
+
|
18463
|
+
var self = this;
|
18464
|
+
|
18465
|
+
return new Promise(function (fulfill, reject) {
|
18466
|
+
|
18467
|
+
|
18468
|
+
self.readHeader().then(function (reader) {
|
18469
|
+
|
18470
|
+
var group = self.groupCache[name],
|
18471
|
+
indexEntry = self.groupIndex[name];
|
18472
|
+
|
18473
|
+
if (group) {
|
18474
|
+
fulfill(group);
|
18475
|
+
}
|
18476
|
+
else if (indexEntry === undefined) {
|
18477
|
+
return fulfill(null);
|
18478
|
+
}
|
18479
|
+
else {
|
18480
|
+
|
18481
|
+
|
18482
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {
|
18483
|
+
range: {
|
18484
|
+
start: indexEntry.position,
|
18485
|
+
size: indexEntry.size
|
18486
|
+
}
|
18487
|
+
}))
|
18488
|
+
.then(function (data) {
|
18489
|
+
|
18490
|
+
if (!data) {
|
18491
|
+
reject("no data");
|
18492
|
+
return;
|
18493
|
+
}
|
18494
|
+
|
18495
|
+
var binaryParser = new igv.BinaryParser(new DataView(data));
|
18496
|
+
|
18497
|
+
var nAttributes = binaryParser.getInt();
|
18498
|
+
var group = {name: name};
|
18499
|
+
while (nAttributes-- > 0) {
|
18500
|
+
group[binaryParser.getString()] = binaryParser.getString();
|
18501
|
+
}
|
18502
|
+
|
18503
|
+
self.groupCache[name] = group;
|
18504
|
+
|
18505
|
+
fulfill(group);
|
18506
|
+
|
18507
|
+
}).catch(reject);
|
18508
|
+
}
|
18509
|
+
}).catch(reject);
|
18510
|
+
});
|
18511
|
+
}
|
18512
|
+
|
18513
|
+
|
18514
|
+
function createFixedStep(binaryParser, nTracks) {
|
18515
|
+
var nPositions = binaryParser.getInt(),
|
18516
|
+
start = binaryParser.getInt(),
|
18517
|
+
span = binaryParser.getFloat(),
|
18518
|
+
np = nPositions,
|
18519
|
+
nt = nTracks,
|
18520
|
+
data,
|
18521
|
+
dtrack;
|
18522
|
+
|
18523
|
+
|
18524
|
+
data = [];
|
18525
|
+
while (nt-- > 0) {
|
18526
|
+
np = nPositions;
|
18527
|
+
dtrack = [];
|
18528
|
+
while (np-- > 0) {
|
18529
|
+
dtrack.push(binaryParser.getFloat());
|
18530
|
+
}
|
18531
|
+
data.push(dtrack);
|
18532
|
+
}
|
18533
|
+
|
18534
|
+
return {
|
18535
|
+
type: "fixedStep",
|
18536
|
+
start: start,
|
18537
|
+
span: span,
|
18538
|
+
data: data,
|
18539
|
+
nTracks: nTracks,
|
18540
|
+
nPositions: nPositions
|
18541
|
+
}
|
18542
|
+
}
|
18543
|
+
|
18544
|
+
function createVariableStep(binaryParser, nTracks) {
|
18545
|
+
|
18546
|
+
var tileStart = binaryParser.getInt(),
|
18547
|
+
span = binaryParser.getFloat(),
|
18548
|
+
nPositions = binaryParser.getInt(),
|
18549
|
+
np = nPositions,
|
18550
|
+
nt = nTracks,
|
18551
|
+
start = [],
|
18552
|
+
data,
|
18553
|
+
dtrack;
|
18554
|
+
|
18555
|
+
while (np-- > 0) {
|
18556
|
+
start.push(binaryParser.getInt());
|
18557
|
+
}
|
18558
|
+
|
18559
|
+
var nS = binaryParser.getInt(); // # of samples, ignored but should === nTracks
|
18560
|
+
|
18561
|
+
data = [];
|
18562
|
+
while (nt-- > 0) {
|
18563
|
+
np = nPositions;
|
18564
|
+
dtrack = [];
|
18565
|
+
while (np-- > 0) {
|
18566
|
+
dtrack.push(binaryParser.getFloat());
|
18567
|
+
}
|
18568
|
+
data.push(dtrack);
|
18569
|
+
}
|
18570
|
+
|
18571
|
+
return {
|
18572
|
+
type: "variableStep",
|
18573
|
+
tileStart: tileStart,
|
18574
|
+
span: span,
|
18575
|
+
start: start,
|
18576
|
+
data: data,
|
18577
|
+
nTracks: nTracks,
|
18578
|
+
nPositions: nPositions
|
18579
|
+
}
|
18580
|
+
}
|
18581
|
+
|
18582
|
+
function createBed(binaryParser, nTracks, type) {
|
18583
|
+
var nPositions, start, end, nS, data, name, n, nt;
|
18584
|
+
|
18585
|
+
nPositions = binaryParser.getInt();
|
18586
|
+
|
18587
|
+
n = nPositions;
|
18588
|
+
start = [];
|
18589
|
+
while (n-- > 0) {
|
18590
|
+
start.push(binaryParser.getInt());
|
18591
|
+
}
|
18592
|
+
|
18593
|
+
n = nPositions;
|
18594
|
+
end = [];
|
18595
|
+
while (n-- > 0) {
|
18596
|
+
end.push(binaryParser.getInt());
|
18597
|
+
}
|
18598
|
+
|
18599
|
+
var nS = binaryParser.getInt(); // # of samples, ignored but should === nTracks
|
18600
|
+
|
18601
|
+
data = [];
|
18602
|
+
nt = nTracks;
|
18603
|
+
while (nt-- > 0) {
|
18604
|
+
np = nPositions;
|
18605
|
+
dtrack = [];
|
18606
|
+
while (np-- > 0) {
|
18607
|
+
dtrack.push(binaryParser.getFloat());
|
18608
|
+
}
|
18609
|
+
data.push(dtrack);
|
18610
|
+
}
|
18611
|
+
|
18612
|
+
if (type === "bedWithName") {
|
18613
|
+
n = nPositions;
|
18614
|
+
name = [];
|
18615
|
+
while (n-- > 0) {
|
18616
|
+
name.push(binaryParser.getString());
|
18617
|
+
}
|
18618
|
+
}
|
18619
|
+
|
18620
|
+
return {
|
18621
|
+
type: type,
|
18622
|
+
start: start,
|
18623
|
+
end: end,
|
18624
|
+
data: data,
|
18625
|
+
name: name,
|
18626
|
+
nTracks: nTracks,
|
18627
|
+
nPositions: nPositions
|
18628
|
+
}
|
18629
|
+
|
18630
|
+
}
|
18631
|
+
|
18632
|
+
|
18633
|
+
igv.TDFReader.prototype.readTile = function (indexEntry, nTracks) {
|
18634
|
+
|
18635
|
+
var self = this;
|
18636
|
+
|
18637
|
+
return new Promise(function (fulfill, reject) {
|
18638
|
+
|
18639
|
+
igvxhr.loadArrayBuffer(self.path, Object.assign(self.config, {
|
18640
|
+
range: {
|
18641
|
+
start: indexEntry.position,
|
18642
|
+
size: indexEntry.size
|
18643
|
+
}
|
18644
|
+
}))
|
18645
|
+
.then(function (data) {
|
18646
|
+
|
18647
|
+
if (!data) {
|
18648
|
+
reject("no data");
|
18649
|
+
return;
|
18650
|
+
}
|
18651
|
+
|
18652
|
+
if (self.compressed) {
|
18653
|
+
var inflate = new Zlib.Inflate(new Uint8Array(data));
|
18654
|
+
var plain = inflate.decompress();
|
18655
|
+
data = plain.buffer;
|
18656
|
+
}
|
18657
|
+
|
18658
|
+
var binaryParser = new igv.BinaryParser(new DataView(data));
|
18659
|
+
|
18660
|
+
var type = binaryParser.getString();
|
18661
|
+
|
18662
|
+
switch (type) {
|
18663
|
+
case "fixedStep":
|
18664
|
+
fulfill(createFixedStep(binaryParser, nTracks));
|
18665
|
+
break;
|
18666
|
+
case "variableStep":
|
18667
|
+
fulfill(createVariableStep(binaryParser, nTracks));
|
18668
|
+
break;
|
18669
|
+
case "bed":
|
18670
|
+
case "bedWithName":
|
18671
|
+
fulfill(createBed(binaryParser, nTracks, type));
|
18672
|
+
break;
|
18673
|
+
default:
|
18674
|
+
reject("Unknown tile type: " + type);
|
18675
|
+
}
|
18676
|
+
|
18677
|
+
|
18678
|
+
}).catch(reject);
|
18679
|
+
|
18680
|
+
});
|
18681
|
+
|
18682
|
+
}
|
18683
|
+
|
18684
|
+
return igv;
|
18685
|
+
|
18686
|
+
})
|
18687
|
+
(igv || {});
|
18688
|
+
|
18689
|
+
/*
|
18690
|
+
* The MIT License (MIT)
|
18691
|
+
*
|
18692
|
+
* Copyright (c) 2016 University of California San Diego
|
18693
|
+
* Author: Jim Robinson
|
18694
|
+
*
|
18695
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
18696
|
+
* of this software and associated documentation files (the "Software"), to deal
|
18697
|
+
* in the Software without restriction, including without limitation the rights
|
18698
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18699
|
+
* copies of the Software, and to permit persons to whom the Software is
|
18700
|
+
* furnished to do so, subject to the following conditions:
|
18701
|
+
*
|
18702
|
+
* The above copyright notice and this permission notice shall be included in
|
18703
|
+
* all copies or substantial portions of the Software.
|
18704
|
+
*
|
18705
|
+
*
|
18706
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18707
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18708
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18709
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18710
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18711
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
18712
|
+
* THE SOFTWARE.
|
18713
|
+
*/
|
18714
|
+
|
18715
|
+
/**
|
18716
|
+
* Created by jrobinso on 11/27/16.
|
18717
|
+
*/
|
18718
|
+
|
18719
|
+
|
18720
|
+
var igv = (function (igv) {
|
18721
|
+
|
18722
|
+
igv.TDFSource = function (config) {
|
18723
|
+
|
18724
|
+
this.windowFunction = config.windowFunction || "mean";
|
18725
|
+
this.reader = new igv.TDFReader(config);
|
18726
|
+
};
|
18727
|
+
|
18728
|
+
igv.TDFSource.prototype.getFeatures = function (chr, bpStart, bpEnd) {
|
18729
|
+
|
18730
|
+
var self = this,
|
18731
|
+
bpPerPixel = igv.browser.referenceFrame.bpPerPixel;
|
18732
|
+
|
18733
|
+
return new Promise(function (fulfill, reject) {
|
18734
|
+
|
18735
|
+
self.reader.readRootGroup().then(function (group) {
|
18736
|
+
|
18737
|
+
var zoom = zoomLevelForScale(chr, bpPerPixel),
|
18738
|
+
queryChr = self.reader.chrNameMap[chr],
|
18739
|
+
maxZoom = self.reader.maxZoom,
|
18740
|
+
wf,
|
18741
|
+
dataset;
|
18742
|
+
|
18743
|
+
if (queryChr === undefined) queryChr = chr;
|
18744
|
+
if (maxZoom === undefined) maxZoom = -1;
|
18745
|
+
|
18746
|
+
wf = zoom > maxZoom ? "raw" : self.windowFunction;
|
18747
|
+
|
18748
|
+
self.reader.readDataset(queryChr, wf, zoom).then(function (dataset) {
|
18749
|
+
|
18750
|
+
if(dataset == null) {
|
18751
|
+
fulfill(null);
|
18752
|
+
return;
|
18753
|
+
}
|
18754
|
+
|
18755
|
+
var tileWidth = dataset.tileWidth,
|
18756
|
+
startTile = Math.floor(bpStart / tileWidth),
|
18757
|
+
endTile = Math.floor(bpEnd / tileWidth),
|
18758
|
+
i,
|
18759
|
+
p = [],
|
18760
|
+
NTRACKS = 1; // TODO read this
|
18761
|
+
|
18762
|
+
for (i = startTile; i <= endTile; i++) {
|
18763
|
+
if(dataset.tiles[i] !== undefined) {
|
18764
|
+
p.push(self.reader.readTile(dataset.tiles[i], NTRACKS));
|
18765
|
+
}
|
18766
|
+
}
|
18767
|
+
|
18768
|
+
Promise.all(p).then(function (tiles) {
|
18769
|
+
var features = [];
|
18770
|
+
tiles.forEach(function (tile) {
|
18771
|
+
switch (tile.type) {
|
18772
|
+
case "bed":
|
18773
|
+
decodeBedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features);
|
18774
|
+
break;
|
18775
|
+
case "variableStep":
|
18776
|
+
decodeVaryTile(tile, chr, bpStart, bpEnd, bpPerPixel, features);
|
18777
|
+
break;
|
18778
|
+
case "fixedStep":
|
18779
|
+
decodeFixedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features);
|
18780
|
+
break;
|
18781
|
+
default:
|
18782
|
+
reject("Unknown tile type: " + tile.type);
|
18783
|
+
return;
|
18784
|
+
}
|
18785
|
+
})
|
18786
|
+
fulfill(features);
|
18787
|
+
|
18788
|
+
}).catch(reject)
|
18789
|
+
|
18790
|
+
|
18791
|
+
}).catch(reject)
|
18792
|
+
})
|
18793
|
+
});
|
18794
|
+
}
|
18795
|
+
|
18796
|
+
function decodeBedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {
|
18797
|
+
|
18798
|
+
var nPositions = tile.nPositions,
|
18799
|
+
starts = tile.start,
|
18800
|
+
ends = tile.end,
|
18801
|
+
data = tile.data[0], // Single track for now
|
18802
|
+
i;
|
18803
|
+
|
18804
|
+
for (i = 0; i < nPositions; i++) {
|
18805
|
+
|
18806
|
+
var s = starts[i];
|
18807
|
+
var e = ends[i];
|
18808
|
+
|
18809
|
+
if (e < bpStart) continue;
|
18810
|
+
if (s > bpEnd) break;
|
18811
|
+
|
18812
|
+
features.push({
|
18813
|
+
start: s,
|
18814
|
+
end: e,
|
18815
|
+
value: data[i]
|
18816
|
+
});
|
18817
|
+
}
|
18818
|
+
}
|
18819
|
+
|
18820
|
+
function decodeVaryTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {
|
18821
|
+
|
18822
|
+
var nPositions = tile.nPositions,
|
18823
|
+
starts = tile.start,
|
18824
|
+
span = tile.span,
|
18825
|
+
data = tile.data[0], // Single track for now
|
18826
|
+
i;
|
18827
|
+
|
18828
|
+
for (i = 0; i < nPositions; i++) {
|
18829
|
+
|
18830
|
+
var s = starts[i];
|
18831
|
+
var e = s + span;
|
18832
|
+
|
18833
|
+
if (e < bpStart) continue;
|
18834
|
+
if (s > bpEnd) break;
|
18835
|
+
|
18836
|
+
features.push({
|
18837
|
+
start: s,
|
18838
|
+
end: e,
|
18839
|
+
value: data[i]
|
18840
|
+
});
|
18841
|
+
}
|
18842
|
+
}
|
18843
|
+
|
18844
|
+
function decodeFixedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {
|
18845
|
+
|
18846
|
+
var nPositions = tile.nPositions,
|
18847
|
+
s = tile.start,
|
18848
|
+
span = tile.span,
|
18849
|
+
data = tile.data[0], // Single track for now
|
18850
|
+
i;
|
18851
|
+
|
18852
|
+
for (i = 0; i < nPositions; i++) {
|
18853
|
+
|
18854
|
+
var e = s + span;
|
18855
|
+
|
18856
|
+
if (e < bpStart) continue;
|
18857
|
+
if (s > bpEnd) break;
|
18858
|
+
|
18859
|
+
if(!Number.isNaN(data[i])) {
|
18860
|
+
features.push({
|
18861
|
+
start: s,
|
18862
|
+
end: e,
|
18863
|
+
value: data[i]
|
18864
|
+
});
|
18865
|
+
}
|
18866
|
+
|
18867
|
+
s = e;
|
18868
|
+
}
|
18869
|
+
}
|
18870
|
+
|
18871
|
+
|
18872
|
+
var log2 = Math.log(2);
|
18873
|
+
|
18874
|
+
function zoomLevelForScale(chr, bpPerPixel) {
|
18875
|
+
|
18876
|
+
// Convert bpPerPixel to IGV "zoom" level. This is a bit convoluted, IGV computes zoom levels assuming
|
18877
|
+
// display in a 700 pixel window. The fully zoomed out view of a chromosome is zoom level "0".
|
18878
|
+
// Zoom level 1 is magnified 2X, and so forth
|
18879
|
+
|
18880
|
+
var chrSize = igv.browser.genome.getChromosome(chr).bpLength;
|
18881
|
+
|
18882
|
+
return Math.ceil(Math.log(Math.max(0, (chrSize / (bpPerPixel * 700)))) / log2);
|
18883
|
+
}
|
18884
|
+
|
18885
|
+
|
18886
|
+
return igv;
|
18887
|
+
|
18888
|
+
|
18889
|
+
})
|
18890
|
+
(igv || {});
|
18891
|
+
|
18892
|
+
/*
|
18893
|
+
* The MIT License (MIT)
|
18894
|
+
*
|
18895
|
+
* Copyright (c) 2014 Broad Institute
|
18896
|
+
*
|
18897
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
18898
|
+
* of this software and associated documentation files (the "Software"), to deal
|
18899
|
+
* in the Software without restriction, including without limitation the rights
|
18900
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18901
|
+
* copies of the Software, and to permit persons to whom the Software is
|
18902
|
+
* furnished to do so, subject to the following conditions:
|
18903
|
+
*
|
18904
|
+
* The above copyright notice and this permission notice shall be included in
|
18905
|
+
* all copies or substantial portions of the Software.
|
18906
|
+
*
|
18907
|
+
*
|
18908
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18909
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18910
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18911
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18912
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18913
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
18914
|
+
* THE SOFTWARE.
|
18915
|
+
*/
|
18916
|
+
|
18917
|
+
|
18918
|
+
// Generic functions applicable to all track types
|
18919
|
+
|
18920
|
+
var igv = (function (igv) {
|
18921
|
+
|
18922
|
+
/**
|
18923
|
+
* Set defaults for properties applicable to all tracks.
|
18924
|
+
* Insure required "config" properties are set.
|
18925
|
+
* @param track
|
18926
|
+
* @param config
|
18927
|
+
*/
|
18928
|
+
igv.configTrack = function (track, config) {
|
18929
|
+
|
18930
|
+
track.config = config;
|
18931
|
+
track.url = config.url;
|
18932
|
+
|
18933
|
+
config.name = config.name || config.label; // synonym for name, label is deprecated
|
18934
|
+
if (config.name) {
|
18935
|
+
track.name = config.name;
|
18936
|
+
}
|
18937
|
+
else {
|
18938
|
+
if (config.localFile) track.name = config.localFile.name;
|
18939
|
+
else track.name = config.url;
|
18940
|
+
|
18941
|
+
}
|
18942
|
+
|
18943
|
+
track.id = config.id || track.name; // TODO -- remove this property, not used
|
18944
|
+
|
18945
|
+
track.order = config.order;
|
18946
|
+
track.color = config.color || igv.browser.constants.defaultColor;
|
18947
|
+
|
18948
|
+
track.removable = config.removable === undefined ? true : config.removable; // Defaults to true
|
18949
|
+
|
18950
|
+
track.height = config.height || ('wig' === config.type ? 50 : 100);
|
18951
|
+
|
18952
|
+
if(config.autoHeight === undefined) config.autoHeight = config.autoheight; // Some case confusion in the initial releasae
|
18953
|
+
|
18954
|
+
track.autoHeight = config.autoHeight === undefined ?
|
18955
|
+
(config.height === undefined ? true : false) :
|
18956
|
+
config.autoHeight;
|
18957
|
+
track.minHeight = config.minHeight || Math.min(50, track.height);
|
18958
|
+
track.maxHeight = config.maxHeight || Math.max(500, track.height);
|
18959
|
+
|
18960
|
+
if (config.visibilityWindow) {
|
18961
|
+
track.visibilityWindow = config.visibilityWindow;
|
18962
|
+
}
|
18963
|
+
};
|
18964
|
+
|
18965
|
+
|
18966
|
+
igv.setTrackLabel = function (track, label) {
|
18967
|
+
|
18968
|
+
track.name = label;
|
18969
|
+
|
18970
|
+
$(track.trackView.viewportDiv).find('.igv-track-label').html(track.name);
|
18971
|
+
|
18972
|
+
if (track.trackView) {
|
18973
|
+
track.trackView.repaint();
|
18974
|
+
}
|
18975
|
+
};
|
18976
|
+
|
18977
|
+
igv.setTrackColor = function (track, color) {
|
18978
|
+
|
18979
|
+
track.color = color;
|
18980
|
+
|
18981
|
+
if (track.trackView) {
|
18982
|
+
|
18983
|
+
track.trackView.repaint();
|
18984
|
+
|
18985
|
+
}
|
18986
|
+
|
18987
|
+
};
|
18988
|
+
|
18989
|
+
igv.paintAxis = function (ctx, pixelWidth, pixelHeight) {
|
18990
|
+
|
18991
|
+
var x1,
|
18992
|
+
x2,
|
18993
|
+
y1,
|
18994
|
+
y2,
|
18995
|
+
a,
|
18996
|
+
b,
|
18997
|
+
reference,
|
18998
|
+
shim,
|
18999
|
+
font = {
|
19000
|
+
'font': 'normal 10px Arial',
|
19001
|
+
'textAlign': 'right',
|
19002
|
+
'strokeStyle': "black"
|
19003
|
+
};
|
19004
|
+
|
19005
|
+
if (undefined === this.dataRange || undefined === this.dataRange.max || undefined === this.dataRange.min) {
|
19006
|
+
return;
|
19007
|
+
}
|
19008
|
+
|
19009
|
+
igv.graphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
|
19010
|
+
|
19011
|
+
reference = 0.95 * pixelWidth;
|
19012
|
+
x1 = reference - 8;
|
19013
|
+
x2 = reference;
|
19014
|
+
|
19015
|
+
//shim = 0.5 * 0.125;
|
19016
|
+
shim = .01;
|
19017
|
+
y1 = y2 = shim * pixelHeight;
|
19018
|
+
|
19019
|
+
a = {x: x2, y: y1};
|
19020
|
+
|
19021
|
+
// tick
|
19022
|
+
igv.graphics.strokeLine(ctx, x1, y1, x2, y2, font);
|
19023
|
+
igv.graphics.fillText(ctx, prettyPrint(this.dataRange.max), x1 + 4, y1 + 12, font);
|
19024
|
+
|
19025
|
+
//shim = 0.25 * 0.125;
|
19026
|
+
y1 = y2 = (1.0 - shim) * pixelHeight;
|
19027
|
+
|
19028
|
+
b = {x: x2, y: y1};
|
19029
|
+
|
19030
|
+
// tick
|
19031
|
+
igv.graphics.strokeLine(ctx, x1, y1, x2, y2, font);
|
19032
|
+
igv.graphics.fillText(ctx, prettyPrint(this.dataRange.min), x1 + 4, y1 - 4, font);
|
19033
|
+
|
19034
|
+
igv.graphics.strokeLine(ctx, a.x, a.y, b.x, b.y, font);
|
19035
|
+
|
19036
|
+
function prettyPrint(number) {
|
19037
|
+
// if number >= 100, show whole number
|
19038
|
+
// if >= 1 show 1 significant digits
|
19039
|
+
// if < 1 show 2 significant digits
|
19040
|
+
|
19041
|
+
if (number === 0) {
|
19042
|
+
return "0";
|
19043
|
+
} else if (Math.abs(number) >= 10) {
|
19044
|
+
return number.toFixed();
|
19045
|
+
} else if (Math.abs(number) >= 1) {
|
19046
|
+
return number.toFixed(1);
|
19047
|
+
} else {
|
19048
|
+
return number.toFixed(2);
|
19049
|
+
}
|
19050
|
+
}
|
19051
|
+
|
19052
|
+
};
|
19053
|
+
|
19054
|
+
|
19055
|
+
return igv;
|
19056
|
+
})(igv || {});
|
19057
|
+
/*
|
19058
|
+
* The MIT License (MIT)
|
19059
|
+
*
|
19060
|
+
* Copyright (c) 2014 Broad Institute
|
19061
|
+
*
|
19062
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
19063
|
+
* of this software and associated documentation files (the "Software"), to deal
|
19064
|
+
* in the Software without restriction, including without limitation the rights
|
19065
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
19066
|
+
* copies of the Software, and to permit persons to whom the Software is
|
19067
|
+
* furnished to do so, subject to the following conditions:
|
19068
|
+
*
|
19069
|
+
* The above copyright notice and this permission notice shall be included in
|
19070
|
+
* all copies or substantial portions of the Software.
|
19071
|
+
*
|
19072
|
+
*
|
19073
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19074
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19075
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19076
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19077
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19078
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19079
|
+
* THE SOFTWARE.
|
19080
|
+
*/
|
19081
|
+
|
19082
|
+
|
19083
|
+
var igv = (function (igv) {
|
19084
|
+
|
19085
|
+
igv.TrackView = function (track, browser) {
|
19086
|
+
|
19087
|
+
var self = this,
|
19088
|
+
element;
|
19089
|
+
|
19090
|
+
this.track = track;
|
19091
|
+
this.browser = browser;
|
19092
|
+
|
19093
|
+
this.trackDiv = $('<div class="igv-track-div">')[0];
|
19094
|
+
$(browser.trackContainerDiv).append(this.trackDiv);
|
19095
|
+
|
19096
|
+
// Optionally override CSS height
|
19097
|
+
if (track.height) { // Explicit height set, perhaps track.config.height?
|
19098
|
+
this.trackDiv.style.height = track.height + "px";
|
19099
|
+
}
|
19100
|
+
|
19101
|
+
this.appendLeftHandGutterDivToTrackDiv($(this.trackDiv));
|
19102
|
+
this.appendViewportDivToTrackDiv($(this.trackDiv));
|
19103
|
+
|
19104
|
+
element = this.createRightHandGutter();
|
19105
|
+
if (element) {
|
19106
|
+
$(this.trackDiv).append(element);
|
19107
|
+
}
|
19108
|
+
|
19109
|
+
this.trackDiv.appendChild(igv.spinner());
|
19110
|
+
|
19111
|
+
// Track Drag & Drop
|
19112
|
+
makeTrackDraggable(this.track);
|
19113
|
+
|
19114
|
+
if (this.track instanceof igv.RulerTrack) {
|
19115
|
+
|
19116
|
+
this.trackDiv.dataset.rulerTrack = "rulerTrack";
|
19117
|
+
|
19118
|
+
// ruler sweeper widget surface
|
19119
|
+
this.rulerSweeper = $('<div class="igv-ruler-sweeper-div">');
|
19120
|
+
$(this.contentDiv).append(this.rulerSweeper[0]);
|
19121
|
+
|
19122
|
+
addRulerTrackHandlers(this);
|
19123
|
+
|
19124
|
+
} else {
|
19125
|
+
addTrackHandlers(this);
|
19126
|
+
}
|
19127
|
+
|
19128
|
+
$('.igv-ideogram-content-div').addClass('igv-ideogram-gutter-shim');
|
19129
|
+
$('.igv-viewport-div').addClass('igv-gutter-shim');
|
19130
|
+
|
19131
|
+
function makeTrackDraggable(track) {
|
19132
|
+
|
19133
|
+
self.igvTrackDragScrim = $('<div class="igv-track-drag-scrim">')[0];
|
19134
|
+
$(self.viewportDiv).append(self.igvTrackDragScrim);
|
19135
|
+
$(self.igvTrackDragScrim).hide();
|
18399
19136
|
|
18400
19137
|
self.igvTrackManipulationHandle = $('<div class="igv-track-manipulation-handle">')[0];
|
18401
19138
|
$(self.trackDiv).append(self.igvTrackManipulationHandle);
|
@@ -18510,7 +19247,7 @@ var igv = (function (igv) {
|
|
18510
19247
|
description = this.track.description || this.track.name;
|
18511
19248
|
$trackLabel = $('<div class="igv-track-label">');
|
18512
19249
|
|
18513
|
-
$trackLabel.
|
19250
|
+
$trackLabel.html(this.track.name);
|
18514
19251
|
|
18515
19252
|
$trackLabel.click(function (e) {
|
18516
19253
|
igv.popover.presentTrackPopup(e.pageX, e.pageY, description, false);
|
@@ -18612,6 +19349,9 @@ var igv = (function (igv) {
|
|
18612
19349
|
*/
|
18613
19350
|
igv.TrackView.prototype.setContentHeight = function (newHeight) {
|
18614
19351
|
|
19352
|
+
// Maximum height of a canvas is ~32,000 pixels on Chrome, possibly smaller on other platforms
|
19353
|
+
newHeight = Math.min(newHeight, 32000);
|
19354
|
+
|
18615
19355
|
if (this.track.minHeight) newHeight = Math.max(this.track.minHeight, newHeight);
|
18616
19356
|
|
18617
19357
|
var contentHeightStr = newHeight + "px";
|
@@ -19126,6 +19866,253 @@ var igv = (function (igv) {
|
|
19126
19866
|
|
19127
19867
|
})(igv || {});
|
19128
19868
|
|
19869
|
+
/*
|
19870
|
+
* The MIT License (MIT)
|
19871
|
+
*
|
19872
|
+
* Copyright (c) 2014 Broad Institute
|
19873
|
+
*
|
19874
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
19875
|
+
* of this software and associated documentation files (the "Software"), to deal
|
19876
|
+
* in the Software without restriction, including without limitation the rights
|
19877
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
19878
|
+
* copies of the Software, and to permit persons to whom the Software is
|
19879
|
+
* furnished to do so, subject to the following conditions:
|
19880
|
+
*
|
19881
|
+
* The above copyright notice and this permission notice shall be included in
|
19882
|
+
* all copies or substantial portions of the Software.
|
19883
|
+
*
|
19884
|
+
*
|
19885
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19886
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19887
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19888
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19889
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19890
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19891
|
+
* THE SOFTWARE.
|
19892
|
+
*/
|
19893
|
+
|
19894
|
+
/**
|
19895
|
+
* Created by turner on 4/29/15.
|
19896
|
+
*/
|
19897
|
+
var igv = (function (igv) {
|
19898
|
+
|
19899
|
+
igv.AlertDialog = function ($parent, id) {
|
19900
|
+
|
19901
|
+
var self = this,
|
19902
|
+
$header,
|
19903
|
+
$headerBlurb;
|
19904
|
+
|
19905
|
+
this.$container = $('<div>', { "id": id, "class": "igv-grid-container-alert-dialog" });
|
19906
|
+
$parent.append(this.$container);
|
19907
|
+
|
19908
|
+
$header = $('<div class="igv-grid-header">');
|
19909
|
+
$headerBlurb = $('<div class="igv-grid-header-blurb">');
|
19910
|
+
$header.append($headerBlurb);
|
19911
|
+
igv.attachDialogCloseHandlerWithParent($header, function () {
|
19912
|
+
self.hide();
|
19913
|
+
});
|
19914
|
+
this.$container.append($header);
|
19915
|
+
|
19916
|
+
this.$container.append(this.alertTextContainer());
|
19917
|
+
|
19918
|
+
this.$container.append(this.rowOfOk());
|
19919
|
+
|
19920
|
+
};
|
19921
|
+
|
19922
|
+
igv.AlertDialog.prototype.alertTextContainer = function() {
|
19923
|
+
|
19924
|
+
var $rowContainer,
|
19925
|
+
$col;
|
19926
|
+
|
19927
|
+
$rowContainer = $('<div class="igv-grid-rect">');
|
19928
|
+
|
19929
|
+
this.$dialogLabel = $('<div>', { "class": "igv-col igv-col-4-4 igv-alert-dialog-text" });
|
19930
|
+
|
19931
|
+
// $col = $('<div class="igv-col igv-col-4-4">');
|
19932
|
+
// $col.append(this.$dialogLabel);
|
19933
|
+
// $rowContainer.append($col);
|
19934
|
+
|
19935
|
+
$rowContainer.append(this.$dialogLabel);
|
19936
|
+
|
19937
|
+
return $rowContainer;
|
19938
|
+
|
19939
|
+
};
|
19940
|
+
|
19941
|
+
igv.AlertDialog.prototype.rowOfOk = function() {
|
19942
|
+
|
19943
|
+
var self = this,
|
19944
|
+
$rowContainer,
|
19945
|
+
$col;
|
19946
|
+
|
19947
|
+
$rowContainer = $('<div class="igv-grid-rect">');
|
19948
|
+
|
19949
|
+
// shim
|
19950
|
+
$col = $('<div class="igv-col igv-col-1-4">');
|
19951
|
+
$rowContainer.append( $col );
|
19952
|
+
|
19953
|
+
// ok button
|
19954
|
+
$col = $('<div class="igv-col igv-col-2-4">');
|
19955
|
+
this.$ok = $('<div class="igv-col-filler-ok-button">');
|
19956
|
+
this.$ok.text("OK");
|
19957
|
+
|
19958
|
+
this.$ok.unbind();
|
19959
|
+
this.$ok.click(function() {
|
19960
|
+
self.hide();
|
19961
|
+
});
|
19962
|
+
|
19963
|
+
$col.append( this.$ok );
|
19964
|
+
$rowContainer.append( $col );
|
19965
|
+
|
19966
|
+
return $rowContainer;
|
19967
|
+
|
19968
|
+
};
|
19969
|
+
|
19970
|
+
igv.AlertDialog.prototype.hide = function () {
|
19971
|
+
|
19972
|
+
if (this.$container.hasClass('igv-grid-container-dialog')) {
|
19973
|
+
this.$container.offset( { left: 0, top: 0 } );
|
19974
|
+
}
|
19975
|
+
this.$container.hide();
|
19976
|
+
};
|
19977
|
+
|
19978
|
+
igv.AlertDialog.prototype.show = function ($host) {
|
19979
|
+
|
19980
|
+
var body_scrolltop,
|
19981
|
+
track_origin,
|
19982
|
+
track_size,
|
19983
|
+
offset,
|
19984
|
+
_top,
|
19985
|
+
_left;
|
19986
|
+
|
19987
|
+
body_scrolltop = $('body').scrollTop();
|
19988
|
+
|
19989
|
+
if (this.$container.hasClass('igv-grid-container-dialog')) {
|
19990
|
+
|
19991
|
+
offset = $host.offset();
|
19992
|
+
|
19993
|
+
_top = offset.top + body_scrolltop;
|
19994
|
+
_left = $host.outerWidth() - 300;
|
19995
|
+
|
19996
|
+
this.$container.offset( { left: _left, top: _top } );
|
19997
|
+
|
19998
|
+
//track_origin = $host.offset();
|
19999
|
+
//track_size =
|
20000
|
+
//{
|
20001
|
+
// width: $host.outerWidth(),
|
20002
|
+
// height: $host.outerHeight()
|
20003
|
+
//};
|
20004
|
+
//this.$container.offset( { left: (track_size.width - 300), top: (track_origin.top + body_scrolltop) } );
|
20005
|
+
//this.$container.offset( igv.constrainBBox(this.$container, $(igv.browser.trackContainerDiv)) );
|
20006
|
+
}
|
20007
|
+
|
20008
|
+
this.$container.show();
|
20009
|
+
|
20010
|
+
};
|
20011
|
+
|
20012
|
+
return igv;
|
20013
|
+
|
20014
|
+
})(igv || {});
|
20015
|
+
|
20016
|
+
/*
|
20017
|
+
* The MIT License (MIT)
|
20018
|
+
*
|
20019
|
+
* Copyright (c) 2016 University of California San Diego
|
20020
|
+
* Author: Jim Robinson
|
20021
|
+
*
|
20022
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
20023
|
+
* of this software and associated documentation files (the "Software"), to deal
|
20024
|
+
* in the Software without restriction, including without limitation the rights
|
20025
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
20026
|
+
* copies of the Software, and to permit persons to whom the Software is
|
20027
|
+
* furnished to do so, subject to the following conditions:
|
20028
|
+
*
|
20029
|
+
* The above copyright notice and this permission notice shall be included in
|
20030
|
+
* all copies or substantial portions of the Software.
|
20031
|
+
*
|
20032
|
+
*
|
20033
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20034
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20035
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20036
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20037
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20038
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20039
|
+
* THE SOFTWARE.
|
20040
|
+
*/
|
20041
|
+
|
20042
|
+
/**
|
20043
|
+
* Created by dat on 9/1/16.
|
20044
|
+
*/
|
20045
|
+
var igv = (function (igv) {
|
20046
|
+
|
20047
|
+
igv.CenterGuide = function ($parent, config) {
|
20048
|
+
var self = this,
|
20049
|
+
cssDisplay;
|
20050
|
+
|
20051
|
+
this.$container = $('<div class="igv-center-guide igv-center-guide-thin">');
|
20052
|
+
$parent.append(this.$container);
|
20053
|
+
this.$container.css("display", (config.showCenterGuide && true == config.showCenterGuide) ? "block" : "none");
|
20054
|
+
|
20055
|
+
cssDisplay = this.$container.css("display");
|
20056
|
+
this.$centerGuideToggle = $('<div class="igv-toggle-track-labels">');
|
20057
|
+
this.$centerGuideToggle.text(("none" === cssDisplay) ? "show center guide" : "hide center guide");
|
20058
|
+
|
20059
|
+
this.$centerGuideToggle.click(function () {
|
20060
|
+
cssDisplay = self.$container.css("display");
|
20061
|
+
if ("none" === cssDisplay) {
|
20062
|
+
self.$container.css("display", "block");
|
20063
|
+
self.$centerGuideToggle.text("hide center guide");
|
20064
|
+
} else {
|
20065
|
+
self.$container.css("display", "none");
|
20066
|
+
self.$centerGuideToggle.text("show center guide");
|
20067
|
+
}
|
20068
|
+
});
|
20069
|
+
|
20070
|
+
// Hide toggle unless property is set (for now, prior to official release)
|
20071
|
+
if(undefined === config.showCenterGuide || false == config.showCenterGuide) {
|
20072
|
+
this.$centerGuideToggle.css("display", "none");
|
20073
|
+
}
|
20074
|
+
|
20075
|
+
|
20076
|
+
};
|
20077
|
+
|
20078
|
+
igv.CenterGuide.prototype.repaint = function () {
|
20079
|
+
|
20080
|
+
var left,
|
20081
|
+
ls,
|
20082
|
+
ws,
|
20083
|
+
center,
|
20084
|
+
ppb = Math.floor(1.0/igv.browser.referenceFrame.bpPerPixel),
|
20085
|
+
x = this.$container.position.x;
|
20086
|
+
|
20087
|
+
center = x + this.$container.outerWidth()/2;
|
20088
|
+
|
20089
|
+
if (ppb > 1) {
|
20090
|
+
|
20091
|
+
left = center - ppb/2;
|
20092
|
+
ls = left.toString() + 'px';
|
20093
|
+
ws = ppb.toString() + 'px';
|
20094
|
+
this.$container.css({ left:ls, width:ws });
|
20095
|
+
|
20096
|
+
this.$container.removeClass('igv-center-guide-thin');
|
20097
|
+
this.$container.addClass('igv-center-guide-wide');
|
20098
|
+
} else {
|
20099
|
+
|
20100
|
+
// ls = center.toString() + 'px';
|
20101
|
+
ls = '50%';
|
20102
|
+
ws = '1px';
|
20103
|
+
this.$container.css({ left:ls, width:ws });
|
20104
|
+
|
20105
|
+
this.$container.removeClass('igv-center-guide-wide');
|
20106
|
+
this.$container.addClass('igv-center-guide-thin');
|
20107
|
+
}
|
20108
|
+
|
20109
|
+
// console.log('CenterGuide - repaint. PPB ' + ppb);
|
20110
|
+
};
|
20111
|
+
|
20112
|
+
return igv;
|
20113
|
+
|
20114
|
+
}) (igv || {});
|
20115
|
+
|
19129
20116
|
/*
|
19130
20117
|
* The MIT License (MIT)
|
19131
20118
|
*
|
@@ -19173,44 +20160,44 @@ var igv = (function (igv) {
|
|
19173
20160
|
if (id) {
|
19174
20161
|
this.$container.attr("id", id);
|
19175
20162
|
}
|
19176
|
-
$parent.append(this.$container
|
20163
|
+
$parent.append(this.$container);
|
19177
20164
|
|
19178
20165
|
this.$container.draggable();
|
19179
20166
|
|
19180
20167
|
this.$header = $('<div class="igv-grid-header">');
|
19181
20168
|
this.$headerBlurb = $('<div class="igv-grid-header-blurb">');
|
19182
20169
|
|
19183
|
-
this.$header.append(this.$headerBlurb
|
20170
|
+
this.$header.append(this.$headerBlurb);
|
19184
20171
|
|
19185
|
-
igv.
|
20172
|
+
igv.attachDialogCloseHandlerWithParent(this.$header, function () {
|
19186
20173
|
self.hide();
|
19187
20174
|
});
|
19188
20175
|
|
19189
|
-
this.$container.append(this.$header
|
20176
|
+
this.$container.append(this.$header);
|
19190
20177
|
|
19191
20178
|
|
19192
20179
|
// color palette
|
19193
20180
|
for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
19194
|
-
self.$container.append(makeRow(palette.slice(rowIndex * columnCount))
|
20181
|
+
self.$container.append(makeRow(palette.slice(rowIndex * columnCount)));
|
19195
20182
|
}
|
19196
20183
|
|
19197
20184
|
// dividing line
|
19198
|
-
self.$container.append($('<hr class="igv-grid-dividing-line">')
|
20185
|
+
self.$container.append($('<hr class="igv-grid-dividing-line">'));
|
19199
20186
|
|
19200
20187
|
// user colors
|
19201
|
-
self.$container.append(rowOfUserColors()
|
20188
|
+
self.$container.append(rowOfUserColors());
|
19202
20189
|
|
19203
20190
|
//// dividing line
|
19204
20191
|
//self.$container.append($('<hr class="igv-grid-dividing-line">')[ 0 ]);
|
19205
20192
|
|
19206
20193
|
// initial track color
|
19207
|
-
self.$container.append(rowOfPreviousColor()
|
20194
|
+
self.$container.append(rowOfPreviousColor());
|
19208
20195
|
|
19209
20196
|
//// dividing line
|
19210
20197
|
//self.$container.append($('<hr class="igv-grid-dividing-line">')[ 0 ]);
|
19211
20198
|
|
19212
20199
|
// initial track color
|
19213
|
-
self.$container.append(rowOfDefaultColor()
|
20200
|
+
self.$container.append(rowOfDefaultColor());
|
19214
20201
|
|
19215
20202
|
function rowOfUserColors() {
|
19216
20203
|
|
@@ -19230,8 +20217,6 @@ var igv = (function (igv) {
|
|
19230
20217
|
self.$container.append( $row[ 0 ] );
|
19231
20218
|
|
19232
20219
|
$row.find('.igv-col-filler-no-color').addClass("igv-grid-rect-hidden");
|
19233
|
-
|
19234
|
-
//self.$container.append(self.userColors[ digit ][0]);
|
19235
20220
|
}
|
19236
20221
|
|
19237
20222
|
self.userColorsIndex = undefined;
|
@@ -19289,8 +20274,8 @@ var igv = (function (igv) {
|
|
19289
20274
|
|
19290
20275
|
});
|
19291
20276
|
|
19292
|
-
$column.append($userColorInput
|
19293
|
-
$row.append($column
|
20277
|
+
$column.append($userColorInput);
|
20278
|
+
$row.append($column);
|
19294
20279
|
|
19295
20280
|
|
19296
20281
|
// color feedback chip
|
@@ -19300,7 +20285,7 @@ var igv = (function (igv) {
|
|
19300
20285
|
self.$userColorFeeback.hide();
|
19301
20286
|
|
19302
20287
|
$rowContainer = $('<div class="igv-grid-rect">');
|
19303
|
-
$rowContainer.append($row
|
20288
|
+
$rowContainer.append($row);
|
19304
20289
|
|
19305
20290
|
|
19306
20291
|
|
@@ -19310,7 +20295,7 @@ var igv = (function (igv) {
|
|
19310
20295
|
self.$userError.hide();
|
19311
20296
|
|
19312
20297
|
$row = $('<div class="igv-grid-colorpicker-user-error">');
|
19313
|
-
$row.append(self.$userError
|
20298
|
+
$row.append(self.$userError);
|
19314
20299
|
$rowContainer.append($row);
|
19315
20300
|
|
19316
20301
|
function parseColor(value) {
|
@@ -19392,28 +20377,28 @@ var igv = (function (igv) {
|
|
19392
20377
|
$row = $('<div class="igv-grid-colorpicker">');
|
19393
20378
|
|
19394
20379
|
// initial color tile
|
19395
|
-
self
|
19396
|
-
self.
|
20380
|
+
self.$defaultColor = $('<div class="igv-col-filler">');
|
20381
|
+
self.$defaultColor.css("background-color", "#eee");
|
19397
20382
|
|
19398
20383
|
$column = $('<div class="igv-col igv-col-1-8">');
|
19399
|
-
$column.append(self
|
20384
|
+
$column.append(self.$defaultColor);
|
19400
20385
|
|
19401
20386
|
$column.click(function () {
|
19402
20387
|
igv.setTrackColor(self.trackView.track, $(this).find(".igv-col-filler").css("background-color"));
|
19403
20388
|
self.trackView.update();
|
19404
20389
|
});
|
19405
20390
|
|
19406
|
-
$row.append($column
|
20391
|
+
$row.append($column);
|
19407
20392
|
|
19408
20393
|
|
19409
20394
|
// default color label
|
19410
20395
|
$column = $('<div class="igv-col igv-col-7-8 igv-col-label">');
|
19411
20396
|
$column.text("Default Color");
|
19412
|
-
$row.append($column
|
20397
|
+
$row.append($column);
|
19413
20398
|
|
19414
20399
|
|
19415
20400
|
$rowContainer = $('<div class="igv-grid-rect">');
|
19416
|
-
$rowContainer.append($row
|
20401
|
+
$rowContainer.append($row);
|
19417
20402
|
|
19418
20403
|
return $rowContainer;
|
19419
20404
|
}
|
@@ -19427,28 +20412,28 @@ var igv = (function (igv) {
|
|
19427
20412
|
$row = $('<div class="igv-grid-colorpicker">');
|
19428
20413
|
|
19429
20414
|
// initial color tile
|
19430
|
-
self
|
19431
|
-
self.
|
20415
|
+
self.$previousColor = $('<div class="igv-col-filler">');
|
20416
|
+
self.$previousColor.css("background-color", "#eee");
|
19432
20417
|
|
19433
20418
|
$column = $('<div class="igv-col igv-col-1-8">');
|
19434
|
-
$column.append(self
|
20419
|
+
$column.append(self.$previousColor);
|
19435
20420
|
|
19436
20421
|
$column.click(function () {
|
19437
20422
|
igv.setTrackColor(self.trackView.track, $(this).find(".igv-col-filler").css("background-color"));
|
19438
20423
|
self.trackView.update();
|
19439
20424
|
});
|
19440
20425
|
|
19441
|
-
$row.append($column
|
20426
|
+
$row.append($column);
|
19442
20427
|
|
19443
20428
|
|
19444
20429
|
// initial color label
|
19445
20430
|
$column = $('<div class="igv-col igv-col-7-8 igv-col-label">');
|
19446
20431
|
$column.text("Previous Color");
|
19447
|
-
$row.append($column
|
20432
|
+
$row.append($column);
|
19448
20433
|
|
19449
20434
|
|
19450
20435
|
$rowContainer = $('<div class="igv-grid-rect">');
|
19451
|
-
$rowContainer.append($row
|
20436
|
+
$rowContainer.append($row);
|
19452
20437
|
|
19453
20438
|
return $rowContainer;
|
19454
20439
|
}
|
@@ -19460,7 +20445,7 @@ var igv = (function (igv) {
|
|
19460
20445
|
columnIndex;
|
19461
20446
|
|
19462
20447
|
for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
19463
|
-
$row.append(makeColumn(null)
|
20448
|
+
$row.append(makeColumn(null));
|
19464
20449
|
}
|
19465
20450
|
|
19466
20451
|
$rowContainer.append($row);
|
@@ -19474,7 +20459,7 @@ var igv = (function (igv) {
|
|
19474
20459
|
i;
|
19475
20460
|
|
19476
20461
|
for (i = 0; i < Math.min(columnCount, colors.length); i++) {
|
19477
|
-
$row.append(makeColumn(colors[i])
|
20462
|
+
$row.append(makeColumn(colors[i]));
|
19478
20463
|
}
|
19479
20464
|
|
19480
20465
|
$rowContainer.append($row);
|
@@ -19486,7 +20471,7 @@ var igv = (function (igv) {
|
|
19486
20471
|
var $column = $('<div class="igv-col igv-col-1-8">'),
|
19487
20472
|
$filler = $('<div>');
|
19488
20473
|
|
19489
|
-
$column.append($filler
|
20474
|
+
$column.append($filler);
|
19490
20475
|
|
19491
20476
|
if (null !== colorOrNull) {
|
19492
20477
|
|
@@ -19510,6 +20495,15 @@ var igv = (function (igv) {
|
|
19510
20495
|
|
19511
20496
|
};
|
19512
20497
|
|
20498
|
+
igv.ColorPicker.prototype.configure = function (trackView) {
|
20499
|
+
|
20500
|
+
this.trackView = trackView;
|
20501
|
+
|
20502
|
+
this.$defaultColor.css("background-color", trackView.track.config.color || igv.browser.constants.defaultColor);
|
20503
|
+
this.$previousColor.css("background-color", trackView.track.color);
|
20504
|
+
|
20505
|
+
};
|
20506
|
+
|
19513
20507
|
igv.ColorPicker.prototype.hide = function () {
|
19514
20508
|
$(this.$container).offset({left: 0, top: 0});
|
19515
20509
|
this.$container.hide();
|
@@ -19526,13 +20520,8 @@ var igv = (function (igv) {
|
|
19526
20520
|
size = {width: $(this.$container).outerWidth(), height: $(this.$container).outerHeight()},
|
19527
20521
|
obj;
|
19528
20522
|
|
19529
|
-
//$(this.$container).offset( { left: (track_size.width - size.width)/2, top: track_origin.top } );
|
19530
|
-
|
19531
20523
|
$(this.$container).offset({left: (track_size.width - 300), top: (track_origin.top + body_scrolltop)});
|
19532
20524
|
|
19533
|
-
this.previousTrackColorTile.css("background-color", this.trackView.track.color);
|
19534
|
-
|
19535
|
-
this.defaultTrackColorTile.css("background-color", (this.trackView.track.defaultColor || igv.browser.constants.defaultColor));
|
19536
20525
|
|
19537
20526
|
obj = $(".igv-user-input-color");
|
19538
20527
|
obj.val("");
|
@@ -19596,7 +20585,7 @@ var igv = (function (igv) {
|
|
19596
20585
|
|
19597
20586
|
this.header.append(this.headerBlurb[ 0 ]);
|
19598
20587
|
|
19599
|
-
igv.
|
20588
|
+
igv.attachDialogCloseHandlerWithParent(this.header, function () {
|
19600
20589
|
self.hide();
|
19601
20590
|
});
|
19602
20591
|
|
@@ -19852,7 +20841,7 @@ var igv = (function (igv) {
|
|
19852
20841
|
|
19853
20842
|
constructorHelper(this);
|
19854
20843
|
|
19855
|
-
igv.
|
20844
|
+
igv.attachDialogCloseHandlerWithParent($header, function () {
|
19856
20845
|
self.hide();
|
19857
20846
|
});
|
19858
20847
|
|
@@ -19870,19 +20859,6 @@ var igv = (function (igv) {
|
|
19870
20859
|
|
19871
20860
|
};
|
19872
20861
|
|
19873
|
-
igv.Dialog.alertConstructor = function (dialog) {
|
19874
|
-
|
19875
|
-
dialog.$container.removeClass("igv-grid-container-dialog");
|
19876
|
-
dialog.$container.addClass("igv-grid-container-alert-dialog");
|
19877
|
-
|
19878
|
-
dialog.$container.append(dialog.rowOfLabel()[ 0 ]);
|
19879
|
-
|
19880
|
-
dialog.$container.append(dialog.rowOfInput()[ 0 ]);
|
19881
|
-
|
19882
|
-
dialog.$container.append(dialog.rowOfOk()[ 0 ]);
|
19883
|
-
|
19884
|
-
};
|
19885
|
-
|
19886
20862
|
igv.Dialog.prototype.rowOfOk = function() {
|
19887
20863
|
|
19888
20864
|
var $rowContainer,
|
@@ -20030,7 +21006,14 @@ var igv = (function (igv) {
|
|
20030
21006
|
self.$dialogInput.val(inputValue);
|
20031
21007
|
|
20032
21008
|
self.$dialogInput.unbind();
|
20033
|
-
self.$dialogInput.change(
|
21009
|
+
self.$dialogInput.change(function(){
|
21010
|
+
|
21011
|
+
if (clickFunction) {
|
21012
|
+
clickFunction();
|
21013
|
+
}
|
21014
|
+
|
21015
|
+
self.hide();
|
21016
|
+
});
|
20034
21017
|
|
20035
21018
|
self.$dialogInput.show();
|
20036
21019
|
} else {
|
@@ -20156,7 +21139,7 @@ var igv = (function (igv) {
|
|
20156
21139
|
popoverHeader = $('<div class="igv-popoverHeader">');
|
20157
21140
|
this.popover.append(popoverHeader[ 0 ]);
|
20158
21141
|
|
20159
|
-
igv.
|
21142
|
+
igv.attachDialogCloseHandlerWithParent(popoverHeader, function () {
|
20160
21143
|
self.hide();
|
20161
21144
|
});
|
20162
21145
|
|
@@ -20191,35 +21174,26 @@ var igv = (function (igv) {
|
|
20191
21174
|
var $container = $('<div class="igv-track-menu-container">'),
|
20192
21175
|
trackMenuItems = igv.trackMenuItems(this, trackView);
|
20193
21176
|
|
20194
|
-
trackMenuItems.forEach(function (
|
20195
|
-
|
20196
|
-
var ob = trackMenuItem.object;
|
20197
|
-
$container.append(ob[ 0 ]);
|
20198
|
-
} else {
|
20199
|
-
$container.append(trackMenuItem)
|
20200
|
-
}
|
21177
|
+
trackMenuItems.forEach(function (item) {
|
21178
|
+
$container.append(item.object || item)
|
20201
21179
|
});
|
20202
21180
|
|
20203
21181
|
this.$popoverContent.empty();
|
20204
21182
|
|
20205
21183
|
this.$popoverContent.removeClass("igv-popoverTrackPopupContent");
|
20206
|
-
this.$popoverContent.append($container
|
21184
|
+
this.$popoverContent.append($container);
|
20207
21185
|
|
20208
21186
|
// Attach click handler AFTER inserting markup in DOM.
|
20209
21187
|
// Insertion beforehand will cause it to have NO effect
|
20210
21188
|
// when clicked.
|
20211
|
-
trackMenuItems.forEach(function (
|
20212
|
-
|
20213
|
-
var ob = trackMenuItem.object,
|
20214
|
-
cl = trackMenuItem.click,
|
20215
|
-
init = trackMenuItem.init;
|
21189
|
+
trackMenuItems.forEach(function (item) {
|
20216
21190
|
|
20217
|
-
if (
|
20218
|
-
|
21191
|
+
if (item.object && item.click) {
|
21192
|
+
item.object.click( item.click );
|
20219
21193
|
}
|
20220
21194
|
|
20221
|
-
if (init) {
|
20222
|
-
init();
|
21195
|
+
if (item.init) {
|
21196
|
+
item.init();
|
20223
21197
|
}
|
20224
21198
|
|
20225
21199
|
});
|
@@ -20621,6 +21595,8 @@ var igv = (function (igv) {
|
|
20621
21595
|
self = this;
|
20622
21596
|
|
20623
21597
|
fields = [
|
21598
|
+
{name: "Chr", value: this.chr},
|
21599
|
+
{name: "Pos", value: (this.pos + 1)},
|
20624
21600
|
{name: "Names", value: this.names ? this.names : ""},
|
20625
21601
|
{name: "Ref", value: this.referenceBases},
|
20626
21602
|
{name: "Alt", value: this.alternateBases},
|