genoverse 3.2.0 → 4.0.0-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/.eslintrc.js +93 -162
  2. package/.github/workflows/test.yml +9 -10
  3. package/.github/workflows/update-gh-pages.yml +33 -0
  4. package/LICENSE.TXT +2 -2
  5. package/README.md +176 -3
  6. package/{i → assets}/sort_handle.png +0 -0
  7. package/babel.config.js +19 -0
  8. package/dist/129.css +334 -0
  9. package/dist/129.css.map +1 -0
  10. package/dist/129.genoverse.js +2 -0
  11. package/dist/129.genoverse.js.map +1 -0
  12. package/dist/15d98c18221c8bcb2334.ttf +0 -0
  13. package/dist/166.css +2 -0
  14. package/dist/166.genoverse.js +1 -0
  15. package/dist/216.css +20 -0
  16. package/dist/216.css.map +1 -0
  17. package/dist/232.css +114 -0
  18. package/dist/232.css.map +1 -0
  19. package/dist/232.genoverse.js +2 -0
  20. package/dist/232.genoverse.js.map +1 -0
  21. package/dist/2e659e443f3e98569e9f.png +0 -0
  22. package/dist/394.css +114 -0
  23. package/dist/394.css.map +1 -0
  24. package/dist/394.genoverse.js +2 -0
  25. package/dist/394.genoverse.js.map +1 -0
  26. package/dist/469.css +24 -0
  27. package/dist/469.css.map +1 -0
  28. package/dist/469.genoverse.js +2 -0
  29. package/dist/469.genoverse.js.map +1 -0
  30. package/dist/4896d4b04430cc3dfb06.woff2 +0 -0
  31. package/dist/530.css +39 -0
  32. package/dist/530.css.map +1 -0
  33. package/dist/530.genoverse.js +2 -0
  34. package/dist/530.genoverse.js.map +1 -0
  35. package/dist/547.css +469 -0
  36. package/dist/547.css.map +1 -0
  37. package/dist/547.genoverse.js +1 -0
  38. package/dist/729.css +315 -0
  39. package/dist/729.css.map +1 -0
  40. package/dist/79da213423ac0def2058.ttf +0 -0
  41. package/dist/804.genoverse.js +2 -0
  42. package/dist/804.genoverse.js.map +1 -0
  43. package/dist/842.genoverse.js +2 -0
  44. package/dist/842.genoverse.js.map +1 -0
  45. package/dist/893.genoverse.js +2 -0
  46. package/dist/893.genoverse.js.map +1 -0
  47. package/dist/949.css +315 -0
  48. package/dist/949.css.map +1 -0
  49. package/dist/949.genoverse.js +2 -0
  50. package/dist/949.genoverse.js.map +1 -0
  51. package/dist/952.css +315 -0
  52. package/dist/952.css.map +1 -0
  53. package/dist/952.genoverse.js +2 -0
  54. package/dist/952.genoverse.js.map +1 -0
  55. package/dist/d79c2ec96ab9ff1161a2.woff2 +0 -0
  56. package/dist/genoverse.js +2 -0
  57. package/dist/genoverse.js.map +1 -0
  58. package/index.html +13 -14
  59. package/jest.config.js +5 -0
  60. package/jest.setup.js +13 -0
  61. package/package.json +29 -12
  62. package/{css → src/css}/controlPanel.css +0 -0
  63. package/{css → src/css}/fileDrop.css +0 -0
  64. package/src/css/fontawesome.css +3 -0
  65. package/{css → src/css}/fullscreen.css +0 -0
  66. package/{css → src/css}/genoverse.css +1 -1
  67. package/{css → src/css}/karyotype.css +2 -0
  68. package/{css → src/css}/resizer.css +0 -0
  69. package/{css → src/css}/tooltips.css +0 -0
  70. package/{css → src/css}/trackControls.css +0 -0
  71. package/src/js/Genoverse.js +1747 -0
  72. package/{js → src/js}/Track/Controller/Sequence.js +6 -4
  73. package/src/js/Track/Controller/Stranded.js +83 -0
  74. package/{js → src/js}/Track/Controller.js +201 -160
  75. package/src/js/Track/Model/File/BAM.js +47 -0
  76. package/src/js/Track/Model/File/BED.js +122 -0
  77. package/src/js/Track/Model/File/GFF.js +42 -0
  78. package/src/js/Track/Model/File/VCF.js +109 -0
  79. package/src/js/Track/Model/File/WIG.js +82 -0
  80. package/src/js/Track/Model/File.js +36 -0
  81. package/src/js/Track/Model/Gene/Ensembl.js +24 -0
  82. package/{js → src/js}/Track/Model/Gene.js +3 -1
  83. package/src/js/Track/Model/Sequence/Ensembl.js +6 -0
  84. package/{js → src/js}/Track/Model/Sequence/Fasta.js +24 -17
  85. package/{js → src/js}/Track/Model/Sequence.js +10 -7
  86. package/{js → src/js}/Track/Model/SequenceVariation.js +17 -11
  87. package/{js → src/js}/Track/Model/Stranded.js +11 -8
  88. package/src/js/Track/Model/Transcript/Ensembl.js +73 -0
  89. package/{js → src/js}/Track/Model/Transcript.js +3 -1
  90. package/{js → src/js}/Track/Model.js +128 -97
  91. package/{js → src/js}/Track/View/Gene/Ensembl.js +6 -4
  92. package/src/js/Track/View/Gene.js +8 -0
  93. package/{js → src/js}/Track/View/Sequence.js +18 -22
  94. package/src/js/Track/View/SequenceVariation.js +117 -0
  95. package/src/js/Track/View/Transcript/Ensembl.js +17 -0
  96. package/src/js/Track/View/Transcript.js +32 -0
  97. package/{js → src/js}/Track/View.js +200 -159
  98. package/{js → src/js}/Track/library/Chromosome.js +18 -13
  99. package/src/js/Track/library/File/BAM.js +34 -0
  100. package/src/js/Track/library/File/BED.js +27 -0
  101. package/src/js/Track/library/File/BIGBED.js +51 -0
  102. package/src/js/Track/library/File/BIGWIG.js +54 -0
  103. package/src/js/Track/library/File/GFF.js +10 -0
  104. package/{js → src/js}/Track/library/File/VCF.js +29 -22
  105. package/src/js/Track/library/File/WIG.js +8 -0
  106. package/{js → src/js}/Track/library/File.js +4 -2
  107. package/src/js/Track/library/Gene.js +44 -0
  108. package/src/js/Track/library/Graph/Bar.js +263 -0
  109. package/src/js/Track/library/Graph/Line.js +335 -0
  110. package/{js → src/js}/Track/library/Graph.js +137 -114
  111. package/{js → src/js}/Track/library/HighlightRegion.js +118 -93
  112. package/src/js/Track/library/Legend.js +258 -0
  113. package/{js → src/js}/Track/library/Scalebar.js +69 -49
  114. package/{js → src/js}/Track/library/Scaleline.js +29 -27
  115. package/src/js/Track/library/Static.js +82 -0
  116. package/{js → src/js}/Track/library/dbSNP.js +47 -50
  117. package/src/js/Track.js +649 -0
  118. package/{js → src/js}/genomes/grch37.js +52 -52
  119. package/{js → src/js}/genomes/grch38.js +52 -52
  120. package/src/js/lib/BWReader.js +562 -0
  121. package/src/js/lib/VCFReader.js +296 -0
  122. package/src/js/lib/dalliance/bam.js +517 -0
  123. package/src/js/lib/dalliance/bin.js +317 -0
  124. package/src/js/lib/dalliance/jszlib-inflate.js +2159 -0
  125. package/src/js/lib/dalliance/lh3utils.js +105 -0
  126. package/src/js/lib/dalliance/sha1.js +334 -0
  127. package/src/js/lib/import-tracks.js +42 -0
  128. package/{js/lib → src/js/lib/jquery-plugins}/jquery.mousehold.js +0 -0
  129. package/{js/lib → src/js/lib/jquery-plugins}/jquery.mousewheel.js +0 -0
  130. package/{js/lib → src/js/lib/jquery-plugins}/jquery.tipsy.js +0 -0
  131. package/src/js/lib/jquery.js +26 -0
  132. package/src/js/lib/polyfills.js +11 -0
  133. package/src/js/lib/wrap-functions.js +88 -0
  134. package/src/js/plugins/controlPanel.js +388 -0
  135. package/src/js/plugins/fileDrop.js +81 -0
  136. package/src/js/plugins/focusRegion.js +13 -0
  137. package/{js → src/js}/plugins/fullscreen.js +18 -14
  138. package/{js → src/js}/plugins/karyotype.js +51 -45
  139. package/src/js/plugins/resizer.js +52 -0
  140. package/{js → src/js}/plugins/tooltips.js +31 -29
  141. package/src/js/plugins/trackControls.js +159 -0
  142. package/test/View/render-legends.test.js +1 -1
  143. package/test/create-and-destroy.test.js +2 -2
  144. package/test/track-ordering.test.js +3 -2
  145. package/test/track_config/config-settings.test.js +1 -1
  146. package/test/utils.js +4 -2
  147. package/webpack.config.js +103 -34
  148. package/css/font-awesome.css +0 -3
  149. package/expanded.html +0 -120
  150. package/fontawesome/css/fontawesome.min.css +0 -5
  151. package/fontawesome/css/regular.min.css +0 -5
  152. package/fontawesome/css/solid.min.css +0 -5
  153. package/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  154. package/fontawesome/webfonts/fa-brands-400.woff +0 -0
  155. package/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  156. package/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  157. package/fontawesome/webfonts/fa-regular-400.woff +0 -0
  158. package/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  159. package/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  160. package/fontawesome/webfonts/fa-solid-900.woff +0 -0
  161. package/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  162. package/help.pdf +0 -0
  163. package/index.js +0 -83
  164. package/js/Genoverse.js +0 -1681
  165. package/js/Track/Controller/Stranded.js +0 -73
  166. package/js/Track/Model/File/BAM.js +0 -44
  167. package/js/Track/Model/File/BED.js +0 -116
  168. package/js/Track/Model/File/GFF.js +0 -40
  169. package/js/Track/Model/File/VCF.js +0 -101
  170. package/js/Track/Model/File/WIG.js +0 -67
  171. package/js/Track/Model/File.js +0 -36
  172. package/js/Track/Model/Gene/Ensembl.js +0 -22
  173. package/js/Track/Model/Sequence/Ensembl.js +0 -4
  174. package/js/Track/Model/Transcript/Ensembl.js +0 -67
  175. package/js/Track/View/Gene.js +0 -6
  176. package/js/Track/View/Sequence/Variation.js +0 -115
  177. package/js/Track/View/Transcript/Ensembl.js +0 -12
  178. package/js/Track/View/Transcript.js +0 -28
  179. package/js/Track/library/File/BAM.js +0 -30
  180. package/js/Track/library/File/BED.js +0 -24
  181. package/js/Track/library/File/BIGBED.js +0 -47
  182. package/js/Track/library/File/BIGWIG.js +0 -52
  183. package/js/Track/library/File/GFF.js +0 -9
  184. package/js/Track/library/File/WIG.js +0 -5
  185. package/js/Track/library/Gene.js +0 -37
  186. package/js/Track/library/Graph/Bar.js +0 -235
  187. package/js/Track/library/Graph/Line.js +0 -296
  188. package/js/Track/library/Legend.js +0 -224
  189. package/js/Track/library/Static.js +0 -78
  190. package/js/Track.js +0 -632
  191. package/js/genoverse.min.js +0 -2
  192. package/js/genoverse.min.js.map +0 -1
  193. package/js/lib/BWReader.js +0 -578
  194. package/js/lib/Base.js +0 -145
  195. package/js/lib/VCFReader.js +0 -286
  196. package/js/lib/dalliance/js/bam.js +0 -494
  197. package/js/lib/dalliance/js/bin.js +0 -185
  198. package/js/lib/dalliance/js/das.js +0 -749
  199. package/js/lib/dalliance/js/utils.js +0 -370
  200. package/js/lib/dalliance-lib.js +0 -3594
  201. package/js/lib/dalliance-lib.min.js +0 -68
  202. package/js/lib/jDataView.js +0 -2
  203. package/js/lib/jParser.js +0 -192
  204. package/js/lib/jquery-ui.js +0 -8
  205. package/js/lib/jquery.js +0 -2
  206. package/js/lib/rtree.js +0 -1
  207. package/js/plugins/controlPanel.js +0 -395
  208. package/js/plugins/fileDrop.js +0 -62
  209. package/js/plugins/focusRegion.js +0 -12
  210. package/js/plugins/resizer.js +0 -45
  211. package/js/plugins/trackControls.js +0 -143
  212. package/utils/expandedTemplate.html +0 -46
  213. package/utils/git-hooks/post-commit +0 -9
  214. package/utils/git-hooks/pre-commit +0 -7
  215. package/utils/git-hooks/setup +0 -6
  216. package/utils/makeExpanded.js +0 -19
@@ -1,9 +1,11 @@
1
- Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({
1
+ import Model from '../Model';
2
+
3
+ export default Model.extend({
2
4
  init: function (reset) {
3
5
  this.base(reset);
4
6
 
5
7
  if (!reset) {
6
- var otherTrack = this.prop('forwardTrack');
8
+ const otherTrack = this.prop('forwardTrack');
7
9
 
8
10
  if (otherTrack) {
9
11
  this.featuresByChr = otherTrack.prop('featuresByChr');
@@ -13,16 +15,17 @@ Genoverse.Track.Model.Stranded = Genoverse.Track.Model.extend({
13
15
  }
14
16
  },
15
17
 
16
- parseURL: function () {
18
+ parseURL: function (...args) {
17
19
  if (!this.urlParams.strand) {
18
20
  this.urlParams.strand = this.prop('featureStrand');
19
21
  }
20
22
 
21
- return this.base.apply(this, arguments);
23
+ return this.base(...args);
22
24
  },
23
25
 
24
- findFeatures: function () {
25
- var strand = this.track.featureStrand;
26
- return $.grep(this.base.apply(this, arguments), function (feature) { return feature.strand === strand; });
27
- }
26
+ findFeatures: function (...args) {
27
+ const strand = this.track.featureStrand;
28
+
29
+ return this.base(...args).filter(feature => feature.strand === strand);
30
+ },
28
31
  });
@@ -0,0 +1,73 @@
1
+ import Model from '../Transcript';
2
+
3
+ // Ensembl REST API Transcript model
4
+ export default Model.extend({
5
+ url : '//rest.ensembl.org/overlap/region/human/__CHR__:__START__-__END__?feature=transcript;feature=exon;feature=cds;content-type=application/json',
6
+ dataRequestLimit : 5000000, // As per e! REST API restrictions
7
+
8
+ setDefaults: function (...args) {
9
+ this.geneIds = {};
10
+ this.seenGenes = 0;
11
+
12
+ this.base(...args);
13
+ },
14
+
15
+ // The url above responds in json format, data is an array
16
+ // See rest.ensembl.org/documentation/info/overlap_region for more details
17
+ parseData: function (data, chr) {
18
+ const featuresById = this.featuresById;
19
+ const ids = [];
20
+
21
+ data.filter(d => d.feature_type === 'transcript').forEach(
22
+ (feature, i) => {
23
+ if (!featuresById[feature.id]) {
24
+ this.geneIds[feature.Parent] = this.geneIds[feature.Parent] || ++this.seenGenes;
25
+
26
+ feature.chr = feature.chr || chr;
27
+ feature.label = parseInt(feature.strand, 10) === 1 ? `${feature.external_name || feature.id} >` : `< ${feature.external_name || feature.id}`;
28
+ feature.sort = (this.geneIds[feature.Parent] * 1e10) + (feature.logic_name.indexOf('ensembl_havana') === 0 ? 0 : 2e9) + (feature.biotype === 'protein_coding' ? 0 : 1e9) + feature.start + i;
29
+ feature.cdsStart = Infinity;
30
+ feature.cdsEnd = -Infinity;
31
+ feature.exons = {};
32
+ feature.subFeatures = [];
33
+
34
+ this.insertFeature(feature);
35
+ }
36
+
37
+ ids.push(feature.id);
38
+ }
39
+ );
40
+
41
+ data.filter(d => d.feature_type === 'cds' && featuresById[d.Parent]).forEach(
42
+ (cds) => {
43
+ featuresById[cds.Parent].cdsStart = Math.min(featuresById[cds.Parent].cdsStart, cds.start);
44
+ featuresById[cds.Parent].cdsEnd = Math.max(featuresById[cds.Parent].cdsEnd, cds.end);
45
+ }
46
+ );
47
+
48
+ data.filter(d => d.feature_type === 'exon' && featuresById[d.Parent] && !featuresById[d.Parent].exons[d.id]).forEach(
49
+ (exon) => {
50
+ if (exon.end < featuresById[exon.Parent].cdsStart || exon.start > featuresById[exon.Parent].cdsEnd) {
51
+ featuresById[exon.Parent].subFeatures.push({ utr: true, ...exon });
52
+ } else {
53
+ if (exon.start < featuresById[exon.Parent].cdsStart) {
54
+ featuresById[exon.Parent].subFeatures.push({ utr: true, ...exon, end: featuresById[exon.Parent].cdsStart });
55
+ }
56
+
57
+ featuresById[exon.Parent].subFeatures.push({
58
+ ...exon,
59
+ start : Math.max(exon.start, featuresById[exon.Parent].cdsStart),
60
+ end : Math.min(exon.end, featuresById[exon.Parent].cdsEnd),
61
+ strand : featuresById[exon.Parent].strand,
62
+ });
63
+
64
+ if (exon.end > featuresById[exon.Parent].cdsEnd) {
65
+ featuresById[exon.Parent].subFeatures.push({ utr: true, ...exon, start: featuresById[exon.Parent].cdsEnd });
66
+ }
67
+ }
68
+ }
69
+ );
70
+
71
+ ids.forEach(id => featuresById[id].subFeatures.sort((a, b) => a.start - b.start));
72
+ },
73
+ });
@@ -1,5 +1,7 @@
1
+ import Model from '../Model';
2
+
1
3
  // Abstract Transcript model
2
4
  // see sub-models for more specific examples
3
- Genoverse.Track.Model.Transcript = Genoverse.Track.Model.extend({
5
+ export default Model.extend({
4
6
 
5
7
  });
@@ -1,4 +1,8 @@
1
- Genoverse.Track.Model = Base.extend({
1
+ import Base from 'basejs';
2
+ import RTree from 'rtree';
3
+ import wrapFunctions from '../lib/wrap-functions';
4
+
5
+ export default Base.extend({
2
6
  dataType : 'json',
3
7
  allData : false,
4
8
  dataBuffer : undefined, // e.g. { start: 0, end: 0 } - basepairs to extend data region for, when getting data from the origin
@@ -11,8 +15,15 @@ Genoverse.Track.Model = Base.extend({
11
15
  showServerErrors : false, // if true, error messages return from the server by getData requests will be shown on the track
12
16
 
13
17
  constructor: function (properties) {
14
- $.extend(this, properties);
15
- Genoverse.wrapFunctions(this);
18
+ Object.entries(properties).forEach(
19
+ ([ key, val ]) => {
20
+ if (typeof val !== 'undefined') {
21
+ this[key] = val;
22
+ }
23
+ }
24
+ );
25
+
26
+ wrapFunctions(this, 'Model');
16
27
  this.init();
17
28
  },
18
29
 
@@ -20,9 +31,7 @@ Genoverse.Track.Model = Base.extend({
20
31
  this.setDefaults(reset);
21
32
 
22
33
  if (reset) {
23
- for (var i in this.featuresById) {
24
- delete this.featuresById[i].position;
25
- }
34
+ Object.values(this.featuresById).forEach((feature) => { delete feature.position; });
26
35
  }
27
36
 
28
37
  if (!reset || this.data) {
@@ -52,7 +61,7 @@ Genoverse.Track.Model = Base.extend({
52
61
  },
53
62
 
54
63
  setChrProps: function () {
55
- var chr = this.browser.chr;
64
+ const chr = this.browser.chr;
56
65
 
57
66
  this.dataRangesByChr = this.dataRangesByChr || {};
58
67
  this.featuresByChr = this.featuresByChr || {};
@@ -78,26 +87,29 @@ Genoverse.Track.Model = Base.extend({
78
87
  },
79
88
 
80
89
  getData: function (chr, start, end, done) {
90
+ const jQuery = this.browser.jQuery;
91
+
81
92
  start = Math.max(1, start);
82
93
  end = Math.min(this.browser.getChromosomeSize(chr), end);
83
94
 
84
- var deferred = $.Deferred();
95
+ const deferred = jQuery.Deferred();
85
96
 
86
97
  if (typeof this.data !== 'undefined') {
87
- this.receiveData(typeof this.data.sort === 'function' ? this.data.sort(function (a, b) { return a.start - b.start; }) : this.data, chr, start, end);
88
- return deferred.resolveWith(this);
98
+ this.receiveData(typeof this.data.sort === 'function' ? this.data.sort((a, b) => a.start - b.start) : this.data, chr, start, end);
99
+
100
+ return deferred.resolve();
89
101
  }
90
102
 
91
- var model = this;
92
- var bins = [];
93
- var length = end - start + 1;
103
+ const model = this;
104
+ const bins = [];
105
+ const length = end - start + 1;
94
106
 
95
107
  if (!this.url) {
96
- return deferred.resolveWith(this);
108
+ return deferred.resolve();
97
109
  }
98
110
 
99
111
  if (this.dataRequestLimit && length > this.dataRequestLimit) {
100
- var i = Math.ceil(length / this.dataRequestLimit);
112
+ let i = Math.ceil(length / this.dataRequestLimit);
101
113
 
102
114
  while (i--) {
103
115
  bins.push([ start, i ? start += this.dataRequestLimit - 1 : end ]);
@@ -107,39 +119,43 @@ Genoverse.Track.Model = Base.extend({
107
119
  bins.push([ start, end ]);
108
120
  }
109
121
 
110
- $.when.apply($, $.map(bins, function (bin) {
111
- var request = $.ajax({
112
- url : model.parseURL(chr, bin[0], bin[1]),
113
- data : model.urlParams,
114
- dataType : model.dataType,
115
- context : model,
116
- xhrFields : model.xhrFields,
117
- success : function (data) {
118
- this.receiveData(data, chr, bin[0], bin[1]);
119
- },
120
- error: function (xhr, statusText) {
121
- this.track.controller.showError(
122
- this.showServerErrors && (xhr.responseJSON || {}).message
123
- ? xhr.responseJSON.message
124
- : statusText + ' while getting the data, see console for more details',
125
- arguments
126
- );
127
- },
128
- complete: function (xhr) {
129
- this.dataLoading = $.grep(this.dataLoading, function (t) { return xhr !== t; });
122
+ jQuery.when(
123
+ ...bins.map(
124
+ (bin) => {
125
+ const request = jQuery.ajax({
126
+ url : model.parseURL(chr, bin[0], bin[1]),
127
+ data : model.urlParams,
128
+ dataType : model.dataType,
129
+ context : model,
130
+ xhrFields : model.xhrFields,
131
+ success : function (data) {
132
+ this.receiveData(data, chr, bin[0], bin[1]);
133
+ },
134
+ error: function (xhr, statusText, ...args) {
135
+ this.track.controller.showError(
136
+ this.showServerErrors && (xhr.responseJSON || {}).message
137
+ ? xhr.responseJSON.message
138
+ : `${statusText} while getting the data, see console for more details`,
139
+ [ xhr, statusText, ...args ]
140
+ );
141
+ },
142
+ complete: function (xhr) {
143
+ this.dataLoading = this.dataLoading.filter(loading => xhr !== loading);
144
+ },
145
+ });
146
+
147
+ request.coords = [ chr, bin[0], bin[1] ]; // store actual chr, start and end on the request, in case they are needed
148
+
149
+ if (typeof done === 'function') {
150
+ request.done(done);
151
+ }
152
+
153
+ model.dataLoading.push(request);
154
+
155
+ return request;
130
156
  }
131
- });
132
-
133
- request.coords = [ chr, bin[0], bin[1] ]; // store actual chr, start and end on the request, in case they are needed
134
-
135
- if (typeof done === 'function') {
136
- request.done(done);
137
- }
138
-
139
- model.dataLoading.push(request);
140
-
141
- return request;
142
- })).done(function () { deferred.resolveWith(model); });
157
+ )
158
+ ).done(deferred.resolve);
143
159
 
144
160
  return deferred;
145
161
  },
@@ -177,17 +193,15 @@ Genoverse.Track.Model = Base.extend({
177
193
  * and call this.insertFeature(feature)
178
194
  */
179
195
  parseData: function (data, chr, start) { // end is also passed in, but not used in this case
180
- var feature;
181
-
182
196
  // Example of parseData function when data is an array of hashes like { start: ..., end: ... }
183
- for (var i = 0; i < data.length; i++) {
184
- feature = data[i];
185
-
186
- feature.chr = feature.chr || chr;
187
- feature.sort = start + i;
197
+ data.forEach(
198
+ (feature, i) => {
199
+ feature.chr = feature.chr || chr;
200
+ feature.sort = start + i;
188
201
 
189
- this.insertFeature(feature);
190
- }
202
+ this.insertFeature(feature);
203
+ }
204
+ );
191
205
  },
192
206
 
193
207
  updateData: function (data) {
@@ -208,20 +222,22 @@ Genoverse.Track.Model = Base.extend({
208
222
  start = Math.max(1, start);
209
223
  end = Math.min(this.browser.getChromosomeSize(chr), end);
210
224
 
211
- var ranges = this.dataRanges(chr).search({ x: start, w: end - start + 1, y: 0, h: 1 }).sort(function (a, b) { return a[0] - b[0]; });
225
+ const ranges = this.dataRanges(chr).search({ x: start, w: end - start + 1, y: 0, h: 1 }).sort((a, b) => a[0] - b[0]);
212
226
 
213
227
  if (!ranges.length) {
214
228
  return false;
215
229
  }
216
230
 
217
- var s = ranges.length === 1 ? ranges[0][0] : 9e99;
218
- var e = ranges.length === 1 ? ranges[0][1] : -9e99;
231
+ let s = ranges.length === 1 ? ranges[0][0] : 9e99;
232
+ let e = ranges.length === 1 ? ranges[0][1] : -9e99;
219
233
 
220
- for (var i = 0; i < ranges.length - 1; i++) {
221
- // s0 <= s1 && ((e0 >= e1) || (e0 + 1 >= s1))
222
- if (ranges[i][0] <= ranges[i + 1][0] && ((ranges[i][1] >= ranges[i + 1][1]) || (ranges[i][1] + 1 >= ranges[i + 1][0]))) {
223
- s = Math.min(s, ranges[i][0]);
224
- e = Math.max(e, ranges[i][1], ranges[i + 1][1]);
234
+ for (let i = 0; i < ranges.length - 1; i++) {
235
+ const [ s0, s1 ] = ranges[i];
236
+ const [ e0, e1 ] = ranges[i + 1];
237
+
238
+ if (s0 <= s1 && ((e0 >= e1) || (e0 + 1 >= s1))) {
239
+ s = Math.min(s, s0);
240
+ e = Math.max(e, e0, e1);
225
241
  } else {
226
242
  return false;
227
243
  }
@@ -237,67 +253,82 @@ Genoverse.Track.Model = Base.extend({
237
253
 
238
254
  // Make sure we have a unique ID, this method is not efficient, so better supply your own id
239
255
  if (!feature.id) {
240
- feature.id = feature.ID || this.hashCode(JSON.stringify($.extend({}, feature, { sort: '' }))); // sort is dependant on the browser's region, so will change on zoom
256
+ feature.id = feature.ID || this.hashCode(JSON.stringify({ ...feature, sort: '' })); // sort is dependant on the browser's region, so will change on zoom
241
257
  }
242
258
 
243
- var features = this.features(feature.chr);
259
+ const features = this.features(feature.chr);
244
260
 
245
261
  if (features && !this.featuresById[feature.id]) {
246
262
  if (feature.subFeatures) {
247
- feature.subFeatures.sort(function (a, b) { return a.start - b.start; });
248
-
249
- for (var i = 0; i < feature.subFeatures.length; i++) {
250
- feature.subFeatures[i].start = Math.min(Math.max(feature.subFeatures[i].start, feature.start), feature.end);
251
- feature.subFeatures[i].end = Math.max(Math.min(feature.subFeatures[i].end, feature.end), feature.start);
252
- }
263
+ feature.subFeatures.sort(
264
+ (a, b) => a.start - b.start
265
+ ).forEach(
266
+ (subFeature) => {
267
+ subFeature.start = Math.min(Math.max(subFeature.start, feature.start), feature.end);
268
+ subFeature.end = Math.max(Math.min(subFeature.end, feature.end), feature.start);
269
+ }
270
+ );
253
271
 
254
272
  // Add "fake" sub-features at the start and end of the feature - this will allow joins to be drawn when there are no sub-features in the current region.
255
273
  feature.subFeatures.unshift({ start: feature.start, end: feature.start, fake: true });
256
- feature.subFeatures.push({ start: feature.end, end: feature.end, fake: true });
274
+ feature.subFeatures.push({ start: feature.end, end: feature.end, fake: true });
257
275
  }
258
276
 
259
277
  features.insert({ x: feature.start, y: 0, w: feature.end - feature.start + 1, h: 1 }, feature);
278
+
260
279
  this.featuresById[feature.id] = feature;
261
280
  }
262
281
  },
263
282
 
264
283
  findFeatures: function (chr, start, end) {
265
- var features = this.features(chr).search({ x: start - this.dataBuffer.start, y: 0, w: end - start + this.dataBuffer.start + this.dataBuffer.end + 1, h: 1 });
266
- var filters = this.prop('featureFilters') || [];
267
-
268
- for (var i = 0; i < filters.length; i++) {
269
- features = $.grep(features, $.proxy(filters[i], this));
270
- }
284
+ let features = this.features(chr).search({
285
+ x : start - this.dataBuffer.start,
286
+ y : 0,
287
+ w : end - start + this.dataBuffer.start + this.dataBuffer.end + 1,
288
+ h : 1,
289
+ });
290
+
291
+ (this.prop('featureFilters') || []).forEach(
292
+ (filter) => {
293
+ features = features.filter(feature => filter.call(this, feature));
294
+ }
295
+ );
271
296
 
272
297
  return this.sortFeatures(features);
273
298
  },
274
299
 
275
300
  sortFeatures: function (features) {
276
- return features.sort(function (a, b) { return a.sort - b.sort; });
301
+ return features.sort((a, b) => a.sort - b.sort);
277
302
  },
278
303
 
279
- abort: function () {
280
- for (var i = 0; i < this.dataLoading.length; i++) {
281
- this.dataLoading[i].abort();
304
+ hashCode: function (string) {
305
+ let hash = 0;
306
+
307
+ if (string.length) {
308
+ for (let i = 0; i < string.length; i++) {
309
+ const c = string.charCodeAt(i);
310
+
311
+ hash = ((hash << 5) - hash) + c;
312
+ hash &= hash; // Convert to 32bit integer
313
+ }
282
314
  }
283
315
 
284
- this.dataLoading = [];
316
+ return String(hash);
285
317
  },
286
318
 
287
- hashCode: function (string) {
288
- var hash = 0;
289
- var c;
319
+ abort: function () {
320
+ this.dataLoading.forEach(loading => loading.abort());
290
321
 
291
- if (!string.length) {
292
- return hash;
293
- }
322
+ this.dataLoading = [];
323
+ },
294
324
 
295
- for (var i = 0; i < string.length; i++) {
296
- c = string.charCodeAt(i);
297
- hash = ((hash << 5) - hash) + c;
298
- hash &= hash; // Convert to 32bit integer
299
- }
325
+ destroy: function () {
326
+ this.abort();
300
327
 
301
- return '' + hash;
302
- }
328
+ // Force garbage collection
329
+ delete this.data;
330
+ delete this.dataRangesByChr;
331
+ delete this.featuresByChr;
332
+ delete this.featuresById;
333
+ },
303
334
  });
@@ -1,6 +1,8 @@
1
- Genoverse.Track.View.Gene.Ensembl = Genoverse.Track.View.Gene.extend({
1
+ import View from '../Gene';
2
+
3
+ export default View.extend({
2
4
  setFeatureColor: function (feature) {
3
- var processedTranscript = {
5
+ const processedTranscript = {
4
6
  'sense_intronic' : 1,
5
7
  'sense_overlapping' : 1,
6
8
  'processed_transcript' : 1,
@@ -12,7 +14,7 @@ Genoverse.Track.View.Gene.Ensembl = Genoverse.Track.View.Gene.extend({
12
14
  'non_coding' : 1,
13
15
  'ambiguous_orf' : 1,
14
16
  'disrupted_domain' : 1,
15
- '3prime_overlapping_ncrna' : 1
17
+ '3prime_overlapping_ncrna' : 1,
16
18
  };
17
19
 
18
20
  feature.color = '#000000';
@@ -42,5 +44,5 @@ Genoverse.Track.View.Gene.Ensembl = Genoverse.Track.View.Gene.extend({
42
44
  }
43
45
 
44
46
  feature.labelColor = feature.labelColor || feature.color;
45
- }
47
+ },
46
48
  });
@@ -0,0 +1,8 @@
1
+ import View from '../View';
2
+
3
+ export default View.extend({
4
+ featureHeight : 5,
5
+ labels : true,
6
+ repeatLabels : true,
7
+ bump : true,
8
+ });
@@ -1,14 +1,15 @@
1
- Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({
1
+ import View from '../View';
2
+
3
+ export default View.extend({
2
4
  featureMargin : { top: 0, right: 0, bottom: 0, left: 0 },
3
5
  colors : { 'default': '#CCCCCC', A: '#73E973', T: '#DE4C61', G: '#FFFF77', C: '#688EC0' },
4
6
  labelColors : { 'default': '#000000', T: '#FFFFFF', C: '#FFFFFF' },
5
7
  labels : 'overlay',
6
8
 
7
- setDefaults: function () {
8
- this.base.apply(this, arguments);
9
+ setDefaults: function (...args) {
10
+ this.base(...args);
9
11
 
10
- var lowerCase = this.prop('lowerCase');
11
- var key;
12
+ const lowerCase = this.prop('lowerCase');
12
13
 
13
14
  this.labelYOffset = typeof this.labelYOffset === 'number' ? this.labelYOffset : (this.featureHeight + 1) / 2;
14
15
  this.widestLabel = typeof this.widestLabel === 'string' ? this.widestLabel : lowerCase ? 'g' : 'G';
@@ -17,13 +18,11 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({
17
18
  this.labelWidth[this.widestLabel] = Math.ceil(this.context.measureText(this.widestLabel).width) + 1;
18
19
 
19
20
  if (lowerCase) {
20
- for (key in this.colors) {
21
- this.colors[key.toLowerCase()] = this.colors[key];
22
- }
23
-
24
- for (key in this.labelColors) {
25
- this.labelColors[key.toLowerCase()] = this.labelColors[key];
26
- }
21
+ [ this.colors, this.labelColors ].forEach(
22
+ colorObject => Object.entries(colorObject).forEach(([ letter, color ]) => {
23
+ colorObject[letter.toLowerCase()] = color;
24
+ })
25
+ );
27
26
  }
28
27
  },
29
28
 
@@ -31,25 +30,22 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({
31
30
  featureContext.textBaseline = 'middle';
32
31
  featureContext.textAlign = 'center';
33
32
 
34
- var width = Math.max(scale, this.minScaledWidth);
33
+ const width = Math.max(scale, this.minScaledWidth);
35
34
 
36
- for (var i = 0; i < features.length; i++) {
37
- this.drawSequence(features[i], featureContext, scale, width);
38
- }
35
+ features.forEach(feature => this.drawSequence(feature, featureContext, scale, width));
39
36
  },
40
37
 
41
38
  drawSequence: function (feature, context, scale, width) {
42
- var drawLabels = this.labelWidth[this.widestLabel] < width - 1;
43
- var start, bp;
39
+ const drawLabels = this.labelWidth[this.widestLabel] < width - 1;
44
40
 
45
- for (var i = 0; i < feature.sequence.length; i++) {
46
- start = feature.position[scale].X + i * scale;
41
+ for (let i = 0; i < feature.sequence.length; i++) {
42
+ const start = feature.position[scale].X + i * scale;
47
43
 
48
44
  if (start < -scale || start > context.canvas.width) {
49
45
  continue;
50
46
  }
51
47
 
52
- bp = feature.sequence.charAt(i);
48
+ const bp = feature.sequence.charAt(i);
53
49
 
54
50
  context.fillStyle = this.colors[bp] || this.colors.default;
55
51
  context.fillRect(start, feature.position[scale].Y, width, this.featureHeight);
@@ -59,5 +55,5 @@ Genoverse.Track.View.Sequence = Genoverse.Track.View.extend({
59
55
  context.fillText(bp, start + (width / 2), feature.position[scale].Y + this.labelYOffset);
60
56
  }
61
57
  }
62
- }
58
+ },
63
59
  });