genoverse 3.2.0

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 (148) hide show
  1. package/.eslintrc.js +197 -0
  2. package/.github/workflows/test.yml +24 -0
  3. package/LICENSE.TXT +24 -0
  4. package/README.md +11 -0
  5. package/css/controlPanel.css +200 -0
  6. package/css/fileDrop.css +22 -0
  7. package/css/font-awesome.css +3 -0
  8. package/css/fullscreen.css +19 -0
  9. package/css/genoverse.css +466 -0
  10. package/css/karyotype.css +85 -0
  11. package/css/resizer.css +36 -0
  12. package/css/tooltips.css +26 -0
  13. package/css/trackControls.css +111 -0
  14. package/expanded.html +120 -0
  15. package/fontawesome/css/fontawesome.min.css +5 -0
  16. package/fontawesome/css/regular.min.css +5 -0
  17. package/fontawesome/css/solid.min.css +5 -0
  18. package/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  19. package/fontawesome/webfonts/fa-brands-400.woff +0 -0
  20. package/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  21. package/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  22. package/fontawesome/webfonts/fa-regular-400.woff +0 -0
  23. package/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  24. package/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  25. package/fontawesome/webfonts/fa-solid-900.woff +0 -0
  26. package/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  27. package/help.pdf +0 -0
  28. package/i/sort_handle.png +0 -0
  29. package/index.html +68 -0
  30. package/index.js +83 -0
  31. package/jest.config.js +4 -0
  32. package/js/Genoverse.js +1681 -0
  33. package/js/Track/Controller/Sequence.js +17 -0
  34. package/js/Track/Controller/Stranded.js +73 -0
  35. package/js/Track/Controller.js +620 -0
  36. package/js/Track/Model/File/BAM.js +44 -0
  37. package/js/Track/Model/File/BED.js +116 -0
  38. package/js/Track/Model/File/GFF.js +40 -0
  39. package/js/Track/Model/File/VCF.js +101 -0
  40. package/js/Track/Model/File/WIG.js +67 -0
  41. package/js/Track/Model/File.js +36 -0
  42. package/js/Track/Model/Gene/Ensembl.js +22 -0
  43. package/js/Track/Model/Gene.js +5 -0
  44. package/js/Track/Model/Sequence/Ensembl.js +4 -0
  45. package/js/Track/Model/Sequence/Fasta.js +60 -0
  46. package/js/Track/Model/Sequence.js +50 -0
  47. package/js/Track/Model/SequenceVariation.js +41 -0
  48. package/js/Track/Model/Stranded.js +28 -0
  49. package/js/Track/Model/Transcript/Ensembl.js +67 -0
  50. package/js/Track/Model/Transcript.js +5 -0
  51. package/js/Track/Model.js +303 -0
  52. package/js/Track/View/Gene/Ensembl.js +46 -0
  53. package/js/Track/View/Gene.js +6 -0
  54. package/js/Track/View/Sequence/Variation.js +115 -0
  55. package/js/Track/View/Sequence.js +63 -0
  56. package/js/Track/View/Transcript/Ensembl.js +12 -0
  57. package/js/Track/View/Transcript.js +28 -0
  58. package/js/Track/View.js +566 -0
  59. package/js/Track/library/Chromosome.js +145 -0
  60. package/js/Track/library/File/BAM.js +30 -0
  61. package/js/Track/library/File/BED.js +24 -0
  62. package/js/Track/library/File/BIGBED.js +47 -0
  63. package/js/Track/library/File/BIGWIG.js +52 -0
  64. package/js/Track/library/File/GFF.js +9 -0
  65. package/js/Track/library/File/VCF.js +71 -0
  66. package/js/Track/library/File/WIG.js +5 -0
  67. package/js/Track/library/File.js +10 -0
  68. package/js/Track/library/Gene.js +37 -0
  69. package/js/Track/library/Graph/Bar.js +235 -0
  70. package/js/Track/library/Graph/Line.js +296 -0
  71. package/js/Track/library/Graph.js +355 -0
  72. package/js/Track/library/HighlightRegion.js +292 -0
  73. package/js/Track/library/Legend.js +224 -0
  74. package/js/Track/library/Scalebar.js +227 -0
  75. package/js/Track/library/Scaleline.js +91 -0
  76. package/js/Track/library/Static.js +78 -0
  77. package/js/Track/library/dbSNP.js +142 -0
  78. package/js/Track.js +632 -0
  79. package/js/genomes/grch37.js +990 -0
  80. package/js/genomes/grch38.js +990 -0
  81. package/js/genoverse.min.js +2 -0
  82. package/js/genoverse.min.js.map +1 -0
  83. package/js/lib/BWReader.js +578 -0
  84. package/js/lib/Base.js +145 -0
  85. package/js/lib/VCFReader.js +286 -0
  86. package/js/lib/dalliance/js/bam.js +494 -0
  87. package/js/lib/dalliance/js/bin.js +185 -0
  88. package/js/lib/dalliance/js/das.js +749 -0
  89. package/js/lib/dalliance/js/utils.js +370 -0
  90. package/js/lib/dalliance-lib.js +3594 -0
  91. package/js/lib/dalliance-lib.min.js +68 -0
  92. package/js/lib/jDataView.js +2 -0
  93. package/js/lib/jParser.js +192 -0
  94. package/js/lib/jquery-ui.js +8 -0
  95. package/js/lib/jquery.js +2 -0
  96. package/js/lib/jquery.mousehold.js +53 -0
  97. package/js/lib/jquery.mousewheel.js +84 -0
  98. package/js/lib/jquery.tipsy.js +258 -0
  99. package/js/lib/rtree.js +1 -0
  100. package/js/plugins/controlPanel.js +395 -0
  101. package/js/plugins/fileDrop.js +62 -0
  102. package/js/plugins/focusRegion.js +12 -0
  103. package/js/plugins/fullscreen.js +77 -0
  104. package/js/plugins/karyotype.js +210 -0
  105. package/js/plugins/resizer.js +45 -0
  106. package/js/plugins/tooltips.js +94 -0
  107. package/js/plugins/trackControls.js +143 -0
  108. package/package.json +43 -0
  109. package/test/View/__snapshots__/render-bar-graph.test.js.snap +111 -0
  110. package/test/View/__snapshots__/render-blocks.test.js.snap +105 -0
  111. package/test/View/__snapshots__/render-chromosome.test.js.snap +5 -0
  112. package/test/View/__snapshots__/render-highlights.test.js.snap +73 -0
  113. package/test/View/__snapshots__/render-insert-variants.test.js.snap +9 -0
  114. package/test/View/__snapshots__/render-labels.test.js.snap +241 -0
  115. package/test/View/__snapshots__/render-legends.test.js.snap +13 -0
  116. package/test/View/__snapshots__/render-line-graph.test.js.snap +349 -0
  117. package/test/View/__snapshots__/render-scalebar.test.js.snap +49 -0
  118. package/test/View/__snapshots__/render-scaleline.test.js.snap +31 -0
  119. package/test/View/__snapshots__/render-sequence.test.js.snap +23 -0
  120. package/test/View/__snapshots__/render-stranded.test.js.snap +5 -0
  121. package/test/View/__snapshots__/render-transcripts.test.js.snap +193 -0
  122. package/test/View/render-bar-graph.test.js +87 -0
  123. package/test/View/render-blocks.test.js +171 -0
  124. package/test/View/render-chromosome.test.js +40 -0
  125. package/test/View/render-highlights.test.js +67 -0
  126. package/test/View/render-insert-variants.test.js +11 -0
  127. package/test/View/render-labels.test.js +266 -0
  128. package/test/View/render-legends.test.js +31 -0
  129. package/test/View/render-line-graph.test.js +169 -0
  130. package/test/View/render-scalebar.test.js +36 -0
  131. package/test/View/render-scaleline.test.js +28 -0
  132. package/test/View/render-sequence.test.js +49 -0
  133. package/test/View/render-stranded.test.js +10 -0
  134. package/test/View/render-transcripts.test.js +165 -0
  135. package/test/create-and-destroy.test.js +63 -0
  136. package/test/track-ordering.test.js +514 -0
  137. package/test/track_config/__snapshots__/config-settings.test.js.snap +23 -0
  138. package/test/track_config/config-settings.test.js +321 -0
  139. package/test/track_config/zoom-level-settings.test.js +98 -0
  140. package/test/utils.js +80 -0
  141. package/utils/createGenome.js +52 -0
  142. package/utils/devServer.js +36 -0
  143. package/utils/expandedTemplate.html +46 -0
  144. package/utils/git-hooks/post-commit +9 -0
  145. package/utils/git-hooks/pre-commit +7 -0
  146. package/utils/git-hooks/setup +6 -0
  147. package/utils/makeExpanded.js +19 -0
  148. package/webpack.config.js +39 -0
@@ -0,0 +1,210 @@
1
+ Genoverse.Plugins.karyotype = function (pluginConf) {
2
+ 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;
7
+
8
+ if (pluginConf.showAssembly && assemblyName) {
9
+ container.addClass('gv-show-assembly');
10
+ }
11
+
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;
14
+
15
+ measureWidth.remove();
16
+
17
+ this.karyotype = new Genoverse({
18
+ parent : this,
19
+ container : chromosome,
20
+ width : chromosome.width(),
21
+ genome : this.genome,
22
+ chr : this.chr,
23
+ start : 1,
24
+ end : this.chromosomeSize,
25
+ isStatic : true,
26
+ tracks : [
27
+ Genoverse.Track.Chromosome.extend({
28
+ name : name,
29
+ height : 20,
30
+ featureHeight : 20,
31
+ border : false,
32
+ legend : false,
33
+ unsortable : true,
34
+
35
+ 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];
39
+
40
+ if (f) {
41
+ if (e.type === 'mouseup') {
42
+ if (!this.browser.parent.isStatic) {
43
+ this.browser.parent.moveTo(f.chr, f.start, f.end, true);
44
+ }
45
+ } else if (this.hoverFeature !== f && !this.browser.hideTooltip) {
46
+ this.container.tipsy('hide');
47
+
48
+ 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; });
51
+ }
52
+
53
+ this.hoverFeature = f;
54
+ }
55
+ }
56
+ },
57
+
58
+ addUserEventHandlers: function () {
59
+ var track = this;
60
+
61
+ this.base();
62
+
63
+ this.container.on({
64
+ mousemove : function (e) { track.click(e); },
65
+ mouseout : function (e) {
66
+ if (track.browser.viewPoint.is(e.relatedTarget) || track.browser.viewPoint.find(e.relatedTarget).length) {
67
+ return true;
68
+ }
69
+
70
+ track.container.tipsy('hide');
71
+ track.hoverFeature = false;
72
+ }
73
+ }, '.gv-image-container');
74
+
75
+ // Don't allow zooming in and out on the karyotype image
76
+ this.container.on('mousewheel', '.gv-image-container, .gv-selector', function (e) {
77
+ e.stopPropagation();
78
+ });
79
+ },
80
+
81
+ afterSetName: function () {
82
+ this.label.css('lineHeight', this.label.height() + 'px');
83
+ }
84
+ })
85
+ ],
86
+
87
+ addUserEventHandlers: $.noop,
88
+
89
+ afterInit: function () {
90
+ this.updatePosition();
91
+ this.viewPoint.fadeIn();
92
+ },
93
+
94
+ afterAddTracks: function () {
95
+ this.track = this.tracks[0];
96
+ },
97
+
98
+ afterAddDomElements: function () {
99
+ var karyotype = this;
100
+ var parent = this.parent;
101
+
102
+ function hideTooltip() {
103
+ karyotype.hideTooltip = true;
104
+ karyotype.track.prop('container').tipsy('hide');
105
+ }
106
+
107
+ function updateLocation(e, ui) {
108
+ karyotype.hideTooltip = false;
109
+
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;
114
+
115
+ if (start !== parent.start || end !== parent.end) {
116
+ parent.moveTo(karyotype.chr, start, end, true, e.type === 'dragstop');
117
+ }
118
+ }
119
+
120
+ if (pluginConf.karyotypeLabel === false) {
121
+ this.labelContainer.remove();
122
+ this.labelContainer = $();
123
+ container.addClass('gv-no-label');
124
+ } else {
125
+ this.labelContainer.width(labelWidth);
126
+ }
127
+
128
+ this.viewPoint = $('<div class="gv-karyotype-viewpoint-wrapper"><div class="gv-karyotype-viewpoint"></div></div>').appendTo(container).css({
129
+ left : labelWidth,
130
+ width : this.width - labelWidth
131
+ }).children().on({
132
+ mousemove : function (e) { karyotype.track.controller.click(e); },
133
+ mouseout : function (e) {
134
+ var el = $(e.relatedTarget);
135
+
136
+ if (karyotype.viewPoint.is(el) || karyotype.viewPoint.find(el).length || (el.prop('nodeName') === 'IMG' && el.parent().is(karyotype.track.prop('imgContainers')[0]))) {
137
+ return true;
138
+ }
139
+
140
+ karyotype.track.prop('container').tipsy('hide');
141
+ karyotype.track.prop('hoverFeature', false);
142
+ }
143
+ });
144
+
145
+ if (!parent.isStatic) {
146
+ this.viewPoint.draggable({
147
+ axis : 'x',
148
+ containment : this.wrapper,
149
+ start : hideTooltip,
150
+ stop : updateLocation
151
+ }).resizable({
152
+ handles : 'e, w',
153
+ containment : 'parent',
154
+ start : hideTooltip,
155
+ stop : updateLocation,
156
+ resize : function (e, ui) {
157
+ ui.element.css('left', Math.max(0, ui.position.left));
158
+
159
+ if (ui.position.left > 0) {
160
+ ui.element.width(Math.min(ui.size.width, ui.element.parent().width() - ui.position.left));
161
+ } else {
162
+ ui.element.width(ui.size.width + ui.position.left);
163
+ }
164
+ }
165
+ });
166
+ }
167
+ },
168
+
169
+ updatePosition: function () {
170
+ var left = this.parent.start * this.scale;
171
+ var width = (this.parent.end * this.scale) - left;
172
+
173
+ this.viewPoint.css({ left: left, width: width });
174
+ }
175
+ });
176
+
177
+ if (this.loadedPlugins.controlPanel !== true) {
178
+ $('<li class="gv-unsortable">').height(function (i, h) {
179
+ return h + container.height();
180
+ }).prependTo(this.labelContainer);
181
+ }
182
+ }
183
+
184
+ function recreateKaryotype() {
185
+ var container = this.karyotype.container.parent();
186
+
187
+ this.karyotype.destroy();
188
+ container.remove();
189
+
190
+ createKaryotype.call(this);
191
+ }
192
+
193
+ this.on({
194
+ afterInit: createKaryotype,
195
+
196
+ afterSetRange: function () {
197
+ if (this.karyotype) {
198
+ this.karyotype.updatePosition();
199
+ }
200
+ },
201
+
202
+ afterSetWidth: recreateKaryotype,
203
+
204
+ afterMoveTo: function (chr) {
205
+ if (this.karyotype && this.karyotype.chr !== chr) {
206
+ recreateKaryotype.call(this);
207
+ }
208
+ }
209
+ });
210
+ };
@@ -0,0 +1,45 @@
1
+ Genoverse.Plugins.resizer = function () {
2
+ this.on('afterSetMVC', 'tracks', function () {
3
+ if (this.prop('resizable') !== true) {
4
+ return;
5
+ }
6
+
7
+ var track = this;
8
+ var controller = this.controller;
9
+ var resizer = this.prop('resizer');
10
+ var height = this.prop('height');
11
+
12
+ if (!resizer) {
13
+ resizer = this.prop('resizer', $('<div class="gv-resizer gv-static"><div class="gv-handle"></div></div>').appendTo(track.prop('container')).draggable({
14
+ axis : 'y',
15
+ start : function () { $('body').addClass('gv-dragging'); },
16
+ stop : function (e, ui) {
17
+ $('body').removeClass('gv-dragging');
18
+ controller.resize(track.prop('height') + ui.position.top - ui.originalPosition.top, true);
19
+ $(this).css({ top: 'auto', bottom: 0 }); // returns the resizer to the bottom of the container - needed when the track is resized to 0
20
+ }
21
+ }).on('click', function () {
22
+ var h = track.prop('fullVisibleHeight');
23
+
24
+ if (h) {
25
+ controller.resize(h, true);
26
+ }
27
+ }));
28
+ }
29
+
30
+ resizer.css({ width: this.width, left: 0 })[this.prop('autoHeight') ? 'hide' : 'show']();
31
+
32
+ if (!this.prop('autoHeight') && height - this.prop('margin') === this.prop('featureHeight')) {
33
+ controller.resize(height + resizer.height());
34
+ this.prop('initialHeight', this.prop('height'));
35
+ }
36
+ });
37
+
38
+ this.on('afterToggleExpander', 'tracks', function () {
39
+ var resizer = this.prop('resizer');
40
+
41
+ if (resizer) {
42
+ resizer[this.expander && this.expander.is(':visible') ? 'addClass' : 'removeClass']('gv-resizer-expander');
43
+ }
44
+ });
45
+ };
@@ -0,0 +1,94 @@
1
+ // tipsy, facebook style tooltips for jquery
2
+ // version 1.0.0a
3
+ // (c) 2008-2010 jason frame [jason@onehackoranother.com]
4
+ // released under the MIT license
5
+
6
+ Genoverse.Plugins.tooltips = function () {
7
+ var genoverse = this;
8
+
9
+ function toggleTooltips(browser, tooltips, action) {
10
+ var offset = browser.superContainer.offset();
11
+
12
+ tooltips = tooltips || browser.superContainer.find('.gv-tooltip');
13
+ action = action || $(this).toggleClass('gv-active').hasClass('gv-active') ? 'show' : 'hide';
14
+
15
+ tooltips.each(function () {
16
+ var el = $(this);
17
+
18
+ if (el.is(':visible')) {
19
+ el.tipsy(action).data('tipsy').$tip.data({ parent: el }).appendTo(browser.superContainer).css({
20
+ marginTop : -offset.top,
21
+ marginLeft : -offset.left
22
+ });
23
+ } else if (el.data('tipsy').$tip) {
24
+ el.tipsy('hide');
25
+ }
26
+ });
27
+ }
28
+
29
+ function updateTooltips() {
30
+ var tooltips = $();
31
+
32
+ $.each([
33
+ [ 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();
37
+
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
+ }
42
+
43
+ tooltips = tooltips.add(el);
44
+ });
45
+
46
+ // Remove any tooltips orphaned by the removal of a track
47
+ genoverse.superContainer.find('.tipsy').not(function () {
48
+ var parent = $(this).data('parent');
49
+ return parent && genoverse.superContainer.find(parent).length;
50
+ }).remove();
51
+
52
+ if (genoverse.controlPanel.find('.gv-tooltips').hasClass('gv-active')) {
53
+ toggleTooltips(genoverse, tooltips, 'show');
54
+ }
55
+
56
+ return tooltips;
57
+ }
58
+
59
+ this.controls.push({
60
+ icon : '<i class="fas fa-question-circle"></i>',
61
+ class : 'gv-tooltips',
62
+ name : 'Tooltips',
63
+ action : toggleTooltips
64
+ });
65
+
66
+ this.on('afterInit', function () {
67
+ this.superContainer.find('.gv-panel-left .gv-button-set[title]').tipsy({ gravity: 'w', fade: true, trigger: 'manual' }).addClass('gv-tooltip');
68
+ this.superContainer.find('.gv-panel-right .gv-button-set[title]').tipsy({ gravity: 'e', fade: true, trigger: 'manual' }).addClass('gv-tooltip');
69
+
70
+ // 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({
72
+ gravity : 's',
73
+ fade : true,
74
+ trigger : 'manual',
75
+ fallback : 'Scroll left and right by dragging with your mouse, click on any feature in any track for more info'
76
+ }).addClass('gv-tooltip');
77
+
78
+ updateTooltips();
79
+ });
80
+
81
+ this.on('beforeSetWidth', function () {
82
+ this.controlPanel.find('.gv-tooltips.gv-active').trigger('click');
83
+ });
84
+
85
+ this.on('afterSortTracks', function () {
86
+ updateTooltips();
87
+ });
88
+
89
+ this.on('afterResize', 'tracks', function () {
90
+ updateTooltips();
91
+ });
92
+ };
93
+
94
+ Genoverse.Plugins.tooltips.requires = 'controlPanel';
@@ -0,0 +1,143 @@
1
+ Genoverse.Plugins.trackControls = function () {
2
+ var defaultControls = [
3
+ $('<a title="More info" class="fas fa-question-circle">').on('click', function () {
4
+ var track = $(this).data('track');
5
+ var menu = track.prop('menus').filter('.gv-track-info');
6
+
7
+ if (!menu.length) {
8
+ var info = track.prop('info');
9
+
10
+ menu = { title: track.name };
11
+ menu[typeof info === 'function' ? info.call(track) : info || ''] = '';
12
+
13
+ menu = track.prop('menus', track.prop('menus').add(track.browser.makeMenu(menu).addClass('gv-track-info')));
14
+ }
15
+
16
+ menu.show().position({ of: track.prop('container'), at: 'center top', my: 'center top', collision: 'none' });
17
+ }),
18
+
19
+ $(
20
+ '<a class="gv-height-toggle">' +
21
+ '<i class="fas fa-sort"></i>' +
22
+ '<i class="fas fa-sort-down"></i>' +
23
+ '<i class="fas fa-sort-up"></i>' +
24
+ '</a>'
25
+ ).on({
26
+ click: function () {
27
+ var track = $(this).data('track');
28
+ var height;
29
+
30
+ if (track.prop('autoHeight', !track.prop('autoHeight'))) {
31
+ track.prop('heightBeforeToggle', track.prop('height'));
32
+ height = track.prop('fullVisibleHeight');
33
+ } else {
34
+ height = track.prop('heightBeforeToggle') || track.prop('initialHeight');
35
+ }
36
+
37
+ $(this).trigger('toggleState');
38
+
39
+ track.controller.resize(height, true);
40
+ },
41
+ toggleState: function () { // custom event to set title and change the icon
42
+ var track = $(this).data('track');
43
+ var autoHeight = track.prop('autoHeight');
44
+ var resizer = track.prop('resizer');
45
+
46
+ this.title = autoHeight ? 'Set track to fixed height' : 'Set track to auto-adjust height';
47
+ $(this)[autoHeight ? 'addClass' : 'removeClass']('gv-auto-height');
48
+
49
+ if (resizer) {
50
+ resizer[autoHeight ? 'hide' : 'show']();
51
+ }
52
+ }
53
+ })
54
+ ];
55
+
56
+ var remove = $('<a title="Remove track" class="far fa-trash-alt">').on('click', function () {
57
+ $(this).data('track').remove();
58
+ });
59
+
60
+ var toggle = $(
61
+ '<a class="gv-track-controls-toggle">' +
62
+ '<span><i class="fas fa-angle-double-left"></i><i class="fas fa-cog"></i></span>' +
63
+ '<span><i class="fas fa-angle-double-right"></i></span>' +
64
+ '</a>'
65
+ ).on('click', function () {
66
+ $(this).parent().toggleClass('gv-maximized');
67
+ });
68
+
69
+ this.on({
70
+ afterAddDomElements: function () {
71
+ var controls = this.prop('controls');
72
+
73
+ if (controls === 'off') {
74
+ return;
75
+ }
76
+
77
+ var defaultConfig = this.prop('defaultConfig');
78
+ var savedConfig = this.browser.savedConfig ? this.browser.savedConfig[this.prop('id')] || {} : {};
79
+ var prop, el, j;
80
+
81
+ controls = (controls || []).concat(defaultControls, this.prop('removable') === false ? [] : remove);
82
+
83
+ this.trackControls = $('<div class="gv-track-controls">').prependTo(this.container);
84
+
85
+ var controlsContainer = $('<div class="gv-track-controls-container">').appendTo(this.trackControls);
86
+
87
+ for (var i = 0; i < controls.length; i++) {
88
+ if ($.isPlainObject(controls[i]) && controls[i].type) {
89
+ el = $('<' + controls[i].type + '>').data('control', controls[i].name);
90
+
91
+ if (controls[i].options) {
92
+ for (j = 0; j < controls[i].options.length; j++) {
93
+ el.append('<option value="' + controls[i].options[j].value + '">' + controls[i].options[j].text + '</option>');
94
+ }
95
+ }
96
+ } else if (typeof controls[i] === 'string') {
97
+ el = $(controls[i]);
98
+ } else if (typeof controls[i] === 'object' && controls[i].constructor && controls[i] instanceof $) {
99
+ el = controls[i].clone(true);
100
+ }
101
+
102
+ el.data('track', this.track).appendTo(controlsContainer);
103
+
104
+ // TODO: other control types
105
+ if (el.is('select')) {
106
+ prop = el.data('control');
107
+
108
+ el.find('option[value=' + (savedConfig[prop] || defaultConfig[prop] || 'all') + ']').attr('selected', true).end().change(function () {
109
+ $(this).data('track').setConfig($(this).data('control'), this.value);
110
+ });
111
+ }
112
+ }
113
+
114
+ this.prop('heightToggler', controlsContainer.children('.gv-height-toggle').trigger('toggleState'));
115
+
116
+ var toggler = toggle.clone(true).data('track', this.track).appendTo(this.trackControls);
117
+
118
+ toggler.trigger('click');
119
+ this.minLabelHeight = Math.max(this.minLabelHeight, this.trackControls.outerHeight(true) + this.prop('margin'));
120
+ toggler.trigger('click');
121
+ },
122
+ afterResize: function () {
123
+ if (this.trackControls) {
124
+ this.trackControls[this.prop('height') < this.trackControls.outerHeight(true) ? 'hide' : 'show']();
125
+ }
126
+ },
127
+ afterResetHeight: function () {
128
+ var heightToggler = this.prop('heightToggler');
129
+
130
+ if (this.prop('resizable') === true && heightToggler) {
131
+ heightToggler[this.prop('autoHeight') ? 'addClass' : 'removeClass']('gv-auto-height');
132
+ heightToggler.trigger('toggleState');
133
+ }
134
+ },
135
+ afterSetMVC: function () {
136
+ var heightToggler = this.prop('heightToggler');
137
+
138
+ if (heightToggler) {
139
+ heightToggler.trigger('toggleState')[this.prop('resizable') === true ? 'removeClass' : 'addClass']('gv-hide');
140
+ }
141
+ }
142
+ }, 'tracks');
143
+ };
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "genoverse",
3
+ "version": "3.2.0",
4
+ "description": "Genoverse is a portable, customizable, back-end independent JavaScript and HTML5 based genome browser which allows the user to explore data in a dynamic and interactive manner.",
5
+ "main": "js/Genoverse.js",
6
+ "directories": {
7
+ "lib": "js",
8
+ "test": "test"
9
+ },
10
+ "scripts": {
11
+ "test": "jest",
12
+ "build": "yarn lint && node utils/makeExpanded.js && webpack",
13
+ "lint": "eslint '**/*.js'",
14
+ "server": "node utils/devServer.js"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/wtsi-web/Genoverse.git"
19
+ },
20
+ "author": "Simon Brent",
21
+ "license": "BSD-3-Clause",
22
+ "bugs": {
23
+ "url": "https://github.com/wtsi-web/Genoverse/issues"
24
+ },
25
+ "homepage": "https://wtsi-web.github.io/Genoverse/",
26
+ "devDependencies": {
27
+ "@babel/core": "^7.16.7",
28
+ "@babel/eslint-parser": "^7.16.5",
29
+ "@babel/runtime-corejs3": "^7.16.7",
30
+ "canvas": "^2.8.0",
31
+ "core-js": "^3.20.2",
32
+ "eslint": "^8.6.0",
33
+ "eslint-config-airbnb-base": "^15.0.0",
34
+ "eslint-plugin-align-assignments": "^1.1.2",
35
+ "eslint-plugin-es": "^4.1.0",
36
+ "eslint-plugin-import": "^2.25.4",
37
+ "jest": "^27.4.7",
38
+ "terser-webpack-plugin": "^5.3.0",
39
+ "webpack": "^5.65.0",
40
+ "webpack-cli": "^4.9.1"
41
+ },
42
+ "dependencies": {}
43
+ }