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,16 +1,21 @@
1
- Genoverse.Plugins.karyotype = function (pluginConf) {
1
+ import '../../css/karyotype.css';
2
+ import Chromosome from '../Track/library/Chromosome';
3
+
4
+ const plugin = function (pluginConf) {
5
+ const jQuery = this.jQuery;
6
+
2
7
  function createKaryotype() {
3
- var chromosome = $('<div class="gv-chromosome">');
4
- var container = $('<div class="gv-karyotype-container">').html(chromosome).insertBefore(this.wrapper);
5
- var assemblyName = this.assembly || this.genomeName;
6
- var name = (pluginConf.showAssembly && assemblyName ? assemblyName + ': ' : '') + 'Chr ' + this.chr;
8
+ const chromosome = jQuery('<div class="gv-chromosome">');
9
+ const container = jQuery('<div class="gv-karyotype-container">').html(chromosome).insertBefore(this.wrapper);
10
+ const assemblyName = this.assembly || this.genomeName;
11
+ const name = `${pluginConf.showAssembly && assemblyName ? `${assemblyName}: ` : ''}Chr ${this.chr}`;
7
12
 
8
13
  if (pluginConf.showAssembly && assemblyName) {
9
14
  container.addClass('gv-show-assembly');
10
15
  }
11
16
 
12
- var measureWidth = $('<div class="gv-chromosome"><ul class="gv-label-container"><li><span class="gv-name">' + name + '</span></li></ul></div>').appendTo(container);
13
- var labelWidth = pluginConf.karyotypeLabel === false ? 0 : measureWidth.find('.gv-name').outerWidth(true) + 10;
17
+ const measureWidth = jQuery(`<div class="gv-chromosome"><ul class="gv-label-container"><li><span class="gv-name">${name}</span></li></ul></div>`).appendTo(container);
18
+ const labelWidth = pluginConf.karyotypeLabel === false ? 0 : measureWidth.find('.gv-name').outerWidth(true) + 10;
14
19
 
15
20
  measureWidth.remove();
16
21
 
@@ -24,7 +29,7 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
24
29
  end : this.chromosomeSize,
25
30
  isStatic : true,
26
31
  tracks : [
27
- Genoverse.Track.Chromosome.extend({
32
+ Chromosome.extend({
28
33
  name : name,
29
34
  height : 20,
30
35
  featureHeight : 20,
@@ -33,9 +38,9 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
33
38
  unsortable : true,
34
39
 
35
40
  click: function (e) {
36
- var offset = this.container.parent().offset().left;
37
- var x = e.pageX - offset;
38
- var f = this.featurePositions.search({ x: x, y: 1, w: 1, h: 1 })[0];
41
+ const offset = this.container.parent().offset().left;
42
+ const x = e.pageX - offset;
43
+ const f = this.featurePositions.search({ x: x, y: 1, w: 1, h: 1 })[0];
39
44
 
40
45
  if (f) {
41
46
  if (e.type === 'mouseup') {
@@ -46,8 +51,9 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
46
51
  this.container.tipsy('hide');
47
52
 
48
53
  if (f.label) {
49
- var left = offset + f.position[this.scale].start + f.position[this.scale].width / 2;
50
- this.container.attr('title', f.label[0]).tipsy({ trigger: 'manual', container: 'body' }).tipsy('show').data('tipsy').$tip.css('left', function () { return left - $(this).width() / 2; });
54
+ const left = offset + f.position[this.scale].start + f.position[this.scale].width / 2;
55
+
56
+ this.container.attr('title', f.label[0]).tipsy({ trigger: 'manual', container: 'body' }).tipsy('show').data('tipsy').$tip.css('left', function () { return left - jQuery(this).width() / 2; });
51
57
  }
52
58
 
53
59
  this.hoverFeature = f;
@@ -56,35 +62,35 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
56
62
  },
57
63
 
58
64
  addUserEventHandlers: function () {
59
- var track = this;
65
+ const track = this;
60
66
 
61
67
  this.base();
62
68
 
63
69
  this.container.on({
64
- mousemove : function (e) { track.click(e); },
65
- mouseout : function (e) {
70
+ mousemove : (e) => { track.click(e); },
71
+ mouseout : (e) => {
66
72
  if (track.browser.viewPoint.is(e.relatedTarget) || track.browser.viewPoint.find(e.relatedTarget).length) {
67
73
  return true;
68
74
  }
69
75
 
70
76
  track.container.tipsy('hide');
71
77
  track.hoverFeature = false;
72
- }
78
+ },
73
79
  }, '.gv-image-container');
74
80
 
75
81
  // Don't allow zooming in and out on the karyotype image
76
- this.container.on('mousewheel', '.gv-image-container, .gv-selector', function (e) {
82
+ this.container.on('mousewheel', '.gv-image-container, .gv-selector', (e) => {
77
83
  e.stopPropagation();
78
84
  });
79
85
  },
80
86
 
81
87
  afterSetName: function () {
82
- this.label.css('lineHeight', this.label.height() + 'px');
83
- }
84
- })
88
+ this.label.css('lineHeight', `${this.label.height()}px`);
89
+ },
90
+ }),
85
91
  ],
86
92
 
87
- addUserEventHandlers: $.noop,
93
+ addUserEventHandlers: () => {},
88
94
 
89
95
  afterInit: function () {
90
96
  this.updatePosition();
@@ -96,8 +102,8 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
96
102
  },
97
103
 
98
104
  afterAddDomElements: function () {
99
- var karyotype = this;
100
- var parent = this.parent;
105
+ const karyotype = this;
106
+ const parent = this.parent;
101
107
 
102
108
  function hideTooltip() {
103
109
  karyotype.hideTooltip = true;
@@ -107,10 +113,10 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
107
113
  function updateLocation(e, ui) {
108
114
  karyotype.hideTooltip = false;
109
115
 
110
- var scale = karyotype.chromosomeSize / karyotype.width;
111
- var axis = e.type === 'resizestop' ? $(this).data('ui-resizable').axis : undefined;
112
- var start = axis === 'e' ? parent.start : Math.max(Math.floor(ui.position.left * scale), 1);
113
- var end = axis === 'w' ? parent.end : e.type === 'dragstop' ? start + parent.length - 1 : Math.floor(ui.helper.outerWidth(true) * scale) + start;
116
+ const scale = karyotype.chromosomeSize / karyotype.width;
117
+ const axis = e.type === 'resizestop' ? jQuery(this).data('ui-resizable').axis : undefined;
118
+ const start = axis === 'e' ? parent.start : Math.max(Math.floor(ui.position.left * scale), 1);
119
+ const end = axis === 'w' ? parent.end : e.type === 'dragstop' ? start + parent.length - 1 : Math.floor(ui.helper.outerWidth(true) * scale) + start;
114
120
 
115
121
  if (start !== parent.start || end !== parent.end) {
116
122
  parent.moveTo(karyotype.chr, start, end, true, e.type === 'dragstop');
@@ -119,19 +125,19 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
119
125
 
120
126
  if (pluginConf.karyotypeLabel === false) {
121
127
  this.labelContainer.remove();
122
- this.labelContainer = $();
128
+ this.labelContainer = jQuery();
123
129
  container.addClass('gv-no-label');
124
130
  } else {
125
131
  this.labelContainer.width(labelWidth);
126
132
  }
127
133
 
128
- this.viewPoint = $('<div class="gv-karyotype-viewpoint-wrapper"><div class="gv-karyotype-viewpoint"></div></div>').appendTo(container).css({
134
+ this.viewPoint = jQuery('<div class="gv-karyotype-viewpoint-wrapper"><div class="gv-karyotype-viewpoint"></div></div>').appendTo(container).css({
129
135
  left : labelWidth,
130
- width : this.width - labelWidth
136
+ width : this.width - labelWidth,
131
137
  }).children().on({
132
- mousemove : function (e) { karyotype.track.controller.click(e); },
133
- mouseout : function (e) {
134
- var el = $(e.relatedTarget);
138
+ mousemove : (e) => { karyotype.track.controller.click(e); },
139
+ mouseout : (e) => {
140
+ const el = jQuery(e.relatedTarget);
135
141
 
136
142
  if (karyotype.viewPoint.is(el) || karyotype.viewPoint.find(el).length || (el.prop('nodeName') === 'IMG' && el.parent().is(karyotype.track.prop('imgContainers')[0]))) {
137
143
  return true;
@@ -139,7 +145,7 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
139
145
 
140
146
  karyotype.track.prop('container').tipsy('hide');
141
147
  karyotype.track.prop('hoverFeature', false);
142
- }
148
+ },
143
149
  });
144
150
 
145
151
  if (!parent.isStatic) {
@@ -147,7 +153,7 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
147
153
  axis : 'x',
148
154
  containment : this.wrapper,
149
155
  start : hideTooltip,
150
- stop : updateLocation
156
+ stop : updateLocation,
151
157
  }).resizable({
152
158
  handles : 'e, w',
153
159
  containment : 'parent',
@@ -161,28 +167,26 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
161
167
  } else {
162
168
  ui.element.width(ui.size.width + ui.position.left);
163
169
  }
164
- }
170
+ },
165
171
  });
166
172
  }
167
173
  },
168
174
 
169
175
  updatePosition: function () {
170
- var left = this.parent.start * this.scale;
171
- var width = (this.parent.end * this.scale) - left;
176
+ const left = this.parent.start * this.scale;
177
+ const width = (this.parent.end * this.scale) - left;
172
178
 
173
179
  this.viewPoint.css({ left: left, width: width });
174
- }
180
+ },
175
181
  });
176
182
 
177
183
  if (this.loadedPlugins.controlPanel !== true) {
178
- $('<li class="gv-unsortable">').height(function (i, h) {
179
- return h + container.height();
180
- }).prependTo(this.labelContainer);
184
+ jQuery('<li class="gv-unsortable">').height((i, h) => h + container.height()).prependTo(this.labelContainer);
181
185
  }
182
186
  }
183
187
 
184
188
  function recreateKaryotype() {
185
- var container = this.karyotype.container.parent();
189
+ const container = this.karyotype.container.parent();
186
190
 
187
191
  this.karyotype.destroy();
188
192
  container.remove();
@@ -205,6 +209,8 @@ Genoverse.Plugins.karyotype = function (pluginConf) {
205
209
  if (this.karyotype && this.karyotype.chr !== chr) {
206
210
  recreateKaryotype.call(this);
207
211
  }
208
- }
212
+ },
209
213
  });
210
214
  };
215
+
216
+ export default { karyotype: plugin };
@@ -0,0 +1,52 @@
1
+ import '../../css/resizer.css';
2
+
3
+ const plugin = function () {
4
+ const jQuery = this.jQuery;
5
+
6
+ this.on('afterSetMVC', 'tracks', function () {
7
+ if (this.prop('resizable') !== true) {
8
+ return;
9
+ }
10
+
11
+ const track = this;
12
+ const controller = this.controller;
13
+ const height = this.prop('height');
14
+
15
+ let resizer = this.prop('resizer');
16
+
17
+ if (!resizer) {
18
+ resizer = this.prop('resizer', jQuery('<div class="gv-resizer gv-static"><div class="gv-handle"></div></div>').appendTo(track.prop('container')).draggable({
19
+ axis : 'y',
20
+ start : () => { jQuery('body').addClass('gv-dragging'); },
21
+ stop : function (e, ui) {
22
+ jQuery('body').removeClass('gv-dragging');
23
+ controller.resize(track.prop('height') + ui.position.top - ui.originalPosition.top, true);
24
+ jQuery(this).css({ top: 'auto', bottom: 0 }); // returns the resizer to the bottom of the container - needed when the track is resized to 0
25
+ },
26
+ }).on('click', () => {
27
+ const h = track.prop('fullVisibleHeight');
28
+
29
+ if (h) {
30
+ controller.resize(h, true);
31
+ }
32
+ }));
33
+ }
34
+
35
+ resizer.css({ width: this.width, left: 0 })[this.prop('autoHeight') ? 'hide' : 'show']();
36
+
37
+ if (!this.prop('autoHeight') && height - this.prop('margin') === this.prop('featureHeight')) {
38
+ controller.resize(height + resizer.height());
39
+ this.prop('initialHeight', this.prop('height'));
40
+ }
41
+ });
42
+
43
+ this.on('afterToggleExpander', 'tracks', function () {
44
+ const resizer = this.prop('resizer');
45
+
46
+ if (resizer) {
47
+ resizer[this.expander?.is(':visible') ? 'addClass' : 'removeClass']('gv-resizer-expander');
48
+ }
49
+ });
50
+ };
51
+
52
+ export default { resizer: plugin };
@@ -3,22 +3,26 @@
3
3
  // (c) 2008-2010 jason frame [jason@onehackoranother.com]
4
4
  // released under the MIT license
5
5
 
6
- Genoverse.Plugins.tooltips = function () {
7
- var genoverse = this;
6
+ import '../../css/tooltips.css';
7
+ import controlPanel from './controlPanel';
8
+
9
+ const plugin = function () {
10
+ const genoverse = this;
11
+ const jQuery = this.jQuery;
8
12
 
9
13
  function toggleTooltips(browser, tooltips, action) {
10
- var offset = browser.superContainer.offset();
14
+ const offset = browser.superContainer.offset();
11
15
 
12
16
  tooltips = tooltips || browser.superContainer.find('.gv-tooltip');
13
- action = action || $(this).toggleClass('gv-active').hasClass('gv-active') ? 'show' : 'hide';
17
+ action = action || jQuery(this).toggleClass('gv-active').hasClass('gv-active') ? 'show' : 'hide';
14
18
 
15
19
  tooltips.each(function () {
16
- var el = $(this);
20
+ const el = jQuery(this);
17
21
 
18
22
  if (el.is(':visible')) {
19
23
  el.tipsy(action).data('tipsy').$tip.data({ parent: el }).appendTo(browser.superContainer).css({
20
24
  marginTop : -offset.top,
21
- marginLeft : -offset.left
25
+ marginLeft : -offset.left,
22
26
  });
23
27
  } else if (el.data('tipsy').$tip) {
24
28
  el.tipsy('hide');
@@ -27,25 +31,28 @@ Genoverse.Plugins.tooltips = function () {
27
31
  }
28
32
 
29
33
  function updateTooltips() {
30
- var tooltips = $();
34
+ let tooltips = jQuery();
31
35
 
32
- $.each([
36
+ [
33
37
  [ genoverse.labelContainer.find('.gv-handle'), { gravity: 'w', fade: true, trigger: 'manual', fallback: 'Reorder tracks by dragging this handle' }],
34
- [ genoverse.container.find('.gv-resizer'), { gravity: 'n', fade: true, trigger: 'manual', fallback: 'Resize track by dragging this handle' }]
35
- ], function () {
36
- var el = this[0].filter(':visible').first();
38
+ [ genoverse.container.find('.gv-resizer'), { gravity: 'n', fade: true, trigger: 'manual', fallback: 'Resize track by dragging this handle' }],
39
+ ].forEach(
40
+ ([ selector, options ]) => {
41
+ const el = selector.filter(':visible').first();
37
42
 
38
- if (!el.hasClass('gv-tooltip')) {
39
- this[0].filter('.gv-tooltip').removeClass('gv-tooltip').tipsy('hide').removeData('tipsy');
40
- el.tipsy(this[1]).addClass('gv-tooltip');
41
- }
43
+ if (!el.hasClass('gv-tooltip')) {
44
+ selector.filter('.gv-tooltip').removeClass('gv-tooltip').tipsy('hide').removeData('tipsy');
45
+ el.tipsy(options).addClass('gv-tooltip');
46
+ }
42
47
 
43
- tooltips = tooltips.add(el);
44
- });
48
+ tooltips = tooltips.add(el);
49
+ }
50
+ );
45
51
 
46
52
  // Remove any tooltips orphaned by the removal of a track
47
53
  genoverse.superContainer.find('.tipsy').not(function () {
48
- var parent = $(this).data('parent');
54
+ const parent = jQuery(this).data('parent');
55
+
49
56
  return parent && genoverse.superContainer.find(parent).length;
50
57
  }).remove();
51
58
 
@@ -60,7 +67,7 @@ Genoverse.Plugins.tooltips = function () {
60
67
  icon : '<i class="fas fa-question-circle"></i>',
61
68
  class : 'gv-tooltips',
62
69
  name : 'Tooltips',
63
- action : toggleTooltips
70
+ action : toggleTooltips,
64
71
  });
65
72
 
66
73
  this.on('afterInit', function () {
@@ -68,11 +75,11 @@ Genoverse.Plugins.tooltips = function () {
68
75
  this.superContainer.find('.gv-panel-right .gv-button-set[title]').tipsy({ gravity: 'e', fade: true, trigger: 'manual' }).addClass('gv-tooltip');
69
76
 
70
77
  // In order to force placement of this tooltip to be inside the superContainer boundaries, and just below the karyotype, create a hidden element, positioned where we want the tooltip to appear
71
- $('<i class="gv-wrapper-tooltip">').prependTo(this.wrapper).tipsy({
78
+ jQuery('<i class="gv-wrapper-tooltip">').prependTo(this.wrapper).tipsy({
72
79
  gravity : 's',
73
80
  fade : true,
74
81
  trigger : 'manual',
75
- fallback : 'Scroll left and right by dragging with your mouse, click on any feature in any track for more info'
82
+ fallback : 'Scroll left and right by dragging with your mouse, click on any feature in any track for more info',
76
83
  }).addClass('gv-tooltip');
77
84
 
78
85
  updateTooltips();
@@ -82,13 +89,8 @@ Genoverse.Plugins.tooltips = function () {
82
89
  this.controlPanel.find('.gv-tooltips.gv-active').trigger('click');
83
90
  });
84
91
 
85
- this.on('afterSortTracks', function () {
86
- updateTooltips();
87
- });
88
-
89
- this.on('afterResize', 'tracks', function () {
90
- updateTooltips();
91
- });
92
+ this.on('afterSortTracks', () => { updateTooltips(); });
93
+ this.on('afterResize', 'tracks', () => { updateTooltips(); });
92
94
  };
93
95
 
94
- Genoverse.Plugins.tooltips.requires = 'controlPanel';
96
+ export default { tooltips: plugin, requires: controlPanel };
@@ -0,0 +1,159 @@
1
+ import '../../css/trackControls.css';
2
+
3
+ const plugin = function () {
4
+ const jQuery = this.jQuery;
5
+ const defaultControls = [
6
+ jQuery('<a title="More info" class="fas fa-question-circle">').on('click', function () {
7
+ const track = jQuery(this).data('track');
8
+
9
+ let menu = track.prop('menus').filter('.gv-track-info');
10
+
11
+ if (!menu.length) {
12
+ const info = track.prop('info');
13
+
14
+ menu = track.prop(
15
+ 'menus',
16
+ track.prop('menus').add(
17
+ track.browser.makeMenu({
18
+ title : track.name,
19
+ [typeof info === 'function' ? info.call(track) : info || ''] : '',
20
+ }).addClass('gv-track-info')
21
+ )
22
+ );
23
+ }
24
+
25
+ menu.show().position({ of: track.prop('container'), at: 'center top', my: 'center top', collision: 'none' });
26
+ }),
27
+
28
+ jQuery(`
29
+ <a class="gv-height-toggle">
30
+ <i class="fas fa-sort"></i>
31
+ <i class="fas fa-sort-down"></i>
32
+ <i class="fas fa-sort-up"></i>
33
+ </a>
34
+ `).on({
35
+ click: function () {
36
+ const track = jQuery(this).data('track');
37
+
38
+ let height;
39
+
40
+ if (track.prop('autoHeight', !track.prop('autoHeight'))) {
41
+ track.prop('heightBeforeToggle', track.prop('height'));
42
+ height = track.prop('fullVisibleHeight');
43
+ } else {
44
+ height = track.prop('heightBeforeToggle') || track.prop('initialHeight');
45
+ }
46
+
47
+ jQuery(this).trigger('toggleState');
48
+
49
+ track.controller.resize(height, true);
50
+ },
51
+ toggleState: function () { // custom event to set title and change the icon
52
+ const track = jQuery(this).data('track');
53
+ const autoHeight = track.prop('autoHeight');
54
+ const resizer = track.prop('resizer');
55
+
56
+ this.title = autoHeight ? 'Set track to fixed height' : 'Set track to auto-adjust height';
57
+
58
+ jQuery(this)[autoHeight ? 'addClass' : 'removeClass']('gv-auto-height');
59
+
60
+ if (resizer) {
61
+ resizer[autoHeight ? 'hide' : 'show']();
62
+ }
63
+ },
64
+ }),
65
+ ];
66
+
67
+ const remove = jQuery('<a title="Remove track" class="far fa-trash-alt">').on('click', function () {
68
+ jQuery(this).data('track').remove();
69
+ });
70
+
71
+ const toggle = jQuery(`
72
+ <a class="gv-track-controls-toggle">
73
+ <span><i class="fas fa-angle-double-left"></i><i class="fas fa-cog"></i></span>
74
+ <span><i class="fas fa-angle-double-right"></i></span>
75
+ </a>
76
+ `).on('click', function () {
77
+ jQuery(this).parent().toggleClass('gv-maximized');
78
+ });
79
+
80
+ this.on({
81
+ afterAddDomElements: function () {
82
+ let controls = this.prop('controls');
83
+
84
+ if (controls === 'off') {
85
+ return;
86
+ }
87
+
88
+ const defaultConfig = this.prop('defaultConfig');
89
+ const savedConfig = this.browser.savedConfig?.[this.prop('id')] || {};
90
+
91
+ controls = (controls || []).concat(defaultControls, this.prop('removable') === false ? [] : remove);
92
+
93
+ this.trackControls = jQuery('<div class="gv-track-controls">').prependTo(this.container);
94
+
95
+ const controlsContainer = jQuery('<div class="gv-track-controls-container">').appendTo(this.trackControls);
96
+
97
+ controls.forEach(
98
+ (control) => {
99
+ let el;
100
+
101
+ if (jQuery.isPlainObject(control) && control.type) {
102
+ el = jQuery(`<${control.type}>`).data('control', control.name);
103
+
104
+ (control.options || []).forEach(
105
+ option => el.append(`<option value="${option.value}">${option.text}</option>`)
106
+ );
107
+ } else if (typeof control === 'string') {
108
+ el = jQuery(control);
109
+ } else if (typeof control === 'object' && control.constructor && control instanceof jQuery) {
110
+ el = control.clone(true);
111
+ }
112
+
113
+ el.data('track', this.track).appendTo(controlsContainer);
114
+
115
+ // TODO: other control types
116
+ if (el.is('select')) {
117
+ const prop = el.data('control');
118
+
119
+ el.find(`option[value=${savedConfig[prop] || defaultConfig[prop] || 'all'}]`).attr('selected', true).end().change(function () {
120
+ jQuery(this).data('track').setConfig(jQuery(this).data('control'), this.value);
121
+ });
122
+ }
123
+ }
124
+ );
125
+
126
+ this.prop('heightToggler', controlsContainer.children('.gv-height-toggle').trigger('toggleState'));
127
+
128
+ const toggler = toggle.clone(true).data('track', this.track).appendTo(this.trackControls);
129
+
130
+ toggler.trigger('click');
131
+
132
+ this.minLabelHeight = Math.max(this.minLabelHeight, this.trackControls.outerHeight(true) + this.prop('margin'));
133
+
134
+ toggler.trigger('click');
135
+ },
136
+ afterResize: function () {
137
+ if (this.trackControls) {
138
+ this.trackControls[this.prop('height') < this.trackControls.outerHeight(true) ? 'hide' : 'show']();
139
+ }
140
+ },
141
+ afterResetHeight: function () {
142
+ const heightToggler = this.prop('heightToggler');
143
+
144
+ if (this.prop('resizable') === true && heightToggler) {
145
+ heightToggler[this.prop('autoHeight') ? 'addClass' : 'removeClass']('gv-auto-height');
146
+ heightToggler.trigger('toggleState');
147
+ }
148
+ },
149
+ afterSetMVC: function () {
150
+ const heightToggler = this.prop('heightToggler');
151
+
152
+ if (heightToggler) {
153
+ heightToggler.trigger('toggleState')[this.prop('resizable') === true ? 'removeClass' : 'addClass']('gv-hide');
154
+ }
155
+ },
156
+ }, 'tracks');
157
+ };
158
+
159
+ export default { trackControls: plugin };
@@ -8,7 +8,7 @@ describe('Correctly render legends:', () => {
8
8
  margin : 0,
9
9
  featureHeight : 10,
10
10
  featureMargin : {},
11
- legend : true,
11
+ legend : Genoverse.Track.Legend,
12
12
  };
13
13
 
14
14
  it('multiple feature types', () => testTrackRenderStatic(
@@ -1,5 +1,5 @@
1
- const css = require('fs').readFileSync('css/genoverse.css', 'utf8');
2
- const { Genoverse, afterTest } = require('./utils');
1
+ const css = require('fs').readFileSync('src/css/genoverse.css', 'utf8');
2
+ const { $, Genoverse, afterTest } = require('./utils');
3
3
 
4
4
  const html = `<style>${css}</style><div id="genoverse-test-1"></div><div id="genoverse-test-2"></div><div id="genoverse-test-3"></div>`;
5
5
 
@@ -1,4 +1,4 @@
1
- const { Genoverse, afterTest } = require('./utils');
1
+ const { $, Genoverse, afterTest } = require('./utils');
2
2
 
3
3
  // TODO: unsortable, particularly with unsortable order=9e99, then adding another track
4
4
 
@@ -22,6 +22,7 @@ describe('Track ordering', () => {
22
22
  tracks : tracks.map(t => Genoverse.Track.extend({ url: false, ...t })),
23
23
  _initDeferred : $.Deferred(),
24
24
  saveConfig : () => {},
25
+ loadCSS : () => {},
25
26
  loadGenome : () => {},
26
27
  loadPlugins : () => {},
27
28
  });
@@ -107,7 +108,7 @@ describe('Track ordering', () => {
107
108
 
108
109
  const legendTrack = (id, legendConf) => ({
109
110
  id : id,
110
- legend : legendConf ? Genoverse.Track.Legend.extend(legendConf) : true,
111
+ legend : legendConf ? Genoverse.Track.Legend.extend(legendConf) : Genoverse.Track.Legend,
111
112
  });
112
113
 
113
114
  describe('Simple tracks', () => {
@@ -1,4 +1,4 @@
1
- const { Genoverse, afterTest } = require('../utils');
1
+ const { $, Genoverse, afterTest } = require('../utils');
2
2
 
3
3
  describe('Config settings', () => {
4
4
  afterEach(afterTest);
package/test/utils.js CHANGED
@@ -1,6 +1,7 @@
1
- require('../index'); // Genoverse library
1
+ const Genoverse = require('../src/js/Genoverse').default;
2
+ const $ = require('../src/js/lib/jquery').default;
2
3
 
3
- Genoverse.ready.resolve();
4
+ Genoverse.configure({ css: false, fontawesome: false });
4
5
 
5
6
  const getTrackConfig = features => ({
6
7
  data: features,
@@ -73,6 +74,7 @@ const afterTest = () => {
73
74
  };
74
75
 
75
76
  module.exports = {
77
+ $,
76
78
  Genoverse,
77
79
  testTrackRender,
78
80
  testTrackRenderStatic,