igv-rails 1.0.1.1 → 1.0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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},
|