galaxy-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions

galaxy-dist commit 78d2a72ee1d6: Add name/designation to hda name for new datasets created in collect_primary_datasets.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1287756910 14400
# Node ID 78d2a72ee1d61099fc5958af953fb5976c544de6
# Parent 53d1fa98fa0573f84bbbd8c8264d15bfff0cb90f
Add name/designation to hda name for new datasets created in collect_primary_datasets.
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1741,7 +1741,7 @@ class Tool:
# Move data from temp location to dataset location
shutil.move( filename, primary_data.file_name )
primary_data.set_size()
- primary_data.name = outdata.name
+ primary_data.name = "%s (%s)" % ( outdata.name, designation )
primary_data.info = outdata.info
primary_data.init_meta( copy_from=outdata )
primary_data.dbkey = dbkey
1
0

galaxy-dist commit 6ce4e430b6a0: Workflows now work in Internet Explorer again. IE does not implement Array.indexOf so we define it in galaxy.base. Update excanvas
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1287786227 14400
# Node ID 6ce4e430b6a0d69e6397ca96a01350401ae05d20
# Parent 070749f1a0f12cec2b8f20931a6224d8168a8c95
Workflows now work in Internet Explorer again. IE does not implement Array.indexOf so we define it in galaxy.base. Update excanvas
--- a/static/scripts/packed/excanvas.js
+++ b/static/scripts/packed/excanvas.js
@@ -1,1 +1,1 @@
-if(!window.CanvasRenderingContext2D){(function(){var n;var p={init:function(j){var E=j||document;E.createElement("canvas");if(/MSIE/.test(navigator.userAgent)&&!window.opera){var i=this;C();E.attachEvent("onreadystatechange",function(){i.init_(E)})}},init_:function(G){var F=G.createStyleSheet();F.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}canvas object{width:100%;height:100%;border:0;background:transparen;margin:0}";var E=G.getElementsByTagName("canvas");for(var j=0;j<E.length;j++){if(!E[j].getContext){this.initElement(E[j])}}},initElement:function(j){j.getContext=function(){if(this.context_){return this.context_}return this.context_=new u(this)};var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}j.innerHTML=c();j.attachEvent("onpropertychange",D);return j}};funct
ion D(j){var i=j.srcElement;switch(j.propertyName){case"width":i.style.width=i.attributes.width.nodeValue+"px";i.getContext().clearRect();break;case"height":i.style.height=i.attributes.height.nodeValue+"px";i.getContext().clearRect();break}}p.init();function C(){document.write('<script type=text/xaml><Canvas x:Name="root" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="150" Background="Transparent"></Canvas><\/script>');var i=document.scripts;var j=i[i.length-1];n=j.uniqueID;j.id=n}function c(i){return'<object type="application/x-silverlight" ><param name="windowless" value="true"><param name="background" value="transparent"><param name="source" value="#'+n+'"></object>'}function h(){try{new ActiveXObject("AgControl.AgControl");return true}catch(i){return false}}var k=[];for(var z=0;z<16;z++){for(var y=0;y<16;y++){k[z*16+y]=z.toString(16)+y.toString(16)}}function v(){return[[1,0,0],[0,1,0],[0,0,1]]}f
unction m(F,E){var j=v();for(var i=0;i<3;i++){for(var I=0;I<3;I++){var G=0;for(var H=0;H<3;H++){G+=F[i][H]*E[H][I]}j[i][I]=G}}return j}function l(i){s(i,f(i),i.m_)}function s(j,G,i){var F=G.renderTransform;var E;if(!F){F=r(j,"<MatrixTransform/>");E=r(j,"<Matrix/>");F.matrix=E;G.renderTransform=F}else{E=F.matrix}E.m11=i[0][0];E.m12=i[0][1];E.m21=i[1][0];E.m22=i[1][1];E.offsetX=i[2][0];E.offsetY=i[2][1]}function x(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_}function t(i){var F=/rgba\(([^)]+)\)/gi.exec(i);if(F){var E=F[1].split(",");return"#"+k[Math.floor(Number(E[3])*255)]+k[Number(E[0])]+k[Number(E[1])]+k[Number(E[2])]}var j=/rgb\(([^)]+)\)/gi.exec(i);if(j){var E=j[1].split(",")
;return"#FF"+k[Number(E[0])]+k[Number(E[1])]+k[Number(E[2])]}return i}function w(i){switch(i){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function f(i){return i.canvas.firstChild.content.findName("root")}function r(i,E,F){if(F){E=E.replace(/\%(\d+)/g,function(H,G){return F[Number(G)-1]})}try{return i.canvas.firstChild.content.createFromXaml(E)}catch(j){throw Error("Could not create XAML from: "+E)}}function e(i,F,G){var E=i.lastCanvas_||r(i,"<Canvas/>");var j=r(i,F,G);E.children.add(j);s(i,E,i.m_);if(!i.lastCanvas_){f(i).children.add(E);i.lastCanvas_=E}return j}function a(i,j){if(j instanceof A){return j.createBrush_(i)}else{if(j instanceof o){throw Error("Not implemented")}else{return r(i,'<SolidColorBrush Color="%1"/>',[t(j)])}}}function u(i){this.m_=v();this.lastCanvas_=null;this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt"
;this.miterLimit=10;this.globalAlpha=1;this.canvas=i}var q=u.prototype;q.clearRect=function(){var i=f(this);i.children.clear();this.currentPath_=[];this.lastCanvas_=null};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){this.currentPath_.push("M"+j+","+i)};q.lineTo=function(j,i){if(this.currentPath_.length==0){return}this.currentPath_.push("L"+j+","+i)};q.bezierCurveTo=function(E,i,H,G,F,j){if(this.currentPath_.length==0){return}this.currentPath_.push("C"+E+","+i+" "+H+","+G+" "+F+" "+j)};q.quadraticCurveTo=function(F,E,j,i){if(this.currentPath_.length==0){return}this.currentPath_.push("Q"+F+","+E+" "+j+","+i)};q.arcTo=function(E,G,j,F,i){if(this.currentPath_.length==0){return}};q.arc=function(J,G,I,F,j,E){var i=Math.abs(F-j);if(F==j){return}var P=J+I*Math.cos(j);var O=G+I*Math.sin(j);if(i>=2*Math.PI){this.arc(J,G,I,F,F+Math.PI,E);this.arc(J,G,I,F+Math.PI,F+2*Math.PI,E);this.moveTo(P,O);return}var K=J+I*Math.cos(F);var H=G+I*Math.sin(F);var N=i*180/Math.PI
;var L=E?0:1;var M=N>=180==Boolean(E)?0:1;if(this.currentPath_.length!=0){this.lineTo(K,H)}else{this.moveTo(K,H)}this.currentPath_.push("A"+I+","+I+" "+N+" "+M+" "+L+" "+P+","+O)};q.rect=function(E,j,i,F){this.moveTo(E,j);this.lineTo(E+i,j);this.lineTo(E+i,j+F);this.lineTo(E,j+F);this.closePath()};q.strokeRect=function(E,j,i,F){this.beginPath();this.moveTo(E,j);this.lineTo(E+i,j);this.lineTo(E+i,j+F);this.lineTo(E,j+F);this.closePath();this.stroke();this.currentPath_=[]};q.fillRect=function(E,j,i,F){this.beginPath();this.moveTo(E,j);this.lineTo(E+i,j);this.lineTo(E+i,j+F);this.lineTo(E,j+F);this.closePath();this.fill();this.currentPath_=[]};q.createLinearGradient=function(j,F,i,E){return new d(j,F,i,E)};q.createRadialGradient=function(F,H,E,j,G,i){return new g(F,H,E,j,G,i)};q.drawImage=function(E,M){var P,O,i,I,K,J,L,H;if(arguments.length==3){P=arguments[1];O=arguments[2]}else{if(arguments.length==5){P=arguments[1];O=arguments[2];i=arguments[3];I=arguments[4]}else{if(argumen
ts.length==9){K=arguments[1];J=arguments[2];L=arguments[3];H=arguments[4];P=arguments[5];O=arguments[6];i=arguments[7];I=arguments[8]}else{throw Error("Invalid number of arguments")}}}var G;if(arguments.length==9){G=e(this,'<Image Source="%1"/>',[E.src]);var F=r(this,'<RectangleGeometry Rect="%1,%2,%3,%4"/>',[K,J,L,H]);G.clip=F;var j=v();j[2][0]=-K;j[2][1]=-J;var N=v();N[0][0]=i/L;N[1][1]=I/H;j=m(j,N);j[2][0]+=P;j[2][1]+=O;s(this,G,j)}else{G=e(this,'<Image Source="%1" Canvas.Left="%2" Canvas.Top="%3"/>',[E.src,P,O]);if(i!=undefined||I!=undefined){G.width=i;G.height=I;G.stretch="fill"}}};q.stroke=function(){if(this.currentPath_.length==0){return}var i=e(this,'<Path Data="%1"/>',[this.currentPath_.join(" ")]);i.stroke=a(this,this.strokeStyle);i.opacity=this.globalAlpha;i.strokeThickness=this.lineWidth;i.strokeMiterLimit=this.miterLimit;i.strokeLineJoin=this.lineJoin;i.strokeEndLineCap=i.strokeStartLineCap=w(this.lineCap)};q.fill=function(){if(this.currentPath_.length==0){retur
n}var i=e(this,'<Path Data="%1"/>',[this.currentPath_.join(" ")]);i.data.fillRule="NonZero";i.fill=a(this,this.fillStyle)};q.closePath=function(){this.currentPath_.push("z")};function B(j,i){j.m_=i;j.lastCanvas_=null}q.save=function(){var i={};x(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);B(this,m(v(),this.m_))};q.restore=function(){x(this.aStack_.pop(),this);B(this,this.mStack_.pop())};q.translate=function(E,j){var i=[[1,0,0],[0,1,0],[E,j,1]];B(this,m(i,this.m_))};q.rotate=function(j){var F=Math.cos(j);var E=Math.sin(j);var i=[[F,E,0],[-E,F,0],[0,0,1]];B(this,m(i,this.m_))};q.scale=function(E,j){var i=[[E,0,0],[0,j,0],[0,0,1]];B(this,m(i,this.m_))};q.transform=function(G,F,I,H,j,i){var E=[[G,F,0],[I,H,0],[j,i,1]];B(this,m(E,this.m_))};q.setTransform=function(F,E,H,G,j,i){B(this,[[F,E,0],[H,G,0],[j,i,1],])};q.clip=function(){};q.createPattern=function(){return new o};function A(){this.colors_=[]}A.prototype.addColorStop=function(j,i){i=t(i);this.colors_.push({off
set:j,color:i})};A.prototype.createStops_=function(E,G,j){var I=G.gradientStops;for(var H=0,J;J=j[H];H++){var F=t(J.color);I.add(r(E,'<GradientStop Color="%1" Offset="%2"/>',[F,J.offset]))}};function d(j,F,i,E){A.call(this);this.x0_=j;this.y0_=F;this.x1_=i;this.y1_=E}d.prototype=new A;d.prototype.createBrush_=function(i){var j=r(i,'<LinearGradientBrush MappingMode="Absolute" StartPoint="%1,%2" EndPoint="%3,%4"/>',[this.x0_,this.y0_,this.x1_,this.y1_]);this.createStops_(i,j,this.colors_);return j};function b(i){return isNaN(i)||!isFinite(i)}function g(G,I,F,E,H,i){if(F<0||i<0||b(G)||b(I)||b(E)||b(H)){var j=Error("DOMException.INDEX_SIZE_ERR");j.code=1;throw j}A.call(this);this.x0_=G;this.y0_=I;this.r0_=F;this.x1_=E;this.y1_=H;this.r1_=i}g.prototype=new A;A.prototype.createBrush_=function(F){if(this.x0_==this.x1_&&this.y0_==this.y1_&&this.r0_==this.r1_){return null}var j=Math.max(this.r0_,this.r1_);var I=Math.min(this.r0_,this.r1_);var G=r(F,'<RadialGradientBrush MappingMode="
Absolute" GradientOrigin="%1,%2" Center="%3,%4" RadiusX="%5" RadiusY="%5"/>',[this.x0_,this.y0_,this.x1_,this.y1_,j]);var E=this.colors_.concat();if(this.r1_<this.r0_){E.reverse();for(var H=0,J;J=E[H];H++){J.offset=1-J.offset}}E.sort(function(K,i){return K.offset-i.offset});if(I>0){for(var H=0,J;J=E[H];H++){J.offset=I/j+(j-I)/j*J.offset}}this.createStops_(F,G,E);return G};function o(){}G_vmlCanvasManager=p;CanvasRenderingContext2D=u;CanvasGradient=A;CanvasPattern=o})()};
+if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&").replace(/"/g,""")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(th
is.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j<m.length;j++){this.initElement(m[j])}},initElement:function(j){if(!j.getContext){j.getContext=y;R(j.ownerDocument);j.innerHTML="";j.attachEvent("onpropertychange",x);j.attachEvent("onresize",W);var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}}return j}};function x(j){var i=j.srcElement;switch(j.propertyName){case"width":i.getContext().clearRect();i.style.width=i.attributes.width.nodeValue+"px";i.firstChild.style.width=i.clientWidth+"px";break;case"height":i.getContext().clearRect();i.style.height=i.attributes.height.nodeValue+"px";i.firstChild.style.height=i.clientHeight+"px";break}}function W(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.width=i.clientWidth+"px";i.firstChild.style.height=i.clientHeight+"px"}}e
.init();var k=[];for(var ae=0;ae<16;ae++){for(var ad=0;ad<16;ad++){k[ae*16+ad]=ae.toString(16)+ad.toString(16)}}function B(){return[[1,0,0],[0,1,0],[0,0,1]]}function J(p,m){var j=B();for(var i=0;i<3;i++){for(var ah=0;ah<3;ah++){var Z=0;for(var ag=0;ag<3;ag++){Z+=p[i][ag]*m[ag][ah]}j[i][ah]=Z}}return j}function v(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.font=j.font;i.textAlign=j.textAlign;i.textBaseline=j.textBaseline;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_;i.lineScale_=j.lineScale_}var b={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9E
A0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00"
,lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#D
DA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function M(j){var p=j.indexOf("(",3);var i=j.indexOf(")",p+1);var m=j.substring(p+1,i).split(",");if(m.length!=4||j.charAt(3)!="a"){m[3]=1}return m}function c(i){return parseFloat(i)/100}function r(j,m,i){return Math.min(i,Math.max(m,j))}function I(ag){var i,ai,aj,ah,ak,Z;ah=parseFloat(ag[0])/360%360;if(ah<0){ah++}ak=r(c(ag[1]),0,1);Z=r(c(ag[2]),0,1);if(ak==0){i=ai=aj=Z}else{var j=Z<0.5?Z*(1+ak):Z+ak-Z*ak;var m=2*Z-j;i=a(m,j,ah+1/3);ai=a(m,j,ah);aj=a(m,j,ah-1/3)}return"#"+k[Math.floor(i*255)]+k[Math.floor(ai*255)]+k[Mat
h.floor(aj*255)]}function a(j,i,m){if(m<0){m++}if(m>1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=pars
eFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style.backgroundColor="red";p.
style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+
2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,
i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" <g_vml_:group",' coordsize="',d*i,
",",d*ag,'"',' coordorigin="0,0"',' style="width:',i,"px;height:",ag,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var Z=[];Z.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",n(az.x/d),",","Dy=",n(az.y/d),"");var av=az;var au=V(this,aj+al,ah);var ar=V(this,aj,ah+ay);var an=V(this,aj+al,ah+ay);av.x=ab.max(av.x,au.x,ar.x,an.x);av.y=ab.max(av.y,au.y,ar.y,an.y);ax.push("padding:0 ",n(av.x/d),"px ",n(av.y/d),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",Z.join(""),", sizingmethod='clip');")}else{ax.push("top:",n(az.y/d),"px;left:",n(az.x/d),"px;")}ax.push(' ">','<g_vml_:image src="',aq.src,'"',' style="width:',d*al,"px;"," height:",d*ay,'px"',' cropleft="',ao/ai,'"',' croptop="',am/aw,'"',' cropright="',(ai-ao-at)/ai,'"',' cropbottom="',(aw-am-aA)/aw,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(al){var
aj=[];var Z=false;var m=10;var am=10;aj.push("<g_vml_:shape",' filled="',!!al,'"',' style="position:absolute;width:',m,"px;height:",am,'px;"',' coordorigin="0,0"',' coordsize="',d*m,",",d*am,'"',' stroked="',!al,'"',' path="');var an=false;var ag={x:null,y:null};var ak={x:null,y:null};for(var ah=0;ah<this.currentPath_.length;ah++){var j=this.currentPath_[ah];var ai;switch(j.type){case"moveTo":ai=j;aj.push(" m ",n(j.x),",",n(j.y));break;case"lineTo":aj.push(" l ",n(j.x),",",n(j.y));break;case"close":aj.push(" x ");j=null;break;case"bezierCurveTo":aj.push(" c ",n(j.cp1x),",",n(j.cp1y),",",n(j.cp2x),",",n(j.cp2y),",",n(j.x),",",n(j.y));break;case"at":case"wa":aj.push(" ",j.type," ",n(j.x-this.arcScaleX_*j.radius),",",n(j.y-this.arcScaleY_*j.radius)," ",n(j.x+this.arcScaleX_*j.radius),",",n(j.y+this.arcScaleY_*j.radius)," ",n(j.xStart),",",n(j.yStart)," ",n(j.xEnd),",",n(j.yEnd));break}if(j){if(ag.x==null||j.x<ag.x){ag.x=j.x}if(ak.x==null||j.x>ak.x){ak.x=j.x}if(ag.y==null||j.y<
ag.y){ag.y=j.y}if(ak.y==null||j.y>ak.y){ak.y=j.y}}}aj.push(' ">');if(!al){w(this,aj)}else{G(this,aj,ag,ak)}aj.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",aj.join(""))};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("<g_vml_:stroke",' opacity="',Z,'"',' joinstyle="',m.lineJoin,'"',' miterlimit="',m.miterLimit,'"',' endcap="',S(m.lineCap),'"',' weight="',i,'px"',' color="',p,'" />')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p
/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].color;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH<ap;aH++){var ao=av[aH];aE.push(ao.offset*am+ax+" "+ao.color)}ai.push('<g_vml_:fill type="',aj.type_,'"',' method="none" focus="100%"',' color="',au,'"',' color2="',at,'"',' colors="',aE.join(","),'"',' opacity="',ay,'"',' g_o_:opacity2="',az,'"',' angle="',an,'"',' focusposition="',aF.x,",",aF.y,'" />')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("<g_vml_:fill",' position="',ah/j*aB*aB,",",aC/p*aA*aA,'"',' type="tile"',' src="',aj.src_,'" />')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('<g_vml_:fill color="',aw,'" opacity="',aG,'" />')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"}
)};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform
=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('<g_vml_:line from="',-j,' 0" to="',ar,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!ai,'" stroked="',!!ai,'" style="position:absolute;width:1px;height:1px;">');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size
})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d)+","+n(aq.y/d);ag.push('<g_vml_:skew on="t" matrix="',an,'" ',' offset="',al,'" origin="',j,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',af(am),'" style="v-text-align:',Z,";font:",af(p),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.
textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_M
ODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P})()};
--- a/static/scripts/excanvas.js
+++ b/static/scripts/excanvas.js
@@ -13,9 +13,9 @@
// limitations under the License.
-// Known Issues: (From VML version)
+// Known Issues:
//
-// * Patterns are not implemented.
+// * Patterns only support repeat.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
@@ -28,59 +28,107 @@
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.
-//Known Issues: Silverlight version
-//
-// * Doing a transformation during a path (ie lineTo, transform, lineTo) will
-// not work corerctly because the transform is done to the whole path (ie
-// transform, lineTo, lineTo)
-// * Patterns are not yet implemented.
+// Only add this code if we do not already have a canvas implementation
+if (!document.createElement('canvas').getContext) {
+(function() {
-// only add this code if we do not already have a canvas implementation
-if (!window.CanvasRenderingContext2D) {
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+ var abs = m.abs;
+ var sqrt = m.sqrt;
-(function () {
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
- var xamlId;
+ var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];
+
+ /**
+ * This funtion is assigned to the <canvas> elements as element.getContext().
+ * @this {HTMLElement}
+ * @return {CanvasRenderingContext2D_}
+ */
+ function getContext() {
+ return this.context_ ||
+ (this.context_ = new CanvasRenderingContext2D_(this));
+ }
+
+ var slice = Array.prototype.slice;
+
+ /**
+ * Binds a function to an object. The returned function will always use the
+ * passed in {@code obj} as {@code this}.
+ *
+ * Example:
+ *
+ * g = bind(f, obj, a, b)
+ * g(c, d) // will do f.call(obj, a, b, c, d)
+ *
+ * @param {Function} f The function to bind the object to
+ * @param {Object} obj The object that should act as this when the function
+ * is called
+ * @param {*} var_args Rest arguments that will be used as the initial
+ * arguments when the function is called
+ * @return {Function} A new function that has bound this
+ */
+ function bind(f, obj, var_args) {
+ var a = slice.call(arguments, 2);
+ return function() {
+ return f.apply(obj, a.concat(slice.call(arguments)));
+ };
+ }
+
+ function encodeHtmlAttribute(s) {
+ return String(s).replace(/&/g, '&').replace(/"/g, '"');
+ }
+
+ function addNamespace(doc, prefix, urn) {
+ if (!doc.namespaces[prefix]) {
+ doc.namespaces.add(prefix, urn, '#default#VML');
+ }
+ }
+
+ function addNamespacesAndStylesheet(doc) {
+ addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml');
+ addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office');
+
+ // Setup default CSS. Only add one style sheet per document
+ if (!doc.styleSheets['ex_canvas_']) {
+ var ss = doc.createStyleSheet();
+ ss.owningElement.id = 'ex_canvas_';
+ ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
+ // default size is 300x150 in Gecko and Opera
+ 'text-align:left;width:300px;height:150px}';
+ }
+ }
+
+ // Add namespaces and stylesheet at startup.
+ addNamespacesAndStylesheet(document);
var G_vmlCanvasManager_ = {
- init: function (opt_doc) {
+ init: function(opt_doc) {
var doc = opt_doc || document;
// Create a dummy element so that IE will allow canvas elements to be
// recognized.
doc.createElement('canvas');
- if (/MSIE/.test(navigator.userAgent) && !window.opera) {
- var self = this;
-
- createXamlScriptTag();
-
- doc.attachEvent('onreadystatechange', function () {
- self.init_(doc);
- });
- }
+ doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
},
- init_: function (doc) {
- // setup default css
- var ss = doc.createStyleSheet();
- ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
- // default size is 300x150 in Gecko and Opera
- 'text-align:left;width:300px;height:150px}' +
- 'canvas object{width:100%;height:100%;border:0;' +
- 'background:transparen;margin:0}';
-
+ init_: function(doc) {
// find all canvas elements
var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) {
- if (!els[i].getContext) {
- this.initElement(els[i]);
- }
+ this.initElement(els[i]);
}
},
-
/**
* Public initializes a canvas element so that it can be used as canvas
* element from now on. This is called automatically before the page is
@@ -89,35 +137,39 @@ if (!window.CanvasRenderingContext2D) {
* @param {HTMLElement} el The canvas element to initialize.
* @return {HTMLElement} the element that was created.
*/
- initElement: function (el) {
- el.getContext = function () {
- if (this.context_) {
- return this.context_;
+ initElement: function(el) {
+ if (!el.getContext) {
+ el.getContext = getContext;
+
+ // Add namespaces and stylesheet to document of the element.
+ addNamespacesAndStylesheet(el.ownerDocument);
+
+ // Remove fallback content. There is no way to hide text nodes so we
+ // just remove all childNodes. We could hide all elements and remove
+ // text nodes but who really cares about the fallback content.
+ el.innerHTML = '';
+
+ // do not use inline function because that will leak memory
+ el.attachEvent('onpropertychange', onPropertyChange);
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + 'px';
+ } else {
+ el.width = el.clientWidth;
}
- return this.context_ = new CanvasRenderingContext2D_(this);
- };
-
- var attrs = el.attributes;
- if (attrs.width && attrs.width.specified) {
- // TODO: use runtimeStyle and coordsize
- // el.getContext().setWidth_(attrs.width.nodeValue);
- el.style.width = attrs.width.nodeValue + 'px';
- } else {
- el.width = el.clientWidth;
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + 'px';
+ } else {
+ el.height = el.clientHeight;
+ }
+ //el.getContext().setCoordsize_()
}
- if (attrs.height && attrs.height.specified) {
- // TODO: use runtimeStyle and coordsize
- // el.getContext().setHeight_(attrs.height.nodeValue);
- el.style.height = attrs.height.nodeValue + 'px';
- } else {
- el.height = el.clientHeight;
- }
-
- // insert object tag
- el.innerHTML = getObjectHtml();
-
- // do not use inline function because that will leak memory
- el.attachEvent('onpropertychange', onPropertyChange);
return el;
}
};
@@ -127,58 +179,34 @@ if (!window.CanvasRenderingContext2D) {
switch (e.propertyName) {
case 'width':
+ el.getContext().clearRect();
el.style.width = el.attributes.width.nodeValue + 'px';
- el.getContext().clearRect();
+ // In IE8 this does not trigger onresize.
+ el.firstChild.style.width = el.clientWidth + 'px';
break;
case 'height':
+ el.getContext().clearRect();
el.style.height = el.attributes.height.nodeValue + 'px';
- el.getContext().clearRect();
+ el.firstChild.style.height = el.clientHeight + 'px';
break;
}
}
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
G_vmlCanvasManager_.init();
- function createXamlScriptTag() {
- // This script tag contains the boilerplate XAML.
- document.write('<script type=text/xaml>' +
- '<Canvas x:Name="root" ' +
- 'xmlns="http://schemas.microsoft.com/client/2007" ' +
- 'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ' +
- 'Width="300" ' +
- 'Height="150" ' +
- 'Background="Transparent"> ' +
- '</Canvas>' +
- '</script>');
- // Find the id of the writtenscript file.
- var scripts = document.scripts;
- var script = scripts[scripts.length - 1];
- xamlId = script.uniqueID;
- script.id = xamlId;
- }
-
- function getObjectHtml(fn) {
- return '<object type="application/x-silverlight" >' +
- '<param name="windowless" value="true">' +
- '<param name="background" value="transparent">' +
- '<param name="source" value="#' + xamlId + '">' +
- '</object>';
- }
-
- function hasSilverlight() {
- try {
- new ActiveXObject('AgControl.AgControl');
- return true;
- } catch(_) {
- return false;
- }
- }
-
// precompute "00" to "FF"
- var dec2hex = [];
+ var decToHex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
- dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
+ decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}
@@ -207,30 +235,6 @@ if (!window.CanvasRenderingContext2D) {
return result;
}
- function doTransform(ctx) {
- transformObject(ctx, getRoot(ctx), ctx.m_);
- }
-
- function transformObject(ctx, obj, m) {
- var transform = obj.renderTransform;
- var matrix;
- if (!transform) {
- transform = create(ctx, '<MatrixTransform/>');
- matrix = create(ctx, '<Matrix/>');
- transform.matrix = matrix;
- obj.renderTransform = transform;
- } else {
- matrix = transform.matrix;
- }
-
- matrix.m11 = m[0][0];
- matrix.m12 = m[0][1];
- matrix.m21 = m[1][0];
- matrix.m22 = m[1][1];
- matrix.offsetX = m[2][0];
- matrix.offsetY = m[2][1];
- }
-
function copyState(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
@@ -243,93 +247,327 @@ if (!window.CanvasRenderingContext2D) {
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
o2.globalAlpha = o1.globalAlpha;
+ o2.font = o1.font;
+ o2.textAlign = o1.textAlign;
+ o2.textBaseline = o1.textBaseline;
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
+ o2.lineScale_ = o1.lineScale_;
}
- function translateColor(s) {
- var rgbaMatch = /rgba\(([^)]+)\)/gi.exec(s);
- if (rgbaMatch) {
- var parts = rgbaMatch[1].split(',');
- return '#' + dec2hex[Math.floor(Number(parts[3]) * 255)] +
- dec2hex[Number(parts[0])] +
- dec2hex[Number(parts[1])] +
- dec2hex[Number(parts[2])];
+ var colorData = {
+ aliceblue: '#F0F8FF',
+ antiquewhite: '#FAEBD7',
+ aquamarine: '#7FFFD4',
+ azure: '#F0FFFF',
+ beige: '#F5F5DC',
+ bisque: '#FFE4C4',
+ black: '#000000',
+ blanchedalmond: '#FFEBCD',
+ blueviolet: '#8A2BE2',
+ brown: '#A52A2A',
+ burlywood: '#DEB887',
+ cadetblue: '#5F9EA0',
+ chartreuse: '#7FFF00',
+ chocolate: '#D2691E',
+ coral: '#FF7F50',
+ cornflowerblue: '#6495ED',
+ cornsilk: '#FFF8DC',
+ crimson: '#DC143C',
+ cyan: '#00FFFF',
+ darkblue: '#00008B',
+ darkcyan: '#008B8B',
+ darkgoldenrod: '#B8860B',
+ darkgray: '#A9A9A9',
+ darkgreen: '#006400',
+ darkgrey: '#A9A9A9',
+ darkkhaki: '#BDB76B',
+ darkmagenta: '#8B008B',
+ darkolivegreen: '#556B2F',
+ darkorange: '#FF8C00',
+ darkorchid: '#9932CC',
+ darkred: '#8B0000',
+ darksalmon: '#E9967A',
+ darkseagreen: '#8FBC8F',
+ darkslateblue: '#483D8B',
+ darkslategray: '#2F4F4F',
+ darkslategrey: '#2F4F4F',
+ darkturquoise: '#00CED1',
+ darkviolet: '#9400D3',
+ deeppink: '#FF1493',
+ deepskyblue: '#00BFFF',
+ dimgray: '#696969',
+ dimgrey: '#696969',
+ dodgerblue: '#1E90FF',
+ firebrick: '#B22222',
+ floralwhite: '#FFFAF0',
+ forestgreen: '#228B22',
+ gainsboro: '#DCDCDC',
+ ghostwhite: '#F8F8FF',
+ gold: '#FFD700',
+ goldenrod: '#DAA520',
+ grey: '#808080',
+ greenyellow: '#ADFF2F',
+ honeydew: '#F0FFF0',
+ hotpink: '#FF69B4',
+ indianred: '#CD5C5C',
+ indigo: '#4B0082',
+ ivory: '#FFFFF0',
+ khaki: '#F0E68C',
+ lavender: '#E6E6FA',
+ lavenderblush: '#FFF0F5',
+ lawngreen: '#7CFC00',
+ lemonchiffon: '#FFFACD',
+ lightblue: '#ADD8E6',
+ lightcoral: '#F08080',
+ lightcyan: '#E0FFFF',
+ lightgoldenrodyellow: '#FAFAD2',
+ lightgreen: '#90EE90',
+ lightgrey: '#D3D3D3',
+ lightpink: '#FFB6C1',
+ lightsalmon: '#FFA07A',
+ lightseagreen: '#20B2AA',
+ lightskyblue: '#87CEFA',
+ lightslategray: '#778899',
+ lightslategrey: '#778899',
+ lightsteelblue: '#B0C4DE',
+ lightyellow: '#FFFFE0',
+ limegreen: '#32CD32',
+ linen: '#FAF0E6',
+ magenta: '#FF00FF',
+ mediumaquamarine: '#66CDAA',
+ mediumblue: '#0000CD',
+ mediumorchid: '#BA55D3',
+ mediumpurple: '#9370DB',
+ mediumseagreen: '#3CB371',
+ mediumslateblue: '#7B68EE',
+ mediumspringgreen: '#00FA9A',
+ mediumturquoise: '#48D1CC',
+ mediumvioletred: '#C71585',
+ midnightblue: '#191970',
+ mintcream: '#F5FFFA',
+ mistyrose: '#FFE4E1',
+ moccasin: '#FFE4B5',
+ navajowhite: '#FFDEAD',
+ oldlace: '#FDF5E6',
+ olivedrab: '#6B8E23',
+ orange: '#FFA500',
+ orangered: '#FF4500',
+ orchid: '#DA70D6',
+ palegoldenrod: '#EEE8AA',
+ palegreen: '#98FB98',
+ paleturquoise: '#AFEEEE',
+ palevioletred: '#DB7093',
+ papayawhip: '#FFEFD5',
+ peachpuff: '#FFDAB9',
+ peru: '#CD853F',
+ pink: '#FFC0CB',
+ plum: '#DDA0DD',
+ powderblue: '#B0E0E6',
+ rosybrown: '#BC8F8F',
+ royalblue: '#4169E1',
+ saddlebrown: '#8B4513',
+ salmon: '#FA8072',
+ sandybrown: '#F4A460',
+ seagreen: '#2E8B57',
+ seashell: '#FFF5EE',
+ sienna: '#A0522D',
+ skyblue: '#87CEEB',
+ slateblue: '#6A5ACD',
+ slategray: '#708090',
+ slategrey: '#708090',
+ snow: '#FFFAFA',
+ springgreen: '#00FF7F',
+ steelblue: '#4682B4',
+ tan: '#D2B48C',
+ thistle: '#D8BFD8',
+ tomato: '#FF6347',
+ turquoise: '#40E0D0',
+ violet: '#EE82EE',
+ wheat: '#F5DEB3',
+ whitesmoke: '#F5F5F5',
+ yellowgreen: '#9ACD32'
+ };
+
+
+ function getRgbHslContent(styleString) {
+ var start = styleString.indexOf('(', 3);
+ var end = styleString.indexOf(')', start + 1);
+ var parts = styleString.substring(start + 1, end).split(',');
+ // add alpha if needed
+ if (parts.length != 4 || styleString.charAt(3) != 'a') {
+ parts[3] = 1;
+ }
+ return parts;
+ }
+
+ function percent(s) {
+ return parseFloat(s) / 100;
+ }
+
+ function clamp(v, min, max) {
+ return Math.min(max, Math.max(min, v));
+ }
+
+ function hslToRgb(parts){
+ var r, g, b, h, s, l;
+ h = parseFloat(parts[0]) / 360 % 360;
+ if (h < 0)
+ h++;
+ s = clamp(percent(parts[1]), 0, 1);
+ l = clamp(percent(parts[2]), 0, 1);
+ if (s == 0) {
+ r = g = b = l; // achromatic
+ } else {
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hueToRgb(p, q, h + 1 / 3);
+ g = hueToRgb(p, q, h);
+ b = hueToRgb(p, q, h - 1 / 3);
}
- var rgbMatch = /rgb\(([^)]+)\)/gi.exec(s);
- if (rgbMatch) {
- var parts = rgbMatch[1].split(',');
- return '#FF' + dec2hex[Number(parts[0])] +
- dec2hex[Number(parts[1])] +
- dec2hex[Number(parts[2])];
+ return '#' + decToHex[Math.floor(r * 255)] +
+ decToHex[Math.floor(g * 255)] +
+ decToHex[Math.floor(b * 255)];
+ }
+
+ function hueToRgb(m1, m2, h) {
+ if (h < 0)
+ h++;
+ if (h > 1)
+ h--;
+
+ if (6 * h < 1)
+ return m1 + (m2 - m1) * 6 * h;
+ else if (2 * h < 1)
+ return m2;
+ else if (3 * h < 2)
+ return m1 + (m2 - m1) * (2 / 3 - h) * 6;
+ else
+ return m1;
+ }
+
+ var processStyleCache = {};
+
+ function processStyle(styleString) {
+ if (styleString in processStyleCache) {
+ return processStyleCache[styleString];
}
- return s;
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.charAt(0) == '#') {
+ str = styleString;
+ } else if (/^rgb/.test(styleString)) {
+ var parts = getRgbHslContent(styleString);
+ var str = '#', n;
+ for (var i = 0; i < 3; i++) {
+ if (parts[i].indexOf('%') != -1) {
+ n = Math.floor(percent(parts[i]) * 255);
+ } else {
+ n = +parts[i];
+ }
+ str += decToHex[clamp(n, 0, 255)];
+ }
+ alpha = +parts[3];
+ } else if (/^hsl/.test(styleString)) {
+ var parts = getRgbHslContent(styleString);
+ str = hslToRgb(parts);
+ alpha = parts[3];
+ } else {
+ str = colorData[styleString] || styleString;
+ }
+ return processStyleCache[styleString] = {color: str, alpha: alpha};
}
- function processLineCap(lineCap) {
- switch (lineCap) {
- case 'butt':
- return 'flat';
- case 'round':
- return 'round';
- case 'square':
- default:
- return 'square';
+ var DEFAULT_STYLE = {
+ style: 'normal',
+ variant: 'normal',
+ weight: 'normal',
+ size: 10,
+ family: 'sans-serif'
+ };
+
+ // Internal text style cache
+ var fontStyleCache = {};
+
+ function processFontStyle(styleString) {
+ if (fontStyleCache[styleString]) {
+ return fontStyleCache[styleString];
}
+
+ var el = document.createElement('div');
+ var style = el.style;
+ try {
+ style.font = styleString;
+ } catch (ex) {
+ // Ignore failures to set to invalid font.
+ }
+
+ return fontStyleCache[styleString] = {
+ style: style.fontStyle || DEFAULT_STYLE.style,
+ variant: style.fontVariant || DEFAULT_STYLE.variant,
+ weight: style.fontWeight || DEFAULT_STYLE.weight,
+ size: style.fontSize || DEFAULT_STYLE.size,
+ family: style.fontFamily || DEFAULT_STYLE.family
+ };
}
- function getRoot(ctx) {
- return ctx.canvas.firstChild.content.findName('root');
+ function getComputedStyle(style, element) {
+ var computedStyle = {};
+
+ for (var p in style) {
+ computedStyle[p] = style[p];
+ }
+
+ // Compute the size
+ var canvasFontSize = parseFloat(element.currentStyle.fontSize),
+ fontSize = parseFloat(style.size);
+
+ if (typeof style.size == 'number') {
+ computedStyle.size = style.size;
+ } else if (style.size.indexOf('px') != -1) {
+ computedStyle.size = fontSize;
+ } else if (style.size.indexOf('em') != -1) {
+ computedStyle.size = canvasFontSize * fontSize;
+ } else if(style.size.indexOf('%') != -1) {
+ computedStyle.size = (canvasFontSize / 100) * fontSize;
+ } else if (style.size.indexOf('pt') != -1) {
+ computedStyle.size = fontSize / .75;
+ } else {
+ computedStyle.size = canvasFontSize;
+ }
+
+ // Different scaling between normal text and VML text. This was found using
+ // trial and error to get the same size as non VML text.
+ computedStyle.size *= 0.981;
+
+ return computedStyle;
}
- function create(ctx, s, opt_args) {
- if (opt_args) {
- s = s.replace(/\%(\d+)/g, function(match, index) {
- return opt_args[Number(index) - 1];
- });
- }
-
- try {
- return ctx.canvas.firstChild.content.createFromXaml(s);
- } catch (ex) {
- throw Error('Could not create XAML from: ' + s);
- }
+ function buildStyle(style) {
+ return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +
+ style.size + 'px ' + style.family;
}
- function drawShape(ctx, s, opt_args) {
- var canvas = ctx.lastCanvas_ || create(ctx, '<Canvas/>');
- var shape = create(ctx, s, opt_args);
- canvas.children.add(shape);
- transformObject(ctx, canvas, ctx.m_);
- if (!ctx.lastCanvas_) {
- getRoot(ctx).children.add(canvas);
- ctx.lastCanvas_ = canvas;
- }
- return shape;
- }
+ var lineCapMap = {
+ 'butt': 'flat',
+ 'round': 'round'
+ };
- function createBrushObject(ctx, value) {
- if (value instanceof CanvasGradient_) {
- return value.createBrush_(ctx);
- } else if (value instanceof CanvasPattern_) {
- throw Error('Not implemented');
- } else {
- return create(ctx, '<SolidColorBrush Color="%1"/>',
- [translateColor(value)]);
- }
+ function processLineCap(lineCap) {
+ return lineCapMap[lineCap] || 'square';
}
/**
* This class implements CanvasRenderingContext2D interface as described by
* the WHATWG.
- * @param {HTMLElement} surfaceElement The element that the 2D context should
- * be associated with
+ * @param {HTMLElement} canvasElement The element that the 2D context should
+ * be associated with
*/
- function CanvasRenderingContext2D_(surfaceElement) {
+ function CanvasRenderingContext2D_(canvasElement) {
this.m_ = createMatrixIdentity();
- this.lastCanvas_ = null;
this.mStack_ = [];
this.aStack_ = [];
@@ -342,100 +580,134 @@ if (!window.CanvasRenderingContext2D) {
this.lineWidth = 1;
this.lineJoin = 'miter';
this.lineCap = 'butt';
- this.miterLimit = 10;
+ this.miterLimit = Z * 1;
this.globalAlpha = 1;
- this.canvas = surfaceElement;
- };
+ this.font = '10px sans-serif';
+ this.textAlign = 'left';
+ this.textBaseline = 'alphabetic';
+ this.canvas = canvasElement;
+ var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' +
+ canvasElement.clientHeight + 'px;overflow:hidden;position:absolute';
+ var el = canvasElement.ownerDocument.createElement('div');
+ el.style.cssText = cssText;
+ canvasElement.appendChild(el);
+
+ var overlayEl = el.cloneNode(false);
+ // Use a non transparent background.
+ overlayEl.style.backgroundColor = 'red';
+ overlayEl.style.filter = 'alpha(opacity=0)';
+ canvasElement.appendChild(overlayEl);
+
+ this.element_ = el;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ this.lineScale_ = 1;
+ }
var contextPrototype = CanvasRenderingContext2D_.prototype;
-
contextPrototype.clearRect = function() {
- var root = getRoot(this);
- root.children.clear();
-
- // TODO: Implement
- this.currentPath_ = [];
- this.lastCanvas_ = null;
-
+ if (this.textMeasureEl_) {
+ this.textMeasureEl_.removeNode(true);
+ this.textMeasureEl_ = null;
+ }
+ this.element_.innerHTML = '';
};
contextPrototype.beginPath = function() {
// TODO: Branch current matrix so that save/restore has no effect
// as per safari docs.
-
this.currentPath_ = [];
};
contextPrototype.moveTo = function(aX, aY) {
- this.currentPath_.push('M' + aX + ',' + aY);
+ var p = getCoords(this, aX, aY);
+ this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
+ this.currentX_ = p.x;
+ this.currentY_ = p.y;
};
contextPrototype.lineTo = function(aX, aY) {
- if (this.currentPath_.length == 0) return;
- this.currentPath_.push('L' + aX + ',' + aY);
+ var p = getCoords(this, aX, aY);
+ this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
+
+ this.currentX_ = p.x;
+ this.currentY_ = p.y;
};
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY) {
- if (this.currentPath_.length == 0) return;
- this.currentPath_.push('C' + aCP1x + ',' + aCP1y + ' ' +
- aCP2x + ',' + aCP2y + ' ' +
- aX + ' ' + aY);
+ var p = getCoords(this, aX, aY);
+ var cp1 = getCoords(this, aCP1x, aCP1y);
+ var cp2 = getCoords(this, aCP2x, aCP2y);
+ bezierCurveTo(this, cp1, cp2, p);
};
+ // Helper function that takes the already fixed cordinates.
+ function bezierCurveTo(self, cp1, cp2, p) {
+ self.currentPath_.push({
+ type: 'bezierCurveTo',
+ cp1x: cp1.x,
+ cp1y: cp1.y,
+ cp2x: cp2.x,
+ cp2y: cp2.y,
+ x: p.x,
+ y: p.y
+ });
+ self.currentX_ = p.x;
+ self.currentY_ = p.y;
+ }
+
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
- if (this.currentPath_.length == 0) return;
- this.currentPath_.push('Q' + aCPx + ',' + aCPy + ' ' +
- aX + ',' + aY);
- };
+ // the following is lifted almost directly from
+ // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
- contextPrototype.arcTo = function(x1, y1, x2, y2, radius) {
- if (this.currentPath_.length == 0) return;
- // TODO: Implement
+ var cp = getCoords(this, aCPx, aCPy);
+ var p = getCoords(this, aX, aY);
+
+ var cp1 = {
+ x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
+ y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
+ };
+ var cp2 = {
+ x: cp1.x + (p.x - this.currentX_) / 3.0,
+ y: cp1.y + (p.y - this.currentY_) / 3.0
+ };
+
+ bezierCurveTo(this, cp1, cp2, p);
};
contextPrototype.arc = function(aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise) {
- var deltaAngle = Math.abs(aStartAngle - aEndAngle);
- // If start and stop are the same WebKit and Moz does nothing
- if (aStartAngle == aEndAngle) {
- // different browsers behave differently here so we do the easiest thing
- return;
+ aRadius *= Z;
+ var arcType = aClockwise ? 'at' : 'wa';
+
+ var xStart = aX + mc(aStartAngle) * aRadius - Z2;
+ var yStart = aY + ms(aStartAngle) * aRadius - Z2;
+
+ var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
+ var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
+
+ // IE won't render arches drawn counter clockwise if xStart == xEnd.
+ if (xStart == xEnd && !aClockwise) {
+ xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
+ // that can be represented in binary
}
- var endX = aX + aRadius * Math.cos(aEndAngle);
- var endY = aY + aRadius * Math.sin(aEndAngle);
+ var p = getCoords(this, aX, aY);
+ var pStart = getCoords(this, xStart, yStart);
+ var pEnd = getCoords(this, xEnd, yEnd);
- if (deltaAngle >= 2 * Math.PI) {
- // if larger than 2PI
- this.arc(aX, aY, aRadius, aStartAngle, aStartAngle + Math.PI, aClockwise);
- this.arc(aX, aY, aRadius, aStartAngle + Math.PI,
- aStartAngle + 2 * Math.PI, aClockwise);
- // now move to end point
- this.moveTo(endX, endY);
- return;
- }
+ this.currentPath_.push({type: arcType,
+ x: p.x,
+ y: p.y,
+ radius: aRadius,
+ xStart: pStart.x,
+ yStart: pStart.y,
+ xEnd: pEnd.x,
+ yEnd: pEnd.y});
- var startX = aX + aRadius * Math.cos(aStartAngle);
- var startY = aY + aRadius * Math.sin(aStartAngle);
- var rotationAngle = deltaAngle * 180 / Math.PI; // sign, abs?
- var sweepDirection = aClockwise ? 0 : 1;
- var isLargeArc = rotationAngle >= 180 == Boolean(aClockwise) ? 0 : 1;
-
- if (this.currentPath_.length != 0) {
- // add line to start point
- this.lineTo(startX, startY);
- } else {
- this.moveTo(startX, startY);
- }
-
- this.currentPath_.push('A' + aRadius + ',' + aRadius + ' ' +
- rotationAngle + ' ' +
- isLargeArc + ' ' +
- sweepDirection + ' ' +
- endX + ',' + endY);
};
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
@@ -447,55 +719,85 @@ if (!window.CanvasRenderingContext2D) {
};
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
- // Will destroy any existing path (same as FF behaviour)
+ var oldPath = this.currentPath_;
this.beginPath();
+
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.stroke();
- this.currentPath_ = [];
+
+ this.currentPath_ = oldPath;
};
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
- // Will destroy any existing path (same as FF behaviour)
+ var oldPath = this.currentPath_;
this.beginPath();
+
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.fill();
- this.currentPath_ = [];
+
+ this.currentPath_ = oldPath;
};
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
- return new LinearCanvasGradient_(aX0, aY0, aX1, aY1);
+ var gradient = new CanvasGradient_('gradient');
+ gradient.x0_ = aX0;
+ gradient.y0_ = aY0;
+ gradient.x1_ = aX1;
+ gradient.y1_ = aY1;
+ return gradient;
};
- contextPrototype.createRadialGradient = function(x0, y0,
- r0, x1,
- y1, r1) {
- return new RadialCanvasGradient_(x0, y0, r0, x1, y1, r1);
+ contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
+ aX1, aY1, aR1) {
+ var gradient = new CanvasGradient_('gradientradial');
+ gradient.x0_ = aX0;
+ gradient.y0_ = aY0;
+ gradient.r0_ = aR0;
+ gradient.x1_ = aX1;
+ gradient.y1_ = aY1;
+ gradient.r1_ = aR1;
+ return gradient;
};
- contextPrototype.drawImage = function (image, var_args) {
+ contextPrototype.drawImage = function(image, var_args) {
var dx, dy, dw, dh, sx, sy, sw, sh;
- // For Silverlight we don't need to get the size of the image since
- // Silverlight uses the image original dimension if not provided.
+ // to find the original width we overide the width and height
+ var oldRuntimeWidth = image.runtimeStyle.width;
+ var oldRuntimeHeight = image.runtimeStyle.height;
+ image.runtimeStyle.width = 'auto';
+ image.runtimeStyle.height = 'auto';
+
+ // get the original size
+ var w = image.width;
+ var h = image.height;
+
+ // and remove overides
+ image.runtimeStyle.width = oldRuntimeWidth;
+ image.runtimeStyle.height = oldRuntimeHeight;
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
- // Keep sx, sy, sw, dw, sh and dh undefined
+ sx = sy = 0;
+ sw = dw = w;
+ sh = dh = h;
} else if (arguments.length == 5) {
dx = arguments[1];
dy = arguments[2];
dw = arguments[3];
dh = arguments[4];
- // Keep sx, sy, sw and sh undefined
+ sx = sy = 0;
+ sw = w;
+ sh = h;
} else if (arguments.length == 9) {
sx = arguments[1];
sy = arguments[2];
@@ -509,81 +811,298 @@ if (!window.CanvasRenderingContext2D) {
throw Error('Invalid number of arguments');
}
- var slImage;
+ var d = getCoords(this, dx, dy);
- // If we have a source rect we need to clip the image.
- if (arguments.length == 9) {
- slImage = drawShape(this, '<Image Source="%1"/>', [image.src]);
+ var w2 = sw / 2;
+ var h2 = sh / 2;
- var clipRect = create(this,
- '<RectangleGeometry Rect="%1,%2,%3,%4"/>', [sx, sy, sw, sh]);
- slImage.clip = clipRect;
+ var vmlStr = [];
- var m = createMatrixIdentity();
+ var W = 10;
+ var H = 10;
- // translate to 0,0
- m[2][0] = -sx;
- m[2][1] = -sy;
+ // For some reason that I've now forgotten, using divs didn't work
+ vmlStr.push(' <g_vml_:group',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' coordorigin="0,0"' ,
+ ' style="width:', W, 'px;height:', H, 'px;position:absolute;');
- // scale
- var m2 = createMatrixIdentity();
- m2[0][0] = dw / sw;
- m2[1][1] = dh / sh;
+ // If filters are necessary (rotation exists), create them
+ // filters are bog-slow, so only create them if abbsolutely necessary
+ // The following check doesn't account for skews (which don't exist
+ // in the canvas spec (yet) anyway.
- m = matrixMultiply(m, m2);
+ if (this.m_[0][0] != 1 || this.m_[0][1] ||
+ this.m_[1][1] != 1 || this.m_[1][0]) {
+ var filter = [];
- // translate to destination
- m[2][0] += dx;
- m[2][1] += dy;
+ // Note the 12/21 reversal
+ filter.push('M11=', this.m_[0][0], ',',
+ 'M12=', this.m_[1][0], ',',
+ 'M21=', this.m_[0][1], ',',
+ 'M22=', this.m_[1][1], ',',
+ 'Dx=', mr(d.x / Z), ',',
+ 'Dy=', mr(d.y / Z), '');
- transformObject(this, slImage, m);
+ // Bounding box calculation (need to minimize displayed area so that
+ // filters don't waste time on unused pixels.
+ var max = d;
+ var c2 = getCoords(this, dx + dw, dy);
+ var c3 = getCoords(this, dx, dy + dh);
+ var c4 = getCoords(this, dx + dw, dy + dh);
+
+ max.x = m.max(max.x, c2.x, c3.x, c4.x);
+ max.y = m.max(max.y, c2.y, c3.y, c4.y);
+
+ vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
+ 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
+ filter.join(''), ", sizingmethod='clip');");
} else {
- slImage = drawShape(this,
- '<Image Source="%1" Canvas.Left="%2" Canvas.Top="%3"/>',
- [image.src, dx, dy]);
- if (dw != undefined || dh != undefined) {
- slImage.width = dw;
- slImage.height = dh;
- slImage.stretch = 'fill';
+ vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
+ }
+
+ vmlStr.push(' ">' ,
+ '<g_vml_:image src="', image.src, '"',
+ ' style="width:', Z * dw, 'px;',
+ ' height:', Z * dh, 'px"',
+ ' cropleft="', sx / w, '"',
+ ' croptop="', sy / h, '"',
+ ' cropright="', (w - sx - sw) / w, '"',
+ ' cropbottom="', (h - sy - sh) / h, '"',
+ ' />',
+ '</g_vml_:group>');
+
+ this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
+ };
+
+ contextPrototype.stroke = function(aFill) {
+ var lineStr = [];
+ var lineOpen = false;
+
+ var W = 10;
+ var H = 10;
+
+ lineStr.push('<g_vml_:shape',
+ ' filled="', !!aFill, '"',
+ ' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
+ ' coordorigin="0,0"',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' stroked="', !aFill, '"',
+ ' path="');
+
+ var newSeq = false;
+ var min = {x: null, y: null};
+ var max = {x: null, y: null};
+
+ for (var i = 0; i < this.currentPath_.length; i++) {
+ var p = this.currentPath_[i];
+ var c;
+
+ switch (p.type) {
+ case 'moveTo':
+ c = p;
+ lineStr.push(' m ', mr(p.x), ',', mr(p.y));
+ break;
+ case 'lineTo':
+ lineStr.push(' l ', mr(p.x), ',', mr(p.y));
+ break;
+ case 'close':
+ lineStr.push(' x ');
+ p = null;
+ break;
+ case 'bezierCurveTo':
+ lineStr.push(' c ',
+ mr(p.cp1x), ',', mr(p.cp1y), ',',
+ mr(p.cp2x), ',', mr(p.cp2y), ',',
+ mr(p.x), ',', mr(p.y));
+ break;
+ case 'at':
+ case 'wa':
+ lineStr.push(' ', p.type, ' ',
+ mr(p.x - this.arcScaleX_ * p.radius), ',',
+ mr(p.y - this.arcScaleY_ * p.radius), ' ',
+ mr(p.x + this.arcScaleX_ * p.radius), ',',
+ mr(p.y + this.arcScaleY_ * p.radius), ' ',
+ mr(p.xStart), ',', mr(p.yStart), ' ',
+ mr(p.xEnd), ',', mr(p.yEnd));
+ break;
+ }
+
+
+ // TODO: Following is broken for curves due to
+ // move to proper paths.
+
+ // Figure out dimensions so we can do gradient fills
+ // properly
+ if (p) {
+ if (min.x == null || p.x < min.x) {
+ min.x = p.x;
+ }
+ if (max.x == null || p.x > max.x) {
+ max.x = p.x;
+ }
+ if (min.y == null || p.y < min.y) {
+ min.y = p.y;
+ }
+ if (max.y == null || p.y > max.y) {
+ max.y = p.y;
+ }
}
}
+ lineStr.push(' ">');
+
+ if (!aFill) {
+ appendStroke(this, lineStr);
+ } else {
+ appendFill(this, lineStr, min, max);
+ }
+
+ lineStr.push('</g_vml_:shape>');
+
+ this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
- contextPrototype.stroke = function() {
- if (this.currentPath_.length == 0) return;
- var path = drawShape(this, '<Path Data="%1"/>',
- [this.currentPath_.join(' ')]);
- path.stroke = createBrushObject(this, this.strokeStyle);
- path.opacity = this.globalAlpha;
- path.strokeThickness = this.lineWidth;
- path.strokeMiterLimit = this.miterLimit;
- path.strokeLineJoin = this.lineJoin;
- // Canvas does not differentiate start from end
- path.strokeEndLineCap = path.strokeStartLineCap =
- processLineCap(this.lineCap);
- };
+ function appendStroke(ctx, lineStr) {
+ var a = processStyle(ctx.strokeStyle);
+ var color = a.color;
+ var opacity = a.alpha * ctx.globalAlpha;
+ var lineWidth = ctx.lineScale_ * ctx.lineWidth;
+
+ // VML cannot correctly render a line if the width is less than 1px.
+ // In that case, we dilute the color to make the line look thinner.
+ if (lineWidth < 1) {
+ opacity *= lineWidth;
+ }
+
+ lineStr.push(
+ '<g_vml_:stroke',
+ ' opacity="', opacity, '"',
+ ' joinstyle="', ctx.lineJoin, '"',
+ ' miterlimit="', ctx.miterLimit, '"',
+ ' endcap="', processLineCap(ctx.lineCap), '"',
+ ' weight="', lineWidth, 'px"',
+ ' color="', color, '" />'
+ );
+ }
+
+ function appendFill(ctx, lineStr, min, max) {
+ var fillStyle = ctx.fillStyle;
+ var arcScaleX = ctx.arcScaleX_;
+ var arcScaleY = ctx.arcScaleY_;
+ var width = max.x - min.x;
+ var height = max.y - min.y;
+ if (fillStyle instanceof CanvasGradient_) {
+ // TODO: Gradients transformed with the transformation matrix.
+ var angle = 0;
+ var focus = {x: 0, y: 0};
+
+ // additional offset
+ var shift = 0;
+ // scale factor for offset
+ var expansion = 1;
+
+ if (fillStyle.type_ == 'gradient') {
+ var x0 = fillStyle.x0_ / arcScaleX;
+ var y0 = fillStyle.y0_ / arcScaleY;
+ var x1 = fillStyle.x1_ / arcScaleX;
+ var y1 = fillStyle.y1_ / arcScaleY;
+ var p0 = getCoords(ctx, x0, y0);
+ var p1 = getCoords(ctx, x1, y1);
+ var dx = p1.x - p0.x;
+ var dy = p1.y - p0.y;
+ angle = Math.atan2(dx, dy) * 180 / Math.PI;
+
+ // The angle should be a non-negative number.
+ if (angle < 0) {
+ angle += 360;
+ }
+
+ // Very small angles produce an unexpected result because they are
+ // converted to a scientific notation string.
+ if (angle < 1e-6) {
+ angle = 0;
+ }
+ } else {
+ var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_);
+ focus = {
+ x: (p0.x - min.x) / width,
+ y: (p0.y - min.y) / height
+ };
+
+ width /= arcScaleX * Z;
+ height /= arcScaleY * Z;
+ var dimension = m.max(width, height);
+ shift = 2 * fillStyle.r0_ / dimension;
+ expansion = 2 * fillStyle.r1_ / dimension - shift;
+ }
+
+ // We need to sort the color stops in ascending order by offset,
+ // otherwise IE won't interpret it correctly.
+ var stops = fillStyle.colors_;
+ stops.sort(function(cs1, cs2) {
+ return cs1.offset - cs2.offset;
+ });
+
+ var length = stops.length;
+ var color1 = stops[0].color;
+ var color2 = stops[length - 1].color;
+ var opacity1 = stops[0].alpha * ctx.globalAlpha;
+ var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;
+
+ var colors = [];
+ for (var i = 0; i < length; i++) {
+ var stop = stops[i];
+ colors.push(stop.offset * expansion + shift + ' ' + stop.color);
+ }
+
+ // When colors attribute is used, the meanings of opacity and o:opacity2
+ // are reversed.
+ lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
+ ' method="none" focus="100%"',
+ ' color="', color1, '"',
+ ' color2="', color2, '"',
+ ' colors="', colors.join(','), '"',
+ ' opacity="', opacity2, '"',
+ ' g_o_:opacity2="', opacity1, '"',
+ ' angle="', angle, '"',
+ ' focusposition="', focus.x, ',', focus.y, '" />');
+ } else if (fillStyle instanceof CanvasPattern_) {
+ if (width && height) {
+ var deltaLeft = -min.x;
+ var deltaTop = -min.y;
+ lineStr.push('<g_vml_:fill',
+ ' position="',
+ deltaLeft / width * arcScaleX * arcScaleX, ',',
+ deltaTop / height * arcScaleY * arcScaleY, '"',
+ ' type="tile"',
+ // TODO: Figure out the correct size to fit the scale.
+ //' size="', w, 'px ', h, 'px"',
+ ' src="', fillStyle.src_, '" />');
+ }
+ } else {
+ var a = processStyle(ctx.fillStyle);
+ var color = a.color;
+ var opacity = a.alpha * ctx.globalAlpha;
+ lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
+ '" />');
+ }
+ }
contextPrototype.fill = function() {
- if (this.currentPath_.length == 0) return;
- var path = drawShape(this, '<Path Data="%1"/>',
- [this.currentPath_.join(' ')]);
- // The spec says to use non zero but Silverlight uses EvenOdd by defaul
- path.data.fillRule = 'NonZero';
- path.fill = createBrushObject(this, this.fillStyle);
- // TODO: What about even-odd etc?
+ this.stroke(true);
};
contextPrototype.closePath = function() {
- this.currentPath_.push('z');
+ this.currentPath_.push({type: 'close'});
};
- /**
- * Sets the transformation matrix and marks things as dirty
- */
- function setM(self, m) {
- self.m_ = m;
- self.lastCanvas_ = null;
+ function getCoords(ctx, aX, aY) {
+ var m = ctx.m_;
+ return {
+ x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
+ y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
+ };
};
contextPrototype.save = function() {
@@ -591,14 +1110,38 @@ if (!window.CanvasRenderingContext2D) {
copyState(this, o);
this.aStack_.push(o);
this.mStack_.push(this.m_);
- setM(this, matrixMultiply(createMatrixIdentity(), this.m_));
+ this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
};
contextPrototype.restore = function() {
- copyState(this.aStack_.pop(), this);
- setM(this, this.mStack_.pop());
+ if (this.aStack_.length) {
+ copyState(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop();
+ }
};
+ function matrixIsFinite(m) {
+ return isFinite(m[0][0]) && isFinite(m[0][1]) &&
+ isFinite(m[1][0]) && isFinite(m[1][1]) &&
+ isFinite(m[2][0]) && isFinite(m[2][1]);
+ }
+
+ function setM(ctx, m, updateLineScale) {
+ if (!matrixIsFinite(m)) {
+ return;
+ }
+ ctx.m_ = m;
+
+ if (updateLineScale) {
+ // Get the line scale.
+ // Determinant of this.m_ means how much the area is enlarged by the
+ // transformation. So its square root can be used as a scale factor
+ // for width.
+ var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
+ ctx.lineScale_ = sqrt(abs(det));
+ }
+ }
+
contextPrototype.translate = function(aX, aY) {
var m1 = [
[1, 0, 0],
@@ -606,12 +1149,12 @@ if (!window.CanvasRenderingContext2D) {
[aX, aY, 1]
];
- setM(this, matrixMultiply(m1, this.m_));
+ setM(this, matrixMultiply(m1, this.m_), false);
};
contextPrototype.rotate = function(aRot) {
- var c = Math.cos(aRot);
- var s = Math.sin(aRot);
+ var c = mc(aRot);
+ var s = ms(aRot);
var m1 = [
[c, s, 0],
@@ -619,35 +1162,157 @@ if (!window.CanvasRenderingContext2D) {
[0, 0, 1]
];
- setM(this, matrixMultiply(m1, this.m_));
+ setM(this, matrixMultiply(m1, this.m_), false);
};
contextPrototype.scale = function(aX, aY) {
+ this.arcScaleX_ *= aX;
+ this.arcScaleY_ *= aY;
var m1 = [
[aX, 0, 0],
[0, aY, 0],
[0, 0, 1]
];
- setM(this, matrixMultiply(m1, this.m_));
+ setM(this, matrixMultiply(m1, this.m_), true);
};
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
var m1 = [
[m11, m12, 0],
[m21, m22, 0],
- [ dx, dy, 1]
+ [dx, dy, 1]
];
- setM(this, matrixMultiply(m1, this.m_));
+ setM(this, matrixMultiply(m1, this.m_), true);
};
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
- setM(this, [
+ var m = [
[m11, m12, 0],
[m21, m22, 0],
- [ dx, dy, 1],
- ]);
+ [dx, dy, 1]
+ ];
+
+ setM(this, m, true);
+ };
+
+ /**
+ * The text drawing function.
+ * The maxWidth argument isn't taken in account, since no browser supports
+ * it yet.
+ */
+ contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {
+ var m = this.m_,
+ delta = 1000,
+ left = 0,
+ right = delta,
+ offset = {x: 0, y: 0},
+ lineStr = [];
+
+ var fontStyle = getComputedStyle(processFontStyle(this.font),
+ this.element_);
+
+ var fontStyleString = buildStyle(fontStyle);
+
+ var elementStyle = this.element_.currentStyle;
+ var textAlign = this.textAlign.toLowerCase();
+ switch (textAlign) {
+ case 'left':
+ case 'center':
+ case 'right':
+ break;
+ case 'end':
+ textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';
+ break;
+ case 'start':
+ textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';
+ break;
+ default:
+ textAlign = 'left';
+ }
+
+ // 1.75 is an arbitrary number, as there is no info about the text baseline
+ switch (this.textBaseline) {
+ case 'hanging':
+ case 'top':
+ offset.y = fontStyle.size / 1.75;
+ break;
+ case 'middle':
+ break;
+ default:
+ case null:
+ case 'alphabetic':
+ case 'ideographic':
+ case 'bottom':
+ offset.y = -fontStyle.size / 2.25;
+ break;
+ }
+
+ switch(textAlign) {
+ case 'right':
+ left = delta;
+ right = 0.05;
+ break;
+ case 'center':
+ left = right = delta / 2;
+ break;
+ }
+
+ var d = getCoords(this, x + offset.x, y + offset.y);
+
+ lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
+ ' coordsize="100 100" coordorigin="0 0"',
+ ' filled="', !stroke, '" stroked="', !!stroke,
+ '" style="position:absolute;width:1px;height:1px;">');
+
+ if (stroke) {
+ appendStroke(this, lineStr);
+ } else {
+ // TODO: Fix the min and max params.
+ appendFill(this, lineStr, {x: -left, y: 0},
+ {x: right, y: fontStyle.size});
+ }
+
+ var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +
+ m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';
+
+ var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z);
+
+ lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ',
+ ' offset="', skewOffset, '" origin="', left ,' 0" />',
+ '<g_vml_:path textpathok="true" />',
+ '<g_vml_:textpath on="true" string="',
+ encodeHtmlAttribute(text),
+ '" style="v-text-align:', textAlign,
+ ';font:', encodeHtmlAttribute(fontStyleString),
+ '" /></g_vml_:line>');
+
+ this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
+ };
+
+ contextPrototype.fillText = function(text, x, y, maxWidth) {
+ this.drawText_(text, x, y, maxWidth, false);
+ };
+
+ contextPrototype.strokeText = function(text, x, y, maxWidth) {
+ this.drawText_(text, x, y, maxWidth, true);
+ };
+
+ contextPrototype.measureText = function(text) {
+ if (!this.textMeasureEl_) {
+ var s = '<span style="position:absolute;' +
+ 'top:-20000px;left:0;padding:0;margin:0;border:none;' +
+ 'white-space:pre;"></span>';
+ this.element_.insertAdjacentHTML('beforeEnd', s);
+ this.textMeasureEl_ = this.element_.lastChild;
+ }
+ var doc = this.element_.ownerDocument;
+ this.textMeasureEl_.innerHTML = '';
+ this.textMeasureEl_.style.font = this.font;
+ // Don't use innerHTML or innerText because they allow markup/whitespace.
+ this.textMeasureEl_.appendChild(doc.createTextNode(text));
+ return {width: this.textMeasureEl_.offsetWidth};
};
/******** STUBS ********/
@@ -655,116 +1320,97 @@ if (!window.CanvasRenderingContext2D) {
// TODO: Implement
};
- contextPrototype.createPattern = function() {
- return new CanvasPattern_;
+ contextPrototype.arcTo = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.createPattern = function(image, repetition) {
+ return new CanvasPattern_(image, repetition);
};
// Gradient / Pattern Stubs
- function CanvasGradient_() {
+ function CanvasGradient_(aType) {
+ this.type_ = aType;
+ this.x0_ = 0;
+ this.y0_ = 0;
+ this.r0_ = 0;
+ this.x1_ = 0;
+ this.y1_ = 0;
+ this.r1_ = 0;
this.colors_ = [];
}
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
- aColor = translateColor(aColor);
- this.colors_.push({offset: aOffset, color: aColor});
+ aColor = processStyle(aColor);
+ this.colors_.push({offset: aOffset,
+ color: aColor.color,
+ alpha: aColor.alpha});
};
- CanvasGradient_.prototype.createStops_ = function(ctx, brushObj, colors) {
- var gradientStopCollection = brushObj.gradientStops;
- for (var i = 0, c; c = colors[i]; i++) {
- var color = translateColor(c.color);
- gradientStopCollection.add(create(ctx,
- '<GradientStop Color="%1" Offset="%2"/>', [color, c.offset]));
+ function CanvasPattern_(image, repetition) {
+ assertImageIsValid(image);
+ switch (repetition) {
+ case 'repeat':
+ case null:
+ case '':
+ this.repetition_ = 'repeat';
+ break
+ case 'repeat-x':
+ case 'repeat-y':
+ case 'no-repeat':
+ this.repetition_ = repetition;
+ break;
+ default:
+ throwException('SYNTAX_ERR');
}
- };
- function LinearCanvasGradient_(x0, y0, x1, y1) {
- CanvasGradient_.call(this);
- this.x0_ = x0;
- this.y0_ = y0;
- this.x1_ = x1;
- this.y1_ = y1;
- }
- LinearCanvasGradient_.prototype = new CanvasGradient_;
-
- LinearCanvasGradient_.prototype.createBrush_ = function(ctx) {
- var brushObj = create(ctx, '<LinearGradientBrush MappingMode="Absolute" ' +
- 'StartPoint="%1,%2" EndPoint="%3,%4"/>',
- [this.x0_, this.y0_, this.x1_, this.y1_]);
- this.createStops_(ctx, brushObj, this.colors_);
- return brushObj;
- };
-
- function isNanOrInfinite(v) {
- return isNaN(v) || !isFinite(v);
+ this.src_ = image.src;
+ this.width_ = image.width;
+ this.height_ = image.height;
}
- function RadialCanvasGradient_(x0, y0, r0, x1, y1, r1) {
- if (r0 < 0 || r1 < 0 || isNanOrInfinite(x0) || isNanOrInfinite(y0) ||
- isNanOrInfinite(x1) || isNanOrInfinite(y1)) {
- // IE does not support DOMException so this is as close as we get.
- var error = Error('DOMException.INDEX_SIZE_ERR');
- error.code = 1;
- throw error;
+ function throwException(s) {
+ throw new DOMException_(s);
+ }
+
+ function assertImageIsValid(img) {
+ if (!img || img.nodeType != 1 || img.tagName != 'IMG') {
+ throwException('TYPE_MISMATCH_ERR');
}
+ if (img.readyState != 'complete') {
+ throwException('INVALID_STATE_ERR');
+ }
+ }
- CanvasGradient_.call(this);
- this.x0_ = x0;
- this.y0_ = y0;
- this.r0_ = r0;
- this.x1_ = x1;
- this.y1_ = y1;
- this.r1_ = r1;
+ function DOMException_(s) {
+ this.code = this[s];
+ this.message = s +': DOM Exception ' + this.code;
}
- RadialCanvasGradient_.prototype = new CanvasGradient_;
-
- CanvasGradient_.prototype.createBrush_ = function(ctx) {
- if (this.x0_ == this.x1_ && this.y0_ == this.y1_ && this.r0_ == this.r1_) {
- return null;
- }
-
- var radius = Math.max(this.r0_, this.r1_);
- var minRadius = Math.min(this.r0_, this.r1_);
- var brushObj = create(ctx, '<RadialGradientBrush MappingMode="Absolute" ' +
- 'GradientOrigin="%1,%2" Center="%3,%4" ' +
- 'RadiusX="%5" RadiusY="%5"/>',
- [this.x0_, this.y0_, this.x1_, this.y1_, radius]);
-
- var colors = this.colors_.concat();
-
- if (this.r1_ < this.r0_) {
- // reverse color stop array
- colors.reverse();
- for (var i = 0, c; c = colors[i]; i++) {
- c.offset = 1 - c.offset;
- }
- }
-
- // sort the color stops
- colors.sort(function(c1, c2) {
- return c1.offset - c2.offset;
- });
-
- if (minRadius > 0) {
- // We need to adjust the color stops since SL always have the inner radius
- // at (0, 0) so we change the stops in case the min radius is not 0.
- for (var i = 0, c; c = colors[i]; i++) {
- c.offset = minRadius / radius + (radius - minRadius) / radius * c.offset;
- }
- }
-
- this.createStops_(ctx, brushObj, colors);
- return brushObj;
- };
-
- function CanvasPattern_() {}
+ var p = DOMException_.prototype = new Error;
+ p.INDEX_SIZE_ERR = 1;
+ p.DOMSTRING_SIZE_ERR = 2;
+ p.HIERARCHY_REQUEST_ERR = 3;
+ p.WRONG_DOCUMENT_ERR = 4;
+ p.INVALID_CHARACTER_ERR = 5;
+ p.NO_DATA_ALLOWED_ERR = 6;
+ p.NO_MODIFICATION_ALLOWED_ERR = 7;
+ p.NOT_FOUND_ERR = 8;
+ p.NOT_SUPPORTED_ERR = 9;
+ p.INUSE_ATTRIBUTE_ERR = 10;
+ p.INVALID_STATE_ERR = 11;
+ p.SYNTAX_ERR = 12;
+ p.INVALID_MODIFICATION_ERR = 13;
+ p.NAMESPACE_ERR = 14;
+ p.INVALID_ACCESS_ERR = 15;
+ p.VALIDATION_ERR = 16;
+ p.TYPE_MISMATCH_ERR = 17;
// set up externs
G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_;
CanvasGradient = CanvasGradient_;
CanvasPattern = CanvasPattern_;
-
+ DOMException = DOMException_;
})();
} // if
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -1,3 +1,15 @@
+// IE doesn't implement Array.indexOf
+if (!Array.indexOf) {
+ Array.prototype.indexOf = function(obj) {
+ for (var i = 0, len = this.length; i < len; i++) {
+ if (this[i] == obj) {
+ return i;
+ }
+ }
+ return -1;
+ }
+}
+
// Returns the number of keys (elements) in an array/dictionary.
function obj_length(obj) {
if (obj.length !== undefined) {
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return fa
lse};$(b).bind("click",c)}function make_popupmenu(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");if(obj_length(b)<=0){$("<li/>").html("No options").appendTo(a)}$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d);return a}function show_hide_popupmenu_options(d,c,a){var a=(a===undefined?true:a);var b=new RegExp(c);$(d).find("li").each(function(){if(b.exec($(this).text())){if(a){$(this).show()}else{$(this).hide()}}})}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=wind
ow.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));a.find("a").bind("click",function(b){b.stopPropagation();return true});make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().toLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a,b){if(!jQuery().autocomplete){return}if(a===undefined){a=20}if(b===undefined){b=3000}$("select").each(function(){var d=$(this);var g=d.find("option").length;if((g<a)||(g>b)){return}if(d.attr("multiple")==true){return}if(d.hasClass("no-autocomplete")){return
}var m=d.attr("value");var c=$("<input type='text' class='text-and-autocomplete-select'></input>");c.attr("size",40);c.attr("name",d.attr("name"));c.attr("id",d.attr("id"));c.click(function(){var n=$(this).val();$(this).val("Loading...");$(this).showAllInCache();$(this).val(n);$(this).select()});var e=[];var i={};d.children("option").each(function(){var o=$(this).text();var n=$(this).attr("value");e.push(o);i[o]=n;i[n]=n;if(n==m){c.attr("value",o)}});if(m==""||m=="?"){c.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:b,minChars:0,hideForLessThanMinChars:false};c.autocomplete(e,f);d.replaceWith(c);var k=function(){var o=c.attr("value");var n=i[o];if(n!==null&&n!==undefined){c.attr("value",n)}else{if(m!=""){c.attr("value",m)}else{c.attr("value","?")}}};c.parents("form").submit(function(){k()});$(document).bind("convert_dbkeys",function(){k()});if(d.attr("r
efresh_on_change")=="true"){var h=d.attr("refresh_on_change_values"),l=d.attr("last_selected_value");if(h!==undefined){h=h.split(",")}var j=function(){var n=i[c.attr("value")];if(n!==null&&n!==undefined){if($.inArray(n,h)===-1&&$.inArray(l,h)===-1){return}c.attr("value",n);$(window).trigger("refresh_on_change");c.parents("form").submit()}};c.bind("result",j);c.keyup(function(n){if(n.keyCode===13){j()}});c.keydown(function(n){if(n.keyCode===13){return false}})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m
[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!=""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStore.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_s
tate");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length==0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeC
lass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools");b.css("font-style","italic")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false
}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};$(".trackster-add").live("click",function(){var b=this,a=$(this);$.ajax({url:a.attr("data-url"),dataType:"html",error:function(){alert("Could not add this dataset to browser.")},success:function(c){var d=window.parent;d.show_modal("Add to Browser:",c,{Cancel:function(){d.hide_modal()},"Insert into selected":function(){$(d.document).find("input[name=id]:checked").each(function(){var e=$(this).val();d.location=a.attr("action-url")+"&id="+e})},"Insert into new browser":function(){d.location=a.attr("new-url")}})}})});$(document).ready(function(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(func
tion(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus();replace_big_select_inputs(20,1500)});
+if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scr
ollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return false};$(b).bind("click",c)}function make_popupmenu(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");if(obj_length(b)<=0){$("<li/>").html("No options").appendTo(a)}$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d);return a}function show_hide_popupmenu_options(d,c,a){var a=(a===undefined?true:a);var b=new RegExp(c);$(d).find("li").each(function(){if(b.exec($(this).text())){if(a){$(this).show()}else{$(this).hide()}}})}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("ta
rget");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));a.find("a").bind("click",function(b){b.stopPropagation();return true});make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().toLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a,b){if(!jQuery().autocomplete){return}if(a===undefined){a=20}if(b===undefined){b=3000}$("select").each(function(){var d=$(this);var
g=d.find("option").length;if((g<a)||(g>b)){return}if(d.attr("multiple")==true){return}if(d.hasClass("no-autocomplete")){return}var m=d.attr("value");var c=$("<input type='text' class='text-and-autocomplete-select'></input>");c.attr("size",40);c.attr("name",d.attr("name"));c.attr("id",d.attr("id"));c.click(function(){var n=$(this).val();$(this).val("Loading...");$(this).showAllInCache();$(this).val(n);$(this).select()});var e=[];var i={};d.children("option").each(function(){var o=$(this).text();var n=$(this).attr("value");e.push(o);i[o]=n;i[n]=n;if(n==m){c.attr("value",o)}});if(m==""||m=="?"){c.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:b,minChars:0,hideForLessThanMinChars:false};c.autocomplete(e,f);d.replaceWith(c);var k=function(){var o=c.attr("value");var n=i[o];if(n!==null&&n!==undefined){c.attr("value",n)}else{if(m!=""){c.attr("value",m)}else{c.
attr("value","?")}}};c.parents("form").submit(function(){k()});$(document).bind("convert_dbkeys",function(){k()});if(d.attr("refresh_on_change")=="true"){var h=d.attr("refresh_on_change_values"),l=d.attr("last_selected_value");if(h!==undefined){h=h.split(",")}var j=function(){var n=i[c.attr("value")];if(n!==null&&n!==undefined){if($.inArray(n,h)===-1&&$.inArray(l,h)===-1){return}c.attr("value",n);$(window).trigger("refresh_on_change");c.parents("form").submit()}};c.bind("result",j);c.keyup(function(n){if(n.keyCode===13){j()}});c.keydown(function(n){if(n.keyCode===13){return false}})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).rem
ove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!=""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStore.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){if(h.is
(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_state");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c
=$("#galaxy_tools").contents();if(c.length==0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools");b.css("font-style","italic")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.lo
g_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};$(".trackster-add").live("click",function(){var b=this,a=$(this);$.ajax({url:a.attr("data-url"),dataType:"html",error:function(){alert("Could not add this dataset to browser.")},success:function(c){var d=window.parent;d.show_modal("Add to Browser:",c,{Cancel:function(){d.hide_modal()},"Insert into selected":function(){$(d.document).find("input[name=id]:checked").each(function(){var e=$(this).val();d.location=a.attr("action-url")+"&id="+e})},"Insert into new browser":function(){d.location=a.attr("new-url")}})}})});$(document).ready(function(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)
===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus();replace_big_select_inputs(20,1500)});
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -22,8 +22,8 @@
${parent.javascripts()}
- <!--[if IE]>
- <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script>
+ <!--[if lt IE 9]>
+ <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]-->
${h.js( "jquery",
1
0

galaxy-dist commit f72f73aa68da: Enable FormBuilder to accept and use parameter 'use_panels' in order to show panels. This enables forms built with FormBuilder to include Galaxy header. Use this new functionality to show headers for all workflow forms: create, rename, and import/upload.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287773333 14400
# Node ID f72f73aa68da51e0b5aebc063b11fa7f0b78a261
# Parent 8c1b6b3f706134b1e4ba21637f6a3b8ca5e00b67
Enable FormBuilder to accept and use parameter 'use_panels' in order to show panels. This enables forms built with FormBuilder to include Galaxy header. Use this new functionality to show headers for all workflow forms: create, rename, and import/upload.
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -391,7 +391,8 @@ class WorkflowController( BaseController
#message = "Workflow renamed to '%s'." % new_name
#return self.list_grid( trans, message=message, status='done' )
else:
- return form( url_for( action='rename', id=trans.security.encode_id(stored.id) ), "Rename workflow", submit_text="Rename" ) \
+ return form( url_for( action='rename', id=trans.security.encode_id(stored.id) ),
+ "Rename workflow", submit_text="Rename", use_panels=True ) \
.add_text( "new_name", "Workflow Name", value=to_unicode( stored.name ) )
@web.expose
@@ -638,7 +639,7 @@ class WorkflowController( BaseController
trans.set_message( "Workflow '%s' created" % stored_workflow.name )
return self.list( trans )
else:
- return form( url_for(), "Create New Workflow", submit_text="Create" ) \
+ return form( url_for(), "Create New Workflow", submit_text="Create", use_panels=True ) \
.add_text( "workflow_name", "Workflow Name", value="Unnamed workflow" ) \
.add_text( "workflow_annotation", "Workflow Annotation", value="", help="A description of the workflow; annotation is shown alongside shared or published workflows." )
@@ -1056,7 +1057,7 @@ class WorkflowController( BaseController
@web.expose
def import_workflow( self, trans, workflow_text=None, url=None ):
if workflow_text is None and url is None:
- return form( url_for(), "Import Workflow", submit_text="Import" ) \
+ return form( url_for(), "Import Workflow", submit_text="Import", use_panels=True ) \
.add_text( "url", "URL to load workflow from", "" ) \
.add_input( "textarea", "Encoded workflow (as generated by export workflow)", "workflow_text", "" )
if url:
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -631,8 +631,9 @@ class GalaxyWebTransaction( base.Default
"""
Convenience method for displaying a simple page with a single HTML
form.
- """
- return self.fill_template( template, form=form, header=header, use_panels=use_panels, active_view=active_view )
+ """
+ return self.fill_template( template, form=form, header=header, use_panels=( form.use_panels or use_panels ),
+ active_view=active_view )
def fill_template(self, filename, **kwargs):
"""
Fill in a template, putting any keyword arguments on the context.
@@ -725,12 +726,13 @@ class FormBuilder( object ):
"""
Simple class describing an HTML form
"""
- def __init__( self, action="", title="", name="form", submit_text="submit" ):
+ def __init__( self, action="", title="", name="form", submit_text="submit", use_panels=False ):
self.title = title
self.name = name
self.action = action
self.submit_text = submit_text
self.inputs = []
+ self.use_panels = use_panels
def add_input( self, type, name, label, value=None, error=None, help=None, use_label=True ):
self.inputs.append( FormInput( type, label, name, value, error, help, use_label ) )
return self
1
0

galaxy-dist commit fc88085d47c3: Add some space between adjacent embedded items on Pages.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287780826 14400
# Node ID fc88085d47c384f34070952f84c22007e4a72721
# Parent 1d0eeaf2d06c7835d741fbfdab7120d366baca0b
Add some space between adjacent embedded items on Pages.
--- a/static/june_2007_style/embed_item.css.tmpl
+++ b/static/june_2007_style/embed_item.css.tmpl
@@ -1,5 +1,6 @@
.embedded-item {
+ margin-top: 0.5em
margin-left:auto;
margin-right:auto;
width:90%;
--- a/static/june_2007_style/blue/embed_item.css
+++ b/static/june_2007_style/blue/embed_item.css
@@ -1,4 +1,4 @@
-.embedded-item{margin-left:auto;margin-right:auto;width:90%;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em;}
+.embedded-item{margin-top:0.5em;margin-left:auto;margin-right:auto;width:90%;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em;}
.embedded-item.display {padding: 0.5em;}
.embedded-item.history{background-color:#C1C9E5}
.embedded-item.history p{background:#C1C9E5 no-repeat 2px 2px;margin-top:0;margin-bottom:0;}
1
0

galaxy-dist commit 070749f1a0f1: Graceful failure for ids with non-hex characters in URLs. Fix small typo with invalid history failure
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1287784895 14400
# Node ID 070749f1a0f12cec2b8f20931a6224d8168a8c95
# Parent fc88085d47c384f34070952f84c22007e4a72721
Graceful failure for ids with non-hex characters in URLs. Fix small typo with invalid history failure
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -143,8 +143,10 @@ class UsesVisualization( SharableItemSec
def get_visualization( self, trans, id, check_ownership=True, check_accessible=False ):
""" Get a Visualization from the database by id, verifying ownership. """
# Load workflow from database
- id = trans.security.decode_id( id )
- visualization = trans.sa_session.query( trans.model.Visualization ).get( id )
+ try:
+ visualization = trans.sa_session.query( trans.model.Visualization ).get( trans.security.decode_id( id ) )
+ except TypeError:
+ visualization = None
if not visualization:
error( "Visualization not found" )
else:
@@ -191,12 +193,14 @@ class UsesStoredWorkflow( SharableItemSe
def get_stored_workflow( self, trans, id, check_ownership=True, check_accessible=False ):
""" Get a StoredWorkflow from the database by id, verifying ownership. """
# Load workflow from database
- id = trans.security.decode_id( id )
- stored = trans.sa_session.query( trans.model.StoredWorkflow ).get( id )
- if not stored:
+ try:
+ workflow = trans.sa_session.query( trans.model.StoredWorkflow ).get( trans.security.decode_id( id ) )
+ except TypeError:
+ workflow = None
+ if not workflow:
error( "Workflow not found" )
else:
- return self.security_check( trans.get_user(), stored, check_ownership, check_accessible )
+ return self.security_check( trans.get_user(), workflow, check_ownership, check_accessible )
def get_stored_workflow_steps( self, trans, stored_workflow ):
""" Restores states for a stored workflow's steps. """
for step in stored_workflow.latest_workflow.steps:
@@ -224,10 +228,12 @@ class UsesHistory( SharableItemSecurity
def get_history( self, trans, id, check_ownership=True, check_accessible=False ):
"""Get a History from the database by id, verifying ownership."""
# Load history from database
- id = trans.security.decode_id( id )
- history = trans.sa_session.query( trans.model.History ).get( id )
+ try:
+ history = trans.sa_session.query( trans.model.History ).get( trans.security.decode_id( id ) )
+ except TypeError:
+ history = None
if not history:
- err+msg( "History not found" )
+ error( "History not found" )
else:
return self.security_check( trans.get_user(), history, check_ownership, check_accessible )
def get_history_datasets( self, trans, history, show_deleted=False, show_hidden=False):
1
0

galaxy-dist commit 53d1fa98fa05: Add button that enables uploading or importing a workflow to Galaxy instance.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287691826 14400
# Node ID 53d1fa98fa0573f84bbbd8c8264d15bfff0cb90f
# Parent 9d9f0de20f4f9da28d53be38411b1ee1075201a1
Add button that enables uploading or importing a workflow to Galaxy instance.
--- a/lib/galaxy/web/controllers/workflow.py
+++ b/lib/galaxy/web/controllers/workflow.py
@@ -1077,13 +1077,16 @@ class WorkflowController( BaseController
# Create workflow.
workflow = self._workflow_from_dict( trans, data, source="uploaded file" ).latest_workflow
- # Provide user feedback.
+ # Provide user feedback and show workflow list.
if workflow.has_errors:
- return trans.show_warn_message( "Imported, but some steps in this workflow have validation errors" )
+ trans.set_message( "Imported, but some steps in this workflow have validation errors",
+ type="warning" )
if workflow.has_cycles:
- return trans.show_warn_message( "Imported, but this workflow contains cycles" )
+ trans.set_message( "Imported, but this workflow contains cycles",
+ type="warning" )
else:
- return trans.show_message( "Workflow '%s' imported" % workflow.name )
+ trans.set_message( "Workflow '%s' imported" % workflow.name )
+ return self.list( trans )
@web.json
def get_datatypes( self, trans ):
--- a/templates/workflow/list.mako
+++ b/templates/workflow/list.mako
@@ -17,12 +17,12 @@
%if message:
<%
try:
- messagetype
+ status
except:
- messagetype = "done"
+ status = "done"
%><p />
- <div class="${messagetype}message">
+ <div class="${status}message">
${h.to_unicode( message )}
</div>
%endif
@@ -36,6 +36,12 @@
<span>Create new workflow</span></a></li>
+ <li>
+ <a class="action-button" href="${h.url_for( action='import_workflow' )}">
+ <img src="${h.url_for('/static/images/fugue/arrow-090.png')}" />
+ <span>Upload or import workflow</span>
+ </a>
+ </li></ul>
%if workflows:
Binary file static/images/fugue/arrow-090.png has changed
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -587,12 +587,14 @@ class GalaxyWebTransaction( base.Default
rval = self.template_context[name] = FormData()
rval.values.update( kwargs )
return rval
- def set_message( self, message ):
+ def set_message( self, message, type=None ):
"""
- Convenience method for setting the 'message' element of the template
- context.
+ Convenience method for setting the 'message' and 'message_type'
+ element of the template context.
"""
self.template_context['message'] = message
+ if type:
+ self.template_context['status'] = type
def get_message( self ):
"""
Convenience method for getting the 'message' element of the template
1
0

galaxy-dist commit 8c1b6b3f7061: mutation viz tool UI fixes
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1287761403 14400
# Node ID 8c1b6b3f706134b1e4ba21637f6a3b8ca5e00b67
# Parent 78d2a72ee1d61099fc5958af953fb5976c544de6
mutation viz tool UI fixes
--- a/tools/mutation/visualize.xml
+++ b/tools/mutation/visualize.xml
@@ -21,10 +21,11 @@
<repeat name="sample_chooser" title="Sample"><param name="name" type="text" label="Label" help="Optional" /><param name="a_col" type="data_column" data_ref="input1" multiple="false" numerical="false" label="Base A Column" help="" />
- <param name="totals_col" type="data_column" data_ref="input1" multiple="false" numerical="false" label="Totals Column" help="" />
+ <param name="totals_col" type="data_column" data_ref="input1" multiple="false" numerical="false" label="Coverage Column" help="" /></repeat><param name="zoom_value" type="select" label="Zoom">
+ <option value="interactive">Interactive</option><option value="1">1x</option><option value="2">2x</option><option value="3">3x</option>
@@ -35,7 +36,6 @@
<option value="8">8x</option><option value="9">9x</option><option value="10">10x</option>
- <option value="interactive">Interactive</option></param></inputs>
1
0

galaxy-dist commit 1d0eeaf2d06c: Bug fix for displaying metadata items associated with library datasets that are lists of values.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1287775851 14400
# Node ID 1d0eeaf2d06c7835d741fbfdab7120d366baca0b
# Parent f72f73aa68da51e0b5aebc063b11fa7f0b78a261
Bug fix for displaying metadata items associated with library datasets that are lists of values.
--- a/templates/library/common/ldda_info.mako
+++ b/templates/library/common/ldda_info.mako
@@ -120,6 +120,8 @@
if isinstance( metadata_val, trans.model.MetadataFile ):
metadata_val = metadata_val.file_name
elif isinstance( metadata_val, list ):
+ # Make sure list items are strings
+ metadata_val = [ str( item ) for item in metadata_val ]
metadata_val = ', '.join( metadata_val )
%>
${metadata_val}
1
0

galaxy-dist commit b3763f7ecec7: added more zoom levels for mutation viz tool
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1287603271 14400
# Node ID b3763f7ecec7082e76a5ff407091fa7f0bffb7df
# Parent e226033419a91100e657f6880562dc50ae01ef98
added more zoom levels for mutation viz tool
--- a/tools/mutation/visualize.xml
+++ b/tools/mutation/visualize.xml
@@ -30,6 +30,11 @@
<option value="3">3x</option><option value="4">4x</option><option value="5">5x</option>
+ <option value="6">6x</option>
+ <option value="7">7x</option>
+ <option value="8">8x</option>
+ <option value="9">9x</option>
+ <option value="10">10x</option><option value="interactive">Interactive</option></param>
--- a/tools/mutation/visualize.py
+++ b/tools/mutation/visualize.py
@@ -263,8 +263,8 @@ def mainsvg(opts, args):
# display legend
for i, b in enumerate( bases ):
bt = svg.SVG("tspan", b, style="font-family:Verdana;font-size:20%")
- s.append(svg.SVG("text", bt, x=12+(i*10), y=4, stroke="none", fill="black"))
- s.append(svg.SVG("rect", x=14+(i*10), y=1, width=4, height=3,
+ s.append(svg.SVG("text", bt, x=12+(i*10), y=3, stroke="none", fill="black"))
+ s.append(svg.SVG("rect", x=14+(i*10), y=0, width=4, height=3,
stroke="none", fill=colors[b], fill_opacity=0.5))
reader = open(opts.input_file, 'U')
1
0

galaxy-dist commit 7afd79d131e4: Do not preserve table borders in Pages.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287607913 14400
# Node ID 7afd79d131e40f5f9a61125ec159552dc7c3fabd
# Parent c375c4a8e4e42e5e29e996f3472aacdbdc3d22e0
Do not preserve table borders in Pages.
--- a/templates/page/display.mako
+++ b/templates/page/display.mako
@@ -97,7 +97,6 @@
padding: 8px 5px 5px;
min-width: 500px;
border: none;
- border-collapse: separate;
}
.page-body caption {
text-align: left;
1
0

galaxy-dist commit 151d007da2f4: Stop redirecting output of the taxonomy2tree tool, since the binary has been updated to stop writing info messages to stderr.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1287681255 14400
# Node ID 151d007da2f4709ba546cd5cc76738e28b64e05d
# Parent 8cc9544dd81d6c53e7c79a24b5fb30f58854e45b
Stop redirecting output of the taxonomy2tree tool, since the binary has been updated to stop writing info messages to stderr.
--- a/tools/taxonomy/t2t_report.xml
+++ b/tools/taxonomy/t2t_report.xml
@@ -3,7 +3,7 @@
<requirements><requirement type="package">taxonomy</requirement></requirements>
- <command>taxonomy2tree $input 0 /dev/null $out_file1 0 &> /dev/null</command>
+ <command>taxonomy2tree $input 0 /dev/null $out_file1 0</command><inputs><param format="taxonomy" name="input" type="data" label="Summarize taxonomic representation for"/></inputs>
1
0

galaxy-dist commit 423e72ab1990: trackster: Don't index bottom level for summary_tree, greatly reducing computation time (>5x speedup) while not sacrificing usability
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1287612031 14400
# Node ID 423e72ab19901de8dc8f5e4e2d2e7524921380bc
# Parent 5f9d6d9582e50f134c97e8523a015f210dd3af70
trackster: Don't index bottom level for summary_tree, greatly reducing computation time (>5x speedup) while not sacrificing usability
--- a/lib/galaxy/visualization/tracks/summary.py
+++ b/lib/galaxy/visualization/tracks/summary.py
@@ -1,12 +1,15 @@
'''
2010, Kanwei Li
Summary tree data structure for aggregation
+
+10/20/2010: Changed version to 2 as we no longer look at bottom level, for better performance
'''
import sys, os
import cPickle
-VERSION = 1
+VERSION = 2
+MIN_LEVEL = 2
class SummaryTree:
def __init__(self, block_size, levels, draw_cutoff, detail_cutoff):
@@ -27,11 +30,11 @@ class SummaryTree:
else:
blocks = self.chrom_blocks[chrom] = {}
self.chrom_stats[chrom] = {}
- for level in range(1, self.levels+1):
+ for level in range(MIN_LEVEL, self.levels+1):
blocks[level] = {}
- for level in range(1, self.levels+1):
+ for level in range(MIN_LEVEL, self.levels+1):
block_level = blocks[level]
starting_block = self.find_block(start, level)
ending_block = self.find_block(end, level)
@@ -45,7 +48,7 @@ class SummaryTree:
''' Checks for cutoff and only stores levels above it '''
for chrom, blocks in self.chrom_blocks.iteritems():
cur_best = 999
- for level in range(self.levels, 0, -1):
+ for level in range(self.levels, MIN_LEVEL-1, -1):
max_val = max(blocks[level].values())
if max_val < self.draw_cutoff:
if "draw_level" not in self.chrom_stats[chrom]:
1
0

galaxy-dist commit 8cc9544dd81d: Fix traceback encountered if you try to access the admin job management interface from a server with job running disabled.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1287678598 14400
# Node ID 8cc9544dd81d6c53e7c79a24b5fb30f58854e45b
# Parent 423e72ab19901de8dc8f5e4e2d2e7524921380bc
Fix traceback encountered if you try to access the admin job management interface from a server with job running disabled.
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -1491,6 +1491,8 @@ class Admin( object ):
deleted = []
msg = None
status = None
+ if not trans.app.config.get_bool( "enable_job_running", True ):
+ return trans.show_error_message( 'This Galaxy instance is not configured to run jobs. If using multiple servers, please directly access the job running instance to manage jobs.' )
job_ids = util.listify( stop )
if job_ids and stop_msg in [ None, '' ]:
msg = 'Please enter an error message to display to the user describing why the job was terminated'
1
0

galaxy-dist commit 5f9d6d9582e5: Read zipfiles in chunks when uncompressing in the upload tool. And I continue to wish zipfile was a lot more like tarfile...
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Nate Coraor <nate(a)bx.psu.edu>
# Date 1287608406 14400
# Node ID 5f9d6d9582e50f134c97e8523a015f210dd3af70
# Parent 7afd79d131e40f5f9a61125ec159552dc7c3fabd
Read zipfiles in chunks when uncompressing in the upload tool. And I continue to wish zipfile was a lot more like tarfile...
--- a/tools/data_source/upload.py
+++ b/tools/data_source/upload.py
@@ -258,6 +258,9 @@ def add_file( dataset, registry, json_fi
# See if we have a zip archive
is_zipped = check_zip( dataset.path )
if is_zipped:
+ CHUNK_SIZE = 2**20 # 1Mb
+ uncompressed = None
+ uncompressed_name = None
unzipped = False
z = zipfile.ZipFile( dataset.path )
for name in z.namelist():
@@ -267,18 +270,28 @@ def add_file( dataset, registry, json_fi
stdout = 'ZIP file contained more than one file, only the first file was added to Galaxy.'
break
fd, uncompressed = tempfile.mkstemp( prefix='data_id_%s_upload_zip_' % dataset.dataset_id, dir=os.path.dirname( dataset.path ), text=False )
- try:
- outfile = open( uncompressed, 'wb' )
- outfile.write( z.read( name ) )
- outfile.close()
- shutil.move( uncompressed, dataset.path )
- dataset.name = name
- unzipped = True
- except IOError:
- os.close( fd )
- os.remove( uncompressed )
- file_err( 'Problem decompressing zipped data', dataset, json_file )
- return
+ zipped_file = z.open( name )
+ while 1:
+ try:
+ chunk = zipped_file.read( CHUNK_SIZE )
+ except IOError:
+ os.close( fd )
+ os.remove( uncompressed )
+ file_err( 'Problem decompressing zipped data', dataset, json_file )
+ return
+ if not chunk:
+ break
+ os.write( fd, chunk )
+ os.close( fd )
+ zipped_file.close()
+ uncompressed_name = name
+ unzipped = True
+ z.close()
+ # Replace the zipped file with the decompressed file
+ if uncompressed is not None:
+ shutil.move( uncompressed, dataset.path )
+ dataset.name = uncompressed_name
+ data_type = 'zip'
if not data_type:
if check_binary( dataset.path ):
# We have a binary dataset, but it is not Bam, Sff or Pdf
1
0

galaxy-dist commit c375c4a8e4e4: Fix more unicode issues when listing and running workflows.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287605437 14400
# Node ID c375c4a8e4e42e5e29e996f3472aacdbdc3d22e0
# Parent 647ca0049221bcadde31559d6a99a6ccf236d134
Fix more unicode issues when listing and running workflows.
--- a/templates/workflow/list_for_run.mako
+++ b/templates/workflow/list_for_run.mako
@@ -36,7 +36,7 @@
%for i, workflow in enumerate( workflows ):
<tr><td>
- <a href="${h.url_for( action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a>
+ <a href="${h.url_for( action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name )}</a><a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a></td><td>${len(workflow.latest_workflow.steps)}</td>
--- a/templates/workflow/run.mako
+++ b/templates/workflow/run.mako
@@ -119,7 +119,7 @@ from galaxy.jobs.actions.post import Act
</div></%def>
-<h2>Running workflow "${workflow.name}"</h2>
+<h2>Running workflow "${h.to_unicode( workflow.name )}"</h2>
%if has_upgrade_messages:
<div class="warningmessage">
@@ -130,7 +130,7 @@ from galaxy.jobs.actions.post import Act
%endif
<form id="tool_form" name="tool_form" method="POST">
-## <input type="hidden" name="workflow_name" value="${workflow.name | h}" />
+## <input type="hidden" name="workflow_name" value="${h.to_unicode( workflow.name ) | h}" />
%for i, step in enumerate( steps ):
%if step.type == 'tool' or step.type is None:
<% tool = app.toolbox.tools_by_id[step.tool_id] %>
@@ -153,7 +153,7 @@ from galaxy.jobs.actions.post import Act
% if step.annotations:
<hr/><div class='form-row'>
- <label>Annotation:</label> ${step.annotations[0].annotation}
+ <label>Annotation:</label> ${h.to_unicode( step.annotations[0].annotation )}
</div>
% endif
</div>
1
0

galaxy-dist commit 647ca0049221: Enable display of unicode characters in history and workflow annotations.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287604356 14400
# Node ID 647ca0049221bcadde31559d6a99a6ccf236d134
# Parent b3763f7ecec7082e76a5ff407091fa7f0bffb7df
Enable display of unicode characters in history and workflow annotations.
--- a/templates/workflow/editor.mako
+++ b/templates/workflow/editor.mako
@@ -1038,7 +1038,7 @@
<label>Annotation / Notes:</label><div id="workflow-annotation" class="tooltip editable-text" original-title="Click to edit annotation">
%if annotation:
- ${annotation | h}
+ ${h.to_unicode( annotation ) | h}
%else:
<em>Describe or add notes to workflow</em>
%endif
--- a/templates/root/history.mako
+++ b/templates/root/history.mako
@@ -378,7 +378,7 @@ div.form-row {
<div id="history-annotation-container"><div id="history-annotation" class="tooltip editable-text" title="Click to edit annotation">
%if annotation:
- ${annotation | h}
+ ${h.to_unicode( annotation ) | h}
%else:
<em>Describe or add notes to history</em>
%endif
1
0

galaxy-dist commit 9d9f0de20f4f: Make default initial value for Integer and Float parameters None.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dan Blankenberg <dan(a)bx.psu.edu>
# Date 1287683139 14400
# Node ID 9d9f0de20f4f9da28d53be38411b1ee1075201a1
# Parent 151d007da2f4709ba546cd5cc76738e28b64e05d
Make default initial value for Integer and Float parameters None.
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -212,7 +212,7 @@ class IntegerToolParameter( TextToolPara
if self.value:
return int( self.value )
else:
- return 0
+ return None
class FloatToolParameter( TextToolParameter ):
"""
@@ -254,7 +254,7 @@ class FloatToolParameter( TextToolParame
try:
return float( self.value )
except:
- return float( 0 )
+ return None
class BooleanToolParameter( ToolParameter ):
"""
1
0

galaxy-dist commit 35b379691524: Add dynamic attribute filtering framework for trackster and enable dynamic filtering of VCF quality values and BED score values. Framework enables users to interactively filter a visualized dataset within trackster; for example, a BED file of peaks can be filtering so that only peaks with a score greater than 100 are shown.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287519951 14400
# Node ID 35b379691524c768ec84f86477f1ab49859afec2
# Parent 6372b67c9e370b3a80159bcc719e13d50ddc018f
Add dynamic attribute filtering framework for trackster and enable dynamic filtering of VCF quality values and BED score values. Framework enables users to interactively filter a visualized dataset within trackster; for example, a BED file of peaks can be filtering so that only peaks with a score greater than 100 are shown.
Individual changes include: (a) improvements to datatypes and data providers to support BED score filtering and VCF quality filtering; (b) addition of jQueryUI theme for slider; (c) modifications to trackster to show, update, and apply filters.
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -469,7 +469,7 @@ class Vcf( Tabular ):
MetadataElement( name="columns", default=10, desc="Number of columns", readonly=True, visible=False )
MetadataElement( name="column_types", default=['str','int','str','str','str','int','str','list','str','str'], param=metadata.ColumnTypesParameter, desc="Column types", readonly=True, visible=False )
- MetadataElement( name="viz_filter_columns", default=[5] )
+ MetadataElement( name="viz_filter_cols", default=[5], param=metadata.ColumnParameter, multiple=True )
def sniff( self, filename ):
try:
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return fa
lse};$(b).bind("click",c)}function make_popupmenu(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");if(obj_length(b)<=0){$("<li/>").html("No options").appendTo(a)}$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d)}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=window.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));a.find("a").bind("click",function(b){b.stopPropagation();return true});make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}funct
ion naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().toLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a,b){if(!jQuery().autocomplete){return}if(a===undefined){a=20}if(b===undefined){b=3000}$("select").each(function(){var d=$(this);var g=d.find("option").length;if((g<a)||(g>b)){return}if(d.attr("multiple")==true){return}if(d.hasClass("no-autocomplete")){return}var m=d.attr("value");var c=$("<input type='text' class='text-and-autocomplete-select'></input>");c.attr("size",40);c.attr("name",d.attr("name"));c.attr("id",d.attr("id"));c.click(function(){var n=$(this).
val();$(this).val("Loading...");$(this).showAllInCache();$(this).val(n);$(this).select()});var e=[];var i={};d.children("option").each(function(){var o=$(this).text();var n=$(this).attr("value");e.push(o);i[o]=n;i[n]=n;if(n==m){c.attr("value",o)}});if(m==""||m=="?"){c.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:b,minChars:0,hideForLessThanMinChars:false};c.autocomplete(e,f);d.replaceWith(c);var k=function(){var o=c.attr("value");var n=i[o];if(n!==null&&n!==undefined){c.attr("value",n)}else{if(m!=""){c.attr("value",m)}else{c.attr("value","?")}}};c.parents("form").submit(function(){k()});$(document).bind("convert_dbkeys",function(){k()});if(d.attr("refresh_on_change")=="true"){var h=d.attr("refresh_on_change_values"),l=d.attr("last_selected_value");if(h!==undefined){h=h.split(",")}var j=function(){var n=i[c.attr("value")];if(n!==null&&n!==undefined){if
($.inArray(n,h)===-1&&$.inArray(l,h)===-1){return}c.attr("value",n);$(window).trigger("refresh_on_change");c.parents("form").submit()}};c.bind("result",j);c.keyup(function(n){if(n.keyCode===13){j()}});c.keydown(function(n){if(n.keyCode===13){return false}})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!=""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}}
)}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStore.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_state");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");i
f(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length==0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!="recently_used_wrappe
r"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools");b.css("font-style","italic")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};$(".trackster-add").live("click",function(){var b=this,a=$(this);$.ajax({url:a.attr("data-
url"),dataType:"html",error:function(){alert("Could not add this dataset to browser.")},success:function(c){var d=window.parent;d.show_modal("Add to Browser:",c,{Cancel:function(){d.hide_modal()},"Insert into selected":function(){$(d.document).find("input[name=id]:checked").each(function(){var e=$(this).val();d.location=a.attr("action-url")+"&id="+e})},"Insert into new browser":function(){d.location=a.attr("new-url")}})}})});$(document).ready(function(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(function(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus();replace_big_select_inputs(20,1500)});
+function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function ensure_popup_helper(){if($("#popup-helper").length===0){$("<div id='popup-helper'/>").css({background:"white",opacity:0,zIndex:15000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function attach_popupmenu(b,d){var a=function(){d.unbind().hide();$("#popup-helper").unbind("click.popupmenu").hide()};var c=function(g){$("#popup-helper").bind("click.popupmenu",a).show();d.click(a).css({left:0,top:-1000}).show();var f=g.pageX-d.width()/2;f=Math.min(f,$(document).scrollLeft()+$(window).width()-$(d).width()-20);f=Math.max(f,$(document).scrollLeft()+20);d.css({top:g.pageY-5,left:f});return fa
lse};$(b).bind("click",c)}function make_popupmenu(c,b){ensure_popup_helper();var a=$("<ul id='"+c.attr("id")+"-menu'></ul>");if(obj_length(b)<=0){$("<li/>").html("No options").appendTo(a)}$.each(b,function(f,e){if(e){$("<li/>").html(f).click(e).appendTo(a)}else{$("<li class='head'/>").html(f).appendTo(a)}});var d=$("<div class='popmenu-wrapper'>");d.append(a).append("<div class='overlay-border'>").css("position","absolute").appendTo("body").hide();attach_popupmenu(c,d);return a}function show_hide_popupmenu_options(d,c,a){var a=(a===undefined?true:a);var b=new RegExp(c);$(d).find("li").each(function(){if(b.exec($(this).text())){if(a){$(this).show()}else{$(this).hide()}}})}function make_popup_menus(){jQuery("div[popupmenu]").each(function(){var c={};$(this).find("a").each(function(){var b=$(this).attr("confirm"),d=$(this).attr("href"),e=$(this).attr("target");c[$(this).text()]=function(){if(!b||confirm(b)){var g=window;if(e=="_parent"){g=window.parent}else{if(e=="_top"){g=wind
ow.top}}g.location=d}}});var a=$("#"+$(this).attr("popupmenu"));a.find("a").bind("click",function(b){b.stopPropagation();return true});make_popupmenu(a,c);$(this).remove();a.addClass("popup").show()})}function naturalSort(i,g){var n=/(-?[0-9\.]+)/g,j=i.toString().toLowerCase()||"",f=g.toString().toLowerCase()||"",k=String.fromCharCode(0),l=j.replace(n,k+"$1"+k).split(k),e=f.replace(n,k+"$1"+k).split(k),d=(new Date(j)).getTime(),m=d?(new Date(f)).getTime():null;if(m){if(d<m){return -1}else{if(d>m){return 1}}}for(var h=0,c=Math.max(l.length,e.length);h<c;h++){oFxNcL=parseFloat(l[h])||l[h];oFyNcL=parseFloat(e[h])||e[h];if(oFxNcL<oFyNcL){return -1}else{if(oFxNcL>oFyNcL){return 1}}}return 0}function replace_big_select_inputs(a,b){if(!jQuery().autocomplete){return}if(a===undefined){a=20}if(b===undefined){b=3000}$("select").each(function(){var d=$(this);var g=d.find("option").length;if((g<a)||(g>b)){return}if(d.attr("multiple")==true){return}if(d.hasClass("no-autocomplete")){return
}var m=d.attr("value");var c=$("<input type='text' class='text-and-autocomplete-select'></input>");c.attr("size",40);c.attr("name",d.attr("name"));c.attr("id",d.attr("id"));c.click(function(){var n=$(this).val();$(this).val("Loading...");$(this).showAllInCache();$(this).val(n);$(this).select()});var e=[];var i={};d.children("option").each(function(){var o=$(this).text();var n=$(this).attr("value");e.push(o);i[o]=n;i[n]=n;if(n==m){c.attr("value",o)}});if(m==""||m=="?"){c.attr("value","Click to Search or Select")}if(d.attr("name")=="dbkey"){e=e.sort(naturalSort)}var f={selectFirst:false,autoFill:false,mustMatch:false,matchContains:true,max:b,minChars:0,hideForLessThanMinChars:false};c.autocomplete(e,f);d.replaceWith(c);var k=function(){var o=c.attr("value");var n=i[o];if(n!==null&&n!==undefined){c.attr("value",n)}else{if(m!=""){c.attr("value",m)}else{c.attr("value","?")}}};c.parents("form").submit(function(){k()});$(document).bind("convert_dbkeys",function(){k()});if(d.attr("r
efresh_on_change")=="true"){var h=d.attr("refresh_on_change_values"),l=d.attr("last_selected_value");if(h!==undefined){h=h.split(",")}var j=function(){var n=i[c.attr("value")];if(n!==null&&n!==undefined){if($.inArray(n,h)===-1&&$.inArray(l,h)===-1){return}c.attr("value",n);$(window).trigger("refresh_on_change");c.parents("form").submit()}};c.bind("result",j);c.keyup(function(n){if(n.keyCode===13){j()}});c.keydown(function(n){if(n.keyCode===13){return false}})}})}function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).live("click",function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m
[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!=""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStore.store("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStore.remove("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id;var h=$(this).children("div.historyItemBody");var i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){var k=$.jStore.store("history_expand_s
tate");if(k){delete k[j];$.jStore.store("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){var k=$.jStore.store("history_expand_state");if(k===undefined){k={}}k[j]=true;$.jStore.store("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStore.store("history_expand_state");if(h===undefined){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStore.store("history_expand_state",h)}).show()};if(a){b()}else{$.jStore.init("galaxy");$.jStore.engineReady(function(){b()})}}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length==0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeC
lass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools");b.css("font-style","italic")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false
}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};$(".trackster-add").live("click",function(){var b=this,a=$(this);$.ajax({url:a.attr("data-url"),dataType:"html",error:function(){alert("Could not add this dataset to browser.")},success:function(c){var d=window.parent;d.show_modal("Add to Browser:",c,{Cancel:function(){d.hide_modal()},"Insert into selected":function(){$(d.document).find("input[name=id]:checked").each(function(){var e=$(this).val();d.location=a.attr("action-url")+"&id="+e})},"Insert into new browser":function(){d.location=a.attr("new-url")}})}})});$(document).ready(function(){$("select[refresh_on_change='true']").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").click(func
tion(){return confirm($(this).attr("confirm"))});if($.fn.tipsy){$(".tooltip").tipsy({gravity:"s"})}make_popup_menus();replace_big_select_inputs(20,1500)});
Binary file static/june_2007_style/blue/overcast/images/ui-bg_inset-hard_75_999999_1x100.png has changed
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function()
{RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.
min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview
-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<inp
ut/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=d.chrom_info
;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("dragstart",function(d){this.origin
al_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,h=(a.high-a.
low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g i
n c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.reset_overview();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this
.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a,width:e})}this.update_locatio
n(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Track=function(b,a,c){this.name=b;this.parent_
element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name)}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("e
rror");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined
){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configuration"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},j=function(){d.update_options(d.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){j()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:l,OK
:j})};b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};make_popupmenu(d.name_div,b)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_ca
nvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10
)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:
this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,l,p){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),o=e.get(0).getContext("2d"),k=f+"_"+b;if(p>PX_PER_CHAR){if(this.data_cache.get(k)===undefined){this.get_data(f,b);return}var n=this.data_cache.get(k);if(n===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*p+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*p-this.left_offset});for(var h=0,m=n.length;h<m;h++){var a=Math.round(h*p),j=Math.round(p/2);o.fillText(n[h],a+this.left_offset+j,10)}l.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_
px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;a.container_div.find(".yaxislabel").remove();var e=$("<div />").addCl
ass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,s,c,e){if(this.vertical_range===undefined){return}var t=s*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),w=p+"_"+s;if(this.data_cache.get(w)===undefined){this.get_data(p,s);return}v
ar j=this.data_cache.get(w);if(j===null){return}b.css({position:"absolute",top:0,left:(t-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,u=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();o.fillStyle=this.prefs.color;if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var v,h;for(var q=0,r=data.length;q<r;q++){v=Math.round((data[q][0]-t)*e);h=data[q][1];if(h===null){if(k&&m==="Filled"){o.lineTo(v,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(d-(h-l)/n*d);o.fillRect(v,h,f,d-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(v,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(v,h)}else{k=true;if(m==="Filled"){o.moveTo(v,d);o.lineTo(v,h)}else{o.moveTo(v,h)}}}}}if(m==="Filled"){if(k){o.lineTo(v,d)}o.fill()}else
{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var e="track_"+n+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+n+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),l=$("<input></input>").attr("id",h).val(d),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j);return a.append(m).append(l).append(g).append(f).append(b).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();color=$("#track_"+c+"_color").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value||color!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.prefs.color=color;this.vert
ical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_colo
r!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_
slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefine
d&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(ad,n,r,aq){var M=n*DENSITY*ad,ai=(n+1)*DENSITY*ad,L=ai-M;var ak=(!this.initial_canvas?"initial":M+"_"+ai);var H=this.data_cache.get(ak);var e;if(H===undefined||(this.mode!=="Auto"&&H.dataset_type==="summary_tree")){this.data_queue[[M,ai]]=true;this.get_data(M,ai);return}var a=Math.ceil(L*aq),R=$("<canvas class='tile'></canvas>"),af=this.prefs.label_color,h=this.prefs.block_color,q=this.mode,w=25,ab=(q==="Squish")||(q==="Dense")&&(q!=="Pack")||(q==="Auto"&&(H.extra_info==="no_detail")),V=this.left_offset,ap,C,ar;if(H.dataset_type==="summary_tree"){C=this.summary_draw_height}else{if(q==="Dense"){C=w;ar=10}else{ar=(ab?this.vertical_nodetail_px:this.vertical_detail_px);var
z=(aq<0.0001?1/view.zoom_res:aq);C=this.incremental_slots(z,H.data,ab,q)*ar+w;ap=this.inc_slots[z]}}R.css({position:"absolute",top:0,left:(M-this.view.low)*aq-V});R.get(0).width=a+V;R.get(0).height=C;r.parent().css("height",Math.max(this.height_px,C)+"px");var I=R.get(0).getContext("2d");I.fillStyle=h;I.font=this.default_font;I.textAlign="right";this.container_div.find(".yaxislabel").remove();if(H.dataset_type=="summary_tree"){var X=H.data,K=H.max,p=H.avg,b=Math.ceil(H.delta*aq);var o=$("<div />").addClass("yaxislabel").text(K);o.css({position:"absolute",top:"22px",left:"10px"});o.prependTo(this.container_div);for(var am=0,G=X.length;am<G;am++){var Z=Math.floor((X[am][0]-M)*aq);var Y=X[am][1];if(!Y){continue}var aj=Y/K*this.summary_draw_height;I.fillStyle="black";I.fillRect(Z+V,this.summary_draw_height-aj,b,aj);if(this.prefs.show_counts&&I.measureText(Y).width<b){I.fillStyle="#bbb";I.textAlign="center";I.fillText(Y,Z+V+(b/2),this.summary_draw_height-5)}}e="Summary";r.append
(R);return R}if(H.message){R.css({border:"solid red","border-width":"2px 2px 2px 0px"});I.fillStyle="red";I.textAlign="left";I.fillText(H.message,100+V,ar)}var ao=H.data;var al=0;for(var am=0,G=ao.length;am<G;am++){var S=ao[am],Q=S[0],an=S[1],aa=S[2],N=S[3];if(an<=ai&&aa>=M){var ac=Math.floor(Math.max(0,(an-M)*aq)),J=Math.ceil(Math.min(a,Math.max(0,(aa-M)*aq))),W=(q==="Dense"?1:(1+ap[Q]))*ar;if(H.dataset_type==="bai"){var u=S[4];I.fillStyle=h;if(S[5] instanceof Array){var D=Math.floor(Math.max(0,(S[5][0]-M)*aq)),P=Math.ceil(Math.min(a,Math.max(0,(S[5][1]-M)*aq))),B=Math.floor(Math.max(0,(S[6][0]-M)*aq)),v=Math.ceil(Math.min(a,Math.max(0,(S[6][1]-M)*aq)));if(S[5][1]>=M&&S[5][0]<=ai){this.rect_or_text(I,aq,M,ai,S[5][0],S[5][2],D+V,P-D,W)}if(S[6][1]>=M&&S[6][0]<=ai){this.rect_or_text(I,aq,M,ai,S[6][0],S[6][2],B+V,v-B,W)}if(B>P){I.fillStyle="#999";I.fillRect(P+V,W+5,B-P,1)}}else{I.fillStyle=h;this.rect_or_text(I,aq,M,ai,an,N,ac+V,J-ac,W)}if(q!=="Dense"&&!ab&&an>M){I.fillStyle=th
is.prefs.label_color;if(n===0&&ac-I.measureText(N).width<0){I.textAlign="left";I.fillText(Q,J+2+V,W+8)}else{I.textAlign="right";I.fillText(Q,ac-2+V,W+8)}I.fillStyle=h}}else{if(H.dataset_type==="interval_index"){if(ab){I.fillStyle=h;I.fillRect(ac+V,W+5,J-ac,1)}else{var F=S[4],U=S[5],ae=S[6],g=S[7];var E,ag,O=null,at=null;if(U&&ae){O=Math.floor(Math.max(0,(U-M)*aq));at=Math.ceil(Math.min(a,Math.max(0,(ae-M)*aq)))}if(q!=="Dense"&&N!==undefined&&an>M){I.fillStyle=af;if(n===0&&ac-I.measureText(N).width<0){I.textAlign="left";I.fillText(N,J+2+V,W+8)}else{I.textAlign="right";I.fillText(N,ac-2+V,W+8)}I.fillStyle=h}if(g){if(F){if(F=="+"){I.fillStyle=RIGHT_STRAND}else{if(F=="-"){I.fillStyle=LEFT_STRAND}}I.fillRect(ac+V,W,J-ac,10);I.fillStyle=h}for(var ak=0,f=g.length;ak<f;ak++){var t=g[ak],d=Math.floor(Math.max(0,(t[0]-M)*aq)),T=Math.ceil(Math.min(a,Math.max((t[1]-M)*aq)));if(d>T){continue}E=5;ag=3;I.fillRect(d+V,W+ag,T-d,E);if(O!==undefined&&!(d>at||T<O)){E=9;ag=1;var ah=Math.max(d,O)
,A=Math.min(T,at);I.fillRect(ah+V,W+ag,A-ah,E)}}}else{E=9;ag=1;I.fillRect(ac+V,W+ag,J-ac,E);if(S.strand){if(S.strand=="+"){I.fillStyle=RIGHT_STRAND_INV}else{if(S.strand=="-"){I.fillStyle=LEFT_STRAND_INV}}I.fillRect(ac+V,W,J-ac,10);I.fillStyle=h}}}}else{if(H.dataset_type==="vcf"){if(ab){I.fillStyle=h;I.fillRect(ac+V,W+5,J-ac,1)}else{var s=S[4],m=S[5],c=S[6];E=9;ag=1;I.fillRect(ac+V,W,J-ac,E);if(q!=="Dense"&&N!==undefined&&an>M){I.fillStyle=af;if(n===0&&ac-I.measureText(N).width<0){I.textAlign="left";I.fillText(N,J+2+V,W+8)}else{I.textAlign="right";I.fillText(N,ac-2+V,W+8)}I.fillStyle=h}var l=s+" / "+m;if(an>M&&I.measureText(l).width<(J-ac)){I.fillStyle="white";I.textAlign="center";I.fillText(l,V+ac+(J-ac)/2,W+8);I.fillStyle=h}}}}}al++}}r.append(R);return R},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k
="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vert
ical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";r
ight_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_coun
ter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Ove
rview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return
false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack
(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("drag
start",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.contai
ner.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.rese
t();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.reset_overview();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remo
ve()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a
,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=function(
b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=Number.MIN_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=Number.MIN_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[th
is.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.filte
ring_div.hide();this.filtering_div.bind("drag",function(k){k.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(var e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th class='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);d.text("[0-2]");var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:0,max:1,values:[0,1],slide:function(l,m){var k=m.values;d.text("["+k[0]+"-"+k[1]+"]");a.low=k[0];a.high=k[1];c.draw(true)},change:function(k,l){a.control_element.slider("option","slide").call(a.control_element,k,l)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},i
nit_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.
addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configurat
ion"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},j=function(){d.update_options(d.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){j()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:l,OK:j})};if(d.filters.length>0){b["Show filters"]=function(){var j;if(!d.filtering_div.is(":visible")){j="Hide filters";d.filters_visible=true}else{j="Show filters";d.filters_visible=false}$("#"+d.name_div.attr("id")+"-menu").find("li").eq(2).text(j);d.filtering_div.toggle()}}b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};d.popup_menu=make_popupmenu(d.name_div,b);show_hide_popupmenu_options(d.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(b){var m=this.view.low,g=this.view.high,h=g-m,f=this.view.res
olution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/h,k;this.content_div.append(p),this.max_height=0;var a=Math.floor(m/f/DENSITY);var l=new Object();while((a*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+a;var e=this.tile_cache.get(n);if(!b&&e){var j=a*DENSITY*f;var d=(j-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,a,f,p,q,l)}a+=1}var c=this;var o=setInterval(function(){if(l.length!=0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var r=0;r<c.filters.length;r++){c.filters[r].update_ui_elt()}clearInterval(o)}},50)},delayed_draw:function(c,h,g,e,b,d,j,k,f){var a=setTimeout(function(){if(!(g>c.view.high||e<c.view.low)){tile_element=c.draw_tile(d,b,j,k);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var n=tile_element.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=n.
getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,tile_element);c.show_tile(tile_element,j)}}delete f.id},50);f.id=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a
,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_da
ta:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,l,p){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),o=e.get(0).getContext("2d"),k=f+"_"+b;if(p>PX_PER_CHAR){if(this.data_cache.get(k)===undefined){this.get_data(f,b);return}var n=this.data_cache.get(k);if(n===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*p+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*p-this.left_offset});for(var h=0,m=n.length;h<m;h++){var a=Math.round(h*p),j=Math.round(p/2);o.fillText(n[h],a+this.left_offset+j,10)}l.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=func
tion(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#trac
k_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;a.container_div.find(".yaxislabel").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:func
tion(p,s,c,e){if(this.vertical_range===undefined){return}var t=s*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),w=p+"_"+s;if(this.data_cache.get(w)===undefined){this.get_data(p,s);return}var j=this.data_cache.get(w);if(j===null){return}b.css({position:"absolute",top:0,left:(t-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,u=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();o.fillStyle=this.prefs.color;if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var v,h;for(var q=0,r=data.length;q<r;q++){v=Math.round((data[q][0]-t)*e);h=data[q][1];if(h===null){if(k&&m==="Filled"){o.lineTo(v,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(d-(h-l)/n*d);o.fillRect(v,h,f,d-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";
o.fillRect(v,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(v,h)}else{k=true;if(m==="Filled"){o.moveTo(v,d);o.lineTo(v,h)}else{o.moveTo(v,h)}}}}}if(m==="Filled"){if(k){o.lineTo(v,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var e="track_"+n+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+n+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),l=$("<input></input>").attr("id",h).val(d),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j);return a.append(m).append(l).append(g).append(f).append(b).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();color=$("#track_"+
c+"_color").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value||color!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.prefs.color=color;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE
);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};th
is.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,
f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(ah,o,s,aw){var N=o*DENSITY*ah,am=(o+1)*DENSITY*ah,M=am-N;var ao=(!this.initial_canvas?"initial":N+"_"+am);var I=this.data_cache.get(ao);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,am]]=true;this.get_data(N,am);return}var a=Math.ceil(M*aw),S=$("<canvas class='tile'></canvas>"),aj=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,af=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_inf
o==="no_detail")),X=this.left_offset,av,D,ax;if(I.dataset_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;ax=10}else{ax=(af?this.vertical_nodetail_px:this.vertical_detail_px);var A=(aw<0.0001?1/view.zoom_res:aw);D=this.incremental_slots(A,I.data,af,r)*ax+z;av=this.inc_slots[A]}}S.css({position:"absolute",top:0,left:(N-this.view.low)*aw-X});S.get(0).width=a+X;S.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=S.get(0).getContext("2d");J.fillStyle=l;J.font=this.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Z=I.data,L=I.max,q=I.avg,b=Math.ceil(I.delta*aw);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var aq=0,H=Z.length;aq<H;aq++){var ab=Math.floor((Z[aq][0]-N)*aw);var aa=Z[aq][1];if(!aa){continue}var an=aa/L*this.summary_draw_height;J.fillStyle="black";J.fil
lRect(ab+X,this.summary_draw_height-an,b,an);if(this.prefs.show_counts&&J.measureText(aa).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(aa,ab+X+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(S);return S}if(I.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+X,ax)}var ae=false;if(I.data.length!=0){ae=true;for(var at=0;at<this.filters.length;at++){if(!this.filters[at].applies_to(I.data[0])){ae=false}}}if(ae){S.addClass(FILTERABLE_CLASS)}var au=I.data;var ap=0;for(var aq=0,H=au.length;aq<H;aq++){var T=au[aq],R=T[0],ar=T[1],ad=T[2],O=T[3];var ac=false;var V;for(var at=0;at<this.filters.length;at++){V=this.filters[at];V.update_attrs(T);if(!V.keep(T)){ac=true;break}}if(ac){continue}if(ar<=am&&ad>=N){var ag=Math.floor(Math.max(0,(ar-N)*aw)),K=Math.ceil(Math.min(a,Math.max(0,(ad-N)*aw))),Y=(r==="Dense"?1:(1+av[R]))*ax;if(I.dataset_type==="bai"){var v=T[4];J.fillStyle=l;if(T[5] in
stanceof Array){var E=Math.floor(Math.max(0,(T[5][0]-N)*aw)),Q=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-N)*aw))),C=Math.floor(Math.max(0,(T[6][0]-N)*aw)),w=Math.ceil(Math.min(a,Math.max(0,(T[6][1]-N)*aw)));if(T[5][1]>=N&&T[5][0]<=am){this.rect_or_text(J,aw,N,am,T[5][0],T[5][2],E+X,Q-E,Y)}if(T[6][1]>=N&&T[6][0]<=am){this.rect_or_text(J,aw,N,am,T[6][0],T[6][2],C+X,w-C,Y)}if(C>Q){J.fillStyle="#999";J.fillRect(Q+X,Y+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,aw,N,am,ar,O,ag+X,K-ag,Y)}if(r!=="Dense"&&!af&&ar>N){J.fillStyle=this.prefs.label_color;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(R,ag-2+X,Y+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var G=T[4],W=T[5],ai=T[6],h=T[7];var F,ak,P=null,ay=null;if(W&&ai){P=Math.floor(Math.max(0,(W-N)*aw));ay=Math.ceil(Math.min(a,Math.max(0,(ai-N)*aw)))}if(r!=="Dense"&&O!==undefined&&ar>N){J.fil
lStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}if(h){if(G){if(G=="+"){J.fillStyle=RIGHT_STRAND}else{if(G=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}for(var ao=0,g=h.length;ao<g;ao++){var u=h[ao],d=Math.floor(Math.max(0,(u[0]-N)*aw)),U=Math.ceil(Math.min(a,Math.max((u[1]-N)*aw)));if(d>U){continue}F=5;ak=3;J.fillRect(d+X,Y+ak,U-d,F);if(P!==undefined&&!(d>ay||U<P)){F=9;ak=1;var al=Math.max(d,P),B=Math.min(U,ay);J.fillRect(al+X,Y+ak,B-al,F)}}}else{F=9;ak=1;J.fillRect(ag+X,Y+ak,K-ag,F);if(T.strand){if(T.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var t=T[4],n=T[5],c=T[6];F=9;ak=1;J.fillRect(ag+X,Y,K-ag,F);if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&a
g-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}var m=t+" / "+n;if(ar>N&&J.measureText(m).width<(K-ag)){J.fillStyle="white";J.textAlign="center";J.fillText(m,X+ag+(K-ag)/2,Y+8);J.fillStyle=l}}}}}ap++}}return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_opti
ons:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -10,6 +10,7 @@ var DENSITY = 200,
DATA_NONE = "No data for this chrom/contig.",
DATA_PENDING = "Currently indexing... please wait",
DATA_LOADING = "Loading data...",
+ FILTERABLE_CLASS = "filterable",
CACHED_TILES_FEATURE = 10,
CACHED_TILES_LINE = 30,
CACHED_DATA = 5,
@@ -448,10 +449,100 @@ var View = function( container, chrom, t
}
});
-var Track = function (name, view, parent_element) {
+// Generic filter.
+var Filter = function( name, index, value ) {
this.name = name;
+ this.index = index;
+ this.value = value;
+};
+
+// Number filter for a track.
+var NumberFilter = function( name, index ) {
+ this.name = name;
+ // Index into payload to filter.
+ this.index = index;
+ // Filter low/high. These values are used to filter elements.
+ this.low = Number.MIN_VALUE;
+ this.high = Number.MAX_VALUE;
+ // Slide min/max. These values are used to set/update slider.
+ this.slider_min = Number.MAX_VALUE;
+ this.slider_max = Number.MIN_VALUE;
+ // UI Slider element and label that is associated with filter.
+ this.slider = null;
+ this.slider_label = null;
+};
+$.extend( NumberFilter.prototype, {
+ // Returns true if filter can be applied to element.
+ applies_to: function( element ) {
+ if ( element.length > this.index )
+ return true;
+ return false;
+ },
+ // Returns true iff element is in [low, high]; range is inclusive.
+ keep: function( element ) {
+ if ( !this.applies_to( element ) )
+ // No element to filter on.
+ return true;
+ return ( element[this.index] >= this.low && element[this.index] <= this.high );
+ },
+ // Update filter's min and max values based on element's values.
+ update_attrs: function( element ) {
+ var updated = false;
+ if ( !this.applies_to( element ) ) {
+ return updated;
+ }
+
+ // Update filter's min, max based on element values.
+ if ( element[this.index] < this.slider_min ) {
+ this.slider_min = element[this.index];
+ updated = true;
+ }
+ if ( element[this.index] > this.slider_max ) {
+ this.slider_max = element[this.index];
+ updated = false;
+ }
+ return updated;
+ },
+ // Update filter's slider.
+ update_ui_elt: function () {
+ var
+ slider_min = this.slider.slider( "option", "min" ),
+ slider_max = this.slider.slider( "option", "max" );
+ if (this.slider_min < slider_min || this.slider_max > slider_max) {
+ // Need to update slider.
+ this.slider.slider( "option", "min", this.slider_min );
+ this.slider.slider( "option", "max", this.slider_max );
+ // Refresh slider:
+ // TODO: do we want to keep current values or reset to min/max?
+ // Currently we reset values:
+ this.slider.slider( "option", "values", [ this.slider_min, this.slider_max ] );
+ // To use the current values.
+ //var values = this.slider.slider( "option", "values" );
+ //this.slider.slider( "option", "values", values );
+ }
+ }
+});
+
+// Parse filters dict and return filters.
+var get_filters = function( filters_dict ) {
+ var filters = []
+ for (var i = 0; i < filters_dict.length; i++) {
+ var filter_dict = filters_dict[i];
+ var name = filter_dict['name'], type = filter_dict['type'], index = filter_dict['index'];
+ if ( type == 'int' || type == 'float' ) {
+ filters[i] = new NumberFilter( name, index );
+ }
+ else
+ filters[i] = new Filter( name, index, type );
+ }
+ return filters;
+};
+
+var Track = function (name, view, parent_element, filters) {
+ this.name = name;
+ this.view = view;
this.parent_element = parent_element;
- this.view = view;
+ this.filters = (filters !== undefined ? get_filters( filters ) : []);
this.init_global();
};
$.extend( Track.prototype, {
@@ -462,7 +553,51 @@ var Track = function (name, view, parent
if (this.view.editor) { this.drag_div = $("<div class='draghandle' />").appendTo(this.header_div); }
this.name_div = $("<div class='menubutton popup' />").appendTo(this.header_div);
this.name_div.text(this.name);
+ this.name_div.attr( "id", this.name.replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() );
}
+ // Create track filtering div.
+ this.filtering_div = $("<div class='track-filters'>").appendTo(this.container_div);
+ this.filtering_div.hide();
+ // Dragging is disabled on div so that actions on slider do not impact viz.
+ this.filtering_div.bind( "drag", function(e) {
+ e.stopPropagation();
+ });
+ var filters_table = $("<table class='filters'>").appendTo(this.filtering_div);
+ var track = this;
+ for (var i = 0; i < this.filters.length; i++) {
+ var filter = this.filters[i];
+ var table_row = $("<tr>").appendTo(filters_table);
+ var filter_th = $("<th class='filter-info'>").appendTo(table_row);
+ var name_span = $("<span class='name'>").appendTo(filter_th);
+ name_span.text(filter.name + " "); // Extra spacing to separate name and values
+ var values_span = $("<span class='values'>").appendTo(filter_th);
+ values_span.text("[0-2]");
+ // TODO: generate custom interaction elements based on filter type.
+ var table_data = $("<td>").appendTo(table_row);
+ filter.control_element = $("<div id='" + filter.name + "-filter-control' style='width: 200px; position: relative'>").appendTo(table_data);
+ filter.control_element.slider({
+ range: true,
+ min: 0,
+ max: 1,
+ values: [0, 1],
+ slide: function( event, ui ) {
+ var values = ui.values;
+ // Set new values in UI.
+ values_span.text( "[" + values[0] + "-" + values[1] + "]" );
+ // Set new values in filter.
+ filter.low = values[0];
+ filter.high = values[1];
+ // Redraw track.
+ track.draw( true );
+ },
+ change: function( event, ui ) {
+ filter.control_element.slider( "option", "slide" ).call( filter.control_element, event, ui );
+ }
+ });
+ filter.slider = filter.control_element;
+ filter.slider_label = values_span;
+ }
+
this.content_div = $("<div class='track-content'>").appendTo(this.container_div);
this.parent_element.append(this.container_div);
},
@@ -478,7 +613,7 @@ var Track = function (name, view, parent
track.content_div.text(DATA_LOADING);
}
track.container_div.removeClass("nodata error pending");
-
+
if (track.view.chrom) {
$.getJSON( data_url, params, function (result) {
if (!result || result === "error" || result.kind === "error") {
@@ -577,14 +712,30 @@ var TiledTrack = function() {
"OK": ok_fn
});
};
+ if (track.filters.length > 0) {
+ track_dropdown["Show filters"] = function() {
+ // Set option text and toggle filtering div.
+ var menu_option_text;
+ if (!track.filtering_div.is(":visible")) {
+ menu_option_text = "Hide filters";
+ track.filters_visible = true;
+ }
+ else {
+ menu_option_text = "Show filters";
+ track.filters_visible = false;
+ }
+ $("#" + track.name_div.attr("id") + "-menu").find("li").eq(2).text(menu_option_text);
+ track.filtering_div.toggle();
+ };
+ }
track_dropdown["Remove"] = function() {
view.remove_track(track);
if (view.num_tracks === 0) {
$("#no-tracks").show();
}
};
- make_popupmenu(track.name_div, track_dropdown);
-
+ track.popup_menu = make_popupmenu(track.name_div, track_dropdown);
+ show_hide_popupmenu_options(track.popup_menu, "(Show|Hide) filters", false);
/*
if (track.overview_check_div === undefined) {
track.overview_check_div = $("<div class='right-float' />").css("margin-top", "-3px").appendTo(track.header_div);
@@ -604,7 +755,7 @@ var TiledTrack = function() {
*/
};
$.extend( TiledTrack.prototype, Track.prototype, {
- draw: function() {
+ draw: function( force ) {
var low = this.view.low,
high = this.view.high,
range = high - low,
@@ -614,35 +765,54 @@ var TiledTrack = function() {
w_scale = this.content_div.width() / range,
tile_element;
- this.content_div.children( ":first" ).remove();
this.content_div.append( parent_element ),
this.max_height = 0;
// Index of first tile that overlaps visible region
var tile_index = Math.floor( low / resolution / DENSITY );
+ // A list of setTimeout() ids used when drawing tiles.
+ var draw_tile_ids = new Object();
while ( ( tile_index * DENSITY * resolution ) < high ) {
// Check in cache
var key = this.content_div.width() + '_' + w_scale + '_' + tile_index;
var cached = this.tile_cache.get(key);
- if ( cached ) {
- // console.log("cached tile " + tile_index);
+ if ( !force && cached ) {
var tile_low = tile_index * DENSITY * resolution;
var left = ( tile_low - low ) * w_scale;
if (this.left_offset) {
left -= this.left_offset;
}
cached.css({ left: left });
- // Our responsibility to move the element to the new parent
- parent_element.append( cached );
- this.max_height = Math.max( this.max_height, cached.height() );
- this.content_div.css("height", this.max_height + "px");
+ this.show_tile( cached, parent_element );
} else {
- this.delayed_draw(this, key, low, high, tile_index, resolution, parent_element, w_scale);
+ this.delayed_draw(this, key, low, high, tile_index, resolution, parent_element, w_scale, draw_tile_ids);
}
tile_index += 1;
}
- }, delayed_draw: function(track, key, low, high, tile_index, resolution, parent_element, w_scale) {
+
+ //
+ // Actions to take after new tiles have been loaded/drawn:
+ // (1) remove old tile(s);
+ // (2) update filtering UI elements.
+ //
+ var track = this;
+ var intervalId = setInterval(function() {
+ if ( draw_tile_ids.length != 0 ) {
+ // Add drawing has finished; if there is more than one child in the content div,
+ // remove the first one, which is the oldest.
+ if ( track.content_div.children().length > 1 ) {
+ track.content_div.children( ":first" ).remove();
+ }
+
+ // Update filtering UI.
+ for (var f = 0; f < track.filters.length; f++)
+ track.filters[f].update_ui_elt();
+ // Method complete; do not call it again.
+ clearInterval(intervalId);
+ }
+ }, 50);
+ }, delayed_draw: function(track, key, low, high, tile_index, resolution, parent_element, w_scale, draw_tile_ids) {
// Put a 50ms delay on drawing so that if the user scrolls fast, we don't load extra data
- setTimeout(function() {
+ var id = setTimeout(function() {
if ( !(low > track.view.high || high < track.view.low) ) {
tile_element = track.draw_tile( resolution, tile_index, parent_element, w_scale );
if (tile_element) {
@@ -655,12 +825,36 @@ var TiledTrack = function() {
tgt_ctx.putImageData(data, 0, 0);
track.set_overview();
}
+ // Add tile to cache and show tile.
track.tile_cache.set(key, tile_element);
- track.max_height = Math.max( track.max_height, tile_element.height() );
- track.content_div.css("height", track.max_height + "px");
+ track.show_tile( tile_element, parent_element )
}
}
+ // Remove setTimeout id.
+ delete draw_tile_ids.id;
}, 50);
+ draw_tile_ids.id = true;
+ },
+ // Show track tile and perform associated actions.
+ show_tile: function( tile_element, parent_element ) {
+ // Readability.
+ var track = this;
+
+ // Setup and show tile element.
+ parent_element.append( tile_element );
+ track.max_height = Math.max( track.max_height, tile_element.height() );
+ track.content_div.css("height", track.max_height + "px");
+
+ // Show/hide filters based on whether tile is filterable.
+ if ( tile_element.hasClass(FILTERABLE_CLASS) ) {
+ show_hide_popupmenu_options(track.popup_menu, "(Show|Hide) filters");
+ if (track.filters_visible)
+ track.filtering_div.show();
+ }
+ else {
+ show_hide_popupmenu_options(track.popup_menu, "(Show|Hide) filters", false);
+ track.filtering_div.hide();
+ }
}, set_overview: function() {
var view = this.view;
@@ -986,10 +1180,10 @@ var LineTrack = function ( name, view, d
}
});
-var FeatureTrack = function ( name, view, dataset_id, prefs ) {
+var FeatureTrack = function ( name, view, dataset_id, filters, prefs ) {
this.track_type = "FeatureTrack";
this.display_modes = ["Auto", "Dense", "Squish", "Pack"];
- Track.call( this, name, view, view.viewport_container );
+ Track.call( this, name, view, view.viewport_container, filters );
TiledTrack.call( this );
this.height_px = 0;
@@ -1245,6 +1439,24 @@ var FeatureTrack = function ( name, view
ctx.fillText(result.message, 100 + left_offset, y_scale);
}
+ //
+ // We're now working at the level of individual data points.
+ //
+
+ // See if tile is filterable. If so, add class.
+ var filterable = false;
+ if ( result.data.length != 0 ) {
+ filterable = true;
+ for (var f = 0; f < this.filters.length; f++)
+ if ( !this.filters[f].applies_to( result.data[0] ) ) {
+ filterable = false;
+ }
+ }
+ if ( filterable ) {
+ new_canvas.addClass(FILTERABLE_CLASS);
+ }
+
+ // Draw data points.
var data = result.data;
var j = 0;
for (var i = 0, len = data.length; i < len; i++) {
@@ -1254,6 +1466,20 @@ var FeatureTrack = function ( name, view
feature_end = feature[2],
feature_name = feature[3];
+ // Apply filters to feature.
+ var hide_feature = false;
+ var filter;
+ for (var f = 0; f < this.filters.length; f++) {
+ filter = this.filters[f];
+ filter.update_attrs( feature );
+ if ( !filter.keep( feature ) ) {
+ hide_feature = true;
+ break;
+ }
+ }
+ if ( hide_feature )
+ continue;
+
if (feature_start <= tile_high && feature_end >= tile_low) {
var f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
@@ -1374,6 +1600,7 @@ var FeatureTrack = function ( name, view
}
}
} else if (result.dataset_type === 'vcf') {
+ // VCF track.
if (no_detail) {
ctx.fillStyle = block_color;
ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1);
@@ -1414,7 +1641,6 @@ var FeatureTrack = function ( name, view
j++;
}
}
- parent_element.append(new_canvas);
return new_canvas;
}, gen_options: function(track_id) {
var container = $("<div />").addClass("form-row");
@@ -1446,8 +1672,8 @@ var FeatureTrack = function ( name, view
}
});
-var ReadTrack = function ( name, view, dataset_id, prefs ) {
- FeatureTrack.call( this, name, view, dataset_id, prefs );
+var ReadTrack = function ( name, view, dataset_id, filters, prefs ) {
+ FeatureTrack.call( this, name, view, dataset_id, filters, prefs );
this.track_type = "ReadTrack";
this.vertical_detail_px = 10;
this.vertical_nodetail_px = 5;
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -90,6 +90,20 @@ function make_popupmenu( button_element,
.appendTo( "body" )
.hide();
attach_popupmenu( button_element, wrapper );
+ return menu_element;
+}
+
+// Toggle popup menu options using regular expression on option names.
+function show_hide_popupmenu_options( menu, option_name_re, show ) {
+ var show = (show === undefined ? true : show );
+ var re = new RegExp(option_name_re);
+ $(menu).find("li").each( function() {
+ if ( re.exec( $(this).text() ) )
+ if (show)
+ $(this).show();
+ else
+ $(this).hide();
+ });
}
function make_popup_menus() {
Binary file static/june_2007_style/blue/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png has changed
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -19,10 +19,13 @@ class TracksDataProvider( object ):
""" Base class for tracks data providers. """
"""
- Mapping from column name to index in data. This mapping is used to create
- filters.
+ Mapping from column name to payload data; this mapping is used to create
+ filters. Key is column name, value is a dict with mandatory key 'index' and
+ optional key 'name'. E.g. this defines column 4
+
+ col_name_data_attr_mapping = {4 : { index: 5, name: 'Score' } }
"""
- col_name_data_index_mapping = {}
+ col_name_data_attr_mapping = {}
def __init__( self, converted_dataset=None, original_dataset=None ):
""" Create basic data provider. """
@@ -37,7 +40,7 @@ class TracksDataProvider( object ):
def get_filters( self ):
"""
Returns filters for provider's data. Return value is a list of
- filters; each filter is a dictionary with the keys 'name', 'index', 'value'.
+ filters; each filter is a dictionary with the keys 'name', 'index', 'type'.
NOTE: This method uses the original dataset's datatype and metadata to
create the filters.
"""
@@ -58,17 +61,17 @@ class TracksDataProvider( object ):
# Create and return filters.
filters = []
- if self.original_dataset.metadata.viz_filter_columns:
- for viz_col_index in self.original_dataset.metadata.viz_filter_columns:
+ if self.original_dataset.metadata.viz_filter_cols:
+ for viz_col_index in self.original_dataset.metadata.viz_filter_cols:
col_name = column_names[ viz_col_index ]
# Make sure that column has a mapped index. If not, do not add filter.
try:
- index = self.col_name_data_index_mapping[ col_name ]
+ attrs = self.col_name_data_attr_mapping[ col_name ]
except KeyError:
continue
filters.append(
- { 'name' : col_name, 'value' : column_types[viz_col_index], \
- 'index' : index } )
+ { 'name' : attrs[ 'name' ], 'type' : column_types[viz_col_index], \
+ 'index' : attrs[ 'index' ] } )
return filters
class SummaryTreeDataProvider( TracksDataProvider ):
@@ -119,7 +122,7 @@ class VcfDataProvider( TracksDataProvide
[ uid (offset), start, end, ID, reference base(s), alternate base(s), quality score]
"""
- col_name_data_index_mapping = { 'Qual' : 6 }
+ col_name_data_attr_mapping = { 'Qual' : { 'index': 6 , 'name' : 'Qual' } }
def get_data( self, chrom, start, end, **kwargs ):
""" Returns data in region defined by chrom, start, and end. """
@@ -153,7 +156,7 @@ class VcfDataProvider( TracksDataProvide
# alternative base(s)
feature[4], \
# phred quality score
- feature[5] ]
+ int( feature[5] )]
results.append(payload)
return { 'data_type' : 'vcf', 'data': results, 'message': message }
@@ -306,6 +309,9 @@ class IntervalIndexDataProvider( TracksD
Payload format: [ uid (offset), start, end, name, strand, thick_start, thick_end, blocks ]
"""
+
+ col_name_data_attr_mapping = { 4 : { 'index': 8 , 'name' : 'Score' } }
+
def get_data( self, chrom, start, end, **kwargs ):
start, end = int(start), int(end)
source = open( self.original_dataset.file_name )
@@ -355,6 +361,9 @@ class IntervalIndexDataProvider( TracksD
block_starts = [ int(n) for n in feature[11].split(',') if n != '' ]
blocks = zip(block_sizes, block_starts)
payload.append( [ (start + block[1], start + block[1] + block[0]) for block in blocks] )
+
+ if length >= 5:
+ payload.append( int(feature[4]) ) # score
results.append(payload)
@@ -375,7 +384,7 @@ dataset_type_name_to_data_provider = {
}
dataset_type_to_data_provider = {
- Vcf : VcfDataProvider
+ Vcf : VcfDataProvider,
}
def get_data_provider( name=None, original_dataset=None ):
@@ -395,11 +404,16 @@ def get_data_provider( name=None, origin
# Look for data provider in mapping.
data_provider = dataset_type_to_data_provider.get( original_dataset.datatype.__class__, None )
if not data_provider:
- # If get_track_type is available, then dataset can be added to trackster
- # and hence has at least a generic data provider.
+ # Look up data provider from datatype's informaton.
try:
- original_dataset.datatype.get_track_type()
- data_provider = TracksDataProvider
+ # Get data provider mapping and data provider for 'data'. If
+ # provider available, use it; otherwise use generic provider.
+ _ , data_provider_mapping = original_dataset.datatype.get_track_type()
+ data_provider_name = data_provider_mapping[ 'data' ]
+ if data_provider_name:
+ data_provider = get_data_provider( name=data_provider_name, original_dataset=original_dataset )
+ else:
+ data_provider = TracksDataProvider
except:
pass
return data_provider
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -12,7 +12,7 @@
<%def name="stylesheets()">
${parent.stylesheets()}
-${h.css( "history", "autocomplete_tagging", "trackster" )}
+${h.css( "history", "autocomplete_tagging", "trackster", "overcast/jquery-ui-1.8.5.custom" )}
<style type="text/css">
#center {
@@ -34,6 +34,17 @@
left: 0;
bottom: 0;
}
+ # Styles for filters.
+ .filter-name {
+ float: left;
+ }
+ table.filters {
+ border-collapse: separate;
+ border-spacing: 7px 0px;
+ }
+ .values {
+ padding-right: 1em;
+ }
</style></%def>
@@ -67,7 +78,7 @@
view.editor = true;
%for track in config.get('tracks'):
view.add_track(
- new ${track["track_type"]}( "${track['name'] | h}", view, ${track['dataset_id']}, ${track['prefs']} )
+ new ${track["track_type"]}( "${track['name'] | h}", view, ${track['dataset_id']}, ${track['filters']}, ${track['prefs']} )
);
%endfor
init();
@@ -134,7 +145,7 @@
var add_async_success = function(track_data) {
var td = track_data,
track_types = { "LineTrack": LineTrack, "FeatureTrack": FeatureTrack, "ReadTrack": ReadTrack },
- new_track = new track_types[track_data.track_type]( track_data.name, view, track_data.dataset_id, track_data.prefs);
+ new_track = new track_types[track_data.track_type]( track_data.name, view, track_data.dataset_id, track_data.filters, track_data.prefs);
view.add_track(new_track);
view.has_changes = true;
Binary file static/june_2007_style/blue/overcast/images/ui-bg_glass_35_dddddd_1x400.png has changed
--- /dev/null
+++ b/static/june_2007_style/blue/overcast/jquery-ui-1.8.5.custom.css
@@ -0,0 +1,318 @@
+/*
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Helvetica,%20A…
Highlight=444444&iconColorHighlight=3383bb&bgColorError=c0402a&bgTextureError=01_flat.png&bgImgOpacityError=55&borderColorError=c0402a&fcError=ffffff&iconColorError=fbc856&bgColorOverlay=eeeeee&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0pxdow=0px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #c9c9c9 url(images/ui-bg_inset-soft_50_c9c9c9_1x100.png) 50% bottom repeat-x; color: #333333; }
+.ui-widget-content a { color: #333333; }
+.ui-widget-header { border: 1px solid #bbbbbb; background: #dddddd url(images/ui-bg_glass_35_dddddd_1x400.png) 50% 50% repeat-x; color: #444444; font-weight: bold; }
+.ui-widget-header a { color: #444444; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #eeeeee url(images/ui-bg_glass_60_eeeeee_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #3383bb; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #3383bb; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #bbbbbb; background: #f8f8f8 url(images/ui-bg_glass_100_f8f8f8_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #599fcf; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #599fcf; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #999999; background: #999999 url(images/ui-bg_inset-hard_75_999999_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #ffffff; background: #eeeeee url(images/ui-bg_flat_55_eeeeee_40x100.png) 50% 50% repeat-x; color: #444444; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #444444; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #c0402a; background: #c0402a url(images/ui-bg_flat_55_c0402a_40x100.png) 50% 50% repeat-x; color: #ffffff; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_999999_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_70b2e1_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fbc856_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; }
+.ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
+.ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
+.ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
+.ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #eeeeee url(images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); }
+.ui-widget-shadow { margin: -4px 0 0 -4px; padding: 4px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 0pxdow=0px; -webkit-border-radius: 0pxdow=0px; border-radius: 0pxdow=0px; }/*
+ * jQuery UI Slider @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }
--- a/lib/galaxy/datatypes/interval.py
+++ b/lib/galaxy/datatypes/interval.py
@@ -406,6 +406,7 @@ class Bed( Interval ):
MetadataElement( name="endCol", default=3, desc="End column", param=metadata.ColumnParameter )
MetadataElement( name="strandCol", desc="Strand column (click box & select)", param=metadata.ColumnParameter, optional=True, no_value=0 )
MetadataElement( name="columns", default=3, desc="Number of columns", readonly=True, visible=False )
+ MetadataElement( name="viz_filter_cols", default=[4], param=metadata.ColumnParameter, multiple=True )
###do we need to repeat these? they are the same as should be inherited from interval type
def set_meta( self, dataset, overwrite = True, **kwd ):
Binary file static/june_2007_style/blue/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png has changed
Binary file static/june_2007_style/blue/overcast/images/ui-bg_glass_60_eeeeee_1x400.png has changed
1
0

galaxy-dist commit 73c4c66ff3dd: Add RNA-seq tools -- Tophat + Cufflinks suite -- to main.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287602065 14400
# Node ID 73c4c66ff3dd8101a0e6126077f4f8fc897c71fe
# Parent 14fd007fc550092df7ea23f1019ab2d99ba03ce2
Add RNA-seq tools -- Tophat + Cufflinks suite -- to main.
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -288,7 +288,7 @@
<tool file="indels/indel_table.xml" />"
<tool file="indels/indel_analysis.xml" /></section>
- <section name="NGS: Expression Analysis" id="ngs-rna-tools">
+ <section name="NGS: RNA Analysis" id="ngs-rna-tools"><label text="RNA-seq" id="rna_seq" /><tool file="ngs_rna/tophat_wrapper.xml" /><tool file="ngs_rna/cufflinks_wrapper.xml" />
--- a/tool_conf.xml.main
+++ b/tool_conf.xml.main
@@ -370,6 +370,15 @@
<tool file="genetrack/genetrack_indexer.xml" /><tool file="genetrack/genetrack_peak_prediction.xml" /></section>
+ <section name="NGS: RNA Analysis" id="ngs-rna-tools">
+ <label text="RNA-seq" id="rna_seq" />
+ <tool file="ngs_rna/tophat_wrapper.xml" />
+ <tool file="ngs_rna/cufflinks_wrapper.xml" />
+ <tool file="ngs_rna/cuffcompare_wrapper.xml" />
+ <tool file="ngs_rna/cuffdiff_wrapper.xml" />
+ <label text="Filtering" id="filtering" />
+ <tool file="ngs_rna/filter_transcripts_via_tracking.xml" />
+ </section><label text="RGENETICS" id="rgenetics" /><section name="SNP/WGA: Data; Filters" id="rgdat"><label text="Data: Import and upload" id="rgimport" />
1
0

galaxy-dist commit e226033419a9: Update version numbers of Tophat and Cufflinks wrappers to reflect current tool installations on Galaxy main and test instances.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287602818 14400
# Node ID e226033419a91100e657f6880562dc50ae01ef98
# Parent 73c4c66ff3dd8101a0e6126077f4f8fc897c71fe
Update version numbers of Tophat and Cufflinks wrappers to reflect current tool installations on Galaxy main and test instances.
--- a/tools/ngs_rna/cuffcompare_wrapper.xml
+++ b/tools/ngs_rna/cuffcompare_wrapper.xml
@@ -1,4 +1,4 @@
-<tool id="cuffcompare" name="Cuffcompare" version="0.8.3">
+<tool id="cuffcompare" name="Cuffcompare" version="0.9.1"><description>compare assembled transcripts to a reference annotation and track Cufflinks transcripts across multiple experiments</description><requirements><requirement type="package">cufflinks</requirement>
--- a/tools/ngs_rna/cuffdiff_wrapper.xml
+++ b/tools/ngs_rna/cuffdiff_wrapper.xml
@@ -1,4 +1,4 @@
-<tool id="cuffdiff" name="Cuffdiff" version="0.8.3">
+<tool id="cuffdiff" name="Cuffdiff" version="0.9.1"><description>find significant changes in transcript expression, splicing, and promoter use</description><requirements><requirement type="package">cufflinks</requirement>
--- a/tools/ngs_rna/cufflinks_wrapper.xml
+++ b/tools/ngs_rna/cufflinks_wrapper.xml
@@ -1,4 +1,4 @@
-<tool id="cufflinks" name="Cufflinks" version="0.8.3">
+<tool id="cufflinks" name="Cufflinks" version="0.9.1"><description>transcript assembly and FPKM (RPKM) estimates for RNA-Seq data</description><requirements><requirement type="package">cufflinks</requirement>
--- a/tools/ngs_rna/tophat_wrapper.xml
+++ b/tools/ngs_rna/tophat_wrapper.xml
@@ -1,4 +1,4 @@
-<tool id="tophat" name="Tophat" version="1.0.14">
+<tool id="tophat" name="Tophat" version="1.1.1"><description>Find splice junctions using RNA-seq data</description><requirements><requirement type="package">tophat</requirement>
1
0

galaxy-dist commit 14fd007fc550: Fix setting of minimum and maximum values for tracker slider filters.
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1287549765 14400
# Node ID 14fd007fc550092df7ea23f1019ab2d99ba03ce2
# Parent 11031e92204b1590ff05119515673d37ae834188
Fix setting of minimum and maximum values for tracker slider filters.
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -462,11 +462,11 @@ var NumberFilter = function( name, index
// Index into payload to filter.
this.index = index;
// Filter low/high. These values are used to filter elements.
- this.low = Number.MIN_VALUE;
+ this.low = -Number.MAX_VALUE;
this.high = Number.MAX_VALUE;
// Slide min/max. These values are used to set/update slider.
this.slider_min = Number.MAX_VALUE;
- this.slider_max = Number.MIN_VALUE;
+ this.slider_max = -Number.MAX_VALUE;
// UI Slider element and label that is associated with filter.
this.slider = null;
this.slider_label = null;
@@ -571,15 +571,14 @@ var Track = function (name, view, parent
var name_span = $("<span class='name'>").appendTo(filter_th);
name_span.text(filter.name + " "); // Extra spacing to separate name and values
var values_span = $("<span class='values'>").appendTo(filter_th);
- values_span.text("[0-2]");
// TODO: generate custom interaction elements based on filter type.
var table_data = $("<td>").appendTo(table_row);
filter.control_element = $("<div id='" + filter.name + "-filter-control' style='width: 200px; position: relative'>").appendTo(table_data);
filter.control_element.slider({
range: true,
- min: 0,
- max: 1,
- values: [0, 1],
+ min: Number.MAX_VALUE,
+ max: -Number.MIN_VALUE,
+ values: [0, 0],
slide: function( event, ui ) {
var values = ui.values;
// Set new values in UI.
@@ -804,8 +803,9 @@ var TiledTrack = function() {
}
// Update filtering UI.
- for (var f = 0; f < track.filters.length; f++)
+ for (var f = 0; f < track.filters.length; f++) {
track.filters[f].update_ui_elt();
+ }
// Method complete; do not call it again.
clearInterval(intervalId);
}
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=50,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/st
rand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,d,c,b){this.container=a;this.vis_id=c;this.dbkey=b;this.title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_i
d_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Clo
se Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();r
eturn false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new Referenc
eTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind
("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.
container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(!c.chrom){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.re
set();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.reset_overview();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).re
move()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left
:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=functio
n(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=Number.MIN_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=Number.MIN_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[
this.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.fil
tering_div.hide();this.filtering_div.bind("drag",function(k){k.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(var e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th class='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);d.text("[0-2]");var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:0,max:1,values:[0,1],slide:function(l,m){var k=m.values;d.text("["+k[0]+"-"+k[1]+"]");a.low=k[0];a.high=k[1];c.draw(true)},change:function(k,l){a.control_element.slider("option","slide").call(a.control_element,k,l)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)}
,init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_di
v.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configur
ation"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},j=function(){d.update_options(d.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){j()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:l,OK:j})};if(d.filters.length>0){b["Show filters"]=function(){var j;if(!d.filtering_div.is(":visible")){j="Hide filters";d.filters_visible=true}else{j="Show filters";d.filters_visible=false}$("#"+d.name_div.attr("id")+"-menu").find("li").eq(2).text(j);d.filtering_div.toggle()}}b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};d.popup_menu=make_popupmenu(d.name_div,b);show_hide_popupmenu_options(d.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(b){var m=this.view.low,g=this.view.high,h=g-m,f=this.view.r
esolution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/h,k;this.content_div.append(p),this.max_height=0;var a=Math.floor(m/f/DENSITY);var l=new Object();while((a*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+a;var e=this.tile_cache.get(n);if(!b&&e){var j=a*DENSITY*f;var d=(j-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,a,f,p,q,l)}a+=1}var c=this;var o=setInterval(function(){if(l.length!=0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var r=0;r<c.filters.length;r++){c.filters[r].update_ui_elt()}clearInterval(o)}},50)},delayed_draw:function(c,h,g,e,b,d,j,k,f){var a=setTimeout(function(){if(!(g>c.view.high||e<c.view.low)){tile_element=c.draw_tile(d,b,j,k);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var n=tile_element.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=
n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,tile_element);c.show_tile(tile_element,j)}}delete f.id},50);f.id=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null
,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_
data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,l,p){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),o=e.get(0).getContext("2d"),k=f+"_"+b;if(p>PX_PER_CHAR){if(this.data_cache.get(k)===undefined){this.get_data(f,b);return}var n=this.data_cache.get(k);if(n===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*p+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*p-this.left_offset});for(var h=0,m=n.length;h<m;h++){var a=Math.round(h*p),j=Math.round(p/2);o.fillText(n[h],a+this.left_offset+j,10)}l.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=fu
nction(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#tr
ack_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;a.container_div.find(".yaxislabel").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:fu
nction(p,s,c,e){if(this.vertical_range===undefined){return}var t=s*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),w=p+"_"+s;if(this.data_cache.get(w)===undefined){this.get_data(p,s);return}var j=this.data_cache.get(w);if(j===null){return}b.css({position:"absolute",top:0,left:(t-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,u=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();o.fillStyle=this.prefs.color;if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var v,h;for(var q=0,r=data.length;q<r;q++){v=Math.round((data[q][0]-t)*e);h=data[q][1];if(h===null){if(k&&m==="Filled"){o.lineTo(v,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(d-(h-l)/n*d);o.fillRect(v,h,f,d-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")
";o.fillRect(v,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(v,h)}else{k=true;if(m==="Filled"){o.moveTo(v,d);o.lineTo(v,h)}else{o.moveTo(v,h)}}}}}if(m==="Filled"){if(k){o.lineTo(v,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var e="track_"+n+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+n+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),l=$("<input></input>").attr("id",h).val(d),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j);return a.append(m).append(l).append(g).append(f).append(b).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();color=$("#track_
"+c+"_color").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value||color!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.prefs.color=color;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATU
RE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};t
his.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(v<=MAX_FEATURE_DEPTH){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_ti
le[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(r,m,s,b,q,f,h,e){r.textAlign="center";var l=0,p=Math.round(m/2);for(cig_id in h){var k=h[cig_id],d="MIDNSHP"[k[0]],n=k[1];if(d==="H"||d==="S"){l-=n}var g=q+l,v=Math.floor(Math.max(0,(g-s)*m)),j=Math.floor(Math.max(0,(g+n-s)*m));switch(d){case"S":case"H":case"M":var o=f.slice(l,n);if((this.mode==="Pack"||this.mode==="Auto")&&f!==undefined&&m>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillRect(v+this.left_offset,e+1,j-v,9);r.fillStyle=CONNECTOR_COLOR;for(var t=0,a=o.length;t<a;t++){if(g+t>=s&&g+t<=b){var u=Math.floor(Math.max(0,(g+t-s)*m));r.fillText(o[t],u+this.left_offset+p,e+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(v+this.left_offset,e+4,j-v,3)}break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(v+this.left_offset,e+5,j-v,1);break;case"D":r.fillStyle="red";r.fillRect(v+this.left_offset,e+4,j-v,3);break;case"P":case"I":break}l+=n}},draw_tile:function(
ah,o,s,aw){var N=o*DENSITY*ah,am=(o+1)*DENSITY*ah,M=am-N;var ao=(!this.initial_canvas?"initial":N+"_"+am);var I=this.data_cache.get(ao);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,am]]=true;this.get_data(N,am);return}var a=Math.ceil(M*aw),S=$("<canvas class='tile'></canvas>"),aj=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,af=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_info==="no_detail")),X=this.left_offset,av,D,ax;if(I.dataset_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;ax=10}else{ax=(af?this.vertical_nodetail_px:this.vertical_detail_px);var A=(aw<0.0001?1/view.zoom_res:aw);D=this.incremental_slots(A,I.data,af,r)*ax+z;av=this.inc_slots[A]}}S.css({position:"absolute",top:0,left:(N-this.view.low)*aw-X});S.get(0).width=a+X;S.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=S.get(0).getContext("2d");J.fillStyle=l;J.font=t
his.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Z=I.data,L=I.max,q=I.avg,b=Math.ceil(I.delta*aw);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var aq=0,H=Z.length;aq<H;aq++){var ab=Math.floor((Z[aq][0]-N)*aw);var aa=Z[aq][1];if(!aa){continue}var an=aa/L*this.summary_draw_height;J.fillStyle="black";J.fillRect(ab+X,this.summary_draw_height-an,b,an);if(this.prefs.show_counts&&J.measureText(aa).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(aa,ab+X+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(S);return S}if(I.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+X,ax)}var ae=false;if(I.data.length!=0){ae=true;for(var at=0;at<this.filters.length;at++){if(!this.filters[at].applies_to(I.data[0])){ae=false}}}if(ae){S.
addClass(FILTERABLE_CLASS)}var au=I.data;var ap=0;for(var aq=0,H=au.length;aq<H;aq++){var T=au[aq],R=T[0],ar=T[1],ad=T[2],O=T[3];if(av[R]===undefined){continue}var ac=false;var V;for(var at=0;at<this.filters.length;at++){V=this.filters[at];V.update_attrs(T);if(!V.keep(T)){ac=true;break}}if(ac){continue}if(ar<=am&&ad>=N){var ag=Math.floor(Math.max(0,(ar-N)*aw)),K=Math.ceil(Math.min(a,Math.max(0,(ad-N)*aw))),Y=(r==="Dense"?1:(1+av[R]))*ax;if(I.dataset_type==="bai"){var v=T[4];J.fillStyle=l;if(T[5] instanceof Array){var E=Math.floor(Math.max(0,(T[5][0]-N)*aw)),Q=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-N)*aw))),C=Math.floor(Math.max(0,(T[6][0]-N)*aw)),w=Math.ceil(Math.min(a,Math.max(0,(T[6][1]-N)*aw)));if(T[5][1]>=N&&T[5][0]<=am){this.rect_or_text(J,aw,N,am,T[5][0],T[5][2],v,Y)}if(T[6][1]>=N&&T[6][0]<=am){this.rect_or_text(J,aw,N,am,T[6][0],T[6][2],v,Y)}if(C>Q){J.fillStyle=CONNECTOR_COLOR;J.fillRect(Q+X,Y+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,aw,N,am,ar,O,v,Y)}if(r!=
="Dense"&&!af&&ar>N){J.fillStyle=this.prefs.label_color;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(R,ag-2+X,Y+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var G=T[4],W=T[5],ai=T[6],h=T[7];var F,ak,P=null,ay=null;if(W&&ai){P=Math.floor(Math.max(0,(W-N)*aw));ay=Math.ceil(Math.min(a,Math.max(0,(ai-N)*aw)))}if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}if(h){if(G){if(G=="+"){J.fillStyle=RIGHT_STRAND}else{if(G=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}for(var ao=0,g=h.length;ao<g;ao++){var u=h[ao],d=Math.floor(Math.max(0,(u[0]-N)*aw)),U=Math.ceil(Math.min(a,Math.max((u[1]-N)*aw)));if(d>U){continue}F=5;ak=3;J.fillRect(d+X,Y+ak,U-d,F);if(P!==undefined&&!(d>ay||
U<P)){F=9;ak=1;var al=Math.max(d,P),B=Math.min(U,ay);J.fillRect(al+X,Y+ak,B-al,F)}}}else{F=9;ak=1;J.fillRect(ag+X,Y+ak,K-ag,F);if(T.strand){if(T.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var t=T[4],n=T[5],c=T[6];F=9;ak=1;J.fillRect(ag+X,Y,K-ag,F);if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}var m=t+" / "+n;if(ar>N&&J.measureText(m).width<(K-ag)){J.fillStyle="white";J.textAlign="center";J.fillText(m,X+ag+(K-ag)/2,Y+8);J.fillStyle=l}}}}}ap++}}return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(th
is.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="ReadTrack";this.vert
ical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=50,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/st
rand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,d,c,b){this.container=a;this.vis_id=c;this.dbkey=b;this.title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_i
d_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Clo
se Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();r
eturn false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new Referenc
eTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind
("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.
container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(!c.chrom){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.re
set();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.reset_overview();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).re
move()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left
:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=functio
n(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values"
,[this.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.f
iltering_div.hide();this.filtering_div.bind("drag",function(k){k.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(var e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th class='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(l,m){var k=m.values;d.text("["+k[0]+"-"+k[1]+"]");a.low=k[0];a.high=k[1];c.draw(true)},change:function(k,l){a.control_element.slider("option","slide").call(a.control_element,k,l)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(thi
s.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending
"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}}
;b["Edit configuration"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},j=function(){d.update_options(d.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){j()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:l,OK:j})};if(d.filters.length>0){b["Show filters"]=function(){var j;if(!d.filtering_div.is(":visible")){j="Hide filters";d.filters_visible=true}else{j="Show filters";d.filters_visible=false}$("#"+d.name_div.attr("id")+"-menu").find("li").eq(2).text(j);d.filtering_div.toggle()}}b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};d.popup_menu=make_popupmenu(d.name_div,b);show_hide_popupmenu_options(d.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(b){var m=this.view.low,g=this.view.high,h=
g-m,f=this.view.resolution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/h,k;this.content_div.append(p),this.max_height=0;var a=Math.floor(m/f/DENSITY);var l=new Object();while((a*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+a;var e=this.tile_cache.get(n);if(!b&&e){var j=a*DENSITY*f;var d=(j-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,a,f,p,q,l)}a+=1}var c=this;var o=setInterval(function(){if(l.length!=0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var r=0;r<c.filters.length;r++){c.filters[r].update_ui_elt()}clearInterval(o)}},50)},delayed_draw:function(c,h,g,e,b,d,j,k,f){var a=setTimeout(function(){if(!(g>c.view.high||e<c.view.low)){tile_element=c.draw_tile(d,b,j,k);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var n=tile_element.get(0).getContext("2d");var l=c.initial_canvas.get(0).getCon
text("2d");var m=n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,tile_element);c.show_tile(tile_element,j)}}delete f.id},50);f.id=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Tra
ck.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrac
k.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,l,p){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),o=e.get(0).getContext("2d"),k=f+"_"+b;if(p>PX_PER_CHAR){if(this.data_cache.get(k)===undefined){this.get_data(f,b);return}var n=this.data_cache.get(k);if(n===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*p+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*p-this.left_offset});for(var h=0,m=n.length;h<m;h++){var a=Math.round(h*p),j=Math.round(p/2);o.fillText(n[h],a+this.left_offset+j,10)}l.append(e);return e}this.content_div.css("height","0px")}})
;var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.
min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;a.container_div.find(".yaxislabel").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}
})}},draw_tile:function(p,s,c,e){if(this.vertical_range===undefined){return}var t=s*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),w=p+"_"+s;if(this.data_cache.get(w)===undefined){this.get_data(p,s);return}var j=this.data_cache.get(w);if(j===null){return}b.css({position:"absolute",top:0,left:(t-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,u=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();o.fillStyle=this.prefs.color;if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var v,h;for(var q=0,r=data.length;q<r;q++){v=Math.round((data[q][0]-t)*e);h=data[q][1];if(h===null){if(k&&m==="Filled"){o.lineTo(v,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(d-(h-l)/n*d);o.fillRect(v,h,f,d-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("
+h+","+h+","+h+")";o.fillRect(v,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(v,h)}else{k=true;if(m==="Filled"){o.moveTo(v,d);o.lineTo(v,h)}else{o.moveTo(v,h)}}}}}if(m==="Filled"){if(k){o.lineTo(v,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var e="track_"+n+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+n+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),l=$("<input></input>").attr("id",h).val(d),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j);return a.append(m).append(l).append(g).append(f).append(b).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val()
;color=$("#track_"+c+"_color").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value||color!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.prefs.color=color;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(C
ACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.
inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(v<=MAX_FEATURE_DEPTH){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=
[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(r,m,s,b,q,f,h,e){r.textAlign="center";var l=0,p=Math.round(m/2);for(cig_id in h){var k=h[cig_id],d="MIDNSHP"[k[0]],n=k[1];if(d==="H"||d==="S"){l-=n}var g=q+l,v=Math.floor(Math.max(0,(g-s)*m)),j=Math.floor(Math.max(0,(g+n-s)*m));switch(d){case"S":case"H":case"M":var o=f.slice(l,n);if((this.mode==="Pack"||this.mode==="Auto")&&f!==undefined&&m>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillRect(v+this.left_offset,e+1,j-v,9);r.fillStyle=CONNECTOR_COLOR;for(var t=0,a=o.length;t<a;t++){if(g+t>=s&&g+t<=b){var u=Math.floor(Math.max(0,(g+t-s)*m));r.fillText(o[t],u+this.left_offset+p,e+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(v+this.left_offset,e+4,j-v,3)}break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(v+this.left_offset,e+5,j-v,1);break;case"D":r.fillStyle="red";r.fillRect(v+this.left_offset,e+4,j-v,3);break;case"P":case"I":break}l+=n}},dr
aw_tile:function(ah,o,s,aw){var N=o*DENSITY*ah,am=(o+1)*DENSITY*ah,M=am-N;var ao=(!this.initial_canvas?"initial":N+"_"+am);var I=this.data_cache.get(ao);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,am]]=true;this.get_data(N,am);return}var a=Math.ceil(M*aw),S=$("<canvas class='tile'></canvas>"),aj=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,af=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_info==="no_detail")),X=this.left_offset,av,D,ax;if(I.dataset_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;ax=10}else{ax=(af?this.vertical_nodetail_px:this.vertical_detail_px);var A=(aw<0.0001?1/view.zoom_res:aw);D=this.incremental_slots(A,I.data,af,r)*ax+z;av=this.inc_slots[A]}}S.css({position:"absolute",top:0,left:(N-this.view.low)*aw-X});S.get(0).width=a+X;S.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=S.get(0).getContext("2d");J.fil
lStyle=l;J.font=this.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Z=I.data,L=I.max,q=I.avg,b=Math.ceil(I.delta*aw);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var aq=0,H=Z.length;aq<H;aq++){var ab=Math.floor((Z[aq][0]-N)*aw);var aa=Z[aq][1];if(!aa){continue}var an=aa/L*this.summary_draw_height;J.fillStyle="black";J.fillRect(ab+X,this.summary_draw_height-an,b,an);if(this.prefs.show_counts&&J.measureText(aa).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(aa,ab+X+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(S);return S}if(I.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+X,ax)}var ae=false;if(I.data.length!=0){ae=true;for(var at=0;at<this.filters.length;at++){if(!this.filters[at].applies_to(I.data[0])){ae=
false}}}if(ae){S.addClass(FILTERABLE_CLASS)}var au=I.data;var ap=0;for(var aq=0,H=au.length;aq<H;aq++){var T=au[aq],R=T[0],ar=T[1],ad=T[2],O=T[3];if(av[R]===undefined){continue}var ac=false;var V;for(var at=0;at<this.filters.length;at++){V=this.filters[at];V.update_attrs(T);if(!V.keep(T)){ac=true;break}}if(ac){continue}if(ar<=am&&ad>=N){var ag=Math.floor(Math.max(0,(ar-N)*aw)),K=Math.ceil(Math.min(a,Math.max(0,(ad-N)*aw))),Y=(r==="Dense"?1:(1+av[R]))*ax;if(I.dataset_type==="bai"){var v=T[4];J.fillStyle=l;if(T[5] instanceof Array){var E=Math.floor(Math.max(0,(T[5][0]-N)*aw)),Q=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-N)*aw))),C=Math.floor(Math.max(0,(T[6][0]-N)*aw)),w=Math.ceil(Math.min(a,Math.max(0,(T[6][1]-N)*aw)));if(T[5][1]>=N&&T[5][0]<=am){this.rect_or_text(J,aw,N,am,T[5][0],T[5][2],v,Y)}if(T[6][1]>=N&&T[6][0]<=am){this.rect_or_text(J,aw,N,am,T[6][0],T[6][2],v,Y)}if(C>Q){J.fillStyle=CONNECTOR_COLOR;J.fillRect(Q+X,Y+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,aw,N,am
,ar,O,v,Y)}if(r!=="Dense"&&!af&&ar>N){J.fillStyle=this.prefs.label_color;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(R,ag-2+X,Y+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var G=T[4],W=T[5],ai=T[6],h=T[7];var F,ak,P=null,ay=null;if(W&&ai){P=Math.floor(Math.max(0,(W-N)*aw));ay=Math.ceil(Math.min(a,Math.max(0,(ai-N)*aw)))}if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}if(h){if(G){if(G=="+"){J.fillStyle=RIGHT_STRAND}else{if(G=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}for(var ao=0,g=h.length;ao<g;ao++){var u=h[ao],d=Math.floor(Math.max(0,(u[0]-N)*aw)),U=Math.ceil(Math.min(a,Math.max((u[1]-N)*aw)));if(d>U){continue}F=5;ak=3;J.fillRect(d+X,Y+ak,U-d,F);if(P!==un
defined&&!(d>ay||U<P)){F=9;ak=1;var al=Math.max(d,P),B=Math.min(U,ay);J.fillRect(al+X,Y+ak,B-al,F)}}}else{F=9;ak=1;J.fillRect(ag+X,Y+ak,K-ag,F);if(T.strand){if(T.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var t=T[4],n=T[5],c=T[6];F=9;ak=1;J.fillRect(ag+X,Y,K-ag,F);if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}var m=t+" / "+n;if(ar>N&&J.measureText(m).width<(K-ag)){J.fillStyle="white";J.textAlign="center";J.fillText(m,X+ag+(K-ag)/2,Y+8);J.fillStyle=l}}}}}ap++}}return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr
("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="Rea
dTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
1
0

galaxy-dist commit 11031e92204b: trackster: Add proper CIGAR support to BAM display (properly displays matches, deletions, skipped bases, and clipping. Padding and insertions are skipped as of now as there is no good way to insert new space into the view.)
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1287529137 14400
# Node ID 11031e92204b1590ff05119515673d37ae834188
# Parent ad9bb65d2d153af5db0ae497930eb35d17f63057
trackster: Add proper CIGAR support to BAM display (properly displays matches, deletions, skipped bases, and clipping. Padding and insertions are skipped as of now as there is no good way to insert new space into the view.)
- Don't re-add new datasets when refreshing after using "Add into current viz" link
- To prevent browser lockup, only display up to 50 lines of features by default (user-editable in future). TODO: add warning message when this occurs
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -4,8 +4,9 @@
var DENSITY = 200,
FEATURE_LEVELS = 10,
- MAX_FEATURE_DEPTH = 100,
- DATA_ERROR = "There was an error in indexing this dataset. ",
+ MAX_FEATURE_DEPTH = 50,
+ CONNECTOR_COLOR = "#ccc",
+ DATA_ERROR = "There was an error in indexing this dataset.",
DATA_NOCONVERTER = "A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",
DATA_NONE = "No data for this chrom/contig.",
DATA_PENDING = "Currently indexing... please wait",
@@ -75,12 +76,11 @@ var Cache = function( num_elements ) {
}
});
-var View = function( container, chrom, title, vis_id, dbkey ) {
+var View = function( container, title, vis_id, dbkey ) {
this.container = container;
this.vis_id = vis_id;
this.dbkey = dbkey;
this.title = title;
- this.chrom = chrom;
this.tracks = [];
this.label_tracks = [];
this.max_low = 0;
@@ -271,7 +271,7 @@ var View = function( container, chrom, t
}
if (chrom !== view.chrom) {
view.chrom = chrom;
- if (view.chrom === "") {
+ if (!view.chrom) {
// No chrom selected
view.intro_div.show();
} else {
@@ -1203,7 +1203,7 @@ var FeatureTrack = function ( name, view
this.data_cache = new Cache(20);
this.left_offset = 200;
- this.prefs = { 'block_color': 'black', 'label_color': 'black', 'show_counts': true };
+ this.prefs = { 'block_color': '#444', 'label_color': 'black', 'show_counts': true };
if (prefs.block_color !== undefined) { this.prefs.block_color = prefs.block_color; }
if (prefs.label_color !== undefined) { this.prefs.label_color = prefs.label_color; }
if (prefs.show_counts !== undefined) { this.prefs.show_counts = prefs.show_counts; }
@@ -1294,7 +1294,7 @@ var FeatureTrack = function ( name, view
var j = 0;
// Try to fit the feature to the first slot that doesn't overlap any other features in that slot
- while (true) {
+ while (j <= MAX_FEATURE_DEPTH) {
var found = true;
if (this.s_e_by_tile[level][j] !== undefined) {
for (var k = 0, k_len = this.s_e_by_tile[level][j].length; k < k_len; k++) {
@@ -1318,22 +1318,57 @@ var FeatureTrack = function ( name, view
return highest_slot;
},
- rect_or_text: function( ctx, w_scale, tile_low, tile_high, feature_start, name, x, x_len, y_center ) {
+ rect_or_text: function( ctx, w_scale, tile_low, tile_high, feature_start, orig_seq, cigar, y_center ) {
ctx.textAlign = "center";
- var gap = Math.round(w_scale / 2);
- if ( (this.mode === "Pack" || this.mode === "Auto") && name !== undefined && w_scale > PX_PER_CHAR) {
- ctx.fillStyle = this.prefs.block_color;
- ctx.fillRect(x, y_center + 1, x_len, 9);
- ctx.fillStyle = "#eee";
- for (var c = 0, str_len = name.length; c < str_len; c++) {
- if (feature_start + c >= tile_low && feature_start + c <= tile_high) {
- var c_start = Math.floor( Math.max(0, (feature_start + c - tile_low) * w_scale) );
- ctx.fillText(name[c], c_start + this.left_offset + gap, y_center + 9);
- }
+ var cur_offset = 0,
+ gap = Math.round(w_scale / 2);
+
+ for (cig_id in cigar) {
+ var cig = cigar[cig_id],
+ cig_op = "MIDNSHP"[cig[0]],
+ cig_len = cig[1];
+
+ if (cig_op === "H" || cig_op === "S") {
+ // Go left if it clips
+ cur_offset -= cig_len;
}
- } else {
- ctx.fillStyle = this.prefs.block_color;
- ctx.fillRect(x, y_center + 4, x_len, 3);
+ var seq_start = feature_start + cur_offset,
+ s_start = Math.floor( Math.max(0, (seq_start - tile_low) * w_scale) ),
+ s_end = Math.floor( Math.max(0, (seq_start + cig_len - tile_low) * w_scale) );
+
+ switch (cig_op) {
+ case "S": // Soft clipping
+ case "H": // Hard clipping
+ case "M": // Match
+ var seq = orig_seq.slice(cur_offset, cig_len);
+ if ( (this.mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > PX_PER_CHAR) {
+ ctx.fillStyle = this.prefs.block_color;
+ ctx.fillRect(s_start + this.left_offset, y_center + 1, s_end - s_start, 9);
+ ctx.fillStyle = CONNECTOR_COLOR;
+ for (var c = 0, str_len = seq.length; c < str_len; c++) {
+ if (seq_start + c >= tile_low && seq_start + c <= tile_high) {
+ var c_start = Math.floor( Math.max(0, (seq_start + c - tile_low) * w_scale) );
+ ctx.fillText(seq[c], c_start + this.left_offset + gap, y_center + 9);
+ }
+ }
+ } else {
+ ctx.fillStyle = this.prefs.block_color;
+ ctx.fillRect(s_start + this.left_offset, y_center + 4, s_end - s_start, 3);
+ }
+ break;
+ case "N": // Skipped bases
+ ctx.fillStyle = CONNECTOR_COLOR;
+ ctx.fillRect(s_start + this.left_offset, y_center + 5, s_end - s_start, 1);
+ break;
+ case "D": // Deletion
+ ctx.fillStyle = "red";
+ ctx.fillRect(s_start + this.left_offset, y_center + 4, s_end - s_start, 3);
+ break;
+ case "P": // TODO: No good way to draw insertions/padding right now, so ignore
+ case "I":
+ break;
+ }
+ cur_offset += cig_len;
}
},
draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
@@ -1465,6 +1500,10 @@ var FeatureTrack = function ( name, view
feature_start = feature[1],
feature_end = feature[2],
feature_name = feature[3];
+
+ if (slots[feature_uid] === undefined) {
+ continue;
+ }
// Apply filters to feature.
var hide_feature = false;
@@ -1495,18 +1534,18 @@ var FeatureTrack = function ( name, view
b2_end = Math.ceil( Math.min(width, Math.max(0, (feature[6][1] - tile_low) * w_scale)) );
if (feature[5][1] >= tile_low && feature[5][0] <= tile_high) {
- this.rect_or_text(ctx, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], b1_start + left_offset, b1_end - b1_start, y_center);
+ this.rect_or_text(ctx, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], cigar, y_center);
}
if (feature[6][1] >= tile_low && feature[6][0] <= tile_high) {
- this.rect_or_text(ctx, w_scale, tile_low, tile_high, feature[6][0], feature[6][2], b2_start + left_offset, b2_end - b2_start, y_center);
+ this.rect_or_text(ctx, w_scale, tile_low, tile_high, feature[6][0], feature[6][2], cigar, y_center);
}
if (b2_start > b1_end) {
- ctx.fillStyle = "#999";
+ ctx.fillStyle = CONNECTOR_COLOR;
ctx.fillRect(b1_end + left_offset, y_center + 5, b2_start - b1_end, 1);
}
} else {
ctx.fillStyle = block_color;
- this.rect_or_text(ctx, w_scale, tile_low, tile_high, feature_start, feature_name, f_start + left_offset, f_end - f_start, y_center);
+ this.rect_or_text(ctx, w_scale, tile_low, tile_high, feature_start, feature_name, cigar, y_center);
}
if (mode !== "Dense" && !no_detail && feature_start > tile_low) {
// Draw label
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -193,20 +193,17 @@ class BamDataProvider( TracksDataProvide
message = "Only the first %s pairs are being displayed." % MAX_VALS
break
qname = read.qname
- if no_detail:
- seq = len(read.seq)
- else:
- seq = read.seq
+ seq = read.seq
+ read_len = sum( [cig[1] for cig in read.cigar] ) # Use cigar to determine length
if read.is_proper_pair:
if qname in paired_pending: # one in dict is always first
pair = paired_pending[qname]
- results.append( [ qname, pair['start'], read.pos + read.rlen, seq, read.cigar, [pair['start'], pair['end'], pair['seq']], [read.pos, read.pos + read.rlen, seq] ] )
- # results.append( [read.qname, pair['start'], read.pos + read.rlen, qname, [pair['start'], pair['end']], [read.pos, read.pos + read.rlen] ] )
+ results.append( [ qname, pair['start'], read.pos + read_len, seq, read.cigar, [pair['start'], pair['end'], pair['seq']], [read.pos, read.pos + read_len, seq] ] )
del paired_pending[qname]
else:
- paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read.rlen, 'seq': seq, 'mate_start': read.mpos, 'rlen': read.rlen, 'cigar': read.cigar }
+ paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, 'rlen': read_len, 'cigar': read.cigar }
else:
- results.append( [qname, read.pos, read.pos + read.rlen, seq, read.cigar] )
+ results.append( [qname, read.pos, read.pos + read_len, seq, read.cigar] )
# take care of reads whose mates are out of range
for qname, read in paired_pending.iteritems():
if read['mate_start'] < read['start']:
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -159,9 +159,11 @@ class TracksController( BaseController,
vis = session.query( model.Visualization ).get( decoded_id )
viz_config = self.get_visualization_config( trans, vis )
- # Set config chrom.
- viz_config[ 'chrom' ] = chrom
- return trans.fill_template( 'tracks/browser.mako', config=viz_config, add_dataset=kwargs.get("dataset_id", None) )
+ new_dataset = kwargs.get("dataset_id", None)
+ if new_dataset is not None:
+ if trans.security.decode_id(new_dataset) in [ d["dataset_id"] for d in viz_config.get("tracks") ]:
+ new_dataset = None # Already in browser, so don't add
+ return trans.fill_template( 'tracks/browser.mako', config=viz_config, add_dataset=new_dataset )
@web.json
def chroms(self, trans, vis_id=None, dbkey=None ):
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -74,7 +74,7 @@
$(function() {
%if config:
- view = new View( $("#center"), "${config.get('chrom')}", "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}" );
+ view = new View( $("#center"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}" );
view.editor = true;
%for track in config.get('tracks'):
view.add_track(
@@ -84,7 +84,7 @@
init();
%else:
var continue_fn = function() {
- view = new View( $("#center"), undefined, $("#new-title").val(), undefined, $("#new-dbkey").val() );
+ view = new View( $("#center"), $("#new-title").val(), undefined, $("#new-dbkey").val() );
view.editor = true;
init();
hide_modal();
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";r
ight_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_coun
ter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Ove
rview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return
false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new ReferenceTrack
(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("drag
start",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.contai
ner.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(c.chrom===""){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.rese
t();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.reset_overview();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remo
ve()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a
,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=function(
b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=Number.MIN_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=Number.MIN_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[th
is.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.filte
ring_div.hide();this.filtering_div.bind("drag",function(k){k.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(var e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th class='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);d.text("[0-2]");var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:0,max:1,values:[0,1],slide:function(l,m){var k=m.values;d.text("["+k[0]+"-"+k[1]+"]");a.low=k[0];a.high=k[1];c.draw(true)},change:function(k,l){a.control_element.slider("option","slide").call(a.control_element,k,l)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},i
nit_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.
addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configurat
ion"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},j=function(){d.update_options(d.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){j()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:l,OK:j})};if(d.filters.length>0){b["Show filters"]=function(){var j;if(!d.filtering_div.is(":visible")){j="Hide filters";d.filters_visible=true}else{j="Show filters";d.filters_visible=false}$("#"+d.name_div.attr("id")+"-menu").find("li").eq(2).text(j);d.filtering_div.toggle()}}b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};d.popup_menu=make_popupmenu(d.name_div,b);show_hide_popupmenu_options(d.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(b){var m=this.view.low,g=this.view.high,h=g-m,f=this.view.res
olution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/h,k;this.content_div.append(p),this.max_height=0;var a=Math.floor(m/f/DENSITY);var l=new Object();while((a*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+a;var e=this.tile_cache.get(n);if(!b&&e){var j=a*DENSITY*f;var d=(j-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,a,f,p,q,l)}a+=1}var c=this;var o=setInterval(function(){if(l.length!=0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var r=0;r<c.filters.length;r++){c.filters[r].update_ui_elt()}clearInterval(o)}},50)},delayed_draw:function(c,h,g,e,b,d,j,k,f){var a=setTimeout(function(){if(!(g>c.view.high||e<c.view.low)){tile_element=c.draw_tile(d,b,j,k);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var n=tile_element.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=n.
getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,tile_element);c.show_tile(tile_element,j)}}delete f.id},50);f.id=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a
,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_da
ta:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,l,p){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),o=e.get(0).getContext("2d"),k=f+"_"+b;if(p>PX_PER_CHAR){if(this.data_cache.get(k)===undefined){this.get_data(f,b);return}var n=this.data_cache.get(k);if(n===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*p+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*p-this.left_offset});for(var h=0,m=n.length;h<m;h++){var a=Math.round(h*p),j=Math.round(p/2);o.fillText(n[h],a+this.left_offset+j,10)}l.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=func
tion(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#trac
k_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;a.container_div.find(".yaxislabel").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:func
tion(p,s,c,e){if(this.vertical_range===undefined){return}var t=s*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),w=p+"_"+s;if(this.data_cache.get(w)===undefined){this.get_data(p,s);return}var j=this.data_cache.get(w);if(j===null){return}b.css({position:"absolute",top:0,left:(t-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,u=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();o.fillStyle=this.prefs.color;if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var v,h;for(var q=0,r=data.length;q<r;q++){v=Math.round((data[q][0]-t)*e);h=data[q][1];if(h===null){if(k&&m==="Filled"){o.lineTo(v,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(d-(h-l)/n*d);o.fillRect(v,h,f,d-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";
o.fillRect(v,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(v,h)}else{k=true;if(m==="Filled"){o.moveTo(v,d);o.lineTo(v,h)}else{o.moveTo(v,h)}}}}}if(m==="Filled"){if(k){o.lineTo(v,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var e="track_"+n+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+n+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),l=$("<input></input>").attr("id",h).val(d),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j);return a.append(m).append(l).append(g).append(f).append(b).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();color=$("#track_"+
c+"_color").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value||color!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.prefs.color=color;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE
);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};th
is.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,
f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(ah,o,s,aw){var N=o*DENSITY*ah,am=(o+1)*DENSITY*ah,M=am-N;var ao=(!this.initial_canvas?"initial":N+"_"+am);var I=this.data_cache.get(ao);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,am]]=true;this.get_data(N,am);return}var a=Math.ceil(M*aw),S=$("<canvas class='tile'></canvas>"),aj=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,af=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_inf
o==="no_detail")),X=this.left_offset,av,D,ax;if(I.dataset_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;ax=10}else{ax=(af?this.vertical_nodetail_px:this.vertical_detail_px);var A=(aw<0.0001?1/view.zoom_res:aw);D=this.incremental_slots(A,I.data,af,r)*ax+z;av=this.inc_slots[A]}}S.css({position:"absolute",top:0,left:(N-this.view.low)*aw-X});S.get(0).width=a+X;S.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=S.get(0).getContext("2d");J.fillStyle=l;J.font=this.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Z=I.data,L=I.max,q=I.avg,b=Math.ceil(I.delta*aw);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var aq=0,H=Z.length;aq<H;aq++){var ab=Math.floor((Z[aq][0]-N)*aw);var aa=Z[aq][1];if(!aa){continue}var an=aa/L*this.summary_draw_height;J.fillStyle="black";J.fil
lRect(ab+X,this.summary_draw_height-an,b,an);if(this.prefs.show_counts&&J.measureText(aa).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(aa,ab+X+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(S);return S}if(I.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+X,ax)}var ae=false;if(I.data.length!=0){ae=true;for(var at=0;at<this.filters.length;at++){if(!this.filters[at].applies_to(I.data[0])){ae=false}}}if(ae){S.addClass(FILTERABLE_CLASS)}var au=I.data;var ap=0;for(var aq=0,H=au.length;aq<H;aq++){var T=au[aq],R=T[0],ar=T[1],ad=T[2],O=T[3];var ac=false;var V;for(var at=0;at<this.filters.length;at++){V=this.filters[at];V.update_attrs(T);if(!V.keep(T)){ac=true;break}}if(ac){continue}if(ar<=am&&ad>=N){var ag=Math.floor(Math.max(0,(ar-N)*aw)),K=Math.ceil(Math.min(a,Math.max(0,(ad-N)*aw))),Y=(r==="Dense"?1:(1+av[R]))*ax;if(I.dataset_type==="bai"){var v=T[4];J.fillStyle=l;if(T[5] in
stanceof Array){var E=Math.floor(Math.max(0,(T[5][0]-N)*aw)),Q=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-N)*aw))),C=Math.floor(Math.max(0,(T[6][0]-N)*aw)),w=Math.ceil(Math.min(a,Math.max(0,(T[6][1]-N)*aw)));if(T[5][1]>=N&&T[5][0]<=am){this.rect_or_text(J,aw,N,am,T[5][0],T[5][2],E+X,Q-E,Y)}if(T[6][1]>=N&&T[6][0]<=am){this.rect_or_text(J,aw,N,am,T[6][0],T[6][2],C+X,w-C,Y)}if(C>Q){J.fillStyle="#999";J.fillRect(Q+X,Y+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,aw,N,am,ar,O,ag+X,K-ag,Y)}if(r!=="Dense"&&!af&&ar>N){J.fillStyle=this.prefs.label_color;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(R,ag-2+X,Y+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var G=T[4],W=T[5],ai=T[6],h=T[7];var F,ak,P=null,ay=null;if(W&&ai){P=Math.floor(Math.max(0,(W-N)*aw));ay=Math.ceil(Math.min(a,Math.max(0,(ai-N)*aw)))}if(r!=="Dense"&&O!==undefined&&ar>N){J.fil
lStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}if(h){if(G){if(G=="+"){J.fillStyle=RIGHT_STRAND}else{if(G=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}for(var ao=0,g=h.length;ao<g;ao++){var u=h[ao],d=Math.floor(Math.max(0,(u[0]-N)*aw)),U=Math.ceil(Math.min(a,Math.max((u[1]-N)*aw)));if(d>U){continue}F=5;ak=3;J.fillRect(d+X,Y+ak,U-d,F);if(P!==undefined&&!(d>ay||U<P)){F=9;ak=1;var al=Math.max(d,P),B=Math.min(U,ay);J.fillRect(al+X,Y+ak,B-al,F)}}}else{F=9;ak=1;J.fillRect(ag+X,Y+ak,K-ag,F);if(T.strand){if(T.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var t=T[4],n=T[5],c=T[6];F=9;ak=1;J.fillRect(ag+X,Y,K-ag,F);if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&a
g-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}var m=t+" / "+n;if(ar>N&&J.measureText(m).width<(K-ag)){J.fillStyle="white";J.textAlign="center";J.fillText(m,X+ag+(K-ag)/2,Y+8);J.fillStyle=l}}}}}ap++}}return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_opti
ons:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=50,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/st
rand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,d,c,b){this.container=a;this.vis_id=c;this.dbkey=b;this.title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_i
d_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var c=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_container=$("<div/>").addClass("nav-container").appendTo(c);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Clo
se Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(d){if(d.type==="focusout"||(d.keyCode||d.which)===13||(d.keyCode||d.which)===27){if((d.keyCode||d.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();r
eturn false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(d){if(d.reference){a.add_label_track(new Referenc
eTrack(a))}a.chrom_data=d.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(d){a.zoom_in(d.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(d){this.current_x=d.offsetX}).bind("drag",function(d){var g=d.offsetX-this.current_x;this.current_x=d.offsetX;var f=Math.round(g/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-f)});this.overview_close.bind("click",function(){for(var d in a.tracks){a.tracks[d].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind
("dragstart",function(d){this.original_low=a.low;this.current_height=d.clientY;this.current_x=d.offsetX;this.enable_pan=(d.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(g){if(!this.enable_pan||this.in_reordering){return}var d=$(this);var j=g.offsetX-this.current_x;var f=d.scrollTop()-(g.clientY-this.current_height);d.scrollTop(f);this.current_height=g.clientY;this.current_x=g.offsetX;var h=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(h)});this.top_labeltrack.bind("dragstart",function(d){this.drag_origin_x=d.clientX;this.drag_origin_pos=d.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+30,top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var f=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,d=Math.max(j.clientX,this.drag_origin_x)-a.
container.offset().left,h=(a.high-a.low),g=a.viewport_container.width();a.update_location(Math.round(f/g*h)+a.low,Math.round(d/g*h)+a.low);this.drag_div.css({left:f+"px",width:(d-f)+"px"})}).bind("dragend",function(k){var f=Math.min(k.clientX,this.drag_origin_x),d=Math.max(k.clientX,this.drag_origin_x),h=(a.high-a.low),g=a.viewport_container.width(),j=a.low;a.low=Math.round(f/g*h)+j;a.high=Math.round(d/g*h)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data,function(h,j){return h.chrom===d})[0];if(e===undefined){return}if(d!==c.chrom){c.chrom=d;if(!c.chrom){c.intro_div.show()}else{c.intro_div.hide()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.re
set();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.reset_overview();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).re
move()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=this.low/(this.max_high-this.max_low)*this.overview_viewport.width();var e=(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width();var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left
:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=functio
n(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=Number.MIN_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=Number.MIN_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[
this.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.fil
tering_div.hide();this.filtering_div.bind("drag",function(k){k.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(var e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th class='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);d.text("[0-2]");var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:0,max:1,values:[0,1],slide:function(l,m){var k=m.values;d.text("["+k[0]+"-"+k[1]+"]");a.low=k[0];a.high=k[1];c.draw(true)},change:function(k,l){a.control_element.slider("option","slide").call(a.control_element,k,l)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)}
,init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_di
v.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var d=this,c=d.view;if(d.hidden){return}if(d.display_modes!==undefined){if(d.mode_div===undefined){d.mode_div=$("<div class='right-float menubutton popup' />").appendTo(d.header_div);var h=d.display_modes[0];d.mode=h;d.mode_div.text(h);var a=function(j){d.mode_div.text(j);d.mode=j;d.tile_cache.clear();d.draw()};var f={};for(var e in d.display_modes){var g=d.display_modes[e];f[g]=function(j){return function(){a(j)}}(g)}make_popupmenu(d.mode_div,f)}else{d.mode_div.hide()}}var b={};b["Set as overview"]=function(){c.overview_viewport.find("canvas").remove();d.is_overview=true;d.set_overview();for(var j in c.tracks){if(c.tracks[j]!==d){c.tracks[j].is_overview=false}}};b["Edit configur
ation"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},j=function(){d.update_options(d.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){j()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",d.gen_options(d.track_id),{Cancel:l,OK:j})};if(d.filters.length>0){b["Show filters"]=function(){var j;if(!d.filtering_div.is(":visible")){j="Hide filters";d.filters_visible=true}else{j="Show filters";d.filters_visible=false}$("#"+d.name_div.attr("id")+"-menu").find("li").eq(2).text(j);d.filtering_div.toggle()}}b.Remove=function(){c.remove_track(d);if(c.num_tracks===0){$("#no-tracks").show()}};d.popup_menu=make_popupmenu(d.name_div,b);show_hide_popupmenu_options(d.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(b){var m=this.view.low,g=this.view.high,h=g-m,f=this.view.r
esolution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/h,k;this.content_div.append(p),this.max_height=0;var a=Math.floor(m/f/DENSITY);var l=new Object();while((a*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+a;var e=this.tile_cache.get(n);if(!b&&e){var j=a*DENSITY*f;var d=(j-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,a,f,p,q,l)}a+=1}var c=this;var o=setInterval(function(){if(l.length!=0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var r=0;r<c.filters.length;r++){c.filters[r].update_ui_elt()}clearInterval(o)}},50)},delayed_draw:function(c,h,g,e,b,d,j,k,f){var a=setTimeout(function(){if(!(g>c.view.high||e<c.view.low)){tile_element=c.draw_tile(d,b,j,k);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var n=tile_element.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=
n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,tile_element);c.show_tile(tile_element,j)}}delete f.id},50);f.id=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null
,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_
data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,l,p){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),o=e.get(0).getContext("2d"),k=f+"_"+b;if(p>PX_PER_CHAR){if(this.data_cache.get(k)===undefined){this.get_data(f,b);return}var n=this.data_cache.get(k);if(n===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*p+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*p-this.left_offset});for(var h=0,m=n.length;h<m;h++){var a=Math.round(h*p),j=Math.round(p/2);o.fillText(n[h],a+this.left_offset+j,10)}l.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=fu
nction(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#tr
ack_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;a.container_div.find(".yaxislabel").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);e.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:fu
nction(p,s,c,e){if(this.vertical_range===undefined){return}var t=s*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),w=p+"_"+s;if(this.data_cache.get(w)===undefined){this.get_data(p,s);return}var j=this.data_cache.get(w);if(j===null){return}b.css({position:"absolute",top:0,left:(t-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,u=this.total_frequency,d=this.height_px,m=this.mode;o.beginPath();o.fillStyle=this.prefs.color;if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var v,h;for(var q=0,r=data.length;q<r;q++){v=Math.round((data[q][0]-t)*e);h=data[q][1];if(h===null){if(k&&m==="Filled"){o.lineTo(v,d)}k=false;continue}if(h<l){h=l}else{if(h>g){h=g}}if(m==="Histogram"){h=Math.round(d-(h-l)/n*d);o.fillRect(v,h,f,d-h)}else{if(m==="Intensity"){h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")
";o.fillRect(v,0,f,d)}else{h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(v,h)}else{k=true;if(m==="Filled"){o.moveTo(v,d);o.lineTo(v,h)}else{o.moveTo(v,h)}}}}}if(m==="Filled"){if(k){o.lineTo(v,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(n){var a=$("<div />").addClass("form-row");var e="track_"+n+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+n+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),l=$("<input></input>").attr("id",h).val(d),k="track_"+n+"_maxval",g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j);return a.append(m).append(l).append(g).append(f).append(b).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();color=$("#track_
"+c+"_color").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value||color!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.prefs.color=color;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATU
RE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};t
his.inc_slots[a].w_scale=a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(v<=MAX_FEATURE_DEPTH){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_ti
le[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(r,m,s,b,q,f,h,e){r.textAlign="center";var l=0,p=Math.round(m/2);for(cig_id in h){var k=h[cig_id],d="MIDNSHP"[k[0]],n=k[1];if(d==="H"||d==="S"){l-=n}var g=q+l,v=Math.floor(Math.max(0,(g-s)*m)),j=Math.floor(Math.max(0,(g+n-s)*m));switch(d){case"S":case"H":case"M":var o=f.slice(l,n);if((this.mode==="Pack"||this.mode==="Auto")&&f!==undefined&&m>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillRect(v+this.left_offset,e+1,j-v,9);r.fillStyle=CONNECTOR_COLOR;for(var t=0,a=o.length;t<a;t++){if(g+t>=s&&g+t<=b){var u=Math.floor(Math.max(0,(g+t-s)*m));r.fillText(o[t],u+this.left_offset+p,e+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(v+this.left_offset,e+4,j-v,3)}break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(v+this.left_offset,e+5,j-v,1);break;case"D":r.fillStyle="red";r.fillRect(v+this.left_offset,e+4,j-v,3);break;case"P":case"I":break}l+=n}},draw_tile:function(
ah,o,s,aw){var N=o*DENSITY*ah,am=(o+1)*DENSITY*ah,M=am-N;var ao=(!this.initial_canvas?"initial":N+"_"+am);var I=this.data_cache.get(ao);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,am]]=true;this.get_data(N,am);return}var a=Math.ceil(M*aw),S=$("<canvas class='tile'></canvas>"),aj=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,af=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_info==="no_detail")),X=this.left_offset,av,D,ax;if(I.dataset_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;ax=10}else{ax=(af?this.vertical_nodetail_px:this.vertical_detail_px);var A=(aw<0.0001?1/view.zoom_res:aw);D=this.incremental_slots(A,I.data,af,r)*ax+z;av=this.inc_slots[A]}}S.css({position:"absolute",top:0,left:(N-this.view.low)*aw-X});S.get(0).width=a+X;S.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=S.get(0).getContext("2d");J.fillStyle=l;J.font=t
his.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Z=I.data,L=I.max,q=I.avg,b=Math.ceil(I.delta*aw);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var aq=0,H=Z.length;aq<H;aq++){var ab=Math.floor((Z[aq][0]-N)*aw);var aa=Z[aq][1];if(!aa){continue}var an=aa/L*this.summary_draw_height;J.fillStyle="black";J.fillRect(ab+X,this.summary_draw_height-an,b,an);if(this.prefs.show_counts&&J.measureText(aa).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(aa,ab+X+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(S);return S}if(I.message){S.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+X,ax)}var ae=false;if(I.data.length!=0){ae=true;for(var at=0;at<this.filters.length;at++){if(!this.filters[at].applies_to(I.data[0])){ae=false}}}if(ae){S.
addClass(FILTERABLE_CLASS)}var au=I.data;var ap=0;for(var aq=0,H=au.length;aq<H;aq++){var T=au[aq],R=T[0],ar=T[1],ad=T[2],O=T[3];if(av[R]===undefined){continue}var ac=false;var V;for(var at=0;at<this.filters.length;at++){V=this.filters[at];V.update_attrs(T);if(!V.keep(T)){ac=true;break}}if(ac){continue}if(ar<=am&&ad>=N){var ag=Math.floor(Math.max(0,(ar-N)*aw)),K=Math.ceil(Math.min(a,Math.max(0,(ad-N)*aw))),Y=(r==="Dense"?1:(1+av[R]))*ax;if(I.dataset_type==="bai"){var v=T[4];J.fillStyle=l;if(T[5] instanceof Array){var E=Math.floor(Math.max(0,(T[5][0]-N)*aw)),Q=Math.ceil(Math.min(a,Math.max(0,(T[5][1]-N)*aw))),C=Math.floor(Math.max(0,(T[6][0]-N)*aw)),w=Math.ceil(Math.min(a,Math.max(0,(T[6][1]-N)*aw)));if(T[5][1]>=N&&T[5][0]<=am){this.rect_or_text(J,aw,N,am,T[5][0],T[5][2],v,Y)}if(T[6][1]>=N&&T[6][0]<=am){this.rect_or_text(J,aw,N,am,T[6][0],T[6][2],v,Y)}if(C>Q){J.fillStyle=CONNECTOR_COLOR;J.fillRect(Q+X,Y+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,aw,N,am,ar,O,v,Y)}if(r!=
="Dense"&&!af&&ar>N){J.fillStyle=this.prefs.label_color;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(R,ag-2+X,Y+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var G=T[4],W=T[5],ai=T[6],h=T[7];var F,ak,P=null,ay=null;if(W&&ai){P=Math.floor(Math.max(0,(W-N)*aw));ay=Math.ceil(Math.min(a,Math.max(0,(ai-N)*aw)))}if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}if(h){if(G){if(G=="+"){J.fillStyle=RIGHT_STRAND}else{if(G=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}for(var ao=0,g=h.length;ao<g;ao++){var u=h[ao],d=Math.floor(Math.max(0,(u[0]-N)*aw)),U=Math.ceil(Math.min(a,Math.max((u[1]-N)*aw)));if(d>U){continue}F=5;ak=3;J.fillRect(d+X,Y+ak,U-d,F);if(P!==undefined&&!(d>ay||
U<P)){F=9;ak=1;var al=Math.max(d,P),B=Math.min(U,ay);J.fillRect(al+X,Y+ak,B-al,F)}}}else{F=9;ak=1;J.fillRect(ag+X,Y+ak,K-ag,F);if(T.strand){if(T.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(T.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(ag+X,Y,K-ag,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(af){J.fillStyle=l;J.fillRect(ag+X,Y+5,K-ag,1)}else{var t=T[4],n=T[5],c=T[6];F=9;ak=1;J.fillRect(ag+X,Y,K-ag,F);if(r!=="Dense"&&O!==undefined&&ar>N){J.fillStyle=aj;if(o===0&&ag-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+X,Y+8)}else{J.textAlign="right";J.fillText(O,ag-2+X,Y+8)}J.fillStyle=l}var m=t+" / "+n;if(ar>N&&J.measureText(m).width<(K-ag)){J.fillStyle="white";J.textAlign="center";J.fillText(m,X+ag+(K-ag)/2,Y+8);J.fillStyle=l}}}}}ap++}}return S},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(th
is.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="ReadTrack";this.vert
ical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
1
0

galaxy-dist commit 6372b67c9e37: mutation viz tool test data files
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1287517282 14400
# Node ID 6372b67c9e370b3a80159bcc719e13d50ddc018f
# Parent e029c860e71710d69f725e5c136b7e55fa529a42
mutation viz tool test data files
--- /dev/null
+++ b/test-data/mutation_data1_zoom3x.svg
@@ -0,0 +1,639 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg style="stroke-linejoin:round; stroke:black; stroke-width:0.5pt; text-anchor:middle; fill:none" xmlns="http://www.w3.org/2000/svg" font-family="Helvetica, Arial, FreeSans, Sans, sans, sans-serif" height="1980px" width="208px" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 116 496">
+
+<g id="viewport">
+
+<text y="4" x="12" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">A</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="14" fill="blue" />
+
+<text y="4" x="22" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">C</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="24" fill="green" />
+
+<text y="4" x="32" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">G</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="34" fill="orange" />
+
+<text y="4" x="42" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">T</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="44" fill="red" />
+
+<text y="25" x="23" stroke="none" transform="rotate(-90 23,25)" fill="black"><tspan style="font-family:Verdana;font-size:25%">s1</tspan></text>
+
+<text y="42" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">72</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="38" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="38" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="38" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="39.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="41.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="42.5" x="16" fill="red" />
+
+<text y="50" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">149</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="46" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="46" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="46" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="47.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="49.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="50.5" x="16" fill="red" />
+
+<text y="58" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">194</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="54" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="54" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="54" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="55.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="57.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="58.5" x="16" fill="red" />
+
+<text y="66" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">299</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="62" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="62" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="62" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="63.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="65.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="66.5" x="16" fill="red" />
+
+<text y="74" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">309</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="70" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="70" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="70" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="11" stroke="none" y="71.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="73.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="2" stroke="none" y="74.5" x="16" fill="red" />
+
+<text y="82" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">310</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="78" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="78" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="78" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="4" stroke="none" y="79.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="81.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="9" stroke="none" y="82.5" x="16" fill="red" />
+
+<text y="90" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">409</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="86" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="86" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="86" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="87.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="89.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="90.5" x="16" fill="red" />
+
+<text y="98" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">2353</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="94" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="94" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="94" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="95.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="97.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="98.5" x="16" fill="red" />
+
+<text y="106" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">2484</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="102" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="102" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="102" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="103.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="105.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="106.5" x="16" fill="red" />
+
+<text y="114" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">2707</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="110" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="110" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="110" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="111.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="113.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="114.5" x="16" fill="red" />
+
+<text y="122" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">3011</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="118" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="118" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="118" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="119.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="121.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="122.5" x="16" fill="red" />
+
+<text y="130" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">3434</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="126" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="126" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="126" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="127.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="129.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="130.5" x="16" fill="red" />
+
+<text y="138" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">3480</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="134" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="134" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="134" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="135.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="137.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="138.5" x="16" fill="red" />
+
+<text y="146" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">5063</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="142" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="142" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="142" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="143.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="145.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="146.5" x="16" fill="red" />
+
+<text y="154" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">5580</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="150" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="150" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="150" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="151.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="153.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="154.5" x="16" fill="red" />
+
+<text y="162" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">7028</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="158" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="158" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="158" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="159.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="161.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="162.5" x="16" fill="red" />
+
+<text y="170" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">8701</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="166" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="166" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="166" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="167.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="169.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="170.5" x="16" fill="red" />
+
+<text y="178" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">8992</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="174" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="174" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="174" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="8" stroke="none" y="175.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="177.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="5" stroke="none" y="178.5" x="16" fill="red" />
+
+<text y="186" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">9377</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="182" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="182" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="182" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="183.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="185.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="186.5" x="16" fill="red" />
+
+<text y="194" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">9540</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="190" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="190" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="190" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="191.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="193.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="194.5" x="16" fill="red" />
+
+<text y="202" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10398</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="198" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="198" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="198" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="199.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="201.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="202.5" x="16" fill="red" />
+
+<text y="210" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10550</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="206" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="206" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="206" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="207.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="209.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="210.5" x="16" fill="red" />
+
+<text y="218" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10819</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="214" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="214" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="214" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="215.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="217.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="218.5" x="16" fill="red" />
+
+<text y="226" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10873</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="222" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="222" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="222" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="223.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="225.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="226.5" x="16" fill="red" />
+
+<text y="234" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11017</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="230" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="230" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="230" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="231.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="233.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="234.5" x="16" fill="red" />
+
+<text y="242" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11299</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="238" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="238" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="238" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="239.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="241.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="242.5" x="16" fill="red" />
+
+<text y="250" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11719</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="246" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="246" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="246" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="247.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="249.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="250.5" x="16" fill="red" />
+
+<text y="258" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11722</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="254" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="254" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="254" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="255.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="257.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="258.5" x="16" fill="red" />
+
+<text y="266" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">12705</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="262" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="262" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="262" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="263.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="265.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="266.5" x="16" fill="red" />
+
+<text y="274" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">12850</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="270" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="270" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="270" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="271.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="273.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="274.5" x="16" fill="red" />
+
+<text y="282" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14053</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="278" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="278" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="278" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="279.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="281.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="282.5" x="16" fill="red" />
+
+<text y="290" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14212</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="286" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="286" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="286" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="287.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="289.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="290.5" x="16" fill="red" />
+
+<text y="298" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14580</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="294" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="294" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="294" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="295.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="297.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="298.5" x="16" fill="red" />
+
+<text y="306" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14766</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="302" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="302" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="302" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="303.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="305.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="306.5" x="16" fill="red" />
+
+<text y="314" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14905</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="310" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="310" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="310" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="311.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="313.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="314.5" x="16" fill="red" />
+
+<text y="322" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">15301</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="318" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="318" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="318" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="319.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="321.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="322.5" x="16" fill="red" />
+
+<text y="330" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">15932</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="326" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="326" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="326" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="327.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="329.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="330.5" x="16" fill="red" />
+
+<text y="338" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16172</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="334" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="334" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="334" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="335.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="337.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="338.5" x="16" fill="red" />
+
+<text y="346" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16183</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="342" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="342" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="342" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="343.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="345.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="346.5" x="16" fill="red" />
+
+<text y="354" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16184</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="350" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="350" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="350" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="351.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="353.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="354.5" x="16" fill="red" />
+
+<text y="362" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16189</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="358" x="0" fill="green" />
+
+<text y="370" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16190</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="366" x="0" fill="green" />
+
+<text y="378" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16224</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="374" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="374" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="374" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="375.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="377.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="378.5" x="16" fill="red" />
+
+<text y="386" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16240</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="382" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="382" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="382" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="383.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="385.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="386.5" x="16" fill="red" />
+
+<text y="394" x="7" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16321</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="390" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="390" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="390" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="391.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="393.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="394.5" x="16" fill="red" />
+
+</g>
+
+</svg>
+
--- /dev/null
+++ b/test-data/mutation_data1_interactive.svg
@@ -0,0 +1,868 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
+<script type="text/javascript">
+/**
+ * SVGPan library 1.2
+ * ====================
+ *
+ * Given an unique existing element with id "viewport", including the
+ * the library into any SVG adds the following capabilities:
+ *
+ * - Mouse panning
+ * - Mouse zooming (using the wheel)
+ * - Object dargging
+ *
+ * Known issues:
+ *
+ * - Zooming (while panning) on Safari has still some issues
+ *
+ * Releases:
+ *
+ * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
+ * Fixed a bug with browser mouse handler interaction
+ *
+ * 1.1, Wed Feb 3 17:39:33 GMT 2010, Zeng Xiaohui
+ * Updated the zoom code to support the mouse wheel on Safari/Chrome
+ *
+ * 1.0, Andrea Leofreddi
+ * First release
+ *
+ * This code is licensed under the following BSD license:
+ *
+ * Copyright 2009-2010 Andrea Leofreddi (a.leofreddi(a)itcharm.com) All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of Andrea Leofreddi.
+ */
+
+var root = document.documentElement;
+
+var state = 'none', stateTarget, stateOrigin, stateTf;
+
+setupHandlers(root);
+
+/**
+ * Register handlers
+ */
+function setupHandlers(root){
+ setAttributes(root, {
+ "onmouseup" : "add(evt)",
+ "onmousedown" : "handleMouseDown(evt)",
+ "onmousemove" : "handleMouseMove(evt)",
+ "onmouseup" : "handleMouseUp(evt)",
+ //"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
+ });
+
+ if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
+ window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
+ else
+ window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
+}
+
+/**
+ * Instance an SVGPoint object with given event coordinates.
+ */
+function getEventPoint(evt) {
+ var p = root.createSVGPoint();
+
+ p.x = evt.clientX;
+ p.y = evt.clientY;
+
+ return p;
+}
+
+/**
+ * Sets the current transform matrix of an element.
+ */
+function setCTM(element, matrix) {
+ var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
+
+ element.setAttribute("transform", s);
+}
+
+/**
+ * Dumps a matrix to a string (useful for debug).
+ */
+function dumpMatrix(matrix) {
+ var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n 0, 0, 1 ]";
+
+ return s;
+}
+
+/**
+ * Sets attributes of an element.
+ */
+function setAttributes(element, attributes){
+ for (i in attributes)
+ element.setAttributeNS(null, i, attributes[i]);
+}
+
+/**
+ * Handle mouse move event.
+ */
+function handleMouseWheel(evt) {
+ if(evt.preventDefault)
+ evt.preventDefault();
+
+ evt.returnValue = false;
+
+ var svgDoc = evt.target.ownerDocument;
+
+ var delta;
+
+ if(evt.wheelDelta)
+ delta = evt.wheelDelta / 3600; // Chrome/Safari
+ else
+ delta = evt.detail / -90; // Mozilla
+
+ var z = 1 + delta; // Zoom factor: 0.9/1.1
+
+ var g = svgDoc.getElementById("viewport");
+
+ var p = getEventPoint(evt);
+
+ p = p.matrixTransform(g.getCTM().inverse());
+
+ // Compute new scale matrix in current mouse position
+ var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
+
+ setCTM(g, g.getCTM().multiply(k));
+
+ stateTf = stateTf.multiply(k.inverse());
+}
+
+/**
+ * Handle mouse move event.
+ */
+function handleMouseMove(evt) {
+ if(evt.preventDefault)
+ evt.preventDefault();
+
+ evt.returnValue = false;
+
+ var svgDoc = evt.target.ownerDocument;
+
+ var g = svgDoc.getElementById("viewport");
+
+ if(state == 'pan') {
+ // Pan mode
+ var p = getEventPoint(evt).matrixTransform(stateTf);
+
+ setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
+ } else if(state == 'move') {
+ // Move mode
+ var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
+
+ setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
+
+ stateOrigin = p;
+ }
+}
+
+/**
+ * Handle click event.
+ */
+function handleMouseDown(evt) {
+ if(evt.preventDefault)
+ evt.preventDefault();
+
+ evt.returnValue = false;
+
+ var svgDoc = evt.target.ownerDocument;
+
+ var g = svgDoc.getElementById("viewport");
+
+ if(evt.target.tagName == "svg") {
+ // Pan mode
+ state = 'pan';
+
+ stateTf = g.getCTM().inverse();
+
+ stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
+ }
+ /*else {
+ // Move mode
+ state = 'move';
+
+ stateTarget = evt.target;
+
+ stateTf = g.getCTM().inverse();
+
+ stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
+ }*/
+}
+/**
+ * Handle mouse button release event.
+ */
+function handleMouseUp(evt) {
+ if(evt.preventDefault)
+ evt.preventDefault();
+
+ evt.returnValue = false;
+
+ var svgDoc = evt.target.ownerDocument;
+
+ if(state == 'pan' || state == 'move') {
+ // Quit pan mode
+ state = '';
+ }
+}
+</script>
+
+<g id="viewport">
+
+<text y="4" x="12" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">A</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="14" fill="blue" />
+
+<text y="4" x="22" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">C</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="24" fill="green" />
+
+<text y="4" x="32" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">G</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="34" fill="orange" />
+
+<text y="4" x="42" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:20%">T</tspan></text>
+
+<rect fill-opacity="0.5" height="3" width="4" stroke="none" y="1" x="44" fill="red" />
+
+<text y="35" x="23" stroke="none" transform="rotate(-90 23,35)" fill="black"><tspan style="font-family:Verdana;font-size:25%">s1</tspan></text>
+
+<text y="42" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">72</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="38" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="38" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="38" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="39.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="41.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="42.5" x="16" fill="red" />
+
+<text y="50" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">149</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="46" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="46" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="46" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="47.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="49.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="50.5" x="16" fill="red" />
+
+<text y="58" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">194</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="54" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="54" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="54" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="55.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="57.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="58.5" x="16" fill="red" />
+
+<text y="66" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">299</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="62" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="62" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="62" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="63.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="65.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="66.5" x="16" fill="red" />
+
+<text y="74" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">309</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="70" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="70" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="70" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="11" stroke="none" y="71.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="73.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="2" stroke="none" y="74.5" x="16" fill="red" />
+
+<text y="82" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">310</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="78" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="78" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="78" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="4" stroke="none" y="79.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="81.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="9" stroke="none" y="82.5" x="16" fill="red" />
+
+<text y="90" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">409</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="86" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="86" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="86" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="87.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="89.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="90.5" x="16" fill="red" />
+
+<text y="98" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">2353</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="94" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="94" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="94" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="95.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="97.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="98.5" x="16" fill="red" />
+
+<text y="106" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">2484</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="102" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="102" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="102" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="103.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="105.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="106.5" x="16" fill="red" />
+
+<text y="114" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">2707</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="110" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="110" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="110" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="111.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="113.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="114.5" x="16" fill="red" />
+
+<text y="122" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">3011</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="118" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="118" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="118" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="119.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="121.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="122.5" x="16" fill="red" />
+
+<text y="130" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">3434</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="126" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="126" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="126" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="127.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="129.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="130.5" x="16" fill="red" />
+
+<text y="138" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">3480</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="134" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="134" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="134" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="135.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="137.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="138.5" x="16" fill="red" />
+
+<text y="146" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">5063</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="142" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="142" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="142" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="143.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="145.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="146.5" x="16" fill="red" />
+
+<text y="154" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">5580</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="150" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="150" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="150" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="151.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="153.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="154.5" x="16" fill="red" />
+
+<text y="162" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">7028</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="158" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="158" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="158" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="159.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="161.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="162.5" x="16" fill="red" />
+
+<text y="170" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">8701</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="166" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="166" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="166" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="167.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="169.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="170.5" x="16" fill="red" />
+
+<text y="178" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">8992</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="174" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="174" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="174" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="8" stroke="none" y="175.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="177.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="5" stroke="none" y="178.5" x="16" fill="red" />
+
+<text y="186" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">9377</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="182" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="182" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="182" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="183.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="185.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="186.5" x="16" fill="red" />
+
+<text y="194" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">9540</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="190" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="190" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="190" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="191.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="193.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="194.5" x="16" fill="red" />
+
+<text y="202" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10398</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="198" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="198" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="198" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="199.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="201.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="202.5" x="16" fill="red" />
+
+<text y="210" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10550</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="206" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="206" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="206" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="207.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="209.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="210.5" x="16" fill="red" />
+
+<text y="218" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10819</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="214" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="214" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="214" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="215.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="217.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="218.5" x="16" fill="red" />
+
+<text y="226" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">10873</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="222" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="222" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="222" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="223.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="225.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="226.5" x="16" fill="red" />
+
+<text y="234" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11017</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="230" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="230" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="230" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="231.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="233.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="234.5" x="16" fill="red" />
+
+<text y="242" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11299</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="238" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="238" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="238" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="239.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="241.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="242.5" x="16" fill="red" />
+
+<text y="250" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11719</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="246" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="246" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="246" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="247.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="249.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="250.5" x="16" fill="red" />
+
+<text y="258" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">11722</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="254" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="254" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="254" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="255.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="257.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="258.5" x="16" fill="red" />
+
+<text y="266" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">12705</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="262" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="262" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="262" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="263.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="265.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="266.5" x="16" fill="red" />
+
+<text y="274" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">12850</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="270" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="270" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="270" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="271.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="273.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="274.5" x="16" fill="red" />
+
+<text y="282" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14053</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="278" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="278" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="278" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="279.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="281.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="282.5" x="16" fill="red" />
+
+<text y="290" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14212</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="286" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="286" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="286" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="287.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="289.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="290.5" x="16" fill="red" />
+
+<text y="298" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14580</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="294" x="0" fill="orange" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="294" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="294" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="295.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="297.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="298.5" x="16" fill="red" />
+
+<text y="306" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14766</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="302" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="302" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="302" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="303.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="305.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="306.5" x="16" fill="red" />
+
+<text y="314" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">14905</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="310" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="310" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="310" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="311.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="313.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="314.5" x="16" fill="red" />
+
+<text y="322" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">15301</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="318" x="0" fill="blue" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="318" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="318" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="319.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="321.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="322.5" x="16" fill="red" />
+
+<text y="330" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">15932</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="326" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="326" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="326" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="327.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="329.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="330.5" x="16" fill="red" />
+
+<text y="338" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16172</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="334" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="334" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="334" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="335.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="337.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="338.5" x="16" fill="red" />
+
+<text y="346" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16183</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="342" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="342" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="342" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="343.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="345.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="346.5" x="16" fill="red" />
+
+<text y="354" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16184</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="350" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="350" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="350" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="351.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="353.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="354.5" x="16" fill="red" />
+
+<text y="362" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16189</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="358" x="0" fill="green" />
+
+<text y="370" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16190</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="366" x="0" fill="green" />
+
+<text y="378" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16224</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="374" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="374" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="374" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="375.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="0" stroke="none" y="377.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="378.5" x="16" fill="red" />
+
+<text y="386" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16240</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="382" x="0" fill="green" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="382" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="382" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="383.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="385.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="386.5" x="16" fill="red" />
+
+<text y="394" x="0" stroke="none" fill="black"><tspan style="font-family:Verdana;font-size:25%">16321</tspan></text>
+
+<rect fill-opacity="0.2" height="6" width="14" stroke="none" y="390" x="0" fill="red" />
+
+<rect fill-opacity="0.25" height="6" width="12" stroke="none" y="390" x="16" fill="grey" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="390" x="16" fill="blue" />
+
+<rect fill-opacity="0.6" height="1.5" width="12" stroke="none" y="391.5" x="16" fill="green" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="393.0" x="16" fill="orange" />
+
+<rect fill-opacity="0.6" height="1.5" width="1" stroke="none" y="394.5" x="16" fill="red" />
+
+</g>
+
+</svg>
+
--- /dev/null
+++ b/test-data/mutation_data1.txt
@@ -0,0 +1,1 @@
+chrM 72 73 G 26394 4 49 0 26447 26398 1 23389 3 45 0 23437 23392 1 3133 0 5 0 3138 3133 1 4087 0 6 0 4093 4087 1 9544 0 18 0 9562 9544 1 14437 1 22 1 14461 14439 1 11325 0 3 1 11329 11326 1 3595 0 9 1 3605 3596 1 12029 0 14 0 12043 12029 1 10441 0 21 0 10462 10441 1
chrM 149 150 T 11 50422 2 96 50531 50435 1 4 45417 1 65 45487 45422 1 0 4050 0 2 4052 4050 1 0 4488 0 4 4492 4488 1 3 18713 0 22 18738 18716 1 7 26855 0 33 26895 26862 1 1 13677 1 6 13685 13679 1 0 4635 0 13 4648 4635 1 4 26401 3 44 26452 26408 1 5 19462 0 18 19485 19467 1
chrM 194 195 C 0 102 2 58672 58776 58674 1 1 191 0 52080 52272 52081 1 3 8 0 3709 3720 3712 1 3 7 1 4600 4611 4604 1 1 35 1 21266 21303 21268 1 4 73 1 30175 30253 30180 1 6 14 0 13695 13715 13701 1 1 7 0 4786 4794 4787 1 2 31 1 31363 31397 31366 1 1 29 3 21865 21898 21869 1
chrM 299 300 A 18619 88 12 0 18719 100 0 18153 84 5 0 18242 89 0 568 32 0 0 623 32 2 774 31 0 0 828 31 2 6658 22 1 0 6681 23 0 10589 37 5 0 10631 42 0 2288 85 1 0 2455 86 2 637 30 0 0 696 30 2 8133 41 2 0 8176 43 0 7327 26 5 0 7358 31 0
chrM 309 310 C 6 11340 0 1433 12779 1439 2 3 11229 0 1336 12568 1339 2 1 778 0 4 783 5 0 0 1065 0 3 1069 3 0 0 4297 0 464 4761 464 2 1 6162 1 765 6929 767 2 0 3075 0 6 3083 6 0 0 875 0 1 876 1 0 1 5064 0 644 5709 645 2 2 4468 0 582 5052 584 2
chrM 310 311 T 1 1362 0 3775 5138 1363 2 1 1389 1 4222 5613 1391 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 448 0 1636 2085 449 2 0 795 0 2176 2971 795 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 567 0 2128 2695 567 2 0 558 0 1397 1955 558 2
chrM 409 410 A 2 3 1 30151 30157 30155 1 2 13 3 30355 30373 30371 1 1 0 0 2752 2754 2752 1 1 1 0 2996 2998 2997 1 1 2 0 12262 12265 12264 1 4 8 1 16960 16973 16969 1 3 8 0 8837 8853 8845 1 0 0 0 2942 2942 2942 1 0 3 1 16259 16263 16263 1 1 3 0 11363 11367 11366 1
chrM 2353 2354 C 3 34 3 63620 63660 63626 1 4 15 1 58084 58104 58089 1 1 0 0 2981 2982 2982 1 0 3 0 4267 4271 4267 1 0 7 0 23235 23242 23235 1 5 12 0 35778 35795 35783 1 5 3 0 12254 12264 12259 1 3 1 0 3923 3928 3926 1 4 7 2 32378 32391 32384 1 2 6 0 24366 24374 24368 1
chrM 2484 2485 C 0 20 0 27765 27785 27765 1 2 29 0 24596 24627 24598 1 0 1 0 698 699 698 1 0 5 0 879 884 879 1 0 8 1 10159 10168 10160 1 2 23 1 16036 16062 16039 1 2 5 0 2555 2562 2557 1 0 3 0 761 764 761 1 0 4 2 12896 12902 12898 1 0 14 0 10916 10930 10916 1
chrM 2707 2708 g 27267 1 48 1 27317 27269 1 25550 1 42 1 25594 25552 1 2662 1 4 0 2667 2663 1 3230 0 1 0 3231 3230 1 10833 0 5 1 10839 10834 1 16605 0 24 2 16631 16607 1 9785 0 3 1 9791 9786 1 3116 0 6 1 3123 3117 1 13825 1 33 0 13859 13826 1 10957 0 14 0 10971 10957 1
chrM 3011 3012 G 75871 4 113 2 75990 75877 1 53124 4 84 4 53216 53132 1 8422 0 67 1 8491 8423 1 6613 2 7 0 6622 6615 1 22042 1 37 2 22082 22045 1 28451 4 43 4 28502 28459 1 18438 2 12 12 18464 18452 1 9704 1 10 2 9718 9707 1 37763 2 132 2 37899 37767 1 33885 3 62 3 33953 33891 1
chrM 3434 3435 A 38932 0 22 0 38954 22 0 28983 0 13 0 28996 13 0 1994 0 37 0 2031 37 2 1889 0 5 0 1894 5 0 10426 0 4 0 10430 4 0 10332 0 8 0 10340 8 0 5307 1 4 0 5312 5 0 1790 0 2 1 1793 3 0 25278 0 103 0 25381 103 0 14218 0 17 0 14235 17 0
chrM 3480 3481 A 22066 0 45 1 22112 46 0 17217 1 20 0 17238 21 0 1704 0 37 0 1741 37 2 1732 0 3 0 1735 3 0 6049 2 6 1 6058 9 0 5498 1 6 0 5505 7 0 4669 0 7 0 4676 7 0 1589 0 0 0 1589 0 0 14664 0 95 0 14759 95 0 8272 0 21 1 8294 22 0
chrM 5063 5064 T 3 91 5 79483 79582 99 0 4 59 3 59163 59229 66 0 0 45 0 2293 2338 45 2 1 46 0 2247 2294 47 2 0 16 1 20733 20750 17 0 0 22 0 20220 20242 22 0 2 4 0 5222 5228 6 0 0 5 0 2068 2073 5 0 4 31 2 49253 49290 37 0 2 37 2 28632 28673 41 0
chrM 5580 5581 C 2 13 1 12180 12196 12183 1 0 10 0 8677 8687 8677 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 0 3115 3119 3116 1 0 1 0 2806 2807 2806 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 5995 6001 5995 1 0 6 0 3799 3805 3799 1
chrM 7028 7029 T 8 5269 1 105 5383 5278 2 4 3685 2 55 3746 3691 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1562 0 51 1614 1563 2 1 1396 0 47 1444 1397 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3503 0 341 3847 3506 2 2 1928 0 67 1997 1930 2
chrM 8701 8702 G 65164 7 68 1 65240 65172 1 51607 3 70 1 51681 51611 1 3206 0 2 0 3208 3206 1 3036 0 8 0 3045 3036 1 18911 0 22 0 18933 18911 1 17348 1 21 1 17371 17350 1 7376 0 7 0 7384 7376 1 2752 0 6 0 2758 2752 1 44676 5 36 1 44718 44682 1 24266 1 33 3 24303 24270 1
chrM 8992 8993 C 6 32924 2 16918 49850 16926 2 9 20572 2 16675 37258 16686 2 0 1292 0 587 1879 587 2 0 1324 0 607 1931 607 2 1 9979 0 5030 15010 5031 2 2 9001 3 4879 13885 4884 2 1 2413 0 2171 4585 2172 2 1 828 0 604 1433 605 2 8 22642 1 10798 33449 10807 2 6 12485 0 5968 18459 5974 2
chrM 9377 9378 G 29155 4 68 3 29230 29162 1 22590 1 52 1 22644 22592 1 1311 0 5 0 1316 1311 1 1413 1 4 0 1418 1414 1 8996 0 18 0 9014 8996 1 8356 2 21 0 8379 8358 1 3699 0 5 0 3704 3699 1 1000 0 8 0 1008 1000 1 20883 0 37 1 20921 20884 1 10550 2 27 0 10579 10552 1
chrM 9540 9541 C 4 8 4 28819 28835 28827 1 0 9 1 22950 22960 22951 1 0 1 0 2325 2327 2325 1 0 3 0 2325 2328 2325 1 0 1 2 7816 7819 7818 1 0 2 0 7913 7915 7913 1 0 2 0 5783 5786 5783 1 0 0 0 2036 2036 2036 1 0 5 1 16604 16610 16605 1 0 4 1 11200 11205 11201 1
chrM 10398 10399 G 66134 2 150 8 66294 66144 1 48839 0 93 2 48934 48841 1 2035 0 43 0 2078 2035 2 2565 0 11 0 2576 2565 1 17496 0 24 2 17522 17498 1 16169 1 27 0 16197 16170 1 5940 0 4 1 5945 5941 1 2232 0 5 1 2238 2233 1 36668 4 232 2 36906 36674 1 22711 1 66 0 22778 22712 1
chrM 10550 10551 A 74049 6 63 2 74120 71 0 56316 0 47 0 56363 47 0 3414 0 62 0 3476 62 2 3268 0 3 0 3271 3 0 20413 0 20 1 20434 21 0 20500 1 23 0 20524 24 0 8413 0 4 3 8420 7 0 2905 1 0 0 2906 1 0 49435 3 246 1 49685 250 0 26154 0 39 0 26193 39 0
chrM 10819 10820 G 102048 8 109 0 102165 102056 1 98352 15 73 1 98441 98368 1 11816 1 8 1 11849 11818 1 17967 2 17 1 18020 17970 1 34660 5 38 0 34703 34665 1 45769 5 42 1 45817 45775 1 45832 2 18 6 45917 45840 1 21529 2 17 2 21603 21533 1 55823 7 41 1 55872 55831 1 41514 1 39 1 41555 41516 1
chrM 10873 10874 C 4 334 8 101706 102052 101718 1 6 306 5 110569 110886 110580 1 0 7 0 3345 3352 3345 1 0 8 1 3306 3315 3307 1 1 128 1 41600 41730 41602 1 3 130 3 51874 52010 51880 1 2 16 0 8571 8589 8573 1 0 11 0 3417 3428 3417 1 3 176 4 67437 67620 67444 1 2 92 1 39849 39944 39852 1
chrM 11017 11018 C 2 107 2 56456 56567 56460 1 0 81 1 47605 47687 47606 1 3 14 0 4468 4485 4471 1 5 28 0 8816 8849 8821 1 1 24 0 18568 18593 18569 1 0 28 2 21379 21409 21381 1 8 44 2 28099 28154 28109 1 2 40 5 12017 12064 12024 1 1 36 3 33901 33941 33905 1 1 39 0 20246 20286 20247 1
chrM 11299 11300 T 10 336 9 110226 110581 355 0 11 245 5 88175 88436 261 0 1 105 1 6018 6125 107 2 0 26 0 6381 6407 26 0 3 90 3 34717 34813 96 0 5 122 0 43156 43283 127 0 2 55 0 16730 16787 57 0 1 31 0 8903 8935 32 0 8 365 7 62861 63241 380 0 5 134 6 39079 39224 145 0
chrM 11719 11720 A 99 2 39249 3 39353 39254 1 62 4 34101 8 34175 34113 1 1 0 1332 0 1333 1332 1 1 0 1821 1 1823 1822 1 26 0 14441 0 14467 14441 1 33 0 20179 2 20214 20181 1 4 0 5059 1 5064 5060 1 2 0 1607 0 1609 1607 1 58 3 17478 1 17540 17482 1 30 0 15111 1 15142 15112 1
chrM 11722 11723 C 1 35 0 41858 41894 41859 1 1 29 0 36410 36440 36411 1 0 3 0 1385 1388 1385 1 0 2 0 1935 1937 1935 1 0 6 0 15395 15401 15395 1 0 15 0 21603 21618 21603 1 0 6 2 5159 5167 5161 1 1 2 1 1664 1668 1666 1 0 7 0 18965 18972 18965 1 0 13 1 16136 16150 16137 1
chrM 12705 12706 T 10 75459 0 22 75491 75469 1 10 65631 1 17 65659 65642 1 0 3062 1 0 3063 3063 1 1 4062 0 1 4065 4063 1 3 25753 0 7 25763 25756 1 5 37515 0 12 37532 37520 1 0 11340 0 9 11349 11340 1 0 4052 0 1 4053 4052 1 8 34266 0 3 34277 34274 1 8 27100 0 7 27115 27108 1
chrM 12850 12851 G 46567 1 36 1 46605 46569 1 40398 2 31 0 40431 40400 1 1317 0 0 0 1317 1317 1 1893 0 3 0 1896 1893 1 16848 2 4 0 16854 16850 1 24019 1 20 0 24040 24020 1 4794 0 7 0 4801 4794 1 1550 0 1 0 1551 1550 1 21752 0 13 0 21765 21752 1 17627 0 18 0 17645 17627 1
chrM 14053 14054 A 26124 15 101 4 26244 120 0 26956 4 63 3 27026 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8438 5 15 3 8461 23 0 13898 4 45 3 13950 52 0 687 1 9 2 699 12 1 0 0 0 0 0 0 0 9397 4 23 0 9424 27 0 9886 4 25 0 9915 29 0
chrM 14212 14213 C 2 41 1 56177 56221 56180 1 1 28 1 51914 51944 51916 1 1 2 0 1716 1719 1717 1 0 2 0 2198 2200 2198 1 0 2 2 19614 19618 19616 1 1 23 1 29488 29513 29490 1 1 3 0 6082 6087 6083 1 0 0 0 2066 2066 2066 1 0 9 0 28450 28459 28450 1 0 17 0 21138 21155 21138 1
chrM 14580 14581 G 45013 2 25 1 45041 45016 1 41510 2 24 0 41536 41512 1 2618 0 0 0 2618 2618 1 3842 0 2 2 3846 3844 1 15738 1 8 0 15747 15739 1 23187 1 22 1 23211 23189 1 9996 0 4 1 10001 9997 1 4043 0 1 0 4044 4043 1 19632 1 3 0 19636 19633 1 16565 0 16 0 16581 16565 1
chrM 14766 14767 T 6 46856 3 61 46926 46865 1 6 43558 2 35 43601 43566 1 0 2111 0 2 2113 2111 1 0 3170 0 1 3171 3170 1 2 17178 1 17 17198 17181 1 4 23031 1 30 23066 23036 1 3 8510 0 7 8520 8513 1 1 3048 0 6 3055 3049 1 1 20274 0 51 20326 20275 1 2 17619 0 37 17658 17621 1
chrM 14905 14906 A 15 1 39481 7 39504 39489 1 10 0 35463 9 35482 35472 1 1 0 2479 0 2480 2479 1 0 0 3393 0 3393 3393 1 5 1 15201 0 15207 15202 1 5 1 22237 5 22248 22243 1 1 1 9729 2 9733 9732 1 2 0 3152 0 3154 3152 1 9 0 19057 3 19069 19060 1 4 0 14805 2 14811 14807 1
chrM 15301 15302 A 19 3 46253 2 46277 46258 1 15 0 40199 2 40216 40201 1 0 0 3325 0 3325 3325 1 0 0 4466 0 4466 4466 1 7 1 16415 1 16424 16417 1 6 0 22924 3 22933 22927 1 8 0 12264 5 12277 12269 1 0 0 4301 1 4302 4302 1 5 1 22130 2 22138 22133 1 7 0 18198 0 18205 18198 1
chrM 15932 15933 C 6 15 3 59133 59157 59142 1 0 20 2 54009 54031 54011 1 0 0 0 3323 3323 3323 1 0 6 0 5061 5067 5061 1 0 8 0 21128 21136 21128 1 1 24 0 32868 32893 32869 1 2 3 0 13485 13492 13487 1 0 3 1 5238 5242 5239 1 2 3 0 20445 20450 20447 1 1 14 0 20645 20660 20646 1
chrM 16172 16173 C 4 26 0 10165 10195 10169 1 2 8 0 9289 9299 9291 1 0 15 0 1380 1395 1380 1 0 5 0 1429 1434 1429 1 0 0 1 3986 3987 3987 1 0 2 1 5510 5513 5511 1 0 8 0 4092 4100 4092 1 0 3 0 1404 1407 1404 1 0 3 0 4706 4709 4706 1 0 10 0 3883 3893 3883 1
chrM 16183 16184 C 2687 5 2 0 2694 2689 1 2563 4 1 0 2568 2564 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1174 2 0 0 1176 1174 1 1520 4 0 0 1524 1520 1 477 3 0 1 698 478 1 0 0 0 0 0 0 0 1174 1 0 0 1175 1174 1 1133 1 0 0 1134 1133 1
chrM 16184 16185 C 0 2210 0 0 2210 0 0 0 2051 0 0 2051 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 888 0 0 888 0 0 0 1181 0 0 1181 0 0 306 663 2 0 972 308 2 0 0 0 0 0 0 0 0 924 0 0 924 0 0 0 914 0 0 914 0 0
chrM 16189 16190 C 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 987 0 26 1013 26 2 0 1079 0 39 1118 39 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2974 0 98 3072 98 2 0 998 0 36 1034 36 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0
chrM 16190 16191 C 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 0 931 980 931 2 0 61 0 1080 1141 1080 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 188 0 2842 3030 2842 2 0 55 0 951 1006 951 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0
chrM 16224 16225 T 4 17135 0 11 17150 17139 1 1 14988 0 0 14989 14989 1 0 1957 0 0 1957 1957 1 0 2510 0 2 2513 2510 1 0 6840 0 1 6841 6840 1 2 8277 0 9 8288 8279 1 1 6934 0 3 6938 6935 1 0 2431 1 0 2432 2432 1 1 8744 0 2 8747 8745 1 2 6450 1 3 6456 6453 1
chrM 16240 16241 C 1 48 1 22188 22238 22190 1 0 26 1 19721 19748 19722 1 0 3 0 2305 2308 2305 1 0 5 0 3050 3055 3050 1 0 11 2 8824 8837 8826 1 0 26 0 10813 10839 10813 1 1 7 0 8378 8387 8379 1 0 5 0 2884 2889 2884 1 1 26 0 11620 11647 11621 1 0 9 0 8493 8502 8493 1
chrM 16321 16322 T 4 55783 1 23 55811 55788 1 4 48176 0 16 48196 48180 1 0 4551 1 2 4554 4552 1 0 4846 0 3 4849 4846 1 3 20330 0 11 20344 20333 1 4 27565 0 12 27581 27569 1 2 14910 0 3 14916 14912 1 0 5105 0 2 5108 5105 1 1 26605 0 10 26616 26606 1 5 21141 0 8 21154 21146 1
1
0

galaxy-dist commit ad9bb65d2d15: mutation viz tool help cleanup
by commits-noreply@bitbucket.org 20 Nov '10
by commits-noreply@bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1287520820 14400
# Node ID ad9bb65d2d153af5db0ae497930eb35d17f63057
# Parent 35b379691524c768ec84f86477f1ab49859afec2
mutation viz tool help cleanup
--- a/tools/mutation/visualize.xml
+++ b/tools/mutation/visualize.xml
@@ -20,7 +20,7 @@
<repeat name="sample_chooser" title="Sample"><param name="name" type="text" label="Label" help="Optional" />
- <param name="a_col" type="data_column" data_ref="input1" multiple="false" numerical="false" label="A Column" help="" />
+ <param name="a_col" type="data_column" data_ref="input1" multiple="false" numerical="false" label="Base A Column" help="" /><param name="totals_col" type="data_column" data_ref="input1" multiple="false" numerical="false" label="Totals Column" help="" /></repeat>
@@ -60,27 +60,42 @@
</test></tests><help>
-
-**Example**
+**What it does**
This tool allows you to visualize mutations described in a tabular input file. It generates an SVG image which can be viewed in any web browser.
+You will need to specify the position and reference columns in the input file. Then click on the 'Add new Sample' to add samples in the input file that you would like to visualize. For each sample you select, specify the column for base 'A', the totals column and enter a name.
+This tool assumes the columns specifying bases A, C, G, T are placed consecutively and in that order in an input file.
+
+Interactivity: If interactive zoom option is selected, then the resultant image can be zoomed in or out using the scroll mouse wheel and can be panned by dragging the image using left mouse button.
+
+-----
+
+**General Example**
+
Given the input file::
- gm blood gm cheek
chrM 72 73 G 26394 4 49 0 26447 26398 1 23389 3 45 0 23437 23392 1
chrM 149 150 T 11 50422 2 96 50531 50435 1 4 45417 1 65 45487 45422 1
-You will need to specify the position and reference columns in the input file. Then click on the 'Add new Sample' to add samples in the input file that you would like to visualize. For each sample you select, specify the column for base 'A' and the totals column.
-This tool assumes the columns specifying bases A, C, G, T are placed consecutively and in that order in an input file.
+To visualize the two samples in the input file, the following parameters are selected before running the tool::
+
+ Position column: 2
+ Reference Base column: 4
+ Sample 1 Label: gm blood
+ Sample 1 Base A column: 5
+ Sample 1 Totals column: 9
+ Sample 2 Label: gm cheek
+ Sample 2 Base A column: 12
+ Sample 2 Totals column: 16
-Visualization:
+Visualization output:
.. image:: ../static/images/mutation_visualization_example.png
:width: 150
-Interactivity::
- If interactive zoom option is selected, then the resultant image can be zoomed in or out using the scroll mouse wheel and can be panned by dragging the image using left mouse button.
+Here the left-most column represents the position and the background color is the reference base color. Each column on its right describe each sample.
+In the output above, the blue bar is the longest, which means that base A is maximum in position 72 for both the samples.
</help></tool>
1
0

20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1287147090 14400
# Node ID d4b85e30e56d605edc2236ccba5cde41bda1510a
# Parent fb2a31820ccff6f02bb24a0632f214bfef0a8b0a
sample tracking
- create request search+select box bug fixed.
- sample datasets grid operations fixed
--- a/templates/requests/common/sample_datasets.mako
+++ b/templates/requests/common/sample_datasets.mako
@@ -1,5 +1,5 @@
<%def name="render_sample_datasets( sample )">
- ${len( sample.transferred_dataset_files )}/${len( sample.datasets )}
+ ${len( sample.transferred_dataset_files )} / ${len( sample.datasets )}
</%def>
${render_sample_datasets( sample )}
--- a/templates/requests/common/create_request.mako
+++ b/templates/requests/common/create_request.mako
@@ -21,7 +21,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Create a new request</div>
+ <div class="toolFormTitle">Create a new sequencing request</div>
%if len( request_type_select_field.options ) == 1:
There are no sequencer configurations available for ${trans.user.email} to create sequencing requests.
%else:
--- a/templates/admin/requests/get_data.mako
+++ b/templates/admin/requests/get_data.mako
@@ -104,7 +104,9 @@
<option value="${f}">${f}</option>
%endfor
</select>
- <br/>
+ </div>
+ <div class="form-row">
+ <div id="file_details" class="toolParamHelp" style="clear: both;background-color:#FAFAFA;"></div></div><div class="form-row"><input type="submit" name="select_show_datasets_button" value="Select & show datasets"/>
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -140,9 +140,20 @@ class RequestsCommon( BaseController, Us
request_type = None
# user_id will not be 'none' if an admin user is submitting this request on behalf of another user
# and they selected that user's id from the user_id SelectField.
+ user_id_encoded = True
user_id = params.get( 'user_id', 'none' )
if user_id != 'none':
- user = trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( user_id ) )
+ try:
+ user = trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( user_id ) )
+ except TypeError, e:
+ # We must have an email address rather than an encoded user id
+ # This is because the galaxy.base.js creates a search+select box
+ # when there are more than 20 items in a selectfield
+ user = trans.sa_session.query( trans.model.User ) \
+ .filter( trans.model.User.table.c.email==util.restore_text( user_id ) ) \
+ .first()
+ user_id_encoded = False
+
elif not is_admin:
user = trans.user
else:
@@ -152,6 +163,9 @@ class RequestsCommon( BaseController, Us
if is_admin and user_id == 'none':
message = 'Select the user on behalf of whom you are submitting this request.'
status = 'error'
+ elif user is None:
+ message = 'Invalid user ID (%s)' % str(user_id)
+ status = 'error'
elif not name:
message = 'Enter the name of the request.'
status = 'error'
@@ -170,10 +184,6 @@ class RequestsCommon( BaseController, Us
widgets = []
if request_type is not None or status == 'error':
# Either the user selected a request_type or an error exists on the form.
- if is_admin:
- widgets.append( dict( label='Select user',
- widget=self.__build_user_id_select_field( trans, selected_value=user_id ),
- helptext='Submit the request on behalf of the selected user (Required)'))
widgets.append( dict( label='Name of the Experiment',
widget=TextField( 'name', 40, util.restore_text( params.get( 'name', '' ) ) ),
helptext='(Required)') )
@@ -182,9 +192,20 @@ class RequestsCommon( BaseController, Us
helptext='(Optional)') )
if request_type is not None:
widgets += request_type.request_form.get_widgets( user, **kwd )
- # In case there is an error on the form, make sure to populate widget fields with anything the user
- # may have already entered.
- self.populate_widgets_from_kwd( trans, widgets, **kwd )
+ # In case there is an error on the form, make sure to populate widget fields with anything the user
+ # may have already entered.
+ self.populate_widgets_from_kwd( trans, widgets, **kwd )
+ if request_type is not None or status == 'error':
+ # Either the user selected a request_type or an error exists on the form.
+ if is_admin:
+ if not user_id_encoded:
+ selected_user_id = trans.security.encode_id( user.id )
+ else:
+ selected_user_id = user_id
+ user_widget = dict( label='Select user',
+ widget=self.__build_user_id_select_field( trans, selected_value=selected_user_id ),
+ helptext='Submit the request on behalf of the selected user (Required)')
+ widgets = [ user_widget ] + widgets
return trans.fill_template( '/requests/common/create_request.mako',
cntrller=cntrller,
request_type_select_field=request_type_select_field,
@@ -873,7 +894,7 @@ class RequestsCommon( BaseController, Us
# Build the library_select_field and folder_select_field for the new sample being added.
library_select_field, folder_select_field = self.__build_library_and_folder_select_fields( trans,
user=request.user,
- sample_index=sample_index,
+ sample_index=len( current_samples ),
libraries=libraries,
sample=None,
library_id=library_id,
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -184,23 +184,6 @@ class RequestsAdmin( BaseController, Use
**kwd ) )
# Render the list view
return self.request_grid( trans, **kwd )
- @web.json
- def get_file_details( self, trans, id, folder_path ):
- def print_ticks( d ):
- # pexpect timeout method
- pass
- # Avoid caching
- trans.response.headers['Pragma'] = 'no-cache'
- trans.response.headers['Expires'] = '0'
- request = trans.sa_session.query( trans.model.Request ).get( int( id ) )
- datatx_info = request.type.datatx_info
- cmd = 'ssh %s@%s "ls -oghp \'%s\'"' % ( datatx_info['username'],
- datatx_info['host'],
- folder_path )
- output = pexpect.run( cmd,
- events={ '.ssword:*' : datatx_info[ 'password'] + '\r\n', pexpect.TIMEOUT : print_ticks },
- timeout=10 )
- return unicode( output.replace( '\n', '<br/>' ) )
@web.expose
@web.require_admin
def reject( self, trans, **kwd ):
@@ -244,11 +227,6 @@ class RequestsAdmin( BaseController, Use
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
- sample_id = params.get( 'sample_id', None )
- try:
- sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id ( sample_id ) )
- except:
- return invalid_id_redirect( trans, 'requests_admin', sample_id )
if 'operation' in kwd:
operation = kwd[ 'operation' ].lower()
sample_dataset_id = params.get( 'id', None )
@@ -268,7 +246,9 @@ class RequestsAdmin( BaseController, Use
not_deleted = []
for sample_dataset in selected_sample_datasets:
# Make sure the dataset has been transferred before deleting it.
- if sample_dataset in sample.untransferred_dataset_files:
+ if sample_dataset in sample_dataset.sample.untransferred_dataset_files:
+ # save the sample to which these datasets belong to
+ sample = sample_dataset.sample
trans.sa_session.delete( sample_dataset )
trans.sa_session.flush()
else:
@@ -279,7 +259,7 @@ class RequestsAdmin( BaseController, Use
message = message + ' %s could not be deleted because their transfer status is not "Not Started". ' % str( not_deleted )
return trans.response.send_redirect( web.url_for( controller='requests_admin',
action='manage_datasets',
- sample_id=sample_id,
+ sample_id=trans.security.encode_id( sample.id ),
status=status,
message=message ) )
elif operation == "rename":
@@ -288,7 +268,7 @@ class RequestsAdmin( BaseController, Use
# has not yet been transferred.
no_datasets_transferred = True
for selected_sample_dataset in selected_sample_datasets:
- if selected_sample_dataset in sample.untransferred_dataset_files:
+ if selected_sample_dataset in selected_sample_dataset.sample.untransferred_dataset_files:
no_datasets_transferred = False
break
if no_datasets_transferred:
@@ -296,15 +276,20 @@ class RequestsAdmin( BaseController, Use
message = 'A dataset can be renamed only if it is in the "Not Started" state.'
return trans.response.send_redirect( web.url_for( controller='requests_admin',
action='manage_datasets',
- sample_id=sample_id,
+ sample_id=trans.security.encode_id( selected_sample_datasets[0].sample.id ),
status=status,
message=message ) )
return trans.fill_template( '/admin/requests/rename_datasets.mako',
- sample=sample,
+ sample=selected_sample_datasets[0].sample,
id_list=id_list )
elif operation == "start transfer":
- self.__start_datatx( trans, sample, selected_sample_datasets )
+ self.__start_datatx( trans, selected_sample_datasets[0].sample, selected_sample_datasets )
# Render the grid view
+ sample_id = params.get( 'sample_id', None )
+ try:
+ sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id ( sample_id ) )
+ except:
+ return invalid_id_redirect( trans, 'requests_admin', sample_id )
request_id = trans.security.encode_id( sample.request.id )
library_id = trans.security.encode_id( sample.library.id )
self.datatx_grid.title = 'Datasets of sample "%s"' % sample.name
@@ -395,6 +380,10 @@ class RequestsAdmin( BaseController, Use
if folder_path[-1] == os.sep:
folder_path = os.path.dirname( folder_path[:-1] )
folder_path = self.__check_path( folder_path )
+ elif params.get( 'open_folder', False ):
+ if len(selected_files) == 1:
+ folder_path = os.path.join(folder_path, selected_files[0])
+ folder_path = self.__check_path( folder_path )
elif params.get( 'select_show_datasets_button', False ) or params.get( 'select_more_button', False ):
# get the sample these datasets are associated with
try:
@@ -443,8 +432,26 @@ class RequestsAdmin( BaseController, Use
status=status,
message=message )
@web.json
+ def get_file_details( self, trans, id, folder_path ):
+ def print_ticks( d ):
+ # pexpect timeout method
+ pass
+ # Avoid caching
+ trans.response.headers['Pragma'] = 'no-cache'
+ trans.response.headers['Expires'] = '0'
+ request = trans.sa_session.query( trans.model.Request ).get( int( id ) )
+ datatx_info = request.type.datatx_info
+ cmd = 'ssh %s@%s "ls -oghp \'%s\'"' % ( datatx_info['username'],
+ datatx_info['host'],
+ folder_path )
+ output = pexpect.run( cmd,
+ events={ '.ssword:*' : datatx_info[ 'password'] + '\r\n', pexpect.TIMEOUT : print_ticks },
+ timeout=10 )
+ return unicode( output.replace( '\n', '<br/>' ) )
+ @web.json
def open_folder( self, trans, id, folder_path ):
def print_ticks( d ):
+ # pexpect timeout method
pass
# Avoid caching
trans.response.headers['Pragma'] = 'no-cache'
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -340,8 +340,7 @@ class UsesFormDefinitionWidgets:
widget_dict[ 'widget' ] = widget
else:
# An existing address object was selected
- address_obj = trans.sa_session.query( trans.app.model.UserAddress ).get( int( value ) )
- widget_dict[ 'widget' ] = address_obj
+ widget_dict[ 'widget' ] = widget
# Populate the AddressField params with the form field contents
widget_params_dict = {}
for field_name, label, help_text in widget.fields():
1
0