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.
- package/.eslintrc.js +197 -0
- package/.github/workflows/test.yml +24 -0
- package/LICENSE.TXT +24 -0
- package/README.md +11 -0
- package/css/controlPanel.css +200 -0
- package/css/fileDrop.css +22 -0
- package/css/font-awesome.css +3 -0
- package/css/fullscreen.css +19 -0
- package/css/genoverse.css +466 -0
- package/css/karyotype.css +85 -0
- package/css/resizer.css +36 -0
- package/css/tooltips.css +26 -0
- package/css/trackControls.css +111 -0
- package/expanded.html +120 -0
- package/fontawesome/css/fontawesome.min.css +5 -0
- package/fontawesome/css/regular.min.css +5 -0
- package/fontawesome/css/solid.min.css +5 -0
- package/fontawesome/webfonts/fa-brands-400.ttf +0 -0
- package/fontawesome/webfonts/fa-brands-400.woff +0 -0
- package/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
- package/fontawesome/webfonts/fa-regular-400.ttf +0 -0
- package/fontawesome/webfonts/fa-regular-400.woff +0 -0
- package/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
- package/fontawesome/webfonts/fa-solid-900.ttf +0 -0
- package/fontawesome/webfonts/fa-solid-900.woff +0 -0
- package/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
- package/help.pdf +0 -0
- package/i/sort_handle.png +0 -0
- package/index.html +68 -0
- package/index.js +83 -0
- package/jest.config.js +4 -0
- package/js/Genoverse.js +1681 -0
- package/js/Track/Controller/Sequence.js +17 -0
- package/js/Track/Controller/Stranded.js +73 -0
- package/js/Track/Controller.js +620 -0
- package/js/Track/Model/File/BAM.js +44 -0
- package/js/Track/Model/File/BED.js +116 -0
- package/js/Track/Model/File/GFF.js +40 -0
- package/js/Track/Model/File/VCF.js +101 -0
- package/js/Track/Model/File/WIG.js +67 -0
- package/js/Track/Model/File.js +36 -0
- package/js/Track/Model/Gene/Ensembl.js +22 -0
- package/js/Track/Model/Gene.js +5 -0
- package/js/Track/Model/Sequence/Ensembl.js +4 -0
- package/js/Track/Model/Sequence/Fasta.js +60 -0
- package/js/Track/Model/Sequence.js +50 -0
- package/js/Track/Model/SequenceVariation.js +41 -0
- package/js/Track/Model/Stranded.js +28 -0
- package/js/Track/Model/Transcript/Ensembl.js +67 -0
- package/js/Track/Model/Transcript.js +5 -0
- package/js/Track/Model.js +303 -0
- package/js/Track/View/Gene/Ensembl.js +46 -0
- package/js/Track/View/Gene.js +6 -0
- package/js/Track/View/Sequence/Variation.js +115 -0
- package/js/Track/View/Sequence.js +63 -0
- package/js/Track/View/Transcript/Ensembl.js +12 -0
- package/js/Track/View/Transcript.js +28 -0
- package/js/Track/View.js +566 -0
- package/js/Track/library/Chromosome.js +145 -0
- package/js/Track/library/File/BAM.js +30 -0
- package/js/Track/library/File/BED.js +24 -0
- package/js/Track/library/File/BIGBED.js +47 -0
- package/js/Track/library/File/BIGWIG.js +52 -0
- package/js/Track/library/File/GFF.js +9 -0
- package/js/Track/library/File/VCF.js +71 -0
- package/js/Track/library/File/WIG.js +5 -0
- package/js/Track/library/File.js +10 -0
- package/js/Track/library/Gene.js +37 -0
- package/js/Track/library/Graph/Bar.js +235 -0
- package/js/Track/library/Graph/Line.js +296 -0
- package/js/Track/library/Graph.js +355 -0
- package/js/Track/library/HighlightRegion.js +292 -0
- package/js/Track/library/Legend.js +224 -0
- package/js/Track/library/Scalebar.js +227 -0
- package/js/Track/library/Scaleline.js +91 -0
- package/js/Track/library/Static.js +78 -0
- package/js/Track/library/dbSNP.js +142 -0
- package/js/Track.js +632 -0
- package/js/genomes/grch37.js +990 -0
- package/js/genomes/grch38.js +990 -0
- package/js/genoverse.min.js +2 -0
- package/js/genoverse.min.js.map +1 -0
- package/js/lib/BWReader.js +578 -0
- package/js/lib/Base.js +145 -0
- package/js/lib/VCFReader.js +286 -0
- package/js/lib/dalliance/js/bam.js +494 -0
- package/js/lib/dalliance/js/bin.js +185 -0
- package/js/lib/dalliance/js/das.js +749 -0
- package/js/lib/dalliance/js/utils.js +370 -0
- package/js/lib/dalliance-lib.js +3594 -0
- package/js/lib/dalliance-lib.min.js +68 -0
- package/js/lib/jDataView.js +2 -0
- package/js/lib/jParser.js +192 -0
- package/js/lib/jquery-ui.js +8 -0
- package/js/lib/jquery.js +2 -0
- package/js/lib/jquery.mousehold.js +53 -0
- package/js/lib/jquery.mousewheel.js +84 -0
- package/js/lib/jquery.tipsy.js +258 -0
- package/js/lib/rtree.js +1 -0
- package/js/plugins/controlPanel.js +395 -0
- package/js/plugins/fileDrop.js +62 -0
- package/js/plugins/focusRegion.js +12 -0
- package/js/plugins/fullscreen.js +77 -0
- package/js/plugins/karyotype.js +210 -0
- package/js/plugins/resizer.js +45 -0
- package/js/plugins/tooltips.js +94 -0
- package/js/plugins/trackControls.js +143 -0
- package/package.json +43 -0
- package/test/View/__snapshots__/render-bar-graph.test.js.snap +111 -0
- package/test/View/__snapshots__/render-blocks.test.js.snap +105 -0
- package/test/View/__snapshots__/render-chromosome.test.js.snap +5 -0
- package/test/View/__snapshots__/render-highlights.test.js.snap +73 -0
- package/test/View/__snapshots__/render-insert-variants.test.js.snap +9 -0
- package/test/View/__snapshots__/render-labels.test.js.snap +241 -0
- package/test/View/__snapshots__/render-legends.test.js.snap +13 -0
- package/test/View/__snapshots__/render-line-graph.test.js.snap +349 -0
- package/test/View/__snapshots__/render-scalebar.test.js.snap +49 -0
- package/test/View/__snapshots__/render-scaleline.test.js.snap +31 -0
- package/test/View/__snapshots__/render-sequence.test.js.snap +23 -0
- package/test/View/__snapshots__/render-stranded.test.js.snap +5 -0
- package/test/View/__snapshots__/render-transcripts.test.js.snap +193 -0
- package/test/View/render-bar-graph.test.js +87 -0
- package/test/View/render-blocks.test.js +171 -0
- package/test/View/render-chromosome.test.js +40 -0
- package/test/View/render-highlights.test.js +67 -0
- package/test/View/render-insert-variants.test.js +11 -0
- package/test/View/render-labels.test.js +266 -0
- package/test/View/render-legends.test.js +31 -0
- package/test/View/render-line-graph.test.js +169 -0
- package/test/View/render-scalebar.test.js +36 -0
- package/test/View/render-scaleline.test.js +28 -0
- package/test/View/render-sequence.test.js +49 -0
- package/test/View/render-stranded.test.js +10 -0
- package/test/View/render-transcripts.test.js +165 -0
- package/test/create-and-destroy.test.js +63 -0
- package/test/track-ordering.test.js +514 -0
- package/test/track_config/__snapshots__/config-settings.test.js.snap +23 -0
- package/test/track_config/config-settings.test.js +321 -0
- package/test/track_config/zoom-level-settings.test.js +98 -0
- package/test/utils.js +80 -0
- package/utils/createGenome.js +52 -0
- package/utils/devServer.js +36 -0
- package/utils/expandedTemplate.html +46 -0
- package/utils/git-hooks/post-commit +9 -0
- package/utils/git-hooks/pre-commit +7 -0
- package/utils/git-hooks/setup +6 -0
- package/utils/makeExpanded.js +19 -0
- package/webpack.config.js +39 -0
package/js/lib/rtree.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.RTree=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module,exports){"use strict";var rectangle=_dereq_("./rectangle");var bbox=function(ar,obj){if(obj&&obj.bbox){return{leaf:obj,x:obj.bbox[0],y:obj.bbox[1],w:obj.bbox[2]-obj.bbox[0],h:obj.bbox[3]-obj.bbox[1]}}var len=ar.length;var i=0;var a=new Array(len);while(i<len){a[i]=[ar[i][0],ar[i][1]];i++}var first=a[0];len=a.length;i=1;var temp={min:[].concat(first),max:[].concat(first)};while(i<len){if(a[i][0]<temp.min[0]){temp.min[0]=a[i][0]}else if(a[i][0]>temp.max[0]){temp.max[0]=a[i][0]}if(a[i][1]<temp.min[1]){temp.min[1]=a[i][1]}else if(a[i][1]>temp.max[1]){temp.max[1]=a[i][1]}i++}var out={x:temp.min[0],y:temp.min[1],w:temp.max[0]-temp.min[0],h:temp.max[1]-temp.min[1]};if(obj){out.leaf=obj}return out};var geoJSON={};geoJSON.point=function(obj,self){return self.insertSubtree({x:obj.geometry.coordinates[0],y:obj.geometry.coordinates[1],w:0,h:0,leaf:obj},self.root)};geoJSON.multiPointLineString=function(obj,self){return self.insertSubtree(bbox(obj.geometry.coordinates,obj),self.root)};geoJSON.multiLineStringPolygon=function(obj,self){return self.insertSubtree(bbox(Array.prototype.concat.apply([],obj.geometry.coordinates),obj),self.root)};geoJSON.multiPolygon=function(obj,self){return self.insertSubtree(bbox(Array.prototype.concat.apply([],Array.prototype.concat.apply([],obj.geometry.coordinates)),obj),self.root)};geoJSON.makeRec=function(obj){return rectangle(obj.x,obj.y,obj.w,obj.h)};geoJSON.geometryCollection=function(obj,self){if(obj.bbox){return self.insertSubtree({leaf:obj,x:obj.bbox[0],y:obj.bbox[1],w:obj.bbox[2]-obj.bbox[0],h:obj.bbox[3]-obj.bbox[1]},self.root)}var geos=obj.geometry.geometries;var i=0;var len=geos.length;var temp=[];var g;while(i<len){g=geos[i];switch(g.type){case"Point":temp.push(geoJSON.makeRec({x:g.coordinates[0],y:g.coordinates[1],w:0,h:0}));break;case"MultiPoint":temp.push(geoJSON.makeRec(bbox(g.coordinates)));break;case"LineString":temp.push(geoJSON.makeRec(bbox(g.coordinates)));break;case"MultiLineString":temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([],g.coordinates))));break;case"Polygon":temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([],g.coordinates))));break;case"MultiPolygon":temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([],Array.prototype.concat.apply([],g.coordinates)))));break;case"GeometryCollection":geos=geos.concat(g.geometries);len=geos.length;break}i++}var first=temp[0];i=1;len=temp.length;while(i<len){first.expand(temp[i]);i++}return self.insertSubtree({leaf:obj,x:first.x(),y:first.y(),h:first.h(),w:first.w()},self.root)};exports.geoJSON=function(prelim){var that=this;var features,feature;if(Array.isArray(prelim)){features=prelim.slice()}else if(prelim.features&&Array.isArray(prelim.features)){features=prelim.features.slice()}else if(prelim instanceof Object){features=[prelim]}else{throw"this isn't what we're looking for"}var len=features.length;var i=0;while(i<len){feature=features[i];if(feature.type==="Feature"){switch(feature.geometry.type){case"Point":geoJSON.point(feature,that);break;case"MultiPoint":geoJSON.multiPointLineString(feature,that);break;case"LineString":geoJSON.multiPointLineString(feature,that);break;case"MultiLineString":geoJSON.multiLineStringPolygon(feature,that);break;case"Polygon":geoJSON.multiLineStringPolygon(feature,that);break;case"MultiPolygon":geoJSON.multiPolygon(feature,that);break;case"GeometryCollection":geoJSON.geometryCollection(feature,that);break}}i++}};exports.bbox=function(){var x1,y1,x2,y2;switch(arguments.length){case 1:x1=arguments[0][0][0];y1=arguments[0][0][1];x2=arguments[0][1][0];y2=arguments[0][1][1];break;case 2:x1=arguments[0][0];y1=arguments[0][1];x2=arguments[1][0];y2=arguments[1][1];break;case 4:x1=arguments[0];y1=arguments[1];x2=arguments[2];y2=arguments[3];break}return this.search({x:x1,y:y1,w:x2-x1,h:y2-y1})}},{"./rectangle":3}],2:[function(_dereq_,module,exports){"use strict";var RTree=_dereq_("./rtree");var geojson=_dereq_("./geojson");RTree.prototype.bbox=geojson.bbox;RTree.prototype.geoJSON=geojson.geoJSON;RTree.Rectangle=_dereq_("./rectangle");module.exports=RTree},{"./geojson":1,"./rectangle":3,"./rtree":4}],3:[function(_dereq_,module,exports){"use strict";function Rectangle(x,y,w,h){if(!(this instanceof Rectangle)){return new Rectangle(x,y,w,h)}var x2,y2,p;if(x.x){w=x.w;h=x.h;y=x.y;if(x.w!==0&&!x.w&&x.x2){w=x.x2-x.x;h=x.y2-x.y}else{w=x.w;h=x.h}x=x.x;x2=x+w;y2=y+h;p=h+w?false:true}else{x2=x+w;y2=y+h;p=h+w?false:true}this.x1=this.x=function(){return x};this.y1=this.y=function(){return y};this.x2=function(){return x2};this.y2=function(){return y2};this.w=function(){return w};this.h=function(){return h};this.p=function(){return p};this.overlap=function(a){if(p||a.p()){return x<=a.x2()&&x2>=a.x()&&y<=a.y2()&&y2>=a.y()}return x<a.x2()&&x2>a.x()&&y<a.y2()&&y2>a.y()};this.expand=function(a){var nx,ny;var ax=a.x();var ay=a.y();var ax2=a.x2();var ay2=a.y2();if(x>ax){nx=ax}else{nx=x}if(y>ay){ny=ay}else{ny=y}if(x2>ax2){w=x2-nx}else{w=ax2-nx}if(y2>ay2){h=y2-ny}else{h=ay2-ny}x=nx;y=ny;return this}}Rectangle.overlapRectangle=function(a,b){if(a.h===0&&a.w===0||b.h===0&&b.w===0){return a.x<=b.x+b.w&&a.x+a.w>=b.x&&a.y<=b.y+b.h&&a.y+a.h>=b.y}else{return a.x<b.x+b.w&&a.x+a.w>b.x&&a.y<b.y+b.h&&a.y+a.h>b.y}};Rectangle.containsRectangle=function(a,b){return a.x+a.w<=b.x+b.w&&a.x>=b.x&&a.y+a.h<=b.y+b.h&&a.y>=b.y};Rectangle.expandRectangle=function(a,b){var nx,ny;var axw=a.x+a.w;var bxw=b.x+b.w;var ayh=a.y+a.h;var byh=b.y+b.h;if(a.x>b.x){nx=b.x}else{nx=a.x}if(a.y>b.y){ny=b.y}else{ny=a.y}if(axw>bxw){a.w=axw-nx}else{a.w=bxw-nx}if(ayh>byh){a.h=ayh-ny}else{a.h=byh-ny}a.x=nx;a.y=ny;return a};Rectangle.makeMBR=function(nodes,rect){if(!nodes.length){return{x:0,y:0,w:0,h:0}}rect=rect||{};rect.x=nodes[0].x;rect.y=nodes[0].y;rect.w=nodes[0].w;rect.h=nodes[0].h;for(var i=1,len=nodes.length;i<len;i++){Rectangle.expandRectangle(rect,nodes[i])}return rect};Rectangle.squarifiedRatio=function(l,w,fill){var lperi=(l+w)/2;var larea=l*w;var lgeo=larea/(lperi*lperi);return larea*fill/lgeo};module.exports=Rectangle},{}],4:[function(_dereq_,module,exports){"use strict";var rectangle=_dereq_("./rectangle");function RTree(width){if(!(this instanceof RTree)){return new RTree(width)}var minWidth=3;var maxWidth=6;if(!isNaN(width)){minWidth=Math.floor(width/2);maxWidth=width}var rootTree={x:0,y:0,w:0,h:0,id:"root",nodes:[]};this.root=rootTree;var flatten=function(tree){var todo=tree.slice();var done=[];var current;while(todo.length){current=todo.pop();if(current.nodes){todo=todo.concat(current.nodes)}else if(current.leaf){done.push(current)}}return done};var removeSubtree=function(rect,obj,root){var hitStack=[];var countStack=[];var retArray=[];var currentDepth=1;var tree,i,ltree;if(!rect||!rectangle.overlapRectangle(rect,root)){return retArray}var retObj={x:rect.x,y:rect.y,w:rect.w,h:rect.h,target:obj};countStack.push(root.nodes.length);hitStack.push(root);while(hitStack.length>0){tree=hitStack.pop();i=countStack.pop()-1;if("target"in retObj){while(i>=0){ltree=tree.nodes[i];if(rectangle.overlapRectangle(retObj,ltree)){if(retObj.target&&"leaf"in ltree&<ree.leaf===retObj.target||!retObj.target&&("leaf"in ltree||rectangle.containsRectangle(ltree,retObj))){if("nodes"in ltree){retArray=flatten(tree.nodes.splice(i,1))}else{retArray=tree.nodes.splice(i,1)}rectangle.makeMBR(tree.nodes,tree);delete retObj.target;break}else if("nodes"in ltree){currentDepth++;countStack.push(i);hitStack.push(tree);tree=ltree;i=ltree.nodes.length}}i--}}else if("nodes"in retObj){tree.nodes.splice(i+1,1);if(tree.nodes.length>0){rectangle.makeMBR(tree.nodes,tree)}for(var t=0;t<retObj.nodes.length;t++){insertSubtree(retObj.nodes[t],tree)}retObj.nodes=[];if(hitStack.length===0&&tree.nodes.length<=1){retObj.nodes=searchSubtree(tree,true,retObj.nodes,tree);tree.nodes=[];hitStack.push(tree);countStack.push(1)}else if(hitStack.length>0&&tree.nodes.length<minWidth){retObj.nodes=searchSubtree(tree,true,retObj.nodes,tree);tree.nodes=[]}else{delete retObj.nodes}}else{rectangle.makeMBR(tree.nodes,tree)}currentDepth-=1}return retArray};var chooseLeafSubtree=function(rect,root){var bestChoiceIndex=-1;var bestChoiceStack=[];var bestChoiceArea;var first=true;bestChoiceStack.push(root);var nodes=root.nodes;while(first||bestChoiceIndex!==-1){if(first){first=false}else{bestChoiceStack.push(nodes[bestChoiceIndex]);nodes=nodes[bestChoiceIndex].nodes;bestChoiceIndex=-1}for(var i=nodes.length-1;i>=0;i--){var ltree=nodes[i];if("leaf"in ltree){bestChoiceIndex=-1;break}var oldLRatio=rectangle.squarifiedRatio(ltree.w,ltree.h,ltree.nodes.length+1);var nw=Math.max(ltree.x+ltree.w,rect.x+rect.w)-Math.min(ltree.x,rect.x);var nh=Math.max(ltree.y+ltree.h,rect.y+rect.h)-Math.min(ltree.y,rect.y);var lratio=rectangle.squarifiedRatio(nw,nh,ltree.nodes.length+2);if(bestChoiceIndex<0||Math.abs(lratio-oldLRatio)<bestChoiceArea){bestChoiceArea=Math.abs(lratio-oldLRatio);bestChoiceIndex=i}}}return bestChoiceStack};var linearSplit=function(nodes){var n=pickLinear(nodes);while(nodes.length>0){pickNext(nodes,n[0],n[1])}return n};var pickNext=function(nodes,a,b){var areaA=rectangle.squarifiedRatio(a.w,a.h,a.nodes.length+1);var areaB=rectangle.squarifiedRatio(b.w,b.h,b.nodes.length+1);var highAreaDelta;var highAreaNode;var lowestGrowthGroup;for(var i=nodes.length-1;i>=0;i--){var l=nodes[i];var newAreaA={};newAreaA.x=Math.min(a.x,l.x);newAreaA.y=Math.min(a.y,l.y);newAreaA.w=Math.max(a.x+a.w,l.x+l.w)-newAreaA.x;newAreaA.h=Math.max(a.y+a.h,l.y+l.h)-newAreaA.y;var changeNewAreaA=Math.abs(rectangle.squarifiedRatio(newAreaA.w,newAreaA.h,a.nodes.length+2)-areaA);var newAreaB={};newAreaB.x=Math.min(b.x,l.x);newAreaB.y=Math.min(b.y,l.y);newAreaB.w=Math.max(b.x+b.w,l.x+l.w)-newAreaB.x;newAreaB.h=Math.max(b.y+b.h,l.y+l.h)-newAreaB.y;var changeNewAreaB=Math.abs(rectangle.squarifiedRatio(newAreaB.w,newAreaB.h,b.nodes.length+2)-areaB);if(!highAreaNode||!highAreaDelta||Math.abs(changeNewAreaB-changeNewAreaA)<highAreaDelta){highAreaNode=i;highAreaDelta=Math.abs(changeNewAreaB-changeNewAreaA);lowestGrowthGroup=changeNewAreaB<changeNewAreaA?b:a}}var tempNode=nodes.splice(highAreaNode,1)[0];if(a.nodes.length+nodes.length+1<=minWidth){a.nodes.push(tempNode);rectangle.expandRectangle(a,tempNode)}else if(b.nodes.length+nodes.length+1<=minWidth){b.nodes.push(tempNode);rectangle.expandRectangle(b,tempNode)}else{lowestGrowthGroup.nodes.push(tempNode);rectangle.expandRectangle(lowestGrowthGroup,tempNode)}};var pickLinear=function(nodes){var lowestHighX=nodes.length-1;var highestLowX=0;var lowestHighY=nodes.length-1;var highestLowY=0;var t1,t2;for(var i=nodes.length-2;i>=0;i--){var l=nodes[i];if(l.x>nodes[highestLowX].x){highestLowX=i}else if(l.x+l.w<nodes[lowestHighX].x+nodes[lowestHighX].w){lowestHighX=i}if(l.y>nodes[highestLowY].y){highestLowY=i}else if(l.y+l.h<nodes[lowestHighY].y+nodes[lowestHighY].h){lowestHighY=i}}var dx=Math.abs(nodes[lowestHighX].x+nodes[lowestHighX].w-nodes[highestLowX].x);var dy=Math.abs(nodes[lowestHighY].y+nodes[lowestHighY].h-nodes[highestLowY].y);if(dx>dy){if(lowestHighX>highestLowX){t1=nodes.splice(lowestHighX,1)[0];t2=nodes.splice(highestLowX,1)[0]}else{t2=nodes.splice(highestLowX,1)[0];t1=nodes.splice(lowestHighX,1)[0]}}else{if(lowestHighY>highestLowY){t1=nodes.splice(lowestHighY,1)[0];t2=nodes.splice(highestLowY,1)[0]}else{t2=nodes.splice(highestLowY,1)[0];t1=nodes.splice(lowestHighY,1)[0]}}return[{x:t1.x,y:t1.y,w:t1.w,h:t1.h,nodes:[t1]},{x:t2.x,y:t2.y,w:t2.w,h:t2.h,nodes:[t2]}]};var attachData=function(node,moreTree){node.nodes=moreTree.nodes;node.x=moreTree.x;node.y=moreTree.y;node.w=moreTree.w;node.h=moreTree.h;return node};var searchSubtree=function(rect,returnNode,returnArray,root){var hitStack=[];if(!rectangle.overlapRectangle(rect,root)){return returnArray}hitStack.push(root.nodes);while(hitStack.length>0){var nodes=hitStack.pop();for(var i=nodes.length-1;i>=0;i--){var ltree=nodes[i];if(rectangle.overlapRectangle(rect,ltree)){if("nodes"in ltree){hitStack.push(ltree.nodes)}else if("leaf"in ltree){if(!returnNode){returnArray.push(ltree.leaf)}else{returnArray.push(ltree)}}}}}return returnArray};var insertSubtree=function(node,root){var bc;if(root.nodes.length===0){root.x=node.x;root.y=node.y;root.w=node.w;root.h=node.h;root.nodes.push(node);return}var treeStack=chooseLeafSubtree(node,root);var retObj=node;var pbc;while(treeStack.length>0){if(bc&&"nodes"in bc&&bc.nodes.length===0){pbc=bc;bc=treeStack.pop();for(var t=0;t<bc.nodes.length;t++){if(bc.nodes[t]===pbc||bc.nodes[t].nodes.length===0){bc.nodes.splice(t,1);break}}}else{bc=treeStack.pop()}if("leaf"in retObj||"nodes"in retObj||Array.isArray(retObj)){if(Array.isArray(retObj)){for(var ai=0;ai<retObj.length;ai++){rectangle.expandRectangle(bc,retObj[ai])}bc.nodes=bc.nodes.concat(retObj)}else{rectangle.expandRectangle(bc,retObj);bc.nodes.push(retObj)}if(bc.nodes.length<=maxWidth){retObj={x:bc.x,y:bc.y,w:bc.w,h:bc.h}}else{var a=linearSplit(bc.nodes);retObj=a;if(treeStack.length<1){bc.nodes.push(a[0]);treeStack.push(bc);retObj=a[1]}}}else{rectangle.expandRectangle(bc,retObj);retObj={x:bc.x,y:bc.y,w:bc.w,h:bc.h}}}};this.insertSubtree=insertSubtree;this.getTree=function(){return rootTree};this.setTree=function(newTree,where){if(!where){where=rootTree}return attachData(where,newTree)};this.search=function(rect,returnNode,returnArray){returnArray=returnArray||[];return searchSubtree(rect,returnNode,returnArray,rootTree)};var removeArea=function(rect){var numberDeleted=1,retArray=[],deleted;while(numberDeleted>0){deleted=removeSubtree(rect,false,rootTree);numberDeleted=deleted.length;retArray=retArray.concat(deleted)}return retArray};var removeObj=function(rect,obj){var retArray=removeSubtree(rect,obj,rootTree);return retArray};this.remove=function(rect,obj){if(!obj||typeof obj==="function"){return removeArea(rect,obj)}else{return removeObj(rect,obj)}};this.insert=function(rect,obj){var retArray=insertSubtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj},rootTree);return retArray}}RTree.prototype.toJSON=function(printing){return JSON.stringify(this.root,false,printing)};RTree.fromJSON=function(json){var rt=new RTree;rt.setTree(JSON.parse(json));return rt};module.exports=RTree;if(typeof Array.isArray!=="function"){Array.isArray=function(a){return typeof a==="object"&&{}.toString.call(a)==="[object Array]"}}},{"./rectangle":3}]},{},[2])(2)});
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
Genoverse.Plugins.controlPanel = function (pluginConf) {
|
|
2
|
+
this.controls = [
|
|
3
|
+
// Scroll left/right
|
|
4
|
+
{
|
|
5
|
+
name : 'Scroll left and right by pressing and holding these buttons',
|
|
6
|
+
buttons : [{
|
|
7
|
+
name : 'Scroll left',
|
|
8
|
+
icon : '<i class="fas fa-chevron-left"></i>',
|
|
9
|
+
'class' : 'gv-scroll-left'
|
|
10
|
+
}, {
|
|
11
|
+
name : 'Scroll right',
|
|
12
|
+
icon : '<i class="fas fa-chevron-right"></i>',
|
|
13
|
+
'class' : 'gv-scroll-right'
|
|
14
|
+
}],
|
|
15
|
+
init: function (browser) {
|
|
16
|
+
var el = $(this);
|
|
17
|
+
|
|
18
|
+
el.find('.gv-scroll-left, .gv-scroll-right').on({
|
|
19
|
+
mousedown : function () { browser.startDragScroll(); },
|
|
20
|
+
mouseup : function () { browser.stopDragScroll(); }
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
el.find('.gv-scroll-left').mousehold(50, function () {
|
|
24
|
+
browser.move(browser.scrollDelta);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
el.find('.gv-scroll-right').mousehold(50, function () {
|
|
28
|
+
browser.move(-browser.scrollDelta);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// Zoom in/out
|
|
34
|
+
{
|
|
35
|
+
name : 'Zoom-in and zoom-out',
|
|
36
|
+
buttons : [{
|
|
37
|
+
name : 'Zoom in',
|
|
38
|
+
icon : '<i class="fas fa-search-plus"></i>',
|
|
39
|
+
'class' : 'gv-zoom-in',
|
|
40
|
+
action : function (browser) { browser.zoomIn(); }
|
|
41
|
+
}, {
|
|
42
|
+
name : 'Zoom out',
|
|
43
|
+
icon : '<i class="fas fa-search-minus"></i>',
|
|
44
|
+
'class' : 'gv-zoom-out',
|
|
45
|
+
action : function (browser) { browser.zoomOut(); }
|
|
46
|
+
}]
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// Toogle drag action
|
|
50
|
+
{
|
|
51
|
+
name : 'Toggle your mouse drag action between scroll left/right and select region',
|
|
52
|
+
buttons : [{
|
|
53
|
+
name : 'Mouse drag action to scroll the browser left or right',
|
|
54
|
+
icon : '<i class="fas fa-arrows-alt-h"></i>',
|
|
55
|
+
'class' : 'gv-drag-scroll',
|
|
56
|
+
action : function (browser) {
|
|
57
|
+
browser.setDragAction('scroll');
|
|
58
|
+
$(this).addClass('gv-active').siblings().removeClass('gv-active');
|
|
59
|
+
}
|
|
60
|
+
}, {
|
|
61
|
+
name : 'Mouse drag action to select a region',
|
|
62
|
+
icon : '<i></i>',
|
|
63
|
+
'class' : 'gv-drag-select',
|
|
64
|
+
action : function (browser) {
|
|
65
|
+
browser.setDragAction('select');
|
|
66
|
+
$(this).addClass('gv-active').siblings().removeClass('gv-active');
|
|
67
|
+
}
|
|
68
|
+
}],
|
|
69
|
+
init: function (browser) {
|
|
70
|
+
$(this).find('.gv-drag-' + browser.dragAction).addClass('gv-active').siblings().removeClass('gv-active');
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// Toogle wheel action
|
|
75
|
+
{
|
|
76
|
+
name : 'Toggle your mouse wheel action between zoom in/out and default page scroll',
|
|
77
|
+
buttons : [{
|
|
78
|
+
name : 'Mouse wheel action to scroll the page up and down',
|
|
79
|
+
icon : '<i class="fas fa-arrows-alt-v"></i>',
|
|
80
|
+
'class' : 'gv-wheel-off',
|
|
81
|
+
action : function (browser) {
|
|
82
|
+
browser.setWheelAction('off');
|
|
83
|
+
$(this).addClass('gv-active').siblings().removeClass('gv-active');
|
|
84
|
+
}
|
|
85
|
+
}, {
|
|
86
|
+
name : 'Mouse wheel to zoom in and out',
|
|
87
|
+
icon : '±',
|
|
88
|
+
'class' : 'gv-wheel-zoom',
|
|
89
|
+
action : function (browser) {
|
|
90
|
+
browser.setWheelAction('zoom');
|
|
91
|
+
$(this).addClass('gv-active').siblings().removeClass('gv-active');
|
|
92
|
+
}
|
|
93
|
+
}],
|
|
94
|
+
init: function (browser) {
|
|
95
|
+
$(this).find('.gv-wheel-' + browser.wheelAction).addClass('gv-active').siblings().removeClass('gv-active');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
if (this.saveable) {
|
|
101
|
+
this.controls.push({
|
|
102
|
+
icon : '<i class="fas fa-undo"></i>',
|
|
103
|
+
name : 'Reset tracks and configuration',
|
|
104
|
+
action : function (browser) { browser.resetConfig(); }
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.on({
|
|
109
|
+
beforeInit: function () {
|
|
110
|
+
var browser = this;
|
|
111
|
+
|
|
112
|
+
if (!this.tracksLibrary) {
|
|
113
|
+
this.tracksLibrary = $.grep(this.tracks, function (track) { return track.prototype.name; });
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
var panel = $(
|
|
117
|
+
'<table cellspacing=0 cellpadding=0 class="gv">' +
|
|
118
|
+
' <tr>' +
|
|
119
|
+
' <td class="gv-panel gv-panel-left"></td>' +
|
|
120
|
+
' <td class="gv-canvas-container"></td>' +
|
|
121
|
+
' <td class="gv-panel gv-panel-right"></td>' +
|
|
122
|
+
' </tr>' +
|
|
123
|
+
'</table>'
|
|
124
|
+
).appendTo(this.container).find('.gv-panel-right');
|
|
125
|
+
|
|
126
|
+
this.controlPanel = panel;
|
|
127
|
+
this.superContainer = this.container;
|
|
128
|
+
this.container = $('.gv-canvas-container', this.container);
|
|
129
|
+
|
|
130
|
+
for (var i = 0; i < browser.controls.length; i++) {
|
|
131
|
+
(function (control) {
|
|
132
|
+
var buttonSet = $('<div class="gv-button-set">').attr('title', control.name).appendTo(browser.superContainer.find('.gv-panel-right'));
|
|
133
|
+
var buttons = control.buttons || [ control ];
|
|
134
|
+
|
|
135
|
+
$.each(buttons, function (j, button) {
|
|
136
|
+
var el = $('<button>' + button.icon + '</button>').addClass(button.class).attr('title', button.name).appendTo(buttonSet);
|
|
137
|
+
|
|
138
|
+
if (button.action) {
|
|
139
|
+
el.on('click', function () {
|
|
140
|
+
button.action.call(this, browser);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (button.init && button !== control) {
|
|
145
|
+
button.init.call(el[0], browser);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
if (control.init) {
|
|
150
|
+
control.init.call(buttonSet, browser);
|
|
151
|
+
}
|
|
152
|
+
}(browser.controls[i]));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.superContainer.width(this.width);
|
|
156
|
+
|
|
157
|
+
// ESC key to toggle crosshair select to drag mode and close menus
|
|
158
|
+
$(document).on('keydown', function (e) {
|
|
159
|
+
if (e.keyCode === 27) {
|
|
160
|
+
if (panel.find('button.gv-drag-select').hasClass('gv-active')) {
|
|
161
|
+
panel.find('button.gv-drag-scroll').trigger('click');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
$('.gv-menu .gv-close').trigger('click');
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
afterInit: function () {
|
|
170
|
+
var browser = this;
|
|
171
|
+
var tracksButton = $('<button class="gv-tracks-library-button" title="Tracks menu"><i class="fas fa-bars"></i> Tracks</button>').on('click', function () {
|
|
172
|
+
var button = this;
|
|
173
|
+
|
|
174
|
+
function getTrackTags(track, tags) {
|
|
175
|
+
if (track.constructor && track.constructor.ancestor && track.constructor.ancestor.prototype) {
|
|
176
|
+
tags = getTrackTags(track.constructor.ancestor.prototype, tags.concat(track.constructor.ancestor.prototype.tags || []));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return tags;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if ($(this).hasClass('gv-active')) {
|
|
183
|
+
$('.gv-menu.gv-tracks-menu .gv-close').trigger('click');
|
|
184
|
+
$(this).removeClass('gv-active');
|
|
185
|
+
} else {
|
|
186
|
+
var menu = $(this).data('menu');
|
|
187
|
+
|
|
188
|
+
if (menu) {
|
|
189
|
+
menu.show();
|
|
190
|
+
} else {
|
|
191
|
+
menu = browser.makeMenu({
|
|
192
|
+
'Currently enabled tracks:' : 'Available tracks:',
|
|
193
|
+
'<div class="gv-current-tracks"></div>' : '<input placeholder="Search"><div class="gv-available-tracks"></div>'
|
|
194
|
+
}).addClass('gv-tracks-menu');
|
|
195
|
+
|
|
196
|
+
$('input[placeholder=Search]', menu).on('keyup', function () {
|
|
197
|
+
var str = this.value.toLowerCase();
|
|
198
|
+
|
|
199
|
+
$('.gv-tracks-library-item', menu).each(function () {
|
|
200
|
+
var track = $(this).data('track');
|
|
201
|
+
var match = false;
|
|
202
|
+
|
|
203
|
+
if (track.name && track.name.toLowerCase().indexOf(str) >= 0) {
|
|
204
|
+
match = true;
|
|
205
|
+
} else {
|
|
206
|
+
var tags = getTrackTags(track, []).concat(track.tags || []);
|
|
207
|
+
|
|
208
|
+
for (var i = 0; i < tags.length; i++) {
|
|
209
|
+
if (tags[i].toLowerCase().indexOf(str) >= 0) {
|
|
210
|
+
match = true;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
$(this)[match ? 'removeClass' : 'addClass']('gv-hide');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
$('.gv-tracks-library-category', menu).each(function () {
|
|
220
|
+
var visibleTracks = $(this).children('.gv-tracks-library-item:not(.gv-hide)');
|
|
221
|
+
|
|
222
|
+
$(this)[visibleTracks.length ? 'removeClass' : 'addClass']('gv-hide');
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
$('.gv-close', menu).on('click', function () {
|
|
227
|
+
$(button).removeClass('gv-active');
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
var availableTracks = $('.gv-available-tracks', menu);
|
|
231
|
+
var currentTracks = $('.gv-current-tracks', menu).before('<div class="gv-current-tracks-instructions">Drag and drop to reorder</div>').data({
|
|
232
|
+
reload : function () { $(this).empty().data('listTracks')(); },
|
|
233
|
+
listTracks : function () {
|
|
234
|
+
for (var i = 0; i < browser.tracks.length; i++) {
|
|
235
|
+
if (browser.tracks[i].name && !(browser.tracks[i].removable === false && browser.tracks[i].unsortable) && !browser.tracks[i].parentTrack && !browser.tracks[i].lockToTrack) {
|
|
236
|
+
(function (track) {
|
|
237
|
+
var el = $('<div class="gv-tracks-menu-track">')
|
|
238
|
+
.append('<span class="gv-tracks-menu-track-name" title="' + track.name + '">' + track.defaultName + '</span>')
|
|
239
|
+
.appendTo(currentTracks)
|
|
240
|
+
.data('track', track)
|
|
241
|
+
.addClass(track.unsortable ? 'gv-unsortable' : '');
|
|
242
|
+
|
|
243
|
+
if (track.removable === false) {
|
|
244
|
+
el.prepend('<i class="gv-remove-track gv-menu-button fas fa-circle">');
|
|
245
|
+
} else {
|
|
246
|
+
el.prepend($('<i class="gv-remove-track gv-menu-button fas fa-times-circle">').on('click', function () { track.remove(); }));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
var trackNameEl = el.find('.gv-tracks-menu-track-name').tipsy({ gravity: 'w', trigger: 'manual' }).on('mouseenter', function () {
|
|
250
|
+
var tip = $(this).tipsy('show').data('tipsy').$tip;
|
|
251
|
+
|
|
252
|
+
if (tip) {
|
|
253
|
+
tip.css('zIndex', 1002);
|
|
254
|
+
}
|
|
255
|
+
}).on('mouseleave', function () {
|
|
256
|
+
$(this).tipsy('hide');
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
if (track.name === track.defaultName) {
|
|
260
|
+
trackNameEl.tipsy('disable');
|
|
261
|
+
}
|
|
262
|
+
}(browser.tracks[i]));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}).sortable({
|
|
267
|
+
items : 'div:not(.gv-unsortable)',
|
|
268
|
+
cursor : 'move',
|
|
269
|
+
axis : 'y',
|
|
270
|
+
handle : 'span',
|
|
271
|
+
update : $.proxy(browser.updateTrackOrder, browser),
|
|
272
|
+
start : function () {
|
|
273
|
+
currentTracks.find('.gv-tracks-menu-track-name').each(function () { $(this).tipsy('hide').tipsy('disable'); });
|
|
274
|
+
},
|
|
275
|
+
stop: function () {
|
|
276
|
+
currentTracks.find('.gv-tracks-menu-track-name').each(function () { $(this).tipsy('enable'); });
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
currentTracks.data('listTracks')();
|
|
281
|
+
|
|
282
|
+
if (browser.saveable) {
|
|
283
|
+
$('<div class="gv-tracks-menu-reset gv-menu-button"><i class="fas fa-undo"></i> Reset tracks and configuration</div>').insertAfter(currentTracks).on('click', function (e) {
|
|
284
|
+
e.preventDefault();
|
|
285
|
+
browser.resetConfig();
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (browser.tracksLibrary && browser.tracksLibrary.length) {
|
|
290
|
+
var tracksLibraryCategories = browser.tracksLibrary.filter(function (track) {
|
|
291
|
+
return track.prototype.name && track.prototype.removable !== false;
|
|
292
|
+
}).reduce(
|
|
293
|
+
function (acc, track) {
|
|
294
|
+
var categoryName = track.prototype.category || '';
|
|
295
|
+
|
|
296
|
+
acc[categoryName] = acc[categoryName] || [];
|
|
297
|
+
acc[categoryName].push([ track.prototype.name.toLowerCase(), track ]);
|
|
298
|
+
|
|
299
|
+
return acc;
|
|
300
|
+
},
|
|
301
|
+
{}
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
var tracksLibraryCategoryOrder = ((pluginConf && pluginConf.tracksLibraryCategoryOrder) || []).reduce(
|
|
305
|
+
function (acc, categoryName, i) {
|
|
306
|
+
acc[categoryName] = i + 1;
|
|
307
|
+
return acc;
|
|
308
|
+
},
|
|
309
|
+
{}
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
Object.keys(tracksLibraryCategories).sort(function (a, b) {
|
|
313
|
+
return (Boolean(b) - Boolean(a)) || (tracksLibraryCategoryOrder[a] - tracksLibraryCategoryOrder[b]) || a.localeCompare(b);
|
|
314
|
+
}).forEach(function (categoryName, i, allCategoryNames) {
|
|
315
|
+
var parentEl = (
|
|
316
|
+
allCategoryNames.length > 1
|
|
317
|
+
? $('<div class="gv-tracks-library-category">').append(
|
|
318
|
+
$('<div class="gv-tracks-library-category-header">').html(categoryName || 'Other')
|
|
319
|
+
).appendTo(availableTracks)
|
|
320
|
+
: availableTracks
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
tracksLibraryCategories[categoryName].sort(function (a, b) {
|
|
324
|
+
return a[0].localeCompare(b[0]);
|
|
325
|
+
}).forEach(
|
|
326
|
+
function (row) {
|
|
327
|
+
var track = row[1];
|
|
328
|
+
|
|
329
|
+
$('<div class="gv-tracks-library-item">').append(
|
|
330
|
+
$('<i class="gv-add-track gv-menu-button fas fa-plus-circle">').on('click', function () {
|
|
331
|
+
browser.trackIds = browser.trackIds || {};
|
|
332
|
+
browser.trackIds[track.prototype.id] = browser.trackIds[track.prototype.id] || 1;
|
|
333
|
+
|
|
334
|
+
browser.addTrack(track.extend({ id: track.prototype.id + (browser.tracksById[track.prototype.id] ? browser.trackIds[track.prototype.id]++ : '') }));
|
|
335
|
+
})
|
|
336
|
+
).append('<span>' + track.prototype.name + '</span>').appendTo(parentEl).data('track', track.prototype);
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
menu.css({ left: '50%', marginLeft: menu.width() / -2 });
|
|
343
|
+
|
|
344
|
+
$(this).data('menu', menu);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
$(this).addClass('gv-active');
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
this.labelContainer.prepend(
|
|
352
|
+
$('<li class="gv-unsortable">').append(
|
|
353
|
+
$('<div class="gv-button-set" title="Tracks menu">').append(tracksButton)
|
|
354
|
+
)
|
|
355
|
+
);
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
afterAddDomElements: function () {
|
|
359
|
+
this.wrapper.after('<div class="gv-powered-by">Powered by <a target="_blank" href="https://wtsi-web.github.io/Genoverse/">Genoverse</a></div>');
|
|
360
|
+
this.superContainer.find('.gv-panel-left').append(this.labelContainer);
|
|
361
|
+
},
|
|
362
|
+
|
|
363
|
+
'afterAddTracks afterRemoveTracks': function () {
|
|
364
|
+
var currentTracks = this.superContainer.find('.gv-tracks-menu .gv-current-tracks');
|
|
365
|
+
|
|
366
|
+
if (currentTracks.length) {
|
|
367
|
+
currentTracks.data('reload').call(currentTracks);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
this.on({
|
|
373
|
+
afterSetName: function (name) {
|
|
374
|
+
var track = this.track;
|
|
375
|
+
|
|
376
|
+
if (track && track.browser) {
|
|
377
|
+
var menu = track.browser.superContainer.find('.gv-tracks-library-button').data('menu');
|
|
378
|
+
|
|
379
|
+
if (menu) {
|
|
380
|
+
menu.find('.gv-tracks-menu-track').filter(function () {
|
|
381
|
+
return $(this).data('track') === track;
|
|
382
|
+
}).children('.gv-tracks-menu-track-name').attr('title', name).each(function () {
|
|
383
|
+
if (name === track.defaultName) {
|
|
384
|
+
$(this).tipsy('hide').tipsy('disable');
|
|
385
|
+
} else {
|
|
386
|
+
$(this).tipsy('enable');
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}, 'tracks');
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
Genoverse.Plugins.controlPanel.requires = 'karyotype';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Genoverse.Plugins.fileDrop = function () {
|
|
2
|
+
this.on('afterInit', function () {
|
|
3
|
+
var browser = this;
|
|
4
|
+
var wrapper = this.wrapper;
|
|
5
|
+
|
|
6
|
+
$(window).on('dragenter', function (e) {
|
|
7
|
+
var dataTransfer = e.originalEvent.dataTransfer;
|
|
8
|
+
|
|
9
|
+
if (dataTransfer && dataTransfer.types && (dataTransfer.types[0] === 'Files' || dataTransfer.types[1] === 'Files' || dataTransfer.types[2] === 'Files') && !$('.gv-file-drop-total-overlay').length) {
|
|
10
|
+
var fileDropDiv = $('<div class="gv-file-drop">').appendTo(wrapper);
|
|
11
|
+
var totalDropOverlay = $('<div class="gv-file-drop-total-overlay">').prependTo('body');
|
|
12
|
+
|
|
13
|
+
var dragleave = function () {
|
|
14
|
+
fileDropDiv.remove();
|
|
15
|
+
totalDropOverlay.remove();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
totalDropOverlay.on('dragenter', function (ev) { ev.preventDefault(); ev.stopPropagation(); });
|
|
19
|
+
totalDropOverlay.on('dragover', function (ev) { ev.preventDefault(); ev.stopPropagation(); });
|
|
20
|
+
totalDropOverlay.on('dragleave', dragleave);
|
|
21
|
+
totalDropOverlay.on('drop', function (ev) {
|
|
22
|
+
dragleave();
|
|
23
|
+
ev.preventDefault();
|
|
24
|
+
ev.stopPropagation();
|
|
25
|
+
|
|
26
|
+
// Sort in order to ensure that .bam files are before their .bam.bai files
|
|
27
|
+
var files = $.map(ev.originalEvent.dataTransfer.files, function (f) { return f; }).sort(function (a, b) { return a.name.localeCompare(b.name); });
|
|
28
|
+
|
|
29
|
+
for (var i = 0; i < files.length; i++) {
|
|
30
|
+
var file = files[i];
|
|
31
|
+
var parts = file.name.split('.').reverse();
|
|
32
|
+
var gz = parts[0] === 'gz';
|
|
33
|
+
var ext = parts[gz ? 1 : 0];
|
|
34
|
+
var track = Genoverse.Track.File[ext.toUpperCase()];
|
|
35
|
+
var indexFile;
|
|
36
|
+
|
|
37
|
+
if (typeof track === 'undefined') {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (track.prototype.indexExt && (files[i + 1] || {}).name === file.name + track.prototype.indexExt) {
|
|
42
|
+
indexFile = files[++i];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
track = track.extend({
|
|
46
|
+
name : file.name,
|
|
47
|
+
info : 'Local file `' + file.name + '`, size: ' + file.size + ' bytes',
|
|
48
|
+
isLocal : true,
|
|
49
|
+
dataFile : file,
|
|
50
|
+
indexFile : indexFile,
|
|
51
|
+
gz : gz
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
browser.addTrack(track, browser.tracks.length - 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return false;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Genoverse.Plugins.focusRegion = function () {
|
|
2
|
+
this.controls.push({
|
|
3
|
+
icon : '<i class="fas fa-map-marker-alt"></i>',
|
|
4
|
+
'class' : 'gv-button-large',
|
|
5
|
+
name : 'Reset focus to ' + (this.focusRegion && this.focusRegion.name ? this.focusRegion.name : this.chr + ':' + this.start + '-' + this.end),
|
|
6
|
+
action : function (browser) { browser.moveTo(browser.focusRegion.chr, browser.focusRegion.start, browser.focusRegion.end, true); },
|
|
7
|
+
init : function (browser) { browser.focusRegion = browser.focusRegion || { chr: browser.chr, start: browser.start, end: browser.end }; }
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
Genoverse.Plugins.focusRegion.requires = 'controlPanel';
|
|
12
|
+
Genoverse.Plugins.focusRegion.noCSS = true;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Genoverse.Plugins.fullscreen = function () {
|
|
2
|
+
var genoverse = this;
|
|
3
|
+
var supported = true;
|
|
4
|
+
var eventName = 'fullscreenchange'; // All the browsers have different names
|
|
5
|
+
var elemName = 'fullscreenElement'; // ... even the capitalisation varies!
|
|
6
|
+
var requestName = 'requestFullscreen';
|
|
7
|
+
var cancelName = 'exitFullscreen';
|
|
8
|
+
|
|
9
|
+
if (document.onmsfullscreenchange || document.onmsfullscreenchange === null) {
|
|
10
|
+
// We need the IE11 version of this to work; IE9-10 have the actions but not the events.
|
|
11
|
+
// The key must be present, i.e. value may be null but it must not return undefined
|
|
12
|
+
eventName = 'MSFullscreenChange';
|
|
13
|
+
elemName = 'msFullscreenElement';
|
|
14
|
+
cancelName = 'msExitFullscreen';
|
|
15
|
+
requestName = 'msRequestFullscreen';
|
|
16
|
+
} else if (document.body.mozRequestFullScreen) {
|
|
17
|
+
eventName = 'mozfullscreenchange';
|
|
18
|
+
elemName = 'mozFullScreenElement';
|
|
19
|
+
cancelName = 'mozCancelFullScreen';
|
|
20
|
+
requestName = 'mozRequestFullScreen';
|
|
21
|
+
} else if (document.body.webkitRequestFullscreen) {
|
|
22
|
+
eventName = 'webkitfullscreenchange';
|
|
23
|
+
elemName = 'webkitFullscreenElement';
|
|
24
|
+
cancelName = 'webkitCancelFullScreen';
|
|
25
|
+
requestName = 'webkitRequestFullscreen';
|
|
26
|
+
} else if (!document.onfullscreenchange) {
|
|
27
|
+
supported = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
genoverse.fullscreenVars = {
|
|
31
|
+
eventName : eventName,
|
|
32
|
+
elemName : elemName,
|
|
33
|
+
cancelName : cancelName,
|
|
34
|
+
requestName : requestName,
|
|
35
|
+
|
|
36
|
+
enterEvent: function (browser) {
|
|
37
|
+
browser.preFullscreenWidth = browser.superContainer.width();
|
|
38
|
+
browser.superContainer.addClass('gv-fullscreen');
|
|
39
|
+
browser.setWidth(window.innerWidth);
|
|
40
|
+
browser.controlPanel.find('.gv-fullscreen-button .fas').removeClass('fa-expand-arrows-alt').addClass('fa-compress-arrows-alt');
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
exitEvent: function (browser) {
|
|
44
|
+
if (browser.superContainer.hasClass('gv-fullscreen')) {
|
|
45
|
+
browser.superContainer.removeClass('gv-fullscreen');
|
|
46
|
+
browser.setWidth(browser.preFullscreenWidth);
|
|
47
|
+
browser.controlPanel.find('.gv-fullscreen-button .fas').removeClass('fa-compress-arrows-alt').addClass('fa-expand-arrows-alt');
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
eventListener: function () {
|
|
52
|
+
if (!genoverse.superContainer.is(document[genoverse.fullscreenVars.elemName])) {
|
|
53
|
+
genoverse.fullscreenVars.exitEvent(genoverse);
|
|
54
|
+
document.removeEventListener(genoverse.fullscreenVars.eventName, genoverse.fullscreenVars.eventListener);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
if (supported) {
|
|
60
|
+
genoverse.controls.push({
|
|
61
|
+
icon : '<i class="fas fa-expand-arrows-alt"></i>',
|
|
62
|
+
class : 'gv-fullscreen-button',
|
|
63
|
+
name : 'Toggle fullscreen view',
|
|
64
|
+
action : function (browser) {
|
|
65
|
+
if (browser.superContainer.hasClass('gv-fullscreen')) {
|
|
66
|
+
document[browser.fullscreenVars.cancelName]();
|
|
67
|
+
} else {
|
|
68
|
+
document.addEventListener(browser.fullscreenVars.eventName, browser.fullscreenVars.eventListener);
|
|
69
|
+
browser.superContainer[0][browser.fullscreenVars.requestName]();
|
|
70
|
+
browser.fullscreenVars.enterEvent(browser);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
Genoverse.Plugins.fullscreen.requires = 'controlPanel';
|