galaxy-commits
Threads by month
- ----- 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
February 2014
- 1 participants
- 192 discussions
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/fa8bdf1f6fc7/
Changeset: fa8bdf1f6fc7
Branch: stable
User: inithello
Date: 2014-02-14 21:59:35
Summary: Also check for tool config path when installing migrated tools and rewriting the tool_conf.xml. This resolves the issue described in pull request 324.
Affected #: 1 file
diff -r 75672e1cba2bd569b729156f3d8f8f1f994240f0 -r fa8bdf1f6fc7318d120a3420c50e4045dbdb1e8b lib/tool_shed/galaxy_install/install_manager.py
--- a/lib/tool_shed/galaxy_install/install_manager.py
+++ b/lib/tool_shed/galaxy_install/install_manager.py
@@ -197,8 +197,7 @@
file_path = section_elem.get( 'file', None )
if file_path:
file_name = suc.strip_path( file_path )
-
- if file_name in tool_configs_to_filter:
+ if file_name in tool_configs_to_filter or file_path in tool_configs_to_filter:
elem.remove( section_elem )
persist_required = True
if persist_required:
@@ -223,7 +222,7 @@
# The proprietary_tool_panel_elem looks something like <tool file="emboss_5/emboss_antigenic.xml" />.
proprietary_tool_config = proprietary_tool_panel_elem.get( 'file' )
proprietary_name = suc.strip_path( proprietary_tool_config )
- if tool_config == proprietary_name:
+ if tool_config == proprietary_name or tool_config == proprietary_tool_config:
# The tool is loaded outside of any sections.
tool_sections.append( None )
if not is_displayed:
@@ -235,7 +234,7 @@
# The section_elem looks something like <tool file="emboss_5/emboss_antigenic.xml" />.
proprietary_tool_config = section_elem.get( 'file' )
proprietary_name = suc.strip_path( proprietary_tool_config )
- if tool_config == proprietary_name:
+ if tool_config == proprietary_name or tool_config == proprietary_tool_config:
# The tool is loaded inside of the section_elem.
tool_sections.append( ToolSection( proprietary_tool_panel_elem ) )
if not is_displayed:
@@ -314,7 +313,7 @@
file_path = elem.get( 'file', None )
if file_path:
name = suc.strip_path( file_path )
- if name in migrated_tool_configs:
+ if name in migrated_tool_configs or file_path in migrated_tool_configs:
if elem not in tool_panel_elems:
tool_panel_elems.append( elem )
elif elem.tag == 'section':
@@ -324,7 +323,7 @@
file_path = section_elem.get( 'file', None )
if file_path:
name = suc.strip_path( file_path )
- if name in migrated_tool_configs:
+ if name in migrated_tool_configs or file_path in migrated_tool_configs:
# Append the section, not the tool.
if elem not in tool_panel_elems:
tool_panel_elems.append( elem )
https://bitbucket.org/galaxy/galaxy-central/commits/5079dae08441/
Changeset: 5079dae08441
User: inithello
Date: 2014-02-14 22:00:00
Summary: Merge bugfix from stable.
Affected #: 1 file
diff -r 479b72075bc8a68ec602081987375ca1dfa20a2f -r 5079dae08441dcf125cc9fee87b28aaba7a38f9d lib/tool_shed/galaxy_install/install_manager.py
--- a/lib/tool_shed/galaxy_install/install_manager.py
+++ b/lib/tool_shed/galaxy_install/install_manager.py
@@ -197,8 +197,7 @@
file_path = section_elem.get( 'file', None )
if file_path:
file_name = suc.strip_path( file_path )
-
- if file_name in tool_configs_to_filter:
+ if file_name in tool_configs_to_filter or file_path in tool_configs_to_filter:
elem.remove( section_elem )
persist_required = True
if persist_required:
@@ -223,7 +222,7 @@
# The proprietary_tool_panel_elem looks something like <tool file="emboss_5/emboss_antigenic.xml" />.
proprietary_tool_config = proprietary_tool_panel_elem.get( 'file' )
proprietary_name = suc.strip_path( proprietary_tool_config )
- if tool_config == proprietary_name:
+ if tool_config == proprietary_name or tool_config == proprietary_tool_config:
# The tool is loaded outside of any sections.
tool_sections.append( None )
if not is_displayed:
@@ -235,7 +234,7 @@
# The section_elem looks something like <tool file="emboss_5/emboss_antigenic.xml" />.
proprietary_tool_config = section_elem.get( 'file' )
proprietary_name = suc.strip_path( proprietary_tool_config )
- if tool_config == proprietary_name:
+ if tool_config == proprietary_name or tool_config == proprietary_tool_config:
# The tool is loaded inside of the section_elem.
tool_sections.append( ToolSection( proprietary_tool_panel_elem ) )
if not is_displayed:
@@ -314,7 +313,7 @@
file_path = elem.get( 'file', None )
if file_path:
name = suc.strip_path( file_path )
- if name in migrated_tool_configs:
+ if name in migrated_tool_configs or file_path in migrated_tool_configs:
if elem not in tool_panel_elems:
tool_panel_elems.append( elem )
elif elem.tag == 'section':
@@ -324,7 +323,7 @@
file_path = section_elem.get( 'file', None )
if file_path:
name = suc.strip_path( file_path )
- if name in migrated_tool_configs:
+ if name in migrated_tool_configs or file_path in migrated_tool_configs:
# Append the section, not the tool.
if elem not in tool_panel_elems:
tool_panel_elems.append( elem )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Scatterplot: small style fixes
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/479b72075bc8/
Changeset: 479b72075bc8
User: carlfeberhard
Date: 2014-02-14 21:34:27
Summary: Scatterplot: small style fixes
Affected #: 5 files
diff -r 8494c2b3a3edff7f900a9994ccd806d063d5010f -r 479b72075bc8a68ec602081987375ca1dfa20a2f config/plugins/visualizations/scatterplot/src/scatterplot-display.js
--- a/config/plugins/visualizations/scatterplot/src/scatterplot-display.js
+++ b/config/plugins/visualizations/scatterplot/src/scatterplot-display.js
@@ -53,14 +53,14 @@
template : function(){
var html = [
'<div class="controls clear">',
- '<div class="left">',
- '<div class="page-control"></div>',
- '</div>',
'<div class="right">',
'<p class="scatterplot-data-info"></p>',
'<button class="stats-toggle-btn">Stats</button>',
'<button class="rerender-btn">Redraw</button>',
'</div>',
+ '<div class="left">',
+ '<div class="page-control"></div>',
+ '</div>',
'</div>',
'<svg/>', //TODO: id
'<div class="stats-display"></div>'
diff -r 8494c2b3a3edff7f900a9994ccd806d063d5010f -r 479b72075bc8a68ec602081987375ca1dfa20a2f config/plugins/visualizations/scatterplot/static/scatterplot-edit.js
--- a/config/plugins/visualizations/scatterplot/static/scatterplot-edit.js
+++ b/config/plugins/visualizations/scatterplot/static/scatterplot-edit.js
@@ -1,1 +1,1 @@
-function scatterplot(a,b,c){function d(){var a={v:{},h:{}};return a.v.lines=p.selectAll("line.v-grid-line").data(m.x.ticks(q.x.fn.ticks()[0])),a.v.lines.enter().append("svg:line").classed("grid-line v-grid-line",!0),a.v.lines.attr("x1",m.x).attr("x2",m.x).attr("y1",0).attr("y2",b.height),a.v.lines.exit().remove(),a.h.lines=p.selectAll("line.h-grid-line").data(m.y.ticks(q.y.fn.ticks()[0])),a.h.lines.enter().append("svg:line").classed("grid-line h-grid-line",!0),a.h.lines.attr("x1",0).attr("x2",b.width).attr("y1",m.y).attr("y2",m.y),a.h.lines.exit().remove(),a}function e(){return t.attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).style("display","block").filter(function(){var a=d3.select(this).attr("cx"),c=d3.select(this).attr("cy");return 0>a||a>b.width?!0:0>c||c>b.height?!0:!1}).style("display","none")}function f(){$(".chart-info-box").remove(),q.redraw(),e(),s=d(),$(o.node()).trigger("zoom.scatterplot",{scale:n.scale(),translate:n.translate()})}function g(a,c,d){return c+=8,$(['<div class="chart-info-box" style="position: absolute">',void 0!==b.idColumn?"<div>"+d[b.idColumn]+"</div>":"","<div>",j(d),"</div>","<div>",k(d),"</div>","</div>"].join("")).css({top:a,left:c,"z-index":2})}var h=function(a,b){return"translate("+a+","+b+")"},i=function(a,b,c){return"rotate("+a+","+b+","+c+")"},j=function(a){return a[b.xColumn]},k=function(a){return a[b.yColumn]},l={x:{extent:d3.extent(c,j)},y:{extent:d3.extent(c,k)}},m={x:d3.scale.linear().domain(l.x.extent).range([0,b.width]),y:d3.scale.linear().domain(l.y.extent).range([b.height,0])},n=d3.behavior.zoom().x(m.x).y(m.y).scaleExtent([1,30]).scale(b.scale||1).translate(b.translate||[0,0]),o=d3.select(a).attr("class","scatterplot").attr("width","100%").attr("height",b.height+(b.margin.top+b.margin.bottom)),p=o.append("g").attr("class","content").attr("transform",h(b.margin.left,b.margin.top)).call(n);p.append("rect").attr("class","zoom-rect").attr("width",b.width).attr("height",b.height).style("fill","transparent");var q={x:{},y:{}};q.x.fn=d3.svg.axis().orient("bottom").scale(m.x).ticks(b.x.ticks).tickFormat(d3.format("s")),q.y.fn=d3.svg.axis().orient("left").scale(m.y).ticks(b.y.ticks).tickFormat(d3.format("s")),q.x.g=p.append("g").attr("class","x axis").attr("transform",h(0,b.height)).call(q.x.fn),q.y.g=p.append("g").attr("class","y axis").call(q.y.fn);var r=6;q.x.label=o.append("text").attr("class","axis-label").text(b.x.label).attr("text-anchor","middle").attr("dominant-baseline","text-after-edge").attr("x",b.width/2+b.margin.left).attr("y",b.height+b.margin.bottom+b.margin.top-r),q.y.label=o.append("text").attr("class","axis-label").text(b.y.label).attr("text-anchor","middle").attr("dominant-baseline","text-before-edge").attr("x",r).attr("y",b.height/2).attr("transform",i(-90,r,b.height/2)),q.redraw=function(){o.select(".x.axis").call(q.x.fn),o.select(".y.axis").call(q.y.fn)};var s=d(),t=p.selectAll(".glyph").data(c).enter().append("svg:circle").classed("glyph",!0).attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).attr("r",0);t.transition().duration(b.animDuration).attr("r",b.datapointSize),e(),n.on("zoom",f),t.on("mouseover",function(a,c){var d=d3.select(this);d.classed("highlight",!0).style("fill","red").style("fill-opacity",1),p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")-b.datapointSize).attr("y1",d.attr("cy")).attr("x2",0).attr("y2",d.attr("cy")).classed("hoverline",!0),d.attr("cy")<b.height&&p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")).attr("y1",+d.attr("cy")+b.datapointSize).attr("x2",d.attr("cx")).attr("y2",b.height).classed("hoverline",!0);var e=this.getBoundingClientRect();$("body").append(g(e.top,e.right,a)),$(o.node()).trigger("mouseover-datapoint.scatterplot",[this,a,c])}),t.on("mouseout",function(){d3.select(this).classed("highlight",!1).style("fill","black").style("fill-opacity",.2),p.selectAll(".hoverline").remove(),$(".chart-info-box").remove()})}this.scatterplot=this.scatterplot||{},this.scatterplot.chartcontrol=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f,g="",h="function",i=this.escapeExpression;return g+='<p class="help-text">\n Use the following controls to how the chart is displayed.\n The slide controls can be moved by the mouse or, if the \'handle\' is in focus, your keyboard\'s arrow keys.\n Move the focus between controls by using the tab or shift+tab keys on your keyboard.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n<div data-config-key="datapointSize" class="form-input numeric-slider-input">\n <label for="datapointSize">Size of data point: </label>\n <div class="slider-output">',(f=c.datapointSize)?f=f.call(b,{hash:{},data:e}):(f=b.datapointSize,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n Size of the graphic representation of each data point\n </p>\n</div>\n\n<div data-config-key="width" class="form-input numeric-slider-input">\n <label for="width">Chart width: </label>\n <div class="slider-output">',(f=c.width)?f=f.call(b,{hash:{},data:e}):(f=b.width,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="height" class="form-input numeric-slider-input">\n <label for="height">Chart height: </label>\n <div class="slider-output">',(f=c.height)?f=f.call(b,{hash:{},data:e}):(f=b.height,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="X-axis-label"class="text-input form-input">\n <label for="X-axis-label">Re-label the X axis: </label>\n <input type="text" name="X-axis-label" id="X-axis-label" value="'+i((f=b.x,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<div data-config-key="Y-axis-label" class="text-input form-input">\n <label for="Y-axis-label">Re-label the Y axis: </label>\n <input type="text" name="Y-axis-label" id="Y-axis-label" value="'+i((f=b.y,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.datacontrol=Handlebars.template(function(a,b,c,d,e){function f(a,b){var d,e="";return e+='\n <option value="',(d=c.index)?d=d.call(a,{hash:{},data:b}):(d=a.index,d=typeof d===j?d.apply(a):d),e+=k(d)+'">',(d=c.name)?d=d.call(a,{hash:{},data:b}):(d=a.name,d=typeof d===j?d.apply(a):d),e+=k(d)+"</option>\n "}function g(){return'checked="true"'}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var h,i="",j="function",k=this.escapeExpression,l=this;return i+='<p class="help-text">\n Use the following controls to change the data used by the chart.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n\n<div class="column-select">\n <label>Data column for X: </label>\n <select name="xColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n<div class="column-select">\n <label>Data column for Y: </label>\n <select name="yColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="include-id">\n <label for="include-id-checkbox">Include a third column as data point IDs?</label>\n <input type="checkbox" name="include-id" id="include-id-checkbox" />\n <p class="help-text-small">\n These will be displayed (along with the x and y values) when you hover over\n a data point.\n </p>\n</div>\n<div class="column-select" style="display: none">\n <label for="ID-select">Data column for IDs: </label>\n <select name="idColumn">\n ',h=c.each.call(b,b.allColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="first-line-header" style="display: none;">\n <p>Possible headers: ',(h=c.possibleHeaders)?h=h.call(b,{hash:{},data:e}):(h=b.possibleHeaders,h=typeof h===j?h.apply(b):h),i+=k(h)+'\n </p>\n <label for="first-line-header-checkbox">Use the above as column headers?</label>\n <input type="checkbox" name="include-id" id="first-line-header-checkbox"\n ',h=c["if"].call(b,b.usePossibleHeaders,{hash:{},inverse:l.noop,fn:l.program(3,g,e),data:e}),(h||0===h)&&(i+=h),i+='/>\n <p class="help-text-small">\n It looks like Galaxy couldn\'t get proper column headers for this data.\n Would you like to use the column headers above as column names to select columns?\n </p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.editor=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f="";return f+='<div class="scatterplot-editor tabbable tabs-left">\n \n <ul class="nav nav-tabs">\n \n <li class="active">\n <a title="Use this tab to change which data are used"\n href="#data-control" data-toggle="tab">Data Controls</a>\n </li>\n <li>\n <a title="Use this tab to change how the chart is drawn"\n href="#chart-control" data-toggle="tab" >Chart Controls</a>\n </li>\n \n <li class="disabled">\n <a title="This tab will display the chart"\n href="#chart-display" data-toggle="tab">Chart</a>\n </li>\n \n <li class="file-controls">\n<!-- <button class="copy-btn btn btn-default"\n title="Save this as a new visualization">Save to new</button>-->\n <button class="save-btn btn btn-default">Save</button>\n </li>\n </ul>\n\n \n <div class="tab-content">\n \n <div id="data-control" class="scatterplot-config-control tab-pane active">\n \n </div>\n \n \n <div id="chart-control" class="scatterplot-config-control tab-pane">\n \n </div>\n\n \n <div id="chart-display" class="scatterplot-display tab-pane"></div>\n\n </div>\n</div>\n'});var ScatterplotConfigEditor=Backbone.View.extend(LoggableMixin).extend({className:"scatterplot-control-form",initialize:function(a){if(this.model||(this.model=new Visualization({type:"scatterplot"})),this.log(this+".initialize, attributes:",a),!a||!a.dataset)throw new Error("ScatterplotConfigEditor requires a dataset");this.dataset=a.dataset,this.log("dataset:",this.dataset),this.display=new ScatterplotDisplay({dataset:a.dataset,model:this.model})},render:function(){this.$el.empty().append(ScatterplotConfigEditor.templates.mainLayout({})),this.model.id&&(this.$el.find(".copy-btn").show(),this.$el.find(".save-btn").text("Update saved")),this.$el.find("[title]").tooltip(),this._render_dataControl(),this._render_chartControls(),this._render_chartDisplay();var a=this.model.get("config");return this.model.id&&_.isFinite(a.xColumn)&&_.isFinite(a.yColumn)&&this.renderChart(),this},_render_dataControl:function(a){a=a||this.$el;var b=this,c=this.dataset,d=c.metadata_column_names||[],e=this.model.get("config"),f=[],g=_.map(c.metadata_column_types,function(a,b){var c={index:b,type:a,name:d[b]||"column "+(b+1)};return("int"===c.type||"float"===c.type)&&f.push(c),c});f.length<2&&(f=g);var h=a.find(".tab-pane#data-control");h.html(ScatterplotConfigEditor.templates.dataControl({allColumns:g,numericColumns:f}));var i={xColumn:_.isFinite(e.xColumn)?e.xColumn:f[0].index,yColumn:_.isFinite(e.yColumn)?e.yColumn:f[1].index,idColumn:g[0].index};if(_.isFinite(e.idColumn))i.idColumn=e.idColumn;else if(g.length>2){var j=_.find(g,function(a,b){return b!==i.xColumn&&b!==i.yColumn});i.idColumn=j.index}return e=this.model.set("config",i,{silent:!0}).get("config"),h.find('[name="xColumn"]').val(e.xColumn).on("change",function(){b.model.set("config",{xColumn:Number($(this).val())})}),h.find('[name="yColumn"]').val(e.yColumn).on("change",function(){b.model.set("config",{yColumn:Number($(this).val())})}),h.find('select[name="idColumn"]').val(e.idColumn).on("change",function(){b.model.set("config",{idColumn:Number($(this).val())})}),void 0!==e.idColumn&&h.find("#include-id-checkbox").prop("checked",!0).trigger("change"),h.find("[title]").tooltip(),h},_render_chartControls:function(a){function b(){var a=$(this),b=a.slider("value");c.model.set("config",_.object([[a.parent().data("config-key"),b]])),a.siblings(".slider-output").text(b)}a=a||this.$el;var c=this,d=this.model.get("config"),e=a.find("#chart-control");e.html(ScatterplotConfigEditor.templates.chartControl(d));var f={datapointSize:{min:2,max:10,step:1},width:{min:200,max:800,step:20},height:{min:200,max:800,step:20}};e.find(".numeric-slider-input").each(function(){var a=$(this),c=a.attr("data-config-key"),e=_.extend(f[c],{value:d[c],change:b,slide:b});a.find(".slider").slider(e),a.children(".slider-output").text(d[c])});var g=this.dataset.metadata_column_names||[],h=d.xLabel||g[d.xColumn]||"X",i=d.yLabel||g[d.yColumn]||"Y";return e.find('input[name="X-axis-label"]').val(h).on("change",function(){c.model.set("config",{xLabel:$(this).val()})}),e.find('input[name="Y-axis-label"]').val(i).on("change",function(){c.model.set("config",{yLabel:$(this).val()})}),e.find("[title]").tooltip(),e},_render_chartDisplay:function(a){a=a||this.$el;var b=a.find(".tab-pane#chart-display");return this.display.setElement(b),this.display.render(),b.find("[title]").tooltip(),b},events:{"change #include-id-checkbox":"toggleThirdColumnSelector","click #data-control .render-button":"renderChart","click #chart-control .render-button":"renderChart","click .save-btn":"saveVisualization"},saveVisualization:function(){var a=this;this.model.save().fail(function(b,c,d){console.error(b,c,d),a.trigger("save:error",view),alert("Error loading data:\n"+b.responseText)}).then(function(){a.display.render()})},toggleThirdColumnSelector:function(){this.$el.find('select[name="idColumn"]').parent().toggle()},renderChart:function(){this.$el.find(".nav li.disabled").removeClass("disabled"),this.$el.find("ul.nav").find('a[href="#chart-display"]').tab("show"),this.display.fetchData()},toString:function(){return"ScatterplotConfigEditor("+(this.dataset?this.dataset.id:"")+")"}});ScatterplotConfigEditor.templates={mainLayout:scatterplot.editor,dataControl:scatterplot.datacontrol,chartControl:scatterplot.chartcontrol};var ScatterplotDisplay=Backbone.View.extend({initialize:function(a){this.data=null,this.dataset=a.dataset,this.lineCount=this.dataset.metadata_data_lines||null},fetchData:function(){this.showLoadingIndicator();var a=this,b=this.model.get("config"),c=jQuery.getJSON("/api/datasets/"+this.dataset.id,{data_type:"raw_data",provider:"dataset-column",limit:b.pagination.perPage,offset:b.pagination.currPage*b.pagination.perPage});return c.done(function(b){a.data=b.data,a.trigger("data:fetched",a),a.renderData()}),c.fail(function(b,c,d){console.error(b,c,d),a.trigger("data:error",a),alert("Error loading data:\n"+b.responseText)}),c},showLoadingIndicator:function(){this.$el.find(".scatterplot-data-info").html(['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin"></span>','<span class="loading-indicator-message">loading...</span>',"</div>"].join(""))},template:function(){var a=['<div class="controls clear">','<div class="left">','<div class="page-control"></div>',"</div>",'<div class="right">','<p class="scatterplot-data-info"></p>','<button class="stats-toggle-btn">Stats</button>','<button class="rerender-btn">Redraw</button>',"</div>","</div>","<svg/>",'<div class="stats-display"></div>'].join("");return a},render:function(){return this.$el.addClass("scatterplot-display").html(this.template()),this.data&&this.renderData(),this},renderData:function(){this.renderLeftControls(),this.renderRightControls(),this.renderPlot(this.data),this.getStats()},renderLeftControls:function(){var a=this,b=this.model.get("config");return this.$el.find(".controls .left .page-control").pagination({startingPage:b.pagination.currPage,perPage:b.pagination.perPage,totalDataSize:this.lineCount,currDataSize:this.data.length}).off().on("pagination.page-change",function(c,d){b.pagination.currPage=d,a.model.set("config",{pagination:b.pagination}),a.resetZoom(),a.fetchData()}),this},renderRightControls:function(){var a=this;this.setLineInfo(this.data),this.$el.find(".stats-toggle-btn").off().click(function(){a.toggleStats()}),this.$el.find(".rerender-btn").off().click(function(){a.resetZoom(),a.renderPlot(this.data)})},renderPlot:function(){var a=this,b=this.$el.find("svg");this.toggleStats(!1),b.off().empty().show().on("zoom.scatterplot",function(b,c){a.model.set("config",c)}),scatterplot(b.get(0),this.model.get("config"),this.data)},setLineInfo:function(a,b){if(a){var c=this.model.get("config"),d=this.lineCount||"an unknown total",e=c.pagination.currPage*c.pagination.perPage,f=e+a.length;this.$el.find(".controls p.scatterplot-data-info").text([e+1,"to",f,"of",d].join(" "))}else this.$el.find(".controls p.scatterplot-data-info").html(b||"");return this},resetZoom:function(a,b){return a=void 0!==a?a:1,b=void 0!==b?b:[0,0],this.model.set("config",{scale:a,translate:b}),this},getStats:function(){if(this.data){var a=this,b=this.model.get("config"),c=new Worker("/plugins/visualizations/scatterplot/static/worker-stats.js");c.postMessage({data:this.data,keys:[b.xColumn,b.yColumn]}),c.onerror=function(){c.terminate()},c.onmessage=function(b){a.renderStats(b.data)}}},renderStats:function(a){var b=this.model.get("config"),c=this.$el.find(".stats-display"),d=b.x.label,e=b.y.label,f=$("<table/>").addClass("table").append(["<thead><th></th><th>",d,"</th><th>",e,"</th></thead>"].join("")).append(_.map(a,function(a,b){return $(["<tr><td>",b,"</td><td>",a[0],"</td><td>",a[1],"</td></tr>"].join(""))}));c.empty().append(f)},toggleStats:function(a){var b=this.$el.find(".stats-display");a=void 0===a?b.is(":hidden"):a,a?(this.$el.find("svg").hide(),b.show(),this.$el.find(".controls .stats-toggle-btn").text("Plot")):(b.hide(),this.$el.find("svg").show(),this.$el.find(".controls .stats-toggle-btn").text("Stats"))},toString:function(){return"ScatterplotView()"}}),ScatterplotModel=Visualization.extend({defaults:{type:"scatterplot",config:{pagination:{currPage:0,perPage:3e3},width:400,height:400,margin:{top:16,right:16,bottom:40,left:54},x:{ticks:10,label:"X"},y:{ticks:10,label:"Y"},datapointSize:4,animDuration:500,scale:1,translate:[0,0]}}});
\ No newline at end of file
+function scatterplot(a,b,c){function d(){var a={v:{},h:{}};return a.v.lines=p.selectAll("line.v-grid-line").data(m.x.ticks(q.x.fn.ticks()[0])),a.v.lines.enter().append("svg:line").classed("grid-line v-grid-line",!0),a.v.lines.attr("x1",m.x).attr("x2",m.x).attr("y1",0).attr("y2",b.height),a.v.lines.exit().remove(),a.h.lines=p.selectAll("line.h-grid-line").data(m.y.ticks(q.y.fn.ticks()[0])),a.h.lines.enter().append("svg:line").classed("grid-line h-grid-line",!0),a.h.lines.attr("x1",0).attr("x2",b.width).attr("y1",m.y).attr("y2",m.y),a.h.lines.exit().remove(),a}function e(){return t.attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).style("display","block").filter(function(){var a=d3.select(this).attr("cx"),c=d3.select(this).attr("cy");return 0>a||a>b.width?!0:0>c||c>b.height?!0:!1}).style("display","none")}function f(){$(".chart-info-box").remove(),q.redraw(),e(),s=d(),$(o.node()).trigger("zoom.scatterplot",{scale:n.scale(),translate:n.translate()})}function g(a,c,d){return c+=8,$(['<div class="chart-info-box" style="position: absolute">',void 0!==b.idColumn?"<div>"+d[b.idColumn]+"</div>":"","<div>",j(d),"</div>","<div>",k(d),"</div>","</div>"].join("")).css({top:a,left:c,"z-index":2})}var h=function(a,b){return"translate("+a+","+b+")"},i=function(a,b,c){return"rotate("+a+","+b+","+c+")"},j=function(a){return a[b.xColumn]},k=function(a){return a[b.yColumn]},l={x:{extent:d3.extent(c,j)},y:{extent:d3.extent(c,k)}},m={x:d3.scale.linear().domain(l.x.extent).range([0,b.width]),y:d3.scale.linear().domain(l.y.extent).range([b.height,0])},n=d3.behavior.zoom().x(m.x).y(m.y).scaleExtent([1,30]).scale(b.scale||1).translate(b.translate||[0,0]),o=d3.select(a).attr("class","scatterplot").attr("width","100%").attr("height",b.height+(b.margin.top+b.margin.bottom)),p=o.append("g").attr("class","content").attr("transform",h(b.margin.left,b.margin.top)).call(n);p.append("rect").attr("class","zoom-rect").attr("width",b.width).attr("height",b.height).style("fill","transparent");var q={x:{},y:{}};q.x.fn=d3.svg.axis().orient("bottom").scale(m.x).ticks(b.x.ticks).tickFormat(d3.format("s")),q.y.fn=d3.svg.axis().orient("left").scale(m.y).ticks(b.y.ticks).tickFormat(d3.format("s")),q.x.g=p.append("g").attr("class","x axis").attr("transform",h(0,b.height)).call(q.x.fn),q.y.g=p.append("g").attr("class","y axis").call(q.y.fn);var r=6;q.x.label=o.append("text").attr("class","axis-label").text(b.x.label).attr("text-anchor","middle").attr("dominant-baseline","text-after-edge").attr("x",b.width/2+b.margin.left).attr("y",b.height+b.margin.bottom+b.margin.top-r),q.y.label=o.append("text").attr("class","axis-label").text(b.y.label).attr("text-anchor","middle").attr("dominant-baseline","text-before-edge").attr("x",r).attr("y",b.height/2).attr("transform",i(-90,r,b.height/2)),q.redraw=function(){o.select(".x.axis").call(q.x.fn),o.select(".y.axis").call(q.y.fn)};var s=d(),t=p.selectAll(".glyph").data(c).enter().append("svg:circle").classed("glyph",!0).attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).attr("r",0);t.transition().duration(b.animDuration).attr("r",b.datapointSize),e(),n.on("zoom",f),t.on("mouseover",function(a,c){var d=d3.select(this);d.classed("highlight",!0).style("fill","red").style("fill-opacity",1),p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")-b.datapointSize).attr("y1",d.attr("cy")).attr("x2",0).attr("y2",d.attr("cy")).classed("hoverline",!0),d.attr("cy")<b.height&&p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")).attr("y1",+d.attr("cy")+b.datapointSize).attr("x2",d.attr("cx")).attr("y2",b.height).classed("hoverline",!0);var e=this.getBoundingClientRect();$("body").append(g(e.top,e.right,a)),$(o.node()).trigger("mouseover-datapoint.scatterplot",[this,a,c])}),t.on("mouseout",function(){d3.select(this).classed("highlight",!1).style("fill","black").style("fill-opacity",.2),p.selectAll(".hoverline").remove(),$(".chart-info-box").remove()})}this.scatterplot=this.scatterplot||{},this.scatterplot.chartcontrol=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f,g="",h="function",i=this.escapeExpression;return g+='<p class="help-text">\n Use the following controls to how the chart is displayed.\n The slide controls can be moved by the mouse or, if the \'handle\' is in focus, your keyboard\'s arrow keys.\n Move the focus between controls by using the tab or shift+tab keys on your keyboard.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n<div data-config-key="datapointSize" class="form-input numeric-slider-input">\n <label for="datapointSize">Size of data point: </label>\n <div class="slider-output">',(f=c.datapointSize)?f=f.call(b,{hash:{},data:e}):(f=b.datapointSize,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n Size of the graphic representation of each data point\n </p>\n</div>\n\n<div data-config-key="width" class="form-input numeric-slider-input">\n <label for="width">Chart width: </label>\n <div class="slider-output">',(f=c.width)?f=f.call(b,{hash:{},data:e}):(f=b.width,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="height" class="form-input numeric-slider-input">\n <label for="height">Chart height: </label>\n <div class="slider-output">',(f=c.height)?f=f.call(b,{hash:{},data:e}):(f=b.height,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="X-axis-label"class="text-input form-input">\n <label for="X-axis-label">Re-label the X axis: </label>\n <input type="text" name="X-axis-label" id="X-axis-label" value="'+i((f=b.x,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<div data-config-key="Y-axis-label" class="text-input form-input">\n <label for="Y-axis-label">Re-label the Y axis: </label>\n <input type="text" name="Y-axis-label" id="Y-axis-label" value="'+i((f=b.y,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.datacontrol=Handlebars.template(function(a,b,c,d,e){function f(a,b){var d,e="";return e+='\n <option value="',(d=c.index)?d=d.call(a,{hash:{},data:b}):(d=a.index,d=typeof d===j?d.apply(a):d),e+=k(d)+'">',(d=c.name)?d=d.call(a,{hash:{},data:b}):(d=a.name,d=typeof d===j?d.apply(a):d),e+=k(d)+"</option>\n "}function g(){return'checked="true"'}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var h,i="",j="function",k=this.escapeExpression,l=this;return i+='<p class="help-text">\n Use the following controls to change the data used by the chart.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n\n<div class="column-select">\n <label>Data column for X: </label>\n <select name="xColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n<div class="column-select">\n <label>Data column for Y: </label>\n <select name="yColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="include-id">\n <label for="include-id-checkbox">Include a third column as data point IDs?</label>\n <input type="checkbox" name="include-id" id="include-id-checkbox" />\n <p class="help-text-small">\n These will be displayed (along with the x and y values) when you hover over\n a data point.\n </p>\n</div>\n<div class="column-select" style="display: none">\n <label for="ID-select">Data column for IDs: </label>\n <select name="idColumn">\n ',h=c.each.call(b,b.allColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="first-line-header" style="display: none;">\n <p>Possible headers: ',(h=c.possibleHeaders)?h=h.call(b,{hash:{},data:e}):(h=b.possibleHeaders,h=typeof h===j?h.apply(b):h),i+=k(h)+'\n </p>\n <label for="first-line-header-checkbox">Use the above as column headers?</label>\n <input type="checkbox" name="include-id" id="first-line-header-checkbox"\n ',h=c["if"].call(b,b.usePossibleHeaders,{hash:{},inverse:l.noop,fn:l.program(3,g,e),data:e}),(h||0===h)&&(i+=h),i+='/>\n <p class="help-text-small">\n It looks like Galaxy couldn\'t get proper column headers for this data.\n Would you like to use the column headers above as column names to select columns?\n </p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.editor=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f="";return f+='<div class="scatterplot-editor tabbable tabs-left">\n \n <ul class="nav nav-tabs">\n \n <li class="active">\n <a title="Use this tab to change which data are used"\n href="#data-control" data-toggle="tab">Data Controls</a>\n </li>\n <li>\n <a title="Use this tab to change how the chart is drawn"\n href="#chart-control" data-toggle="tab" >Chart Controls</a>\n </li>\n \n <li class="disabled">\n <a title="This tab will display the chart"\n href="#chart-display" data-toggle="tab">Chart</a>\n </li>\n \n <li class="file-controls">\n<!-- <button class="copy-btn btn btn-default"\n title="Save this as a new visualization">Save to new</button>-->\n <button class="save-btn btn btn-default">Save</button>\n </li>\n </ul>\n\n \n <div class="tab-content">\n \n <div id="data-control" class="scatterplot-config-control tab-pane active">\n \n </div>\n \n \n <div id="chart-control" class="scatterplot-config-control tab-pane">\n \n </div>\n\n \n <div id="chart-display" class="scatterplot-display tab-pane"></div>\n\n </div>\n</div>\n'});var ScatterplotConfigEditor=Backbone.View.extend(LoggableMixin).extend({className:"scatterplot-control-form",initialize:function(a){if(this.model||(this.model=new Visualization({type:"scatterplot"})),this.log(this+".initialize, attributes:",a),!a||!a.dataset)throw new Error("ScatterplotConfigEditor requires a dataset");this.dataset=a.dataset,this.log("dataset:",this.dataset),this.display=new ScatterplotDisplay({dataset:a.dataset,model:this.model})},render:function(){this.$el.empty().append(ScatterplotConfigEditor.templates.mainLayout({})),this.model.id&&(this.$el.find(".copy-btn").show(),this.$el.find(".save-btn").text("Update saved")),this.$el.find("[title]").tooltip(),this._render_dataControl(),this._render_chartControls(),this._render_chartDisplay();var a=this.model.get("config");return this.model.id&&_.isFinite(a.xColumn)&&_.isFinite(a.yColumn)&&this.renderChart(),this},_render_dataControl:function(a){a=a||this.$el;var b=this,c=this.dataset,d=c.metadata_column_names||[],e=this.model.get("config"),f=[],g=_.map(c.metadata_column_types,function(a,b){var c={index:b,type:a,name:d[b]||"column "+(b+1)};return("int"===c.type||"float"===c.type)&&f.push(c),c});f.length<2&&(f=g);var h=a.find(".tab-pane#data-control");h.html(ScatterplotConfigEditor.templates.dataControl({allColumns:g,numericColumns:f}));var i={xColumn:_.isFinite(e.xColumn)?e.xColumn:f[0].index,yColumn:_.isFinite(e.yColumn)?e.yColumn:f[1].index,idColumn:g[0].index};if(_.isFinite(e.idColumn))i.idColumn=e.idColumn;else if(g.length>2){var j=_.find(g,function(a,b){return b!==i.xColumn&&b!==i.yColumn});i.idColumn=j.index}return e=this.model.set("config",i,{silent:!0}).get("config"),h.find('[name="xColumn"]').val(e.xColumn).on("change",function(){b.model.set("config",{xColumn:Number($(this).val())})}),h.find('[name="yColumn"]').val(e.yColumn).on("change",function(){b.model.set("config",{yColumn:Number($(this).val())})}),h.find('select[name="idColumn"]').val(e.idColumn).on("change",function(){b.model.set("config",{idColumn:Number($(this).val())})}),void 0!==e.idColumn&&h.find("#include-id-checkbox").prop("checked",!0).trigger("change"),h.find("[title]").tooltip(),h},_render_chartControls:function(a){function b(){var a=$(this),b=a.slider("value");c.model.set("config",_.object([[a.parent().data("config-key"),b]])),a.siblings(".slider-output").text(b)}a=a||this.$el;var c=this,d=this.model.get("config"),e=a.find("#chart-control");e.html(ScatterplotConfigEditor.templates.chartControl(d));var f={datapointSize:{min:2,max:10,step:1},width:{min:200,max:800,step:20},height:{min:200,max:800,step:20}};e.find(".numeric-slider-input").each(function(){var a=$(this),c=a.attr("data-config-key"),e=_.extend(f[c],{value:d[c],change:b,slide:b});a.find(".slider").slider(e),a.children(".slider-output").text(d[c])});var g=this.dataset.metadata_column_names||[],h=d.xLabel||g[d.xColumn]||"X",i=d.yLabel||g[d.yColumn]||"Y";return e.find('input[name="X-axis-label"]').val(h).on("change",function(){c.model.set("config",{xLabel:$(this).val()})}),e.find('input[name="Y-axis-label"]').val(i).on("change",function(){c.model.set("config",{yLabel:$(this).val()})}),e.find("[title]").tooltip(),e},_render_chartDisplay:function(a){a=a||this.$el;var b=a.find(".tab-pane#chart-display");return this.display.setElement(b),this.display.render(),b.find("[title]").tooltip(),b},events:{"change #include-id-checkbox":"toggleThirdColumnSelector","click #data-control .render-button":"renderChart","click #chart-control .render-button":"renderChart","click .save-btn":"saveVisualization"},saveVisualization:function(){var a=this;this.model.save().fail(function(b,c,d){console.error(b,c,d),a.trigger("save:error",view),alert("Error loading data:\n"+b.responseText)}).then(function(){a.display.render()})},toggleThirdColumnSelector:function(){this.$el.find('select[name="idColumn"]').parent().toggle()},renderChart:function(){this.$el.find(".nav li.disabled").removeClass("disabled"),this.$el.find("ul.nav").find('a[href="#chart-display"]').tab("show"),this.display.fetchData()},toString:function(){return"ScatterplotConfigEditor("+(this.dataset?this.dataset.id:"")+")"}});ScatterplotConfigEditor.templates={mainLayout:scatterplot.editor,dataControl:scatterplot.datacontrol,chartControl:scatterplot.chartcontrol};var ScatterplotDisplay=Backbone.View.extend({initialize:function(a){this.data=null,this.dataset=a.dataset,this.lineCount=this.dataset.metadata_data_lines||null},fetchData:function(){this.showLoadingIndicator();var a=this,b=this.model.get("config"),c=jQuery.getJSON("/api/datasets/"+this.dataset.id,{data_type:"raw_data",provider:"dataset-column",limit:b.pagination.perPage,offset:b.pagination.currPage*b.pagination.perPage});return c.done(function(b){a.data=b.data,a.trigger("data:fetched",a),a.renderData()}),c.fail(function(b,c,d){console.error(b,c,d),a.trigger("data:error",a),alert("Error loading data:\n"+b.responseText)}),c},showLoadingIndicator:function(){this.$el.find(".scatterplot-data-info").html(['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin"></span>','<span class="loading-indicator-message">loading...</span>',"</div>"].join(""))},template:function(){var a=['<div class="controls clear">','<div class="right">','<p class="scatterplot-data-info"></p>','<button class="stats-toggle-btn">Stats</button>','<button class="rerender-btn">Redraw</button>',"</div>",'<div class="left">','<div class="page-control"></div>',"</div>","</div>","<svg/>",'<div class="stats-display"></div>'].join("");return a},render:function(){return this.$el.addClass("scatterplot-display").html(this.template()),this.data&&this.renderData(),this},renderData:function(){this.renderLeftControls(),this.renderRightControls(),this.renderPlot(this.data),this.getStats()},renderLeftControls:function(){var a=this,b=this.model.get("config");return this.$el.find(".controls .left .page-control").pagination({startingPage:b.pagination.currPage,perPage:b.pagination.perPage,totalDataSize:this.lineCount,currDataSize:this.data.length}).off().on("pagination.page-change",function(c,d){b.pagination.currPage=d,a.model.set("config",{pagination:b.pagination}),a.resetZoom(),a.fetchData()}),this},renderRightControls:function(){var a=this;this.setLineInfo(this.data),this.$el.find(".stats-toggle-btn").off().click(function(){a.toggleStats()}),this.$el.find(".rerender-btn").off().click(function(){a.resetZoom(),a.renderPlot(this.data)})},renderPlot:function(){var a=this,b=this.$el.find("svg");this.toggleStats(!1),b.off().empty().show().on("zoom.scatterplot",function(b,c){a.model.set("config",c)}),scatterplot(b.get(0),this.model.get("config"),this.data)},setLineInfo:function(a,b){if(a){var c=this.model.get("config"),d=this.lineCount||"an unknown total",e=c.pagination.currPage*c.pagination.perPage,f=e+a.length;this.$el.find(".controls p.scatterplot-data-info").text([e+1,"to",f,"of",d].join(" "))}else this.$el.find(".controls p.scatterplot-data-info").html(b||"");return this},resetZoom:function(a,b){return a=void 0!==a?a:1,b=void 0!==b?b:[0,0],this.model.set("config",{scale:a,translate:b}),this},getStats:function(){if(this.data){var a=this,b=this.model.get("config"),c=new Worker("/plugins/visualizations/scatterplot/static/worker-stats.js");c.postMessage({data:this.data,keys:[b.xColumn,b.yColumn]}),c.onerror=function(){c.terminate()},c.onmessage=function(b){a.renderStats(b.data)}}},renderStats:function(a){var b=this.model.get("config"),c=this.$el.find(".stats-display"),d=b.x.label,e=b.y.label,f=$("<table/>").addClass("table").append(["<thead><th></th><th>",d,"</th><th>",e,"</th></thead>"].join("")).append(_.map(a,function(a,b){return $(["<tr><td>",b,"</td><td>",a[0],"</td><td>",a[1],"</td></tr>"].join(""))}));c.empty().append(f)},toggleStats:function(a){var b=this.$el.find(".stats-display");a=void 0===a?b.is(":hidden"):a,a?(this.$el.find("svg").hide(),b.show(),this.$el.find(".controls .stats-toggle-btn").text("Plot")):(b.hide(),this.$el.find("svg").show(),this.$el.find(".controls .stats-toggle-btn").text("Stats"))},toString:function(){return"ScatterplotView()"}}),ScatterplotModel=Visualization.extend({defaults:{type:"scatterplot",config:{pagination:{currPage:0,perPage:3e3},width:400,height:400,margin:{top:16,right:16,bottom:40,left:54},x:{ticks:10,label:"X"},y:{ticks:10,label:"Y"},datapointSize:4,animDuration:500,scale:1,translate:[0,0]}}});
\ No newline at end of file
diff -r 8494c2b3a3edff7f900a9994ccd806d063d5010f -r 479b72075bc8a68ec602081987375ca1dfa20a2f config/plugins/visualizations/scatterplot/static/scatterplot.css
--- a/config/plugins/visualizations/scatterplot/static/scatterplot.css
+++ b/config/plugins/visualizations/scatterplot/static/scatterplot.css
@@ -1,8 +1,6 @@
* { margin: 0; padding: 0; }
/* -------------------------------------------- header */
-.chart-header > * { margin: 0; padding: 0; }
-
.chart-header {
margin-bottom: 16px;
overflow: auto;
@@ -40,7 +38,7 @@
/* -------------------------------------------- main layout */
.scatterplot-editor > * { margin: 0; padding: 0; }
.scatterplot-editor .tab-pane {
- padding: 8px;
+ padding-top: 8px;
}
.scatterplot-editor .help-text,
@@ -134,6 +132,7 @@
border: 1px solid lightgrey;
border-radius: 3px;
padding: 8px 8px 4px 8px;
+ overflow: auto;
}
.scatterplot-display .controls button {
@@ -144,25 +143,16 @@
}
.scatterplot-display .pagination-scroll-container {
- /* float left makes this not collapse very well */
- max-width: 540px;
-}
-
-.scatterplot-display .controls .data-prev-next {
+ max-width: 440px;
display: inline-block;
- margin: 0px 4px 0px 0px;
-}
-
-.scatterplot-display .controls {
-}
-
-.scatterplot-display .controls .left,
-.scatterplot-display .controls .right {
- position: relative;
}
.scatterplot-display .controls .left {
- float: left;
+ /*no shrinkwrap, but collapses well (with scroll)*/
+ /*display: inline;*/
+ /*will shrinkwrap*/
+ display: inline-block;
+ /*display: table-cell;*/
}
.scatterplot-display .controls .right {
@@ -186,10 +176,13 @@
margin-left: 4px;
}
+
/* -------------------------------------------- chart area */
svg.scatterplot {
border: 1px solid lightgrey;
border-radius: 3px;
+ /* doesn't work */
+ overflow: auto;
}
svg.scatterplot .grid-line {
diff -r 8494c2b3a3edff7f900a9994ccd806d063d5010f -r 479b72075bc8a68ec602081987375ca1dfa20a2f static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1391,7 +1391,7 @@
.quota-meter-bar-error{background-color:#b93e3a}
.quota-meter-text{position:absolute;top:50%;left:0;width:100px;height:16px;margin-top:-6px;text-align:center;z-index:9001;color:#000;white-space:nowrap}
.pagination{margin:0px}
-.pagination-scroll-container{overflow:auto;background-color:#F8F8F8;border-radius:3px;border:1px solid #BFBFBF}
+.pagination-scroll-container{display:inline-block;background-color:#F8F8F8;border-radius:3px;border:1px solid #BFBFBF;overflow:auto}
.pagination-scroll-container .pagination-page-list{margin:3px 0px 3px 0px}
.pagination-scroll-container .pagination-page-list>li:first-child>a,.pagination-scroll-container .pagination-page-list>li:first-child>span{border-radius:0px;border-left:0px}
.pagination-scroll-container .pagination-page-list>li:last-child>a,.pagination-scroll-container .pagination-page-list>li:last-child>span{border-radius:0px}
diff -r 8494c2b3a3edff7f900a9994ccd806d063d5010f -r 479b72075bc8a68ec602081987375ca1dfa20a2f static/style/src/less/base.less
--- a/static/style/src/less/base.less
+++ b/static/style/src/less/base.less
@@ -514,10 +514,11 @@
}
.pagination-scroll-container {
- overflow : auto;
+ display : inline-block;
background-color: #F8F8F8;
border-radius : 3px;
border : 1px solid #BFBFBF;
+ overflow : auto;
}
.pagination-scroll-container .pagination-page-list {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: (Add mako template missing from b8ff65e)
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8494c2b3a3ed/
Changeset: 8494c2b3a3ed
User: carlfeberhard
Date: 2014-02-14 19:59:44
Summary: (Add mako template missing from b8ff65e)
Affected #: 1 file
diff -r b8ff65e15b1b40a76544ef07e7ab98a9b5ce7221 -r 8494c2b3a3edff7f900a9994ccd806d063d5010f templates/webapps/galaxy/visualization/display_in_frame.mako
--- /dev/null
+++ b/templates/webapps/galaxy/visualization/display_in_frame.mako
@@ -0,0 +1,58 @@
+<%inherit file="/display_base.mako"/>
+
+<%def name="javascripts()">
+ <% config = item_data %>
+ ${parent.javascripts()}
+
+ <script type='text/javascript'>
+ $(function() {
+ // HACK: add bookmarks container and header.
+ $('#right > .unified-panel-body > div').append(
+ $('<div/>').attr('id', 'bookmarks-container')
+ .append( $('<h4/>').text('Bookmarks') )
+ );
+ });
+ </script>
+
+ <!--[if lt IE 9]>
+ <script type='text/javascript' src="${h.url_for('/static/scripts/libs/IE/excanvas.js')}"></script>
+ <![endif]-->
+</%def>
+
+<%def name="stylesheets()">
+ ${parent.stylesheets()}
+
+ ## Style changes needed for display.
+ <style type="text/css">
+ .page-body {
+ padding: 0px;
+ }
+ #bookmarks-container {
+ padding-left: 10px;
+ }
+ .bookmark {
+ margin: 0em;
+ }
+ </style>
+</%def>
+
+<%def name="render_item_header( item )">
+ ## Don't need to show header
+</%def>
+
+<%def name="render_item_links( visualization )">
+ <a
+ href="${h.url_for( controller='/visualization', action='imp', id=trans.security.encode_id( visualization.id ) )}"
+ class="icon-button import"
+ ## Needed to overwide initial width so that link is floated left appropriately.
+ style="width: 100%"
+ title="Import visualization">Import visualization</a>
+</%def>
+
+<%def name="render_item( visualization, config )">
+ <div id="${trans.security.encode_id( visualization.id )}" class="unified-panel-body" style="overflow:none;top:0px;">
+ <iframe frameborder="0" width="100%" height="100%" sandbox="allow-forms allow-same-origin allow-scripts"
+ src="/visualization/saved?id=${encoded_visualization_id}&embedded=True">
+ </iframe>
+ </div>
+</%def>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Visualizations registry: allow registry visualizations to be rendered properly when displayed by slugline; Scatterplot: use embedded to cue loading of display (w/o editor)
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b8ff65e15b1b/
Changeset: b8ff65e15b1b
User: carlfeberhard
Date: 2014-02-14 19:58:30
Summary: Visualizations registry: allow registry visualizations to be rendered properly when displayed by slugline; Scatterplot: use embedded to cue loading of display (w/o editor)
Affected #: 4 files
diff -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae -r b8ff65e15b1b40a76544ef07e7ab98a9b5ce7221 config/plugins/visualizations/scatterplot/static/scatterplot-edit.js
--- a/config/plugins/visualizations/scatterplot/static/scatterplot-edit.js
+++ b/config/plugins/visualizations/scatterplot/static/scatterplot-edit.js
@@ -1,1 +1,1 @@
-function scatterplot(a,b,c){function d(){var a={v:{},h:{}};return a.v.lines=p.selectAll("line.v-grid-line").data(m.x.ticks(q.x.fn.ticks()[0])),a.v.lines.enter().append("svg:line").classed("grid-line v-grid-line",!0),a.v.lines.attr("x1",m.x).attr("x2",m.x).attr("y1",0).attr("y2",b.height),a.v.lines.exit().remove(),a.h.lines=p.selectAll("line.h-grid-line").data(m.y.ticks(q.y.fn.ticks()[0])),a.h.lines.enter().append("svg:line").classed("grid-line h-grid-line",!0),a.h.lines.attr("x1",0).attr("x2",b.width).attr("y1",m.y).attr("y2",m.y),a.h.lines.exit().remove(),a}function e(){return t.attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).style("display","block").filter(function(){var a=d3.select(this).attr("cx"),c=d3.select(this).attr("cy");return 0>a||a>b.width?!0:0>c||c>b.height?!0:!1}).style("display","none")}function f(){$(".chart-info-box").remove(),q.redraw(),e(),s=d(),$(o.node()).trigger("zoom.scatterplot",{scale:n.scale(),translate:n.translate()})}function g(a,c,d){return c+=8,$(['<div class="chart-info-box" style="position: absolute">',void 0!==b.idColumn?"<div>"+d[b.idColumn]+"</div>":"","<div>",j(d),"</div>","<div>",k(d),"</div>","</div>"].join("")).css({top:a,left:c,"z-index":2})}var h=function(a,b){return"translate("+a+","+b+")"},i=function(a,b,c){return"rotate("+a+","+b+","+c+")"},j=function(a){return a[b.xColumn]},k=function(a){return a[b.yColumn]},l={x:{extent:d3.extent(c,j)},y:{extent:d3.extent(c,k)}},m={x:d3.scale.linear().domain(l.x.extent).range([0,b.width]),y:d3.scale.linear().domain(l.y.extent).range([b.height,0])},n=d3.behavior.zoom().x(m.x).y(m.y).scaleExtent([1,30]).scale(b.scale||1).translate(b.translate||[0,0]),o=d3.select(a).attr("class","scatterplot").attr("width","100%").attr("height",b.height+(b.margin.top+b.margin.bottom)),p=o.append("g").attr("class","content").attr("transform",h(b.margin.left,b.margin.top)).call(n);p.append("rect").attr("class","zoom-rect").attr("width",b.width).attr("height",b.height).style("fill","transparent");var q={x:{},y:{}};q.x.fn=d3.svg.axis().orient("bottom").scale(m.x).ticks(b.x.ticks).tickFormat(d3.format("s")),q.y.fn=d3.svg.axis().orient("left").scale(m.y).ticks(b.y.ticks).tickFormat(d3.format("s")),q.x.g=p.append("g").attr("class","x axis").attr("transform",h(0,b.height)).call(q.x.fn),q.y.g=p.append("g").attr("class","y axis").call(q.y.fn);var r=6;q.x.label=o.append("text").attr("class","axis-label").text(b.x.label).attr("text-anchor","middle").attr("dominant-baseline","text-after-edge").attr("x",b.width/2+b.margin.left).attr("y",b.height+b.margin.bottom+b.margin.top-r),q.y.label=o.append("text").attr("class","axis-label").text(b.y.label).attr("text-anchor","middle").attr("dominant-baseline","text-before-edge").attr("x",r).attr("y",b.height/2).attr("transform",i(-90,r,b.height/2)),q.redraw=function(){o.select(".x.axis").call(q.x.fn),o.select(".y.axis").call(q.y.fn)};var s=d(),t=p.selectAll(".glyph").data(c).enter().append("svg:circle").classed("glyph",!0).attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).attr("r",0);t.transition().duration(b.animDuration).attr("r",b.datapointSize),e(),n.on("zoom",f),t.on("mouseover",function(a,c){var d=d3.select(this);d.classed("highlight",!0).style("fill","red").style("fill-opacity",1),p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")-b.datapointSize).attr("y1",d.attr("cy")).attr("x2",0).attr("y2",d.attr("cy")).classed("hoverline",!0),d.attr("cy")<b.height&&p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")).attr("y1",+d.attr("cy")+b.datapointSize).attr("x2",d.attr("cx")).attr("y2",b.height).classed("hoverline",!0);var e=this.getBoundingClientRect();$("body").append(g(e.top,e.right,a)),$(o.node()).trigger("mouseover-datapoint.scatterplot",[this,a,c])}),t.on("mouseout",function(){d3.select(this).classed("highlight",!1).style("fill","black").style("fill-opacity",.2),p.selectAll(".hoverline").remove(),$(".chart-info-box").remove()})}this.scatterplot=this.scatterplot||{},this.scatterplot.chartcontrol=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f,g="",h="function",i=this.escapeExpression;return g+='<p class="help-text">\n Use the following controls to how the chart is displayed.\n The slide controls can be moved by the mouse or, if the \'handle\' is in focus, your keyboard\'s arrow keys.\n Move the focus between controls by using the tab or shift+tab keys on your keyboard.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n<div data-config-key="datapointSize" class="form-input numeric-slider-input">\n <label for="datapointSize">Size of data point: </label>\n <div class="slider-output">',(f=c.datapointSize)?f=f.call(b,{hash:{},data:e}):(f=b.datapointSize,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n Size of the graphic representation of each data point\n </p>\n</div>\n\n<div data-config-key="width" class="form-input numeric-slider-input">\n <label for="width">Chart width: </label>\n <div class="slider-output">',(f=c.width)?f=f.call(b,{hash:{},data:e}):(f=b.width,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="height" class="form-input numeric-slider-input">\n <label for="height">Chart height: </label>\n <div class="slider-output">',(f=c.height)?f=f.call(b,{hash:{},data:e}):(f=b.height,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="X-axis-label"class="text-input form-input">\n <label for="X-axis-label">Re-label the X axis: </label>\n <input type="text" name="X-axis-label" id="X-axis-label" value="'+i((f=b.x,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<div data-config-key="Y-axis-label" class="text-input form-input">\n <label for="Y-axis-label">Re-label the Y axis: </label>\n <input type="text" name="Y-axis-label" id="Y-axis-label" value="'+i((f=b.y,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.datacontrol=Handlebars.template(function(a,b,c,d,e){function f(a,b){var d,e="";return e+='\n <option value="',(d=c.index)?d=d.call(a,{hash:{},data:b}):(d=a.index,d=typeof d===j?d.apply(a):d),e+=k(d)+'">',(d=c.name)?d=d.call(a,{hash:{},data:b}):(d=a.name,d=typeof d===j?d.apply(a):d),e+=k(d)+"</option>\n "}function g(){return'checked="true"'}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var h,i="",j="function",k=this.escapeExpression,l=this;return i+='<p class="help-text">\n Use the following controls to change the data used by the chart.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n\n<div class="column-select">\n <label>Data column for X: </label>\n <select name="xColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n<div class="column-select">\n <label>Data column for Y: </label>\n <select name="yColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="include-id">\n <label for="include-id-checkbox">Include a third column as data point IDs?</label>\n <input type="checkbox" name="include-id" id="include-id-checkbox" />\n <p class="help-text-small">\n These will be displayed (along with the x and y values) when you hover over\n a data point.\n </p>\n</div>\n<div class="column-select" style="display: none">\n <label for="ID-select">Data column for IDs: </label>\n <select name="idColumn">\n ',h=c.each.call(b,b.allColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="first-line-header" style="display: none;">\n <p>Possible headers: ',(h=c.possibleHeaders)?h=h.call(b,{hash:{},data:e}):(h=b.possibleHeaders,h=typeof h===j?h.apply(b):h),i+=k(h)+'\n </p>\n <label for="first-line-header-checkbox">Use the above as column headers?</label>\n <input type="checkbox" name="include-id" id="first-line-header-checkbox"\n ',h=c["if"].call(b,b.usePossibleHeaders,{hash:{},inverse:l.noop,fn:l.program(3,g,e),data:e}),(h||0===h)&&(i+=h),i+='/>\n <p class="help-text-small">\n It looks like Galaxy couldn\'t get proper column headers for this data.\n Would you like to use the column headers above as column names to select columns?\n </p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.editor=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f="";return f+='<div class="scatterplot-editor tabbable tabs-left">\n \n <ul class="nav nav-tabs">\n \n <li class="active">\n <a title="Use this tab to change which data are used"\n href="#data-control" data-toggle="tab">Data Controls</a>\n </li>\n <li>\n <a title="Use this tab to change how the chart is drawn"\n href="#chart-control" data-toggle="tab" >Chart Controls</a>\n </li>\n \n <li class="disabled">\n <a title="This tab will display the chart"\n href="#chart-display" data-toggle="tab">Chart</a>\n </li>\n \n <li class="file-controls">\n<!-- <button class="copy-btn btn btn-default"\n title="Save this as a new visualization">Save to new</button>-->\n <button class="save-btn btn btn-default">Save</button>\n </li>\n </ul>\n\n \n <div class="tab-content">\n \n <div id="data-control" class="scatterplot-config-control tab-pane active">\n \n </div>\n \n \n <div id="chart-control" class="scatterplot-config-control tab-pane">\n \n </div>\n\n \n <div id="chart-display" class="scatterplot-display tab-pane"></div>\n\n </div>\n</div>\n'});var ScatterplotConfigEditor=Backbone.View.extend(LoggableMixin).extend({className:"scatterplot-control-form",initialize:function(a){if(this.model||(this.model=new Visualization({type:"scatterplot"})),this.log(this+".initialize, attributes:",a),!a||!a.dataset)throw new Error("ScatterplotConfigEditor requires a dataset");this.dataset=a.dataset,this.log("dataset:",this.dataset),this.display=new ScatterplotDisplay({dataset:a.dataset,model:this.model})},render:function(){this.$el.empty().append(ScatterplotConfigEditor.templates.mainLayout({})),this.model.id&&(this.$el.find(".copy-btn").show(),this.$el.find(".save-btn").text("Update saved")),this.$el.find("[title]").tooltip(),this._render_dataControl(),this._render_chartControls(),this._render_chartDisplay();var a=this.model.get("config");return this.model.id&&_.isFinite(a.xColumn)&&_.isFinite(a.yColumn)&&this.renderChart(),this},_render_dataControl:function(a){a=a||this.$el;var b=this,c=this.dataset,d=c.metadata_column_names||[],e=this.model.get("config"),f=[],g=_.map(c.metadata_column_types,function(a,b){var c={index:b,type:a,name:d[b]||"column "+(b+1)};return("int"===c.type||"float"===c.type)&&f.push(c),c});f.length<2&&(f=g);var h=a.find(".tab-pane#data-control");h.html(ScatterplotConfigEditor.templates.dataControl({allColumns:g,numericColumns:f}));var i={xColumn:_.isFinite(e.xColumn)?e.xColumn:f[0].index,yColumn:_.isFinite(e.yColumn)?e.yColumn:f[1].index,idColumn:g[0].index};if(_.isFinite(e.idColumn))i.idColumn=e.idColumn;else if(g.length>2){var j=_.find(g,function(a,b){return b!==i.xColumn&&b!==i.yColumn});i.idColumn=j.index}return e=this.model.set("config",i,{silent:!0}).get("config"),h.find('[name="xColumn"]').val(e.xColumn).on("change",function(){b.model.set("config",{xColumn:Number($(this).val())})}),h.find('[name="yColumn"]').val(e.yColumn).on("change",function(){b.model.set("config",{yColumn:Number($(this).val())})}),h.find('select[name="idColumn"]').val(e.idColumn).on("change",function(){b.model.set("config",{idColumn:Number($(this).val())})}),void 0!==e.idColumn&&h.find("#include-id-checkbox").prop("checked",!0).trigger("change"),h.find("[title]").tooltip(),h},_render_chartControls:function(a){function b(){var a=$(this),b=a.slider("value");c.model.set("config",_.object([[a.parent().data("config-key"),b]])),a.siblings(".slider-output").text(b)}a=a||this.$el;var c=this,d=this.model.get("config"),e=a.find("#chart-control");e.html(ScatterplotConfigEditor.templates.chartControl(d));var f={datapointSize:{min:2,max:10,step:1},width:{min:200,max:800,step:20},height:{min:200,max:800,step:20}};e.find(".numeric-slider-input").each(function(){var a=$(this),c=a.attr("data-config-key"),e=_.extend(f[c],{value:d[c],change:b,slide:b});a.find(".slider").slider(e),a.children(".slider-output").text(d[c])});var g=this.dataset.metadata_column_names||[],h=d.xLabel||g[d.xColumn]||"X",i=d.yLabel||g[d.yColumn]||"Y";return e.find('input[name="X-axis-label"]').val(h).on("change",function(){c.model.set("config",{xLabel:$(this).val()})}),e.find('input[name="Y-axis-label"]').val(i).on("change",function(){c.model.set("config",{yLabel:$(this).val()})}),e.find("[title]").tooltip(),e},_render_chartDisplay:function(a){a=a||this.$el;var b=a.find(".tab-pane#chart-display");return this.display.setElement(b),this.display.render(),b.find("[title]").tooltip(),b},events:{"change #include-id-checkbox":"toggleThirdColumnSelector","click #data-control .render-button":"renderChart","click #chart-control .render-button":"renderChart","click .save-btn":"saveVisualization"},saveVisualization:function(){var a=this;this.model.save().fail(function(b,c,d){console.error(b,c,d),a.trigger("save:error",view),alert("Error loading data:\n"+b.responseText)}).then(function(){a.display.render()})},toggleThirdColumnSelector:function(){this.$el.find('select[name="idColumn"]').parent().toggle()},renderChart:function(){this.$el.find(".nav li.disabled").removeClass("disabled"),this.$el.find("ul.nav").find('a[href="#chart-display"]').tab("show"),this.display.fetchData()},toString:function(){return"ScatterplotConfigEditor("+(this.dataset?this.dataset.id:"")+")"}});ScatterplotConfigEditor.templates={mainLayout:scatterplot.editor,dataControl:scatterplot.datacontrol,chartControl:scatterplot.chartcontrol};var ScatterplotDisplay=Backbone.View.extend({initialize:function(a){this.data=null,this.dataset=a.dataset,this.calcNumPages()},calcNumPages:function(){var a=this.model.get("config");this.lineCount=this.dataset.metadata_data_lines,this.numPages=this.lineCount?Math.ceil(this.lineCount/a.pagination.perPage):void 0,this.lineCount&&void 0!==this.numPages||console.warn("no data total found")},fetchData:function(){this.showLoadingIndicator("getting data");var a=this,b=this.model.get("config"),c=jQuery.getJSON("/api/datasets/"+this.dataset.id,{data_type:"raw_data",provider:"dataset-column",limit:b.pagination.perPage,offset:b.pagination.currPage*b.pagination.perPage});return c.done(function(b){a.data=b.data,a.trigger("data:fetched",a),a.renderData()}),c.fail(function(b,c,d){console.error(b,c,d),a.trigger("data:error",a),alert("Error loading data:\n"+b.responseText)}),c},showLoadingIndicator:function(){this.$el.find(".scatterplot-data-info").html(['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin"></span>','<span class="loading-indicator-message">loading...</span>',"</div>"].join(""))},template:function(){var a=['<div class="controls clear">','<div class="left">','<div class="page-control"></div>',"</div>",'<div class="right">','<p class="scatterplot-data-info"></p>','<button class="stats-toggle-btn">Stats</button>','<button class="rerender-btn">Redraw</button>',"</div>","</div>","<svg/>",'<div class="stats-display"></div>'].join("");return a},render:function(){return this.$el.addClass("scatterplot-display").html(this.template()),this.data&&this.renderData(),this},renderData:function(){this.renderLeftControls(),this.renderRightControls(),this.renderPlot(this.data),this.getStats()},renderLeftControls:function(){var a=this,b=this.model.get("config");return this.$el.find(".controls .left .page-control").pagination({startingPage:b.pagination.currPage,perPage:b.pagination.perPage,totalDataSize:this.lineCount||null,currDataSize:this.data.length,maxWidth:540}).off().on("pagination.page-change",function(c,d){b.pagination.currPage=d,a.model.set("config",{pagination:b.pagination}),a.resetZoom(),a.fetchData()}),this},renderRightControls:function(){var a=this;this.setLineInfo(this.data),this.$el.find(".stats-toggle-btn").off().click(function(){a.toggleStats()}),this.$el.find(".rerender-btn").off().click(function(){a.resetZoom(),a.renderPlot(this.data)})},renderPlot:function(){var a=this,b=this.$el.find("svg");this.toggleStats(!1),b.off().empty().show().on("zoom.scatterplot",function(b,c){a.model.set("config",c)}),scatterplot(b.get(0),this.model.get("config"),this.data)},setLineInfo:function(a,b){if(a){var c=this.model.get("config"),d=this.lineCount||"an unknown total",e=c.pagination.currPage*c.pagination.perPage,f=e+a.length;this.$el.find(".controls p.scatterplot-data-info").text([e+1,"to",f,"of",d].join(" "))}else this.$el.find(".controls p.scatterplot-data-info").html(b||"");return this},resetZoom:function(a,b){return a=void 0!==a?a:1,b=void 0!==b?b:[0,0],this.model.set("config",{scale:a,translate:b}),this},getStats:function(){if(this.data){var a=this,b=this.model.get("config"),c=new Worker("/plugins/visualizations/scatterplot/static/worker-stats.js");c.postMessage({data:this.data,keys:[b.xColumn,b.yColumn]}),c.onerror=function(){c.terminate()},c.onmessage=function(b){a.renderStats(b.data)}}},renderStats:function(a){var b=this.model.get("config"),c=this.$el.find(".stats-display"),d=b.x.label,e=b.y.label,f=$("<table/>").addClass("table").append(["<thead><th></th><th>",d,"</th><th>",e,"</th></thead>"].join("")).append(_.map(a,function(a,b){return $(["<tr><td>",b,"</td><td>",a[0],"</td><td>",a[1],"</td></tr>"].join(""))}));c.empty().append(f)},toggleStats:function(a){var b=this.$el.find(".stats-display");a=void 0===a?b.is(":hidden"):a,a?(this.$el.find("svg").hide(),b.show(),this.$el.find(".controls .stats-toggle-btn").text("Plot")):(b.hide(),this.$el.find("svg").show(),this.$el.find(".controls .stats-toggle-btn").text("Stats"))},toString:function(){return"ScatterplotView()"}}),ScatterplotModel=Visualization.extend({defaults:{type:"scatterplot",config:{pagination:{currPage:0,perPage:3e3},width:400,height:400,margin:{top:16,right:16,bottom:40,left:54},x:{ticks:10,label:"X"},y:{ticks:10,label:"Y"},datapointSize:4,animDuration:500,scale:1,translate:[0,0]}}});
\ No newline at end of file
+function scatterplot(a,b,c){function d(){var a={v:{},h:{}};return a.v.lines=p.selectAll("line.v-grid-line").data(m.x.ticks(q.x.fn.ticks()[0])),a.v.lines.enter().append("svg:line").classed("grid-line v-grid-line",!0),a.v.lines.attr("x1",m.x).attr("x2",m.x).attr("y1",0).attr("y2",b.height),a.v.lines.exit().remove(),a.h.lines=p.selectAll("line.h-grid-line").data(m.y.ticks(q.y.fn.ticks()[0])),a.h.lines.enter().append("svg:line").classed("grid-line h-grid-line",!0),a.h.lines.attr("x1",0).attr("x2",b.width).attr("y1",m.y).attr("y2",m.y),a.h.lines.exit().remove(),a}function e(){return t.attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).style("display","block").filter(function(){var a=d3.select(this).attr("cx"),c=d3.select(this).attr("cy");return 0>a||a>b.width?!0:0>c||c>b.height?!0:!1}).style("display","none")}function f(){$(".chart-info-box").remove(),q.redraw(),e(),s=d(),$(o.node()).trigger("zoom.scatterplot",{scale:n.scale(),translate:n.translate()})}function g(a,c,d){return c+=8,$(['<div class="chart-info-box" style="position: absolute">',void 0!==b.idColumn?"<div>"+d[b.idColumn]+"</div>":"","<div>",j(d),"</div>","<div>",k(d),"</div>","</div>"].join("")).css({top:a,left:c,"z-index":2})}var h=function(a,b){return"translate("+a+","+b+")"},i=function(a,b,c){return"rotate("+a+","+b+","+c+")"},j=function(a){return a[b.xColumn]},k=function(a){return a[b.yColumn]},l={x:{extent:d3.extent(c,j)},y:{extent:d3.extent(c,k)}},m={x:d3.scale.linear().domain(l.x.extent).range([0,b.width]),y:d3.scale.linear().domain(l.y.extent).range([b.height,0])},n=d3.behavior.zoom().x(m.x).y(m.y).scaleExtent([1,30]).scale(b.scale||1).translate(b.translate||[0,0]),o=d3.select(a).attr("class","scatterplot").attr("width","100%").attr("height",b.height+(b.margin.top+b.margin.bottom)),p=o.append("g").attr("class","content").attr("transform",h(b.margin.left,b.margin.top)).call(n);p.append("rect").attr("class","zoom-rect").attr("width",b.width).attr("height",b.height).style("fill","transparent");var q={x:{},y:{}};q.x.fn=d3.svg.axis().orient("bottom").scale(m.x).ticks(b.x.ticks).tickFormat(d3.format("s")),q.y.fn=d3.svg.axis().orient("left").scale(m.y).ticks(b.y.ticks).tickFormat(d3.format("s")),q.x.g=p.append("g").attr("class","x axis").attr("transform",h(0,b.height)).call(q.x.fn),q.y.g=p.append("g").attr("class","y axis").call(q.y.fn);var r=6;q.x.label=o.append("text").attr("class","axis-label").text(b.x.label).attr("text-anchor","middle").attr("dominant-baseline","text-after-edge").attr("x",b.width/2+b.margin.left).attr("y",b.height+b.margin.bottom+b.margin.top-r),q.y.label=o.append("text").attr("class","axis-label").text(b.y.label).attr("text-anchor","middle").attr("dominant-baseline","text-before-edge").attr("x",r).attr("y",b.height/2).attr("transform",i(-90,r,b.height/2)),q.redraw=function(){o.select(".x.axis").call(q.x.fn),o.select(".y.axis").call(q.y.fn)};var s=d(),t=p.selectAll(".glyph").data(c).enter().append("svg:circle").classed("glyph",!0).attr("cx",function(a,b){return m.x(j(a,b))}).attr("cy",function(a,b){return m.y(k(a,b))}).attr("r",0);t.transition().duration(b.animDuration).attr("r",b.datapointSize),e(),n.on("zoom",f),t.on("mouseover",function(a,c){var d=d3.select(this);d.classed("highlight",!0).style("fill","red").style("fill-opacity",1),p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")-b.datapointSize).attr("y1",d.attr("cy")).attr("x2",0).attr("y2",d.attr("cy")).classed("hoverline",!0),d.attr("cy")<b.height&&p.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",d.attr("cx")).attr("y1",+d.attr("cy")+b.datapointSize).attr("x2",d.attr("cx")).attr("y2",b.height).classed("hoverline",!0);var e=this.getBoundingClientRect();$("body").append(g(e.top,e.right,a)),$(o.node()).trigger("mouseover-datapoint.scatterplot",[this,a,c])}),t.on("mouseout",function(){d3.select(this).classed("highlight",!1).style("fill","black").style("fill-opacity",.2),p.selectAll(".hoverline").remove(),$(".chart-info-box").remove()})}this.scatterplot=this.scatterplot||{},this.scatterplot.chartcontrol=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f,g="",h="function",i=this.escapeExpression;return g+='<p class="help-text">\n Use the following controls to how the chart is displayed.\n The slide controls can be moved by the mouse or, if the \'handle\' is in focus, your keyboard\'s arrow keys.\n Move the focus between controls by using the tab or shift+tab keys on your keyboard.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n<div data-config-key="datapointSize" class="form-input numeric-slider-input">\n <label for="datapointSize">Size of data point: </label>\n <div class="slider-output">',(f=c.datapointSize)?f=f.call(b,{hash:{},data:e}):(f=b.datapointSize,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n Size of the graphic representation of each data point\n </p>\n</div>\n\n<div data-config-key="width" class="form-input numeric-slider-input">\n <label for="width">Chart width: </label>\n <div class="slider-output">',(f=c.width)?f=f.call(b,{hash:{},data:e}):(f=b.width,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="height" class="form-input numeric-slider-input">\n <label for="height">Chart height: </label>\n <div class="slider-output">',(f=c.height)?f=f.call(b,{hash:{},data:e}):(f=b.height,f=typeof f===h?f.apply(b):f),g+=i(f)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n</div>\n\n<div data-config-key="X-axis-label"class="text-input form-input">\n <label for="X-axis-label">Re-label the X axis: </label>\n <input type="text" name="X-axis-label" id="X-axis-label" value="'+i((f=b.x,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<div data-config-key="Y-axis-label" class="text-input form-input">\n <label for="Y-axis-label">Re-label the Y axis: </label>\n <input type="text" name="Y-axis-label" id="Y-axis-label" value="'+i((f=b.y,f=null==f||f===!1?f:f.label,typeof f===h?f.apply(b):f))+'" />\n <p class="form-help help-text-small"></p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.datacontrol=Handlebars.template(function(a,b,c,d,e){function f(a,b){var d,e="";return e+='\n <option value="',(d=c.index)?d=d.call(a,{hash:{},data:b}):(d=a.index,d=typeof d===j?d.apply(a):d),e+=k(d)+'">',(d=c.name)?d=d.call(a,{hash:{},data:b}):(d=a.name,d=typeof d===j?d.apply(a):d),e+=k(d)+"</option>\n "}function g(){return'checked="true"'}this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var h,i="",j="function",k=this.escapeExpression,l=this;return i+='<p class="help-text">\n Use the following controls to change the data used by the chart.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n</p>\n\n\n<div class="column-select">\n <label>Data column for X: </label>\n <select name="xColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n<div class="column-select">\n <label>Data column for Y: </label>\n <select name="yColumn">\n ',h=c.each.call(b,b.numericColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="include-id">\n <label for="include-id-checkbox">Include a third column as data point IDs?</label>\n <input type="checkbox" name="include-id" id="include-id-checkbox" />\n <p class="help-text-small">\n These will be displayed (along with the x and y values) when you hover over\n a data point.\n </p>\n</div>\n<div class="column-select" style="display: none">\n <label for="ID-select">Data column for IDs: </label>\n <select name="idColumn">\n ',h=c.each.call(b,b.allColumns,{hash:{},inverse:l.noop,fn:l.program(1,f,e),data:e}),(h||0===h)&&(i+=h),i+='\n </select>\n</div>\n\n\n<div id="first-line-header" style="display: none;">\n <p>Possible headers: ',(h=c.possibleHeaders)?h=h.call(b,{hash:{},data:e}):(h=b.possibleHeaders,h=typeof h===j?h.apply(b):h),i+=k(h)+'\n </p>\n <label for="first-line-header-checkbox">Use the above as column headers?</label>\n <input type="checkbox" name="include-id" id="first-line-header-checkbox"\n ',h=c["if"].call(b,b.usePossibleHeaders,{hash:{},inverse:l.noop,fn:l.program(3,g,e),data:e}),(h||0===h)&&(i+=h),i+='/>\n <p class="help-text-small">\n It looks like Galaxy couldn\'t get proper column headers for this data.\n Would you like to use the column headers above as column names to select columns?\n </p>\n</div>\n\n<button class="render-button btn btn-primary active">Draw</button>\n'}),this.scatterplot.editor=Handlebars.template(function(a,b,c,d,e){this.compilerInfo=[4,">= 1.0.0"],c=this.merge(c,a.helpers),e=e||{};var f="";return f+='<div class="scatterplot-editor tabbable tabs-left">\n \n <ul class="nav nav-tabs">\n \n <li class="active">\n <a title="Use this tab to change which data are used"\n href="#data-control" data-toggle="tab">Data Controls</a>\n </li>\n <li>\n <a title="Use this tab to change how the chart is drawn"\n href="#chart-control" data-toggle="tab" >Chart Controls</a>\n </li>\n \n <li class="disabled">\n <a title="This tab will display the chart"\n href="#chart-display" data-toggle="tab">Chart</a>\n </li>\n \n <li class="file-controls">\n<!-- <button class="copy-btn btn btn-default"\n title="Save this as a new visualization">Save to new</button>-->\n <button class="save-btn btn btn-default">Save</button>\n </li>\n </ul>\n\n \n <div class="tab-content">\n \n <div id="data-control" class="scatterplot-config-control tab-pane active">\n \n </div>\n \n \n <div id="chart-control" class="scatterplot-config-control tab-pane">\n \n </div>\n\n \n <div id="chart-display" class="scatterplot-display tab-pane"></div>\n\n </div>\n</div>\n'});var ScatterplotConfigEditor=Backbone.View.extend(LoggableMixin).extend({className:"scatterplot-control-form",initialize:function(a){if(this.model||(this.model=new Visualization({type:"scatterplot"})),this.log(this+".initialize, attributes:",a),!a||!a.dataset)throw new Error("ScatterplotConfigEditor requires a dataset");this.dataset=a.dataset,this.log("dataset:",this.dataset),this.display=new ScatterplotDisplay({dataset:a.dataset,model:this.model})},render:function(){this.$el.empty().append(ScatterplotConfigEditor.templates.mainLayout({})),this.model.id&&(this.$el.find(".copy-btn").show(),this.$el.find(".save-btn").text("Update saved")),this.$el.find("[title]").tooltip(),this._render_dataControl(),this._render_chartControls(),this._render_chartDisplay();var a=this.model.get("config");return this.model.id&&_.isFinite(a.xColumn)&&_.isFinite(a.yColumn)&&this.renderChart(),this},_render_dataControl:function(a){a=a||this.$el;var b=this,c=this.dataset,d=c.metadata_column_names||[],e=this.model.get("config"),f=[],g=_.map(c.metadata_column_types,function(a,b){var c={index:b,type:a,name:d[b]||"column "+(b+1)};return("int"===c.type||"float"===c.type)&&f.push(c),c});f.length<2&&(f=g);var h=a.find(".tab-pane#data-control");h.html(ScatterplotConfigEditor.templates.dataControl({allColumns:g,numericColumns:f}));var i={xColumn:_.isFinite(e.xColumn)?e.xColumn:f[0].index,yColumn:_.isFinite(e.yColumn)?e.yColumn:f[1].index,idColumn:g[0].index};if(_.isFinite(e.idColumn))i.idColumn=e.idColumn;else if(g.length>2){var j=_.find(g,function(a,b){return b!==i.xColumn&&b!==i.yColumn});i.idColumn=j.index}return e=this.model.set("config",i,{silent:!0}).get("config"),h.find('[name="xColumn"]').val(e.xColumn).on("change",function(){b.model.set("config",{xColumn:Number($(this).val())})}),h.find('[name="yColumn"]').val(e.yColumn).on("change",function(){b.model.set("config",{yColumn:Number($(this).val())})}),h.find('select[name="idColumn"]').val(e.idColumn).on("change",function(){b.model.set("config",{idColumn:Number($(this).val())})}),void 0!==e.idColumn&&h.find("#include-id-checkbox").prop("checked",!0).trigger("change"),h.find("[title]").tooltip(),h},_render_chartControls:function(a){function b(){var a=$(this),b=a.slider("value");c.model.set("config",_.object([[a.parent().data("config-key"),b]])),a.siblings(".slider-output").text(b)}a=a||this.$el;var c=this,d=this.model.get("config"),e=a.find("#chart-control");e.html(ScatterplotConfigEditor.templates.chartControl(d));var f={datapointSize:{min:2,max:10,step:1},width:{min:200,max:800,step:20},height:{min:200,max:800,step:20}};e.find(".numeric-slider-input").each(function(){var a=$(this),c=a.attr("data-config-key"),e=_.extend(f[c],{value:d[c],change:b,slide:b});a.find(".slider").slider(e),a.children(".slider-output").text(d[c])});var g=this.dataset.metadata_column_names||[],h=d.xLabel||g[d.xColumn]||"X",i=d.yLabel||g[d.yColumn]||"Y";return e.find('input[name="X-axis-label"]').val(h).on("change",function(){c.model.set("config",{xLabel:$(this).val()})}),e.find('input[name="Y-axis-label"]').val(i).on("change",function(){c.model.set("config",{yLabel:$(this).val()})}),e.find("[title]").tooltip(),e},_render_chartDisplay:function(a){a=a||this.$el;var b=a.find(".tab-pane#chart-display");return this.display.setElement(b),this.display.render(),b.find("[title]").tooltip(),b},events:{"change #include-id-checkbox":"toggleThirdColumnSelector","click #data-control .render-button":"renderChart","click #chart-control .render-button":"renderChart","click .save-btn":"saveVisualization"},saveVisualization:function(){var a=this;this.model.save().fail(function(b,c,d){console.error(b,c,d),a.trigger("save:error",view),alert("Error loading data:\n"+b.responseText)}).then(function(){a.display.render()})},toggleThirdColumnSelector:function(){this.$el.find('select[name="idColumn"]').parent().toggle()},renderChart:function(){this.$el.find(".nav li.disabled").removeClass("disabled"),this.$el.find("ul.nav").find('a[href="#chart-display"]').tab("show"),this.display.fetchData()},toString:function(){return"ScatterplotConfigEditor("+(this.dataset?this.dataset.id:"")+")"}});ScatterplotConfigEditor.templates={mainLayout:scatterplot.editor,dataControl:scatterplot.datacontrol,chartControl:scatterplot.chartcontrol};var ScatterplotDisplay=Backbone.View.extend({initialize:function(a){this.data=null,this.dataset=a.dataset,this.lineCount=this.dataset.metadata_data_lines||null},fetchData:function(){this.showLoadingIndicator();var a=this,b=this.model.get("config"),c=jQuery.getJSON("/api/datasets/"+this.dataset.id,{data_type:"raw_data",provider:"dataset-column",limit:b.pagination.perPage,offset:b.pagination.currPage*b.pagination.perPage});return c.done(function(b){a.data=b.data,a.trigger("data:fetched",a),a.renderData()}),c.fail(function(b,c,d){console.error(b,c,d),a.trigger("data:error",a),alert("Error loading data:\n"+b.responseText)}),c},showLoadingIndicator:function(){this.$el.find(".scatterplot-data-info").html(['<div class="loading-indicator">','<span class="fa fa-spinner fa-spin"></span>','<span class="loading-indicator-message">loading...</span>',"</div>"].join(""))},template:function(){var a=['<div class="controls clear">','<div class="left">','<div class="page-control"></div>',"</div>",'<div class="right">','<p class="scatterplot-data-info"></p>','<button class="stats-toggle-btn">Stats</button>','<button class="rerender-btn">Redraw</button>',"</div>","</div>","<svg/>",'<div class="stats-display"></div>'].join("");return a},render:function(){return this.$el.addClass("scatterplot-display").html(this.template()),this.data&&this.renderData(),this},renderData:function(){this.renderLeftControls(),this.renderRightControls(),this.renderPlot(this.data),this.getStats()},renderLeftControls:function(){var a=this,b=this.model.get("config");return this.$el.find(".controls .left .page-control").pagination({startingPage:b.pagination.currPage,perPage:b.pagination.perPage,totalDataSize:this.lineCount,currDataSize:this.data.length}).off().on("pagination.page-change",function(c,d){b.pagination.currPage=d,a.model.set("config",{pagination:b.pagination}),a.resetZoom(),a.fetchData()}),this},renderRightControls:function(){var a=this;this.setLineInfo(this.data),this.$el.find(".stats-toggle-btn").off().click(function(){a.toggleStats()}),this.$el.find(".rerender-btn").off().click(function(){a.resetZoom(),a.renderPlot(this.data)})},renderPlot:function(){var a=this,b=this.$el.find("svg");this.toggleStats(!1),b.off().empty().show().on("zoom.scatterplot",function(b,c){a.model.set("config",c)}),scatterplot(b.get(0),this.model.get("config"),this.data)},setLineInfo:function(a,b){if(a){var c=this.model.get("config"),d=this.lineCount||"an unknown total",e=c.pagination.currPage*c.pagination.perPage,f=e+a.length;this.$el.find(".controls p.scatterplot-data-info").text([e+1,"to",f,"of",d].join(" "))}else this.$el.find(".controls p.scatterplot-data-info").html(b||"");return this},resetZoom:function(a,b){return a=void 0!==a?a:1,b=void 0!==b?b:[0,0],this.model.set("config",{scale:a,translate:b}),this},getStats:function(){if(this.data){var a=this,b=this.model.get("config"),c=new Worker("/plugins/visualizations/scatterplot/static/worker-stats.js");c.postMessage({data:this.data,keys:[b.xColumn,b.yColumn]}),c.onerror=function(){c.terminate()},c.onmessage=function(b){a.renderStats(b.data)}}},renderStats:function(a){var b=this.model.get("config"),c=this.$el.find(".stats-display"),d=b.x.label,e=b.y.label,f=$("<table/>").addClass("table").append(["<thead><th></th><th>",d,"</th><th>",e,"</th></thead>"].join("")).append(_.map(a,function(a,b){return $(["<tr><td>",b,"</td><td>",a[0],"</td><td>",a[1],"</td></tr>"].join(""))}));c.empty().append(f)},toggleStats:function(a){var b=this.$el.find(".stats-display");a=void 0===a?b.is(":hidden"):a,a?(this.$el.find("svg").hide(),b.show(),this.$el.find(".controls .stats-toggle-btn").text("Plot")):(b.hide(),this.$el.find("svg").show(),this.$el.find(".controls .stats-toggle-btn").text("Stats"))},toString:function(){return"ScatterplotView()"}}),ScatterplotModel=Visualization.extend({defaults:{type:"scatterplot",config:{pagination:{currPage:0,perPage:3e3},width:400,height:400,margin:{top:16,right:16,bottom:40,left:54},x:{ticks:10,label:"X"},y:{ticks:10,label:"Y"},datapointSize:4,animDuration:500,scale:1,translate:[0,0]}}});
\ No newline at end of file
diff -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae -r b8ff65e15b1b40a76544ef07e7ab98a9b5ce7221 config/plugins/visualizations/scatterplot/static/scatterplot.css
--- a/config/plugins/visualizations/scatterplot/static/scatterplot.css
+++ b/config/plugins/visualizations/scatterplot/static/scatterplot.css
@@ -7,18 +7,36 @@
margin-bottom: 16px;
overflow: auto;
background-color: #ebd9b2;
- padding : 16px 12px 12px 12px;
+ padding : 8px 12px 8px 12px;
}
.chart-header h2 {
margin-bottom: 4px;
}
+.chart-header h2:hover {
+ text-decoration: underline;
+ cursor: pointer;
+}
+
.chart-header p {
- color: white;
+ color: #555;
font-size: small;
}
+figcaption {
+ margin-bottom: 8px;
+ font-size: 120%;
+}
+figcaption .title {
+ display: block;
+ font-weight: bold;
+}
+figcaption .title-info {
+ display: block;
+ font-style: italic;
+}
+
/* -------------------------------------------- main layout */
.scatterplot-editor > * { margin: 0; padding: 0; }
.scatterplot-editor .tab-pane {
diff -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae -r b8ff65e15b1b40a76544ef07e7ab98a9b5ce7221 config/plugins/visualizations/scatterplot/templates/scatterplot.mako
--- a/config/plugins/visualizations/scatterplot/templates/scatterplot.mako
+++ b/config/plugins/visualizations/scatterplot/templates/scatterplot.mako
@@ -18,7 +18,6 @@
## ----------------------------------------------------------------------------
<link type="text/css" rel="Stylesheet" media="screen" href="/static/style/base.css"><link type="text/css" rel="Stylesheet" media="screen" href="/static/style/jquery-ui/smoothness/jquery-ui.css">
-
<link type="text/css" rel="Stylesheet" media="screen" href="/plugins/visualizations/scatterplot/static/scatterplot.css">
## ----------------------------------------------------------------------------
@@ -40,8 +39,35 @@
## ----------------------------------------------------------------------------
<body>
-%if not embedded:
-## dataset info: only show if on own page
+%if embedded and saved_visualization:
+<figcaption>
+ <span class="title">${title}</span>
+ <span class="title-info">${info}</span>
+</figcaption>
+<figure class="scatterplot-display"></div>
+
+<script type="text/javascript">
+$(function(){
+ var model = new ScatterplotModel({
+ id : ${h.to_json_string( visualization_id )} || undefined,
+ title : "${title}",
+ config : ${h.to_json_string( config, indent=2 )}
+ });
+ hdaJson = ${h.to_json_string( trans.security.encode_dict_ids( hda.to_dict() ), indent=2 )},
+ display = new ScatterplotDisplay({
+ el : $( '.scatterplot-display' ).attr( 'id', 'scatterplot-display-' + '${visualization_id}' ),
+ model : model,
+ dataset : hdaJson,
+ embedded: "${embedded}"
+ }).render();
+ display.fetchData();
+ //window.model = model;
+ //window.display = display;
+});
+
+</script>
+
+%else:
<div class="chart-header"><h2>${title or default_title}</h2><p>${info}</p>
@@ -61,10 +87,17 @@
model : model,
dataset : hdaJson
}).render();
- window.editor = editor;
+ //window.editor = editor;
+ $( '.chart-header h2' ).click( function(){
+ var returned = prompt( 'Enter a new title:' );
+ if( returned ){
+ model.set( 'title', returned );
+ }
+ });
model.on( 'change:title', function(){
$( '.chart-header h2' ).text( model.get( 'title' ) );
+ document.title = model.get( 'title' ) + ' | ' + '${visualization_display_name}';
})
});
diff -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae -r b8ff65e15b1b40a76544ef07e7ab98a9b5ce7221 lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -584,6 +584,16 @@
ave_item_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, visualization )
# Display.
+ if trans.app.visualizations_registry and visualization.type in trans.app.visualizations_registry.plugins:
+ # if a registry visualization, load a version of display.mako that will load the vis into an iframe :(
+ #TODO: simplest path from A to B but not optimal - will be difficult to do reg visualizations any other way
+ #TODO: this will load the visualization twice (once above, once when the iframe src calls 'saved')
+ encoded_visualization_id = trans.security.encode_id( visualization.id )
+ return trans.stream_template_mako( 'visualization/display_in_frame.mako',
+ item=visualization, encoded_visualization_id=encoded_visualization_id,
+ user_item_rating=user_item_rating, ave_item_rating=ave_item_rating, num_ratings=num_ratings,
+ content_only=True )
+
visualization_config = self.get_visualization_config( trans, visualization )
return trans.stream_template_mako( "visualization/display.mako", item = visualization, item_data = visualization_config,
user_item_rating = user_item_rating, ave_item_rating=ave_item_rating, num_ratings=num_ratings,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Remove stats/wiggle_to_simple, which is an exact duplicate of filters/wiggle_to_simple.
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3c7e8a024e94/
Changeset: 3c7e8a024e94
User: inithello
Date: 2014-02-14 18:34:58
Summary: Remove stats/wiggle_to_simple, which is an exact duplicate of filters/wiggle_to_simple.
Affected #: 4 files
diff -r 128cbb948cc49ef2a08953f3facd59c409344e56 -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae tool_conf.xml.main
--- a/tool_conf.xml.main
+++ b/tool_conf.xml.main
@@ -95,7 +95,7 @@
<tool file="maf/maf_reverse_complement.xml" /></section><section id="scores" name="Get Genomic Scores">
- <tool file="stats/wiggle_to_simple.xml" />
+ <tool file="filters/wiggle_to_simple.xml" /><tool file="stats/aggregate_binned_scores_in_intervals.xml" /></section><section id="bxops" name="Operate on Genomic Intervals">
diff -r 128cbb948cc49ef2a08953f3facd59c409344e56 -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae tool_conf.xml.sample
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -104,7 +104,7 @@
<tool file="maf/maf_filter.xml" /></section><section id="scores" name="Get Genomic Scores">
- <tool file="stats/wiggle_to_simple.xml" />
+ <tool file="filters/wiggle_to_simple.xml" /><tool file="stats/aggregate_binned_scores_in_intervals.xml" /></section><section id="bxops" name="Operate on Genomic Intervals">
diff -r 128cbb948cc49ef2a08953f3facd59c409344e56 -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae tools/stats/wiggle_to_simple.py
--- a/tools/stats/wiggle_to_simple.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Read a wiggle track and print out a series of lines containing
-"chrom position score". Ignores track lines, handles bed, variableStep
-and fixedStep wiggle lines.
-"""
-import sys
-from galaxy import eggs
-import pkg_resources; pkg_resources.require( "bx-python" )
-import bx.wiggle
-from galaxy.tools.exception_handling import *
-
-def stop_err( msg ):
- sys.stderr.write( msg )
- sys.exit()
-
-def main():
- if len( sys.argv ) > 1:
- in_file = open( sys.argv[1] )
- else:
- in_file = open( sys.stdin )
-
- if len( sys.argv ) > 2:
- out_file = open( sys.argv[2], "w" )
- else:
- out_file = sys.stdout
-
- try:
- for fields in bx.wiggle.IntervalReader( UCSCOutWrapper( in_file ) ):
- out_file.write( "%s\n" % "\t".join( map( str, fields ) ) )
- except UCSCLimitException:
- # Wiggle data was truncated, at the very least need to warn the user.
- print 'Encountered message from UCSC: "Reached output limit of 100000 data values", so be aware your data was truncated.'
- except ValueError, e:
- in_file.close()
- out_file.close()
- stop_err( str( e ) )
-
- in_file.close()
- out_file.close()
-
-if __name__ == "__main__": main()
diff -r 128cbb948cc49ef2a08953f3facd59c409344e56 -r 3c7e8a024e9436eb2d7e970b7721f691728c4dae tools/stats/wiggle_to_simple.xml
--- a/tools/stats/wiggle_to_simple.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<tool id="wiggle2simple1" name="Wiggle-to-Interval">
- <description>converter</description>
- <command interpreter="python">wiggle_to_simple.py $input $out_file1 </command>
- <inputs>
- <param format="wig" name="input" type="data" label="Convert"/>
- </inputs>
- <outputs>
- <data format="interval" name="out_file1" />
- </outputs>
- <tests>
- <test>
- <param name="input" value="2.wig" />
- <output name="out_file1" file="2.interval"/>
- </test>
- <test>
- <param name="input" value="3.wig" />
- <output name="out_file1" file="3_wig.bed"/>
- </test>
- </tests>
- <help>
-**Syntax**
-
-This tool converts wiggle data into interval type.
-
-- **Wiggle format**: The .wig format is line-oriented. Wiggle data is preceded by a UCSC track definition line. Following the track definition line is the track data, which can be entered in three different formats described below.
-
- - **BED format** with no declaration line and four columns of data::
-
- chromA chromStartA chromEndA dataValueA
- chromB chromStartB chromEndB dataValueB
-
- - **variableStep** two column data; started by a declaration line and followed with chromosome positions and data values::
-
- variableStep chrom=chrN [span=windowSize]
- chromStartA dataValueA
- chromStartB dataValueB
-
- - **fixedStep** single column data; started by a declaration line and followed with data values::
-
- fixedStep chrom=chrN start=position step=stepInterval [span=windowSize]
- dataValue1
- dataValue2
-
------
-
-**Example**
-
-- input wiggle format file::
-
- #track type=wiggle_0 name="Bed Format" description="BED format"
- chr19 59302000 59302300 -1.0
- chr19 59302300 59302600 -0.75
- chr19 59302600 59302900 -0.50
- chr19 59302900 59303200 -0.25
- chr19 59303200 59303500 0.0
- #track type=wiggle_0 name="variableStep" description="variableStep format"
- variableStep chrom=chr19 span=150
- 59304701 10.0
- 59304901 12.5
- 59305401 15.0
- 59305601 17.5
- #track type=wiggle_0 name="fixedStep" description="fixed step" visibility=full
- fixedStep chrom=chr19 start=59307401 step=300 span=200
- 1000
- 900
- 800
- 700
- 600
-
-- convert the above file to interval file::
-
- chr19 59302000 59302300 + -1.0
- chr19 59302300 59302600 + -0.75
- chr19 59302600 59302900 + -0.5
- chr19 59302900 59303200 + -0.25
- chr19 59303200 59303500 + 0.0
- chr19 59304701 59304851 + 10.0
- chr19 59304901 59305051 + 12.5
- chr19 59305401 59305551 + 15.0
- chr19 59305601 59305751 + 17.5
- chr19 59307701 59307901 + 1000.0
- chr19 59308001 59308201 + 900.0
- chr19 59308301 59308501 + 800.0
- chr19 59308601 59308801 + 700.0
- chr19 59308901 59309101 + 600.0
-
-</help>
-</tool>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/75672e1cba2b/
Changeset: 75672e1cba2b
Branch: stable
User: dannon
Date: 2014-02-11 17:59:38
Summary: Select2 dynamic loading now uses non-static URL (Should fix main's prefixed URL issue)
Affected #: 1 file
diff -r 6f9059801fafb3b7ae2cf844b07848beab0846fa -r 75672e1cba2bd569b729156f3d8f8f1f994240f0 templates/admin/impersonate.mako
--- a/templates/admin/impersonate.mako
+++ b/templates/admin/impersonate.mako
@@ -30,7 +30,7 @@
$("#email_select").select2({
placeholder: "Select a user",
ajax: {
- url: "/api/users/",
+ url: "${h.url_for(controller="/api/users", action="index")}",
dataType: 'json',
quietMillis: 250,
matcher: function(term, text) { return text.toUpperCase().indexOf(term.toUpperCase())>=0; },
https://bitbucket.org/galaxy/galaxy-central/commits/128cbb948cc4/
Changeset: 128cbb948cc4
User: jmchilton
Date: 2014-02-14 17:54:15
Summary: Merge latest stable.
Affected #: 0 files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Saved visualizations list: use vis-reg plugin display name for type column (if available)
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b0919189ecfa/
Changeset: b0919189ecfa
User: carlfeberhard
Date: 2014-02-14 17:21:51
Summary: Saved visualizations list: use vis-reg plugin display name for type column (if available)
Affected #: 1 file
diff -r 044ead55435801561acdf72fe225209239202a5a -r b0919189ecfa6a779d776dfc5a52f541214ddcc5 lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -202,6 +202,12 @@
url_kwargs[ 'action' ] = 'saved'
return url_kwargs
+ def get_display_name( self, trans, item ):
+ if trans.app.visualizations_registry and item.type in trans.app.visualizations_registry.plugins:
+ plugin = trans.app.visualizations_registry.plugins[ item.type ]
+ return plugin.config.get( 'name', item.type )
+ return item.type
+
# Grid definition
title = "Saved Visualizations"
model_class = model.Visualization
@@ -209,8 +215,7 @@
default_filter = dict( title="All", deleted="False", tags="All", sharing="All" )
columns = [
grids.TextColumn( "Title", key="title", attach_popup=True, link=get_url_args ),
- #TODO: should use display name when available
- grids.TextColumn( "Type", key="type" ),
+ grids.TextColumn( "Type", method='get_display_name' ),
grids.TextColumn( "Dbkey", key="dbkey" ),
grids.IndividualTagsColumn( "Tags", key="tags", model_tag_association_class=model.VisualizationTagAssociation, filterable="advanced", grid_name="VisualizationListGrid" ),
grids.SharingStatusColumn( "Sharing", key="sharing", filterable="advanced", sortable=False ),
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Remove scatterplot from legacy visualization framework (it will no longer appear if you haven't enabled visualization_plugins_directory in your universe_wsgi.ini); clean up; pack scripts
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/044ead554358/
Changeset: 044ead554358
User: carlfeberhard
Date: 2014-02-14 16:47:38
Summary: Remove scatterplot from legacy visualization framework (it will no longer appear if you haven't enabled visualization_plugins_directory in your universe_wsgi.ini); clean up; pack scripts
Affected #: 21 files
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a lib/galaxy/datatypes/tabular.py
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -332,24 +332,6 @@
def as_ucsc_display_file( self, dataset, **kwd ):
return open( dataset.file_name )
- def get_visualizations( self, dataset ):
- """
- Returns a list of visualizations for datatype.
- """
- # Can visualize tabular data as scatterplot if there are 2+ numerical
- # columns.
- num_numerical_cols = 0
- if dataset.metadata.column_types:
- for col_type in dataset.metadata.column_types:
- if col_type in [ 'int', 'float' ]:
- num_numerical_cols += 1
-
- vizs = super( Tabular, self ).get_visualizations( dataset )
- if num_numerical_cols >= 2:
- vizs.append( 'scatterplot' )
-
- return vizs
-
# ------------- Dataproviders
@dataproviders.decorators.dataprovider_factory( 'column', dataproviders.column.ColumnarDataProvider.settings )
def column_dataprovider( self, dataset, **settings ):
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -964,16 +964,6 @@
return self.get_visualization( trans, id )
@web.expose
- def scatterplot( self, trans, dataset_id, **kwargs ):
- """
- Returns a page that controls and renders a scatteplot graph.
- """
- hda = self.get_dataset( trans, dataset_id, check_ownership=False, check_accessible=True )
- return trans.fill_template_mako( "visualization/scatterplot.mako",
- hda=hda,
- query_args=kwargs )
-
- @web.expose
def phyloviz( self, trans, id=None, dataset_id=None, tree_index=0, **kwargs ):
config = None
data = None
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/mvc/dataset/hda-edit.js
--- a/static/scripts/mvc/dataset/hda-edit.js
+++ b/static/scripts/mvc/dataset/hda-edit.js
@@ -197,23 +197,18 @@
// map a function to each visualization in the icon's attributes
// create a popupmenu from that map
- var hdaView = this;
/** @inner */
function create_viz_action( visualization ) {
- switch( visualization ){
- case 'trackster':
- return create_trackster_action_fn( visualization_url, params, dbkey );
- case 'scatterplot':
- return create_scatterplot_action_fn( visualization_url, params, hdaView.linkTarget );
- default:
- return function(){
- Galaxy.frame.add({
- title : "Visualization",
- type : "url",
- content : visualization_url + '/' + visualization + '?' + $.param( params )
- });
- };
+ if( visualization === 'trackster' ){
+ return create_trackster_action_fn( visualization_url, params, dbkey );
}
+ return function(){
+ Galaxy.frame.add({
+ title : "Visualization",
+ type : "url",
+ content : visualization_url + '/' + visualization + '?' + $.param( params )
+ });
+ };
}
function titleCase( string ){
@@ -412,29 +407,6 @@
//==============================================================================
//TODO: these belong somewhere else
-
-/** Create scatterplot loading/set up function for use with the visualizations popupmenu.
- * @param {String} url url (gen. 'visualizations') to which to append 'scatterplot' and params
- * @param {Object} params parameters to convert to query string for splot page
- * @returns function that loads the scatterplot
- */
-//TODO: should be imported from scatterplot.js OR abstracted to 'load this in the galaxy_main frame'
-function create_scatterplot_action_fn( url, params, target ){
- action = function() {
- Galaxy.frame.add({
- title : "Scatterplot",
- type : "url",
- content : url + '/scatterplot?' + $.param(params),
- target : target
- });
-
- //TODO: this needs to go away
- $( 'div.popmenu-wrapper' ).remove();
- return false;
- };
- return action;
-}
-
// -----------------------------------------------------------------------------
/** Create trackster loading/set up function for use with the visualizations popupmenu.
* Shows modal dialog for load old/create new.
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/galaxy.tools.js
--- /dev/null
+++ b/static/scripts/packed/galaxy.tools.js
@@ -0,0 +1,1 @@
+define(["mvc/tools"],function(b){var a=function(d,c){$("input[name='"+d+"'][type='checkbox']").attr("checked",!!c)};$("div.checkUncheckAllPlaceholder").each(function(){var c=$(this).attr("checkbox_name");select_link=$("<a class='action-button'></a>").text("Select All").click(function(){a(c,true)});unselect_link=$("<a class='action-button'></a>").text("Unselect All").click(function(){a(c,false)});$(this).append(select_link).append(" ").append(unselect_link)})});
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/mvc/dataset/hda-edit.js
--- a/static/scripts/packed/mvc/dataset/hda-edit.js
+++ b/static/scripts/packed/mvc/dataset/hda-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(d,a){var f=a.HDABaseView.extend(LoggableMixin).extend({initialize:function(g){a.HDABaseView.prototype.initialize.call(this,g);this.hasUser=g.hasUser;this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton];this.tagsEditorShown=g.tagsEditorShown||false;this.annotationEditorShown=g.annotationEditorShown||false},_render_titleButtons:function(){return a.HDABaseView.prototype._render_titleButtons.call(this).concat([this._render_editButton(),this._render_deleteButton()])},_render_editButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var i=this.model.get("purged"),g=this.model.get("deleted"),h={title:_l("Edit attributes"),href:this.urls.edit,target:this.linkTarget,classes:"dataset-edit"};if(g||i){h.disabled=true;if(i){h.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(g){h.title=_l("Undelete dataset to edit attributes")}}}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){h.disabled=true;h.title=_l("This dataset must finish uploading before it can be edited")}}h.faIcon="fa-pencil";return faIconButton(h)},_render_deleteButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var g=this,h={title:_l("Delete"),classes:"dataset-delete",onclick:function(){g.$el.find(".icon-btn.dataset-delete").trigger("mouseout");g.model["delete"]()}};if(this.model.get("deleted")||this.model.get("purged")){h={title:_l("Dataset is already deleted"),disabled:true}}h.faIcon="fa-times";return faIconButton(h)},_render_errButton:function(){if(this.model.get("state")!==d.HistoryDatasetAssociation.STATES.ERROR){return null}return faIconButton({title:_l("View or report this error"),href:this.urls.report_error,classes:"dataset-report-error-btn",target:this.linkTarget,faIcon:"fa-bug"})},_render_rerunButton:function(){return faIconButton({title:_l("Run this job again"),href:this.urls.rerun,classes:"dataset-rerun-btn",target:this.linkTarget,faIcon:"fa-refresh"})},_render_visualizationsButton:function(){var n=this.model.get("visualizations");if((!this.hasUser)||(!this.model.hasData())||(_.isEmpty(n))){return null}if(_.isObject(n[0])){return this._render_visualizationsFrameworkButton(n)}if(!this.urls.visualization){return null}var k=this.model.get("dbkey"),g=this.urls.visualization,j={},h={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(k){h.dbkey=k}var l=faIconButton({title:_l("Visualize"),classes:"dataset-visualize-btn",faIcon:"fa-bar-chart-o"});var m=this;function i(p){switch(p){case"trackster":return b(g,h,k);case"scatterplot":return e(g,h,m.linkTarget);default:return function(){Galaxy.frame.add({title:"Visualization",type:"url",content:g+"/"+p+"?"+$.param(h)})}}}function o(p){return p.charAt(0).toUpperCase()+p.slice(1)}if(n.length===1){l.attr("data-original-title",_l("Visualize in ")+_l(o(n[0])));l.click(i(n[0]))}else{_.each(n,function(p){j[_l(o(p))]=i(p)});make_popupmenu(l,j)}return l},_render_visualizationsFrameworkButton:function(g){if(!(this.model.hasData())||!(g&&!_.isEmpty(g))){return null}var i=faIconButton({title:_l("Visualize"),classes:"dataset-visualize-btn",faIcon:"fa-bar-chart-o"});if(g.length===1){var h=g[0];i.attr("data-original-title",_l("Visualize in ")+h.html);i.attr("href",h.href)}else{var j=[];_.each(g,function(k){k.func=function(){if(Galaxy.frame.active){Galaxy.frame.add({title:"Visualization",type:"url",content:k.href});return false}return true};j.push(k);return false});PopupMenu.create(i,j)}return i},_buildNewRender:function(){var g=a.HDABaseView.prototype._buildNewRender.call(this);g.find(".dataset-deleted-msg").append(_l('Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk'));g.find(".dataset-hidden-msg").append(_l('Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it'));return g},_render_body_failed_metadata:function(){var h=$("<a/>").attr({href:this.urls.edit,target:this.linkTarget}).text(_l("set it manually or retry auto-detection")),g=$("<span/>").text(". "+_l("You may be able to")+" ").append(h),i=a.HDABaseView.prototype._render_body_failed_metadata.call(this);i.find(".warningmessagesmall strong").append(g);return i},_render_body_error:function(){var g=a.HDABaseView.prototype._render_body_error.call(this);g.find(".dataset-actions .left").prepend(this._render_errButton());return g},_render_body_ok:function(){var g=a.HDABaseView.prototype._render_body_ok.call(this);if(this.model.isDeletedOrPurged()){return g}this.makeDbkeyEditLink(g);if(this.hasUser){g.find(".dataset-actions .left").append(this._render_visualizationsButton());this._renderTags(g);this._renderAnnotation(g)}return g},_renderTags:function(g){var h=this;this.tagsEditor=new TagsEditor({model:this.model,el:g.find(".tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){h.tagsEditorShown=true},onhide:function(){h.tagsEditorShown=false},$activator:faIconButton({title:_l("Edit dataset tags"),classes:"dataset-tag-btn",faIcon:"fa-tags"}).appendTo(g.find(".dataset-actions .right"))});if(this.tagsEditorShown){this.tagsEditor.toggle(true)}},_renderAnnotation:function(g){var h=this;this.annotationEditor=new AnnotationEditor({model:this.model,el:g.find(".annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){h.annotationEditorShown=true},onhide:function(){h.annotationEditorShown=false},$activator:faIconButton({title:_l("Edit dataset annotation"),classes:"dataset-annotate-btn",faIcon:"fa-comment"}).appendTo(g.find(".dataset-actions .right"))});if(this.annotationEditorShown){this.annotationEditor.toggle(true)}},makeDbkeyEditLink:function(h){if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){var g=$('<a class="value">?</a>').attr("href",this.urls.edit).attr("target",this.linkTarget);h.find(".dataset-dbkey .value").replaceWith(g)}},events:_.extend(_.clone(a.HDABaseView.prototype.events),{"click .dataset-undelete":function(g){this.model.undelete();return false},"click .dataset-unhide":function(g){this.model.unhide();return false},"click .dataset-purge":"confirmPurge"}),confirmPurge:function c(g){this.model.purge();return false},toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"HDAView("+g+")"}});function e(g,i,h){action=function(){Galaxy.frame.add({title:"Scatterplot",type:"url",content:g+"/scatterplot?"+$.param(i),target:h});$("div.popmenu-wrapper").remove();return false};return action}function b(g,i,h){return function(){var j={};if(h){j["f-dbkey"]=h}$.ajax({url:g+"/list_tracks?"+$.param(j),dataType:"html",error:function(){alert(("Could not add this dataset to browser")+".")},success:function(k){var l=window.parent;l.Galaxy.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){l.Galaxy.modal.hide()},"View in saved visualization":function(){l.Galaxy.modal.show({title:"Add Data to Saved Visualization",body:k,buttons:{Cancel:function(){l.Galaxy.modal.hide()},"Add to visualization":function(){$(l.document).find("input[name=id]:checked").each(function(){l.Galaxy.modal.hide();var m=$(this).val();i.id=m;l.Galaxy.frame.add({title:"Trackster",type:"url",content:g+"/trackster?"+$.param(i)})})}}})},"View in new visualization":function(){l.Galaxy.modal.hide();var m=g+"/trackster?"+$.param(i);l.Galaxy.frame.add({title:"Trackster",type:"url",content:m})}}})}});return false}}return{HDAEditView:f}});
\ No newline at end of file
+define(["mvc/dataset/hda-model","mvc/dataset/hda-base"],function(d,a){var e=a.HDABaseView.extend(LoggableMixin).extend({initialize:function(f){a.HDABaseView.prototype.initialize.call(this,f);this.hasUser=f.hasUser;this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton,this._render_rerunButton];this.tagsEditorShown=f.tagsEditorShown||false;this.annotationEditorShown=f.annotationEditorShown||false},_render_titleButtons:function(){return a.HDABaseView.prototype._render_titleButtons.call(this).concat([this._render_editButton(),this._render_deleteButton()])},_render_editButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.DISCARDED)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var h=this.model.get("purged"),f=this.model.get("deleted"),g={title:_l("Edit attributes"),href:this.urls.edit,target:this.linkTarget,classes:"dataset-edit"};if(f||h){g.disabled=true;if(h){g.title=_l("Cannot edit attributes of datasets removed from disk")}else{if(f){g.title=_l("Undelete dataset to edit attributes")}}}else{if(this.model.get("state")===d.HistoryDatasetAssociation.STATES.UPLOAD){g.disabled=true;g.title=_l("This dataset must finish uploading before it can be edited")}}g.faIcon="fa-pencil";return faIconButton(g)},_render_deleteButton:function(){if((this.model.get("state")===d.HistoryDatasetAssociation.STATES.NEW)||(this.model.get("state")===d.HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){return null}var f=this,g={title:_l("Delete"),classes:"dataset-delete",onclick:function(){f.$el.find(".icon-btn.dataset-delete").trigger("mouseout");f.model["delete"]()}};if(this.model.get("deleted")||this.model.get("purged")){g={title:_l("Dataset is already deleted"),disabled:true}}g.faIcon="fa-times";return faIconButton(g)},_render_errButton:function(){if(this.model.get("state")!==d.HistoryDatasetAssociation.STATES.ERROR){return null}return faIconButton({title:_l("View or report this error"),href:this.urls.report_error,classes:"dataset-report-error-btn",target:this.linkTarget,faIcon:"fa-bug"})},_render_rerunButton:function(){return faIconButton({title:_l("Run this job again"),href:this.urls.rerun,classes:"dataset-rerun-btn",target:this.linkTarget,faIcon:"fa-refresh"})},_render_visualizationsButton:function(){var f=this.model.get("visualizations");if((!this.hasUser)||(!this.model.hasData())||(_.isEmpty(f))){return null}if(_.isObject(f[0])){return this._render_visualizationsFrameworkButton(f)}if(!this.urls.visualization){return null}var h=this.model.get("dbkey"),l=this.urls.visualization,i={},m={dataset_id:this.model.get("id"),hda_ldda:"hda"};if(h){m.dbkey=h}var g=faIconButton({title:_l("Visualize"),classes:"dataset-visualize-btn",faIcon:"fa-bar-chart-o"});function j(n){if(n==="trackster"){return b(l,m,h)}return function(){Galaxy.frame.add({title:"Visualization",type:"url",content:l+"/"+n+"?"+$.param(m)})}}function k(n){return n.charAt(0).toUpperCase()+n.slice(1)}if(f.length===1){g.attr("data-original-title",_l("Visualize in ")+_l(k(f[0])));g.click(j(f[0]))}else{_.each(f,function(n){i[_l(k(n))]=j(n)});make_popupmenu(g,i)}return g},_render_visualizationsFrameworkButton:function(f){if(!(this.model.hasData())||!(f&&!_.isEmpty(f))){return null}var h=faIconButton({title:_l("Visualize"),classes:"dataset-visualize-btn",faIcon:"fa-bar-chart-o"});if(f.length===1){var g=f[0];h.attr("data-original-title",_l("Visualize in ")+g.html);h.attr("href",g.href)}else{var i=[];_.each(f,function(j){j.func=function(){if(Galaxy.frame.active){Galaxy.frame.add({title:"Visualization",type:"url",content:j.href});return false}return true};i.push(j);return false});PopupMenu.create(h,i)}return h},_buildNewRender:function(){var f=a.HDABaseView.prototype._buildNewRender.call(this);f.find(".dataset-deleted-msg").append(_l('Click <a href="javascript:void(0);" class="dataset-undelete">here</a> to undelete it or <a href="javascript:void(0);" class="dataset-purge">here</a> to immediately remove it from disk'));f.find(".dataset-hidden-msg").append(_l('Click <a href="javascript:void(0);" class="dataset-unhide">here</a> to unhide it'));return f},_render_body_failed_metadata:function(){var g=$("<a/>").attr({href:this.urls.edit,target:this.linkTarget}).text(_l("set it manually or retry auto-detection")),f=$("<span/>").text(". "+_l("You may be able to")+" ").append(g),h=a.HDABaseView.prototype._render_body_failed_metadata.call(this);h.find(".warningmessagesmall strong").append(f);return h},_render_body_error:function(){var f=a.HDABaseView.prototype._render_body_error.call(this);f.find(".dataset-actions .left").prepend(this._render_errButton());return f},_render_body_ok:function(){var f=a.HDABaseView.prototype._render_body_ok.call(this);if(this.model.isDeletedOrPurged()){return f}this.makeDbkeyEditLink(f);if(this.hasUser){f.find(".dataset-actions .left").append(this._render_visualizationsButton());this._renderTags(f);this._renderAnnotation(f)}return f},_renderTags:function(f){var g=this;this.tagsEditor=new TagsEditor({model:this.model,el:f.find(".tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){g.tagsEditorShown=true},onhide:function(){g.tagsEditorShown=false},$activator:faIconButton({title:_l("Edit dataset tags"),classes:"dataset-tag-btn",faIcon:"fa-tags"}).appendTo(f.find(".dataset-actions .right"))});if(this.tagsEditorShown){this.tagsEditor.toggle(true)}},_renderAnnotation:function(f){var g=this;this.annotationEditor=new AnnotationEditor({model:this.model,el:f.find(".annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){g.annotationEditorShown=true},onhide:function(){g.annotationEditorShown=false},$activator:faIconButton({title:_l("Edit dataset annotation"),classes:"dataset-annotate-btn",faIcon:"fa-comment"}).appendTo(f.find(".dataset-actions .right"))});if(this.annotationEditorShown){this.annotationEditor.toggle(true)}},makeDbkeyEditLink:function(g){if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){var f=$('<a class="value">?</a>').attr("href",this.urls.edit).attr("target",this.linkTarget);g.find(".dataset-dbkey .value").replaceWith(f)}},events:_.extend(_.clone(a.HDABaseView.prototype.events),{"click .dataset-undelete":function(f){this.model.undelete();return false},"click .dataset-unhide":function(f){this.model.unhide();return false},"click .dataset-purge":"confirmPurge"}),confirmPurge:function c(f){this.model.purge();return false},toString:function(){var f=(this.model)?(this.model+""):("(no model)");return"HDAView("+f+")"}});function b(f,h,g){return function(){var i={};if(g){i["f-dbkey"]=g}$.ajax({url:f+"/list_tracks?"+$.param(i),dataType:"html",error:function(){alert(("Could not add this dataset to browser")+".")},success:function(j){var k=window.parent;k.Galaxy.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){k.Galaxy.modal.hide()},"View in saved visualization":function(){k.Galaxy.modal.show({title:"Add Data to Saved Visualization",body:j,buttons:{Cancel:function(){k.Galaxy.modal.hide()},"Add to visualization":function(){$(k.document).find("input[name=id]:checked").each(function(){k.Galaxy.modal.hide();var l=$(this).val();h.id=l;k.Galaxy.frame.add({title:"Trackster",type:"url",content:f+"/trackster?"+$.param(h)})})}}})},"View in new visualization":function(){k.Galaxy.modal.hide();var l=f+"/trackster?"+$.param(h);k.Galaxy.frame.add({title:"Trackster",type:"url",content:l})}}})}});return false}}return{HDAEditView:e}});
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};(function(){function a(j,p){var d=27,m=13,c=$(j),e=true,g={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(q){},minSearchLen:0,escWillClear:true,oninit:function(){}};function i(q){var r=$(this).parent().children("input");r.val("");r.trigger("clear:searchInput");p.onclear()}function o(r,q){$(this).trigger("search:searchInput",q);if(typeof p.onfirstsearch==="function"&&e){e=false;p.onfirstsearch(q)}else{p.onsearch(q)}}function f(){return['<input type="text" name="',p.name,'" placeholder="',p.placeholder,'" ','class="search-query ',p.classes,'" ',"/>"].join("")}function l(){return $(f()).focus(function(q){$(this).select()}).keyup(function(r){if(r.which===d&&p.escWillClear){i.call(this,r)}else{var q=$(this).val();if((r.which===m)||(p.minSearchLen&&q.length>=p.minSearchLen)){o.call(this,r,q)}else{if(!q.length){i.call(this,r)}}}}).val(p.initialVal)}function k(){return $(['<span class="search-clear fa fa-times-circle" ','title="',_l("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(q){i.call(this,q)})}function n(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',_l("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function h(){c.find(".search-loading").toggle();c.find(".search-clear").toggle()}if(jQuery.type(p)==="string"){if(p==="toggle-loading"){h()}return c}if(jQuery.type(p)==="object"){p=jQuery.extend(true,{},g,p)}return c.addClass("search-input").prepend([l(),k(),n()])}jQuery.fn.extend({searchInput:function b(c){return this.each(function(){return a(this,c)})}})}());(function(){function b(m,l){this.currModeIndex=0;return this.init(m,l)}b.prototype.DATA_KEY="mode-button";b.prototype.defaults={modes:[{mode:"default"}]};b.prototype.init=function f(m,l){l=l||{};this.$element=$(m);this.options=jQuery.extend(true,{},this.defaults,l);var o=this;this.$element.click(function n(p){o.callModeFn();o._incModeIndex();$(this).html(o.options.modes[o.currModeIndex].html)});this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return this};b.prototype._getModeIndex=function j(l){for(var m=0;m<this.options.modes.length;m+=1){if(this.options.modes[m].mode===l){return m}}throw new Error("mode not found: "+l)};b.prototype.getCurrMode=function a(){return this.options.modes[this.currModeIndex]};b.prototype.getMode=function g(l){if(!l){return this.getCurrMode()}return this.options.modes[(this._getModeIndex(l))]};b.prototype.hasMode=function k(l){return !!this.getMode(l)};b.prototype.currentMode=function e(){return this.options.modes[this.currModeIndex]};b.prototype.setMode=function c(m){var l=this.getMode(m);this.$element.html(l.html||null);return this};b.prototype._incModeIndex=function d(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return this};b.prototype.callModeFn=function h(l){var m=this.getMode(l).onclick;if(m&&jQuery.type(m==="function")){return m.call(this)}return undefined};jQuery.fn.extend({modeButton:function i(m){var l=jQuery.makeArray(arguments).slice(1);return this.map(function(){var p=$(this),o=p.data("mode-button");if(jQuery.type(m)==="object"){o=new b(p,m);p.data("mode-button",o)}else{if(o&&jQuery.type(m)==="string"){var n=o[m];if(jQuery.type(n)==="function"){return n.apply(o,l)}}else{if(o){return o}}}return this})}})}());function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}function dropDownSelect(b,c){c=c||((!_.isEmpty(b))?(b[0]):(""));var a=$(['<div class="dropdown-select btn-group">','<button type="button" class="btn btn-default">','<span class="dropdown-select-selected">'+c+"</span>","</button>","</div>"].join("\n"));if(b&&b.length>1){a.find("button").addClass("dropdown-toggle").attr("data-toggle","dropdown").append(' <span class="caret"></span>');a.append(['<ul class="dropdown-menu" role="menu">',_.map(b,function(e){return['<li><a href="javascript:void(0)">',e,"</a></li>"].join("")}).join("\n"),"</ul>"].join("\n"))}function d(g){var h=$(this),f=h.parents(".dropdown-select"),e=h.text();f.find(".dropdown-select-selected").text(e);f.trigger("change.dropdown-select",e)}a.find("a").click(d);return a}(function(){function e(k,j){return this.init(k,j)}e.prototype.DATA_KEY="filter-control";e.prototype.init=function g(k,j){j=j||{filters:[]};this.$element=$(k).addClass("filter-control btn-group");this.options=jQuery.extend(true,{},this.defaults,j);this.currFilter=this.options.filters[0];return this.render()};e.prototype.render=function d(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return this};e.prototype._renderKeySelect=function a(){var j=this;var k=this.options.filters.map(function(l){return l.key});this.$keySelect=dropDownSelect(k,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(m,l){j.currFilter=_.findWhere(j.options.filters,{key:l});j.render()._triggerChange()});return this.$keySelect};e.prototype._renderOpSelect=function i(){var j=this,k=this.currFilter.ops;this.$opSelect=dropDownSelect(k,k[0]).addClass("filter-control-op").on("change.dropdown-select",function(m,l){j._triggerChange()});return this.$opSelect};e.prototype._renderValueInput=function c(){var j=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(l,k){j._triggerChange()})}else{this.$valueSelect=$("<input/>").addClass("form-control").on("change",function(k,l){j._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return this.$valueSelect};e.prototype.val=function b(){var k=this.$element.find(".filter-control-key .dropdown-select-selected").text(),m=this.$element.find(".filter-control-op .dropdown-select-selected").text(),j=this.$element.find(".filter-control-value"),l=(j.hasClass("dropdown-select"))?(j.find(".dropdown-select-selected").text()):(j.val());return{key:k,op:m,value:l}};e.prototype._triggerChange=function h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function f(k){var j=jQuery.makeArray(arguments).slice(1);return this.map(function(){var n=$(this),m=n.data(e.prototype.DATA_KEY);if(jQuery.type(k)==="object"){m=new e(n,k);n.data(e.prototype.DATA_KEY,m)}if(m&&jQuery.type(k)==="string"){var l=m[k];if(jQuery.type(l)==="function"){return l.apply(m,j)}}return this})}})}());
\ No newline at end of file
+var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}(function(){function a(j,p){var d=27,m=13,c=$(j),e=true,g={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(q){},minSearchLen:0,escWillClear:true,oninit:function(){}};function i(q){var r=$(this).parent().children("input");r.val("");r.trigger("clear:searchInput");p.onclear()}function o(r,q){$(this).trigger("search:searchInput",q);if(typeof p.onfirstsearch==="function"&&e){e=false;p.onfirstsearch(q)}else{p.onsearch(q)}}function f(){return['<input type="text" name="',p.name,'" placeholder="',p.placeholder,'" ','class="search-query ',p.classes,'" ',"/>"].join("")}function l(){return $(f()).focus(function(q){$(this).select()}).keyup(function(r){if(r.which===d&&p.escWillClear){i.call(this,r)}else{var q=$(this).val();if((r.which===m)||(p.minSearchLen&&q.length>=p.minSearchLen)){o.call(this,r,q)}else{if(!q.length){i.call(this,r)}}}}).val(p.initialVal)}function k(){return $(['<span class="search-clear fa fa-times-circle" ','title="',_l("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(q){i.call(this,q)})}function n(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',_l("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function h(){c.find(".search-loading").toggle();c.find(".search-clear").toggle()}if(jQuery.type(p)==="string"){if(p==="toggle-loading"){h()}return c}if(jQuery.type(p)==="object"){p=jQuery.extend(true,{},g,p)}return c.addClass("search-input").prepend([l(),k(),n()])}jQuery.fn.extend({searchInput:function b(c){return this.each(function(){return a(this,c)})}})}());(function(){function b(m,l){this.currModeIndex=0;return this.init(m,l)}b.prototype.DATA_KEY="mode-button";b.prototype.defaults={modes:[{mode:"default"}]};b.prototype.init=function f(m,l){l=l||{};this.$element=$(m);this.options=jQuery.extend(true,{},this.defaults,l);var o=this;this.$element.click(function n(p){o.callModeFn();o._incModeIndex();$(this).html(o.options.modes[o.currModeIndex].html)});this.currModeIndex=0;if(this.options.initialMode){this.currModeIndex=this._getModeIndex(this.options.initialMode)}return this};b.prototype._getModeIndex=function j(l){for(var m=0;m<this.options.modes.length;m+=1){if(this.options.modes[m].mode===l){return m}}throw new Error("mode not found: "+l)};b.prototype.getCurrMode=function a(){return this.options.modes[this.currModeIndex]};b.prototype.getMode=function g(l){if(!l){return this.getCurrMode()}return this.options.modes[(this._getModeIndex(l))]};b.prototype.hasMode=function k(l){return !!this.getMode(l)};b.prototype.currentMode=function e(){return this.options.modes[this.currModeIndex]};b.prototype.setMode=function c(m){var l=this.getMode(m);this.$element.html(l.html||null);return this};b.prototype._incModeIndex=function d(){this.currModeIndex+=1;if(this.currModeIndex>=this.options.modes.length){this.currModeIndex=0}return this};b.prototype.callModeFn=function h(l){var m=this.getMode(l).onclick;if(m&&jQuery.type(m==="function")){return m.call(this)}return undefined};jQuery.fn.extend({modeButton:function i(m){var l=jQuery.makeArray(arguments).slice(1);return this.map(function(){var p=$(this),o=p.data("mode-button");if(jQuery.type(m)==="object"){o=new b(p,m);p.data("mode-button",o)}else{if(o&&jQuery.type(m)==="string"){var n=o[m];if(jQuery.type(n)==="function"){return n.apply(o,l)}}else{if(o){return o}}}return this})}})}());function dropDownSelect(b,c){c=c||((!_.isEmpty(b))?(b[0]):(""));var a=$(['<div class="dropdown-select btn-group">','<button type="button" class="btn btn-default">','<span class="dropdown-select-selected">'+c+"</span>","</button>","</div>"].join("\n"));if(b&&b.length>1){a.find("button").addClass("dropdown-toggle").attr("data-toggle","dropdown").append(' <span class="caret"></span>');a.append(['<ul class="dropdown-menu" role="menu">',_.map(b,function(e){return['<li><a href="javascript:void(0)">',e,"</a></li>"].join("")}).join("\n"),"</ul>"].join("\n"))}function d(g){var h=$(this),f=h.parents(".dropdown-select"),e=h.text();f.find(".dropdown-select-selected").text(e);f.trigger("change.dropdown-select",e)}a.find("a").click(d);return a}(function(){function e(k,j){return this.init(k,j)}e.prototype.DATA_KEY="filter-control";e.prototype.init=function g(k,j){j=j||{filters:[]};this.$element=$(k).addClass("filter-control btn-group");this.options=jQuery.extend(true,{},this.defaults,j);this.currFilter=this.options.filters[0];return this.render()};e.prototype.render=function d(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return this};e.prototype._renderKeySelect=function a(){var j=this;var k=this.options.filters.map(function(l){return l.key});this.$keySelect=dropDownSelect(k,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(m,l){j.currFilter=_.findWhere(j.options.filters,{key:l});j.render()._triggerChange()});return this.$keySelect};e.prototype._renderOpSelect=function i(){var j=this,k=this.currFilter.ops;this.$opSelect=dropDownSelect(k,k[0]).addClass("filter-control-op").on("change.dropdown-select",function(m,l){j._triggerChange()});return this.$opSelect};e.prototype._renderValueInput=function c(){var j=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(l,k){j._triggerChange()})}else{this.$valueSelect=$("<input/>").addClass("form-control").on("change",function(k,l){j._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return this.$valueSelect};e.prototype.val=function b(){var k=this.$element.find(".filter-control-key .dropdown-select-selected").text(),m=this.$element.find(".filter-control-op .dropdown-select-selected").text(),j=this.$element.find(".filter-control-value"),l=(j.hasClass("dropdown-select"))?(j.find(".dropdown-select-selected").text()):(j.val());return{key:k,op:m,value:l}};e.prototype._triggerChange=function h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function f(k){var j=jQuery.makeArray(arguments).slice(1);return this.map(function(){var n=$(this),m=n.data(e.prototype.DATA_KEY);if(jQuery.type(k)==="object"){m=new e(n,k);n.data(e.prototype.DATA_KEY,m)}if(m&&jQuery.type(k)==="string"){var l=m[k];if(jQuery.type(l)==="function"){return l.apply(m,j)}}return this})}})}());(function(){function i(o,n){this.numPages=null;this.currPage=0;return this.init(o,n)}i.prototype.DATA_KEY="pagination";i.prototype.defaults={startingPage:0,perPage:20,totalDataSize:null,currDataSize:null};i.prototype.init=function g(n,o){o=o||{};this.$element=n;this.options=jQuery.extend(true,{},this.defaults,o);this.currPage=this.options.startingPage;if(this.options.totalDataSize!==null){this.numPages=Math.ceil(this.options.totalDataSize/this.options.perPage);if(this.currPage>=this.numPages){this.currPage=this.numPages-1}}this.$element.data(i.prototype.DATA_KEY,this);this._render();return this};function m(n){return $(['<li><a href="javascript:void(0);">',n,"</a></li>"].join(""))}i.prototype._render=function e(){if(this.options.totalDataSize===0){return this}if(this.numPages===1){return this}if(this.numPages>0){this._renderPages();this._scrollToActivePage()}else{this._renderPrevNext()}return this};i.prototype._renderPrevNext=function b(){var o=this,p=m("Prev"),n=m("Next"),q=$("<ul/>").addClass("pagination pagination-prev-next");if(this.currPage===0){p.addClass("disabled")}else{p.click(function(){o.prevPage()})}if((this.numPages&&this.currPage===(this.numPages-1))||(this.options.currDataSize&&this.options.currDataSize<this.options.perPage)){n.addClass("disabled")}else{n.click(function(){o.nextPage()})}this.$element.html(q.append([p,n]));return this.$element};i.prototype._renderPages=function a(){var n=this,q=$("<div>").addClass("pagination-scroll-container"),s=$("<ul/>").addClass("pagination pagination-page-list"),r=function(t){n.goToPage($(this).data("page"))};for(var o=0;o<this.numPages;o+=1){var p=m(o+1).attr("data-page",o).click(r);if(o===this.currPage){p.addClass("active")}s.append(p)}return this.$element.html(q.html(s))};i.prototype._scrollToActivePage=function l(){var p=this.$element.find(".pagination-scroll-container");if(!p.size()){return this}var o=this.$element.find("li.active"),n=p.width()/2;p.scrollLeft(p.scrollLeft()+o.position().left-n);return this};i.prototype.goToPage=function j(n){if(n<=0){n=0}if(this.numPages&&n>=this.numPages){n=this.numPages-1}if(n===this.currPage){return this}this.currPage=n;this.$element.trigger("pagination.page-change",this.currPage);this._render();return this};i.prototype.prevPage=function c(){return this.goToPage(this.currPage-1)};i.prototype.nextPage=function h(){return this.goToPage(this.currPage+1)};i.prototype.page=function f(){return this.currPage};i.create=function k(n,o){return new i(n,o)};jQuery.fn.extend({pagination:function d(o){var n=jQuery.makeArray(arguments).slice(1);if(jQuery.type(o)==="object"){return this.map(function(){i.create($(this),o);return this})}var q=$(this[0]),r=q.data(i.prototype.DATA_KEY);if(r){if(jQuery.type(o)==="string"){var p=r[o];if(jQuery.type(p)==="function"){return p.apply(r,n)}}else{return r}}return undefined}})}());
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/templates/compiled/template-visualization-chartControl.js
--- a/static/scripts/packed/templates/compiled/template-visualization-chartControl.js
+++ /dev/null
@@ -1,1 +0,0 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-visualization-chartControl"]=b(function(f,l,e,k,j){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,f.helpers);j=j||{};var h="",c,g="function",i=this.escapeExpression,m=this;function d(o,n){return' checked="true"'}h+='<p class="help-text">\n Use the following controls to how the chart is displayed.\n The slide controls can be moved by the mouse or, if the \'handle\' is in focus, your keyboard\'s arrow keys.\n Move the focus between controls by using the tab or shift+tab keys on your keyboard.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n </p>\n\n <div id="datapointSize" class="form-input numeric-slider-input">\n <label for="datapointSize">Size of data point: </label>\n <div class="slider-output">';if(c=e.datapointSize){c=c.call(l,{hash:{},data:j})}else{c=l.datapointSize;c=typeof c===g?c.apply(l):c}h+=i(c)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n Size of the graphic representation of each data point\n </p>\n </div>\n\n <div id="animDuration" class="form-input checkbox-input">\n <label for="animate-chart">Animate chart transitions?: </label>\n <input type="checkbox" id="animate-chart"\n class="checkbox control"';c=e["if"].call(l,l.animDuration,{hash:{},inverse:m.noop,fn:m.program(1,d,j),data:j});if(c||c===0){h+=c}h+=' />\n <p class="form-help help-text-small">\n Uncheck this to disable the animations used on the chart\n </p>\n </div>\n\n <div id="width" class="form-input numeric-slider-input">\n <label for="width">Chart width: </label>\n <div class="slider-output">';if(c=e.width){c=c.call(l,{hash:{},data:j})}else{c=l.width;c=typeof c===g?c.apply(l):c}h+=i(c)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n </div>\n\n <div id="height" class="form-input numeric-slider-input">\n <label for="height">Chart height: </label>\n <div class="slider-output">';if(c=e.height){c=c.call(l,{hash:{},data:j})}else{c=l.height;c=typeof c===g?c.apply(l):c}h+=i(c)+'</div>\n <div class="slider"></div>\n <p class="form-help help-text-small">\n (not including chart margins and axes)\n </p>\n </div>\n\n <div id="X-axis-label"class="text-input form-input">\n <label for="X-axis-label">Re-label the X axis: </label>\n <input type="text" name="X-axis-label" id="X-axis-label" value="';if(c=e.xLabel){c=c.call(l,{hash:{},data:j})}else{c=l.xLabel;c=typeof c===g?c.apply(l):c}h+=i(c)+'" />\n <p class="form-help help-text-small"></p>\n </div>\n\n <div id="Y-axis-label" class="text-input form-input">\n <label for="Y-axis-label">Re-label the Y axis: </label>\n <input type="text" name="Y-axis-label" id="Y-axis-label" value="';if(c=e.yLabel){c=c.call(l,{hash:{},data:j})}else{c=l.yLabel;c=typeof c===g?c.apply(l):c}h+=i(c)+'" />\n <p class="form-help help-text-small"></p>\n </div>\n\n <input id="render-button" type="button" value="Draw" />';return h})})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/templates/compiled/template-visualization-chartDisplay.js
--- a/static/scripts/packed/templates/compiled/template-visualization-chartDisplay.js
+++ /dev/null
@@ -1,1 +0,0 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-visualization-chartDisplay"]=b(function(e,k,d,j,i){this.compilerInfo=[4,">= 1.0.0"];d=this.merge(d,e.helpers);i=i||{};var g="",c,f="function",h=this.escapeExpression;g+='<svg width="';if(c=d.width){c=c.call(k,{hash:{},data:i})}else{c=k.width;c=typeof c===f?c.apply(k):c}g+=h(c)+'" height="';if(c=d.height){c=c.call(k,{hash:{},data:i})}else{c=k.height;c=typeof c===f?c.apply(k):c}g+=h(c)+'"></svg>';return g})})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/templates/compiled/template-visualization-dataControl.js
--- a/static/scripts/packed/templates/compiled/template-visualization-dataControl.js
+++ /dev/null
@@ -1,1 +0,0 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-visualization-dataControl"]=b(function(g,m,f,l,k){this.compilerInfo=[4,">= 1.0.0"];f=this.merge(f,g.helpers);k=k||{};var i="",d,h="function",j=this.escapeExpression,n=this;function e(r,q){var o="",p;o+='\n <option value="';if(p=f.index){p=p.call(r,{hash:{},data:q})}else{p=r.index;p=typeof p===h?p.apply(r):p}o+=j(p)+'">';if(p=f.name){p=p.call(r,{hash:{},data:q})}else{p=r.name;p=typeof p===h?p.apply(r):p}o+=j(p)+"</option>\n ";return o}function c(p,o){return'checked="true"'}i+='<p class="help-text">\n Use the following controls to change the data used by the chart.\n Use the \'Draw\' button to render (or re-render) the chart with the current settings.\n </p>\n\n \n <div class="column-select">\n <label for="X-select">Data column for X: </label>\n <select name="X" id="X-select">\n ';d=f.each.call(m,m.numericColumns,{hash:{},inverse:n.noop,fn:n.program(1,e,k),data:k});if(d||d===0){i+=d}i+='\n </select>\n </div>\n <div class="column-select">\n <label for="Y-select">Data column for Y: </label>\n <select name="Y" id="Y-select">\n ';d=f.each.call(m,m.numericColumns,{hash:{},inverse:n.noop,fn:n.program(1,e,k),data:k});if(d||d===0){i+=d}i+='\n </select>\n </div>\n\n \n <div id="include-id">\n <label for="include-id-checkbox">Include a third column as data point IDs?</label>\n <input type="checkbox" name="include-id" id="include-id-checkbox" />\n <p class="help-text-small">\n These will be displayed (along with the x and y values) when you hover over\n a data point.\n </p>\n </div>\n <div class="column-select" style="display: none">\n <label for="ID-select">Data column for IDs: </label>\n <select name="ID" id="ID-select">\n ';d=f.each.call(m,m.allColumns,{hash:{},inverse:n.noop,fn:n.program(1,e,k),data:k});if(d||d===0){i+=d}i+='\n </select>\n </div>\n\n \n <div id="first-line-header" style="display: none;">\n <p>Possible headers: ';if(d=f.possibleHeaders){d=d.call(m,{hash:{},data:k})}else{d=m.possibleHeaders;d=typeof d===h?d.apply(m):d}i+=j(d)+'\n </p>\n <label for="first-line-header-checkbox">Use the above as column headers?</label>\n <input type="checkbox" name="include-id" id="first-line-header-checkbox"\n ';d=f["if"].call(m,m.usePossibleHeaders,{hash:{},inverse:n.noop,fn:n.program(3,c,k),data:k});if(d||d===0){i+=d}i+='/>\n <p class="help-text-small">\n It looks like Galaxy couldn\'t get proper column headers for this data.\n Would you like to use the column headers above as column names to select columns?\n </p>\n </div>\n\n <input id="render-button" type="button" value="Draw" />\n <div class="clear"></div>';return i})})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/templates/compiled/template-visualization-scatterplotControlForm.js
--- a/static/scripts/packed/templates/compiled/template-visualization-scatterplotControlForm.js
+++ /dev/null
@@ -1,1 +0,0 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-visualization-scatterplotControlForm"]=b(function(e,k,d,j,i){this.compilerInfo=[4,">= 1.0.0"];d=this.merge(d,e.helpers);i=i||{};var g="",c,f="function",h=this.escapeExpression;g+='\n\n<div class="scatterplot-container chart-container tabbable tabs-left">\n \n <ul class="nav nav-tabs">\n \n <li class="active"><a href="#data-control" data-toggle="tab"\n title="Use this tab to change which data are used">Data Controls</a></li>\n <li><a href="#chart-control" data-toggle="tab"\n title="Use this tab to change how the chart is drawn">Chart Controls</a></li>\n <li><a href="#stats-display" data-toggle="tab"\n title="This tab will display overall statistics for your data">Statistics</a></li>\n <li><a href="#chart-display" data-toggle="tab"\n title="This tab will display the chart">Chart</a>\n \n <div id="loading-indicator" style="display: none;">\n <img class="loading-img" src="';if(c=d.loadingIndicatorImagePath){c=c.call(k,{hash:{},data:i})}else{c=k.loadingIndicatorImagePath;c=typeof c===f?c.apply(k):c}g+=h(c)+'" />\n <span class="loading-message">';if(c=d.message){c=c.call(k,{hash:{},data:i})}else{c=k.message;c=typeof c===f?c.apply(k):c}g+=h(c)+'</span>\n </div>\n </li>\n </ul>\n\n \n <div class="tab-content">\n \n <div id="data-control" class="tab-pane active">\n \n </div>\n \n \n <div id="chart-control" class="tab-pane">\n \n </div>\n\n \n <div id="stats-display" class="tab-pane">\n \n </div>\n\n \n <div id="chart-display" class="tab-pane">\n \n </div>\n\n </div>\n</div>';return g})})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/templates/compiled/template-visualization-statsDisplay.js
--- a/static/scripts/packed/templates/compiled/template-visualization-statsDisplay.js
+++ /dev/null
@@ -1,1 +0,0 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-visualization-statsDisplay"]=b(function(f,l,e,k,j){this.compilerInfo=[4,">= 1.0.0"];e=this.merge(e,f.helpers);j=j||{};var h="",c,g="function",i=this.escapeExpression,m=this;function d(q,p){var n="",o;n+="\n <tr><td>";if(o=e.name){o=o.call(q,{hash:{},data:p})}else{o=q.name;o=typeof o===g?o.apply(q):o}n+=i(o)+"</td><td>";if(o=e.xval){o=o.call(q,{hash:{},data:p})}else{o=q.xval;o=typeof o===g?o.apply(q):o}n+=i(o)+"</td><td>";if(o=e.yval){o=o.call(q,{hash:{},data:p})}else{o=q.yval;o=typeof o===g?o.apply(q):o}n+=i(o)+"</td></tr>\n </tr>\n ";return n}h+='<p class="help-text">By column:</p>\n <table id="chart-stats-table">\n <thead><th></th><th>X</th><th>Y</th></thead>\n ';c=e.each.call(l,l.stats,{hash:{},inverse:m.noop,fn:m.program(1,d,j),data:j});if(c||c===0){h+=c}h+="\n </table>";return h})})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/packed/viz/scatterplot.js
--- a/static/scripts/packed/viz/scatterplot.js
+++ /dev/null
@@ -1,1 +0,0 @@
-function TwoVarScatterplot(d){var b=10,f=7,e=10,c=8,a=5;this.log=function(){if(this.debugging&&console&&console.debug){var g=Array.prototype.slice.call(arguments);g.unshift(this.toString());console.debug.apply(console,g)}};this.log("new TwoVarScatterplot:",d);this.defaults={id:"TwoVarScatterplot",containerSelector:"body",maxDataPoints:30000,datapointSize:4,animDuration:500,xNumTicks:10,yNumTicks:10,xAxisLabelBumpY:40,yAxisLabelBumpX:-40,width:400,height:400,marginTop:50,marginRight:50,marginBottom:50,marginLeft:50,xMin:null,xMax:null,yMin:null,yMax:null,xLabel:"X",yLabel:"Y"};this.config=_.extend({},this.defaults,d);this.log("intial config:",this.config);this.updateConfig=function(g,h){_.extend(this.config,g);this.log(this+".updateConfig:",this.config)};this.toString=function(){return this.config.id};this.translateStr=function(g,h){return"translate("+g+","+h+")"};this.rotateStr=function(h,g,i){return"rotate("+h+","+g+","+i+")"};this.adjustChartDimensions=function(j,h,g,i){j=j||0;h=h||0;g=g||0;i=i||0;this.svg.attr("width",this.config.width+(this.config.marginRight+h)+(this.config.marginLeft+i)).attr("height",this.config.height+(this.config.marginTop+j)+(this.config.marginBottom+g)).style("display","block");this.content=this.svg.select("g.content").attr("transform",this.translateStr(this.config.marginLeft+i,this.config.marginTop+j))};this.preprocessData=function(i,h,g){return(i.length>this.config.maxDataPoints)?(i.slice(0,this.config.maxDataPoints)):(i)};this.findMinMaxes=function(g,i,h){this.xMin=this.config.xMin||(h)?(h[0].min):(d3.min(g));this.xMax=this.config.xMax||(h)?(h[0].max):(d3.max(g));this.yMin=this.config.yMin||(h)?(h[1].min):(d3.min(i));this.yMax=this.config.yMax||(h)?(h[1].max):(d3.max(i))};this.setUpScales=function(){this.xScale=d3.scale.linear().domain([this.xMin,this.xMax]).range([0,this.config.width]),this.yScale=d3.scale.linear().domain([this.yMin,this.yMax]).range([this.config.height,0])};this.setUpXAxis=function(){this.xAxisFn=d3.svg.axis().scale(this.xScale).ticks(this.config.xNumTicks).orient("bottom");this.xAxis.attr("transform",this.translateStr(0,this.config.height)).call(this.xAxisFn);var g=d3.max(_.map([this.xMin,this.xMax],function(h){return(String(h)).length}));if(g>=a){this.xAxis.selectAll("g").filter(":nth-child(odd)").style("display","none")}this.log("this.config.xLabel:",this.config.xLabel);this.xAxisLabel.attr("x",this.config.width/2).attr("y",this.config.xAxisLabelBumpY).attr("text-anchor","middle").text(this.config.xLabel);this.log("xAxisLabel:",this.xAxisLabel)};this.setUpYAxis=function(){this.yAxisFn=d3.svg.axis().scale(this.yScale).ticks(this.config.yNumTicks).orient("left");this.yAxis.call(this.yAxisFn);var g=this.yAxis.selectAll("text").filter(function(k,j){return j!==0});this.log("yTickLabels:",g);this.yLongestLabel=d3.max(g[0].map(function(k,j){return(d3.select(k).text()).length}))||0;var h=b+(this.yLongestLabel*f)+c+e;this.config.yAxisLabelBumpX=-(h-e);if(this.config.marginLeft<h){var i=(h)-this.config.marginLeft;i=(i<0)?(0):(i);this.adjustChartDimensions(0,0,0,i)}this.yAxisLabel.attr("x",this.config.yAxisLabelBumpX).attr("y",this.config.height/2).attr("text-anchor","middle").attr("transform",this.rotateStr(-90,this.config.yAxisLabelBumpX,this.config.height/2)).text(this.config.yLabel)};this.renderGrid=function(){this.vGridLines=this.content.selectAll("line.v-grid-line").data(this.xScale.ticks(this.xAxisFn.ticks()[0]));this.vGridLines.enter().append("svg:line").classed("grid-line v-grid-line",true);this.vGridLines.attr("x1",this.xScale).attr("y1",0).attr("x2",this.xScale).attr("y2",this.config.height);this.vGridLines.exit().remove();this.hGridLines=this.content.selectAll("line.h-grid-line").data(this.yScale.ticks(this.yAxisFn.ticks()[0]));this.hGridLines.enter().append("svg:line").classed("grid-line h-grid-line",true);this.hGridLines.attr("x1",0).attr("y1",this.yScale).attr("x2",this.config.width).attr("y2",this.yScale);this.hGridLines.exit().remove()};this.renderDatapoints=function(g,n,j){this.log(this+".renderDatapoints",arguments);var k=0,m=this,i=function(p,o){return m.xScale(g[o])},h=function(p,o){return m.yScale(n[o])};var l=this.content.selectAll(".glyph").data(g);k=0;l.enter().append("svg:circle").each(function(){k+=1}).classed("glyph",true).attr("cx",0).attr("cy",this.config.height).attr("r",0);this.log(k," new glyphs created");k=0;l.transition().duration(this.config.animDuration).each(function(){k+=1}).attr("cx",i).attr("cy",h).attr("r",m.config.datapointSize);this.log(k," existing glyphs transitioned");l.exit().each(function(){k+=1}).transition().duration(this.config.animDuration).attr("cy",this.config.height).attr("r",0).remove();this.log(k," glyphs removed");this._addDatapointEventhandlers(l,g,n,j)};this._addDatapointEventhandlers=function(j,g,k,h){var i=this;j.on("mouseover",function(o,l){var n=d3.select(this);n.style("fill","red").style("fill-opacity",1);i.content.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",n.attr("cx")-i.config.datapointSize).attr("y1",n.attr("cy")).attr("x2",0).attr("y2",n.attr("cy")).classed("hoverline",true);if(n.attr("cy")<i.config.height){i.content.append("line").attr("stroke","red").attr("stroke-width",1).attr("x1",n.attr("cx")).attr("y1",n.attr("cy")+i.config.datapointSize).attr("x2",n.attr("cx")).attr("y2",i.config.height).classed("hoverline",true)}var m=$(this).offset();i.datapointInfoBox=i.infoBox(m.top,m.left,i.infoHtml(g[l],k[l],(h)?(h[l]):(undefined)));$("body").append(i.datapointInfoBox)}).on("mouseout",function(){d3.select(this).style("fill","black").style("fill-opacity",0.2);i.content.selectAll(".hoverline").remove();if(i.datapointInfoBox){i.datapointInfoBox.remove()}})},this.render=function(i,j){this.log(this+".render",arguments);this.log("\t config:",this.config);var g=i[0],k=i[1],h=(i.length>2)?(i[2]):(undefined);g=this.preprocessData(g);k=this.preprocessData(k);this.log("xCol len",g.length,"yCol len",k.length);this.findMinMaxes(g,k,j);this.setUpScales();if(!this.svg){this.svg=d3.select("svg").attr("class","chart")}if(!this.content){this.content=this.svg.append("svg:g").attr("class","content").attr("id",this.config.id)}this.adjustChartDimensions();if(!this.xAxis){this.xAxis=this.content.append("g").attr("class","axis").attr("id","x-axis")}if(!this.xAxisLabel){this.xAxisLabel=this.xAxis.append("text").attr("class","axis-label").attr("id","x-axis-label")}if(!this.yAxis){this.yAxis=this.content.append("g").attr("class","axis").attr("id","y-axis")}if(!this.yAxisLabel){this.yAxisLabel=this.yAxis.append("text").attr("class","axis-label").attr("id","y-axis-label")}this.setUpXAxis();this.setUpYAxis();this.renderGrid();this.renderDatapoints(g,k,h)};this.infoHtml=function(g,j,i){var h=$("<div/>");if(i){$("<div/>").text(i).css("font-weight","bold").appendTo(h)}$("<div/>").text(g).appendTo(h);$("<div/>").text(j).appendTo(h);return h.html()};this.infoBox=function(l,k,i,h,g){h=h||0;g=g||20;var j=$("<div />").addClass("chart-info-box").css({position:"absolute",top:l+h,left:k+g});j.html(i);return j}};
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/templates/compiled/template-visualization-chartControl.js
--- a/static/scripts/templates/compiled/template-visualization-chartControl.js
+++ /dev/null
@@ -1,40 +0,0 @@
-(function() {
- var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
-templates['template-visualization-chartControl'] = template(function (Handlebars,depth0,helpers,partials,data) {
- this.compilerInfo = [4,'>= 1.0.0'];
-helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
- var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this;
-
-function program1(depth0,data) {
-
-
- return " checked=\"true\"";
- }
-
- buffer += "<p class=\"help-text\">\n Use the following controls to how the chart is displayed.\n The slide controls can be moved by the mouse or, if the 'handle' is in focus, your keyboard's arrow keys.\n Move the focus between controls by using the tab or shift+tab keys on your keyboard.\n Use the 'Draw' button to render (or re-render) the chart with the current settings.\n </p>\n\n <div id=\"datapointSize\" class=\"form-input numeric-slider-input\">\n <label for=\"datapointSize\">Size of data point: </label>\n <div class=\"slider-output\">";
- if (stack1 = helpers.datapointSize) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.datapointSize; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</div>\n <div class=\"slider\"></div>\n <p class=\"form-help help-text-small\">\n Size of the graphic representation of each data point\n </p>\n </div>\n\n <div id=\"animDuration\" class=\"form-input checkbox-input\">\n <label for=\"animate-chart\">Animate chart transitions?: </label>\n <input type=\"checkbox\" id=\"animate-chart\"\n class=\"checkbox control\"";
- stack1 = helpers['if'].call(depth0, depth0.animDuration, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
- if(stack1 || stack1 === 0) { buffer += stack1; }
- buffer += " />\n <p class=\"form-help help-text-small\">\n Uncheck this to disable the animations used on the chart\n </p>\n </div>\n\n <div id=\"width\" class=\"form-input numeric-slider-input\">\n <label for=\"width\">Chart width: </label>\n <div class=\"slider-output\">";
- if (stack1 = helpers.width) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.width; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</div>\n <div class=\"slider\"></div>\n <p class=\"form-help help-text-small\">\n (not including chart margins and axes)\n </p>\n </div>\n\n <div id=\"height\" class=\"form-input numeric-slider-input\">\n <label for=\"height\">Chart height: </label>\n <div class=\"slider-output\">";
- if (stack1 = helpers.height) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.height; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</div>\n <div class=\"slider\"></div>\n <p class=\"form-help help-text-small\">\n (not including chart margins and axes)\n </p>\n </div>\n\n <div id=\"X-axis-label\"class=\"text-input form-input\">\n <label for=\"X-axis-label\">Re-label the X axis: </label>\n <input type=\"text\" name=\"X-axis-label\" id=\"X-axis-label\" value=\"";
- if (stack1 = helpers.xLabel) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.xLabel; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\" />\n <p class=\"form-help help-text-small\"></p>\n </div>\n\n <div id=\"Y-axis-label\" class=\"text-input form-input\">\n <label for=\"Y-axis-label\">Re-label the Y axis: </label>\n <input type=\"text\" name=\"Y-axis-label\" id=\"Y-axis-label\" value=\"";
- if (stack1 = helpers.yLabel) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.yLabel; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\" />\n <p class=\"form-help help-text-small\"></p>\n </div>\n\n <input id=\"render-button\" type=\"button\" value=\"Draw\" />";
- return buffer;
- });
-})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/templates/compiled/template-visualization-chartDisplay.js
--- a/static/scripts/templates/compiled/template-visualization-chartDisplay.js
+++ /dev/null
@@ -1,20 +0,0 @@
-(function() {
- var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
-templates['template-visualization-chartDisplay'] = template(function (Handlebars,depth0,helpers,partials,data) {
- this.compilerInfo = [4,'>= 1.0.0'];
-helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
- var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression;
-
-
- buffer += "<svg width=\"";
- if (stack1 = helpers.width) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.width; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\" height=\"";
- if (stack1 = helpers.height) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.height; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\"></svg>";
- return buffer;
- });
-})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/templates/compiled/template-visualization-dataControl.js
--- a/static/scripts/templates/compiled/template-visualization-dataControl.js
+++ /dev/null
@@ -1,51 +0,0 @@
-(function() {
- var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
-templates['template-visualization-dataControl'] = template(function (Handlebars,depth0,helpers,partials,data) {
- this.compilerInfo = [4,'>= 1.0.0'];
-helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
- var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this;
-
-function program1(depth0,data) {
-
- var buffer = "", stack1;
- buffer += "\n <option value=\"";
- if (stack1 = helpers.index) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.index; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\">";
- if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</option>\n ";
- return buffer;
- }
-
-function program3(depth0,data) {
-
-
- return "checked=\"true\"";
- }
-
- buffer += "<p class=\"help-text\">\n Use the following controls to change the data used by the chart.\n Use the 'Draw' button to render (or re-render) the chart with the current settings.\n </p>\n\n "
- + "\n <div class=\"column-select\">\n <label for=\"X-select\">Data column for X: </label>\n <select name=\"X\" id=\"X-select\">\n ";
- stack1 = helpers.each.call(depth0, depth0.numericColumns, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
- if(stack1 || stack1 === 0) { buffer += stack1; }
- buffer += "\n </select>\n </div>\n <div class=\"column-select\">\n <label for=\"Y-select\">Data column for Y: </label>\n <select name=\"Y\" id=\"Y-select\">\n ";
- stack1 = helpers.each.call(depth0, depth0.numericColumns, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
- if(stack1 || stack1 === 0) { buffer += stack1; }
- buffer += "\n </select>\n </div>\n\n "
- + "\n <div id=\"include-id\">\n <label for=\"include-id-checkbox\">Include a third column as data point IDs?</label>\n <input type=\"checkbox\" name=\"include-id\" id=\"include-id-checkbox\" />\n <p class=\"help-text-small\">\n These will be displayed (along with the x and y values) when you hover over\n a data point.\n </p>\n </div>\n <div class=\"column-select\" style=\"display: none\">\n <label for=\"ID-select\">Data column for IDs: </label>\n <select name=\"ID\" id=\"ID-select\">\n ";
- stack1 = helpers.each.call(depth0, depth0.allColumns, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
- if(stack1 || stack1 === 0) { buffer += stack1; }
- buffer += "\n </select>\n </div>\n\n "
- + "\n <div id=\"first-line-header\" style=\"display: none;\">\n <p>Possible headers: ";
- if (stack1 = helpers.possibleHeaders) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.possibleHeaders; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\n </p>\n <label for=\"first-line-header-checkbox\">Use the above as column headers?</label>\n <input type=\"checkbox\" name=\"include-id\" id=\"first-line-header-checkbox\"\n ";
- stack1 = helpers['if'].call(depth0, depth0.usePossibleHeaders, {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});
- if(stack1 || stack1 === 0) { buffer += stack1; }
- buffer += "/>\n <p class=\"help-text-small\">\n It looks like Galaxy couldn't get proper column headers for this data.\n Would you like to use the column headers above as column names to select columns?\n </p>\n </div>\n\n <input id=\"render-button\" type=\"button\" value=\"Draw\" />\n <div class=\"clear\"></div>";
- return buffer;
- });
-})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/templates/compiled/template-visualization-scatterplotControlForm.js
--- a/static/scripts/templates/compiled/template-visualization-scatterplotControlForm.js
+++ /dev/null
@@ -1,33 +0,0 @@
-(function() {
- var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
-templates['template-visualization-scatterplotControlForm'] = template(function (Handlebars,depth0,helpers,partials,data) {
- this.compilerInfo = [4,'>= 1.0.0'];
-helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
- var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression;
-
-
- buffer += "\n\n<div class=\"scatterplot-container chart-container tabbable tabs-left\">\n "
- + "\n <ul class=\"nav nav-tabs\">\n "
- + "\n <li class=\"active\"><a href=\"#data-control\" data-toggle=\"tab\"\n title=\"Use this tab to change which data are used\">Data Controls</a></li>\n <li><a href=\"#chart-control\" data-toggle=\"tab\"\n title=\"Use this tab to change how the chart is drawn\">Chart Controls</a></li>\n <li><a href=\"#stats-display\" data-toggle=\"tab\"\n title=\"This tab will display overall statistics for your data\">Statistics</a></li>\n <li><a href=\"#chart-display\" data-toggle=\"tab\"\n title=\"This tab will display the chart\">Chart</a>\n "
- + "\n <div id=\"loading-indicator\" style=\"display: none;\">\n <img class=\"loading-img\" src=\"";
- if (stack1 = helpers.loadingIndicatorImagePath) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.loadingIndicatorImagePath; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "\" />\n <span class=\"loading-message\">";
- if (stack1 = helpers.message) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.message; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</span>\n </div>\n </li>\n </ul>\n\n "
- + "\n <div class=\"tab-content\">\n "
- + "\n <div id=\"data-control\" class=\"tab-pane active\">\n "
- + "\n </div>\n \n "
- + "\n <div id=\"chart-control\" class=\"tab-pane\">\n "
- + "\n </div>\n\n "
- + "\n <div id=\"stats-display\" class=\"tab-pane\">\n "
- + "\n </div>\n\n "
- + "\n <div id=\"chart-display\" class=\"tab-pane\">\n "
- + "\n </div>\n\n </div>"
- + "\n</div>";
- return buffer;
- });
-})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/templates/compiled/template-visualization-statsDisplay.js
--- a/static/scripts/templates/compiled/template-visualization-statsDisplay.js
+++ /dev/null
@@ -1,33 +0,0 @@
-(function() {
- var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
-templates['template-visualization-statsDisplay'] = template(function (Handlebars,depth0,helpers,partials,data) {
- this.compilerInfo = [4,'>= 1.0.0'];
-helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
- var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this;
-
-function program1(depth0,data) {
-
- var buffer = "", stack1;
- buffer += "\n <tr><td>";
- if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</td><td>";
- if (stack1 = helpers.xval) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.xval; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</td><td>";
- if (stack1 = helpers.yval) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
- else { stack1 = depth0.yval; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
- buffer += escapeExpression(stack1)
- + "</td></tr>\n </tr>\n ";
- return buffer;
- }
-
- buffer += "<p class=\"help-text\">By column:</p>\n <table id=\"chart-stats-table\">\n <thead><th></th><th>X</th><th>Y</th></thead>\n ";
- stack1 = helpers.each.call(depth0, depth0.stats, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
- if(stack1 || stack1 === 0) { buffer += stack1; }
- buffer += "\n </table>";
- return buffer;
- });
-})();
\ No newline at end of file
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/templates/visualization-templates.html
--- a/static/scripts/templates/visualization-templates.html
+++ /dev/null
@@ -1,182 +0,0 @@
-<script type="text/template" class="template-visualization" id="template-visualization-scatterplotControlForm">
-{{! main layout }}
-
-<div class="scatterplot-container chart-container tabbable tabs-left">
- {{! tab buttons/headers using Bootstrap }}
- <ul class="nav nav-tabs">
- {{! start with the data controls as the displayed tab }}
- <li class="active"><a href="#data-control" data-toggle="tab"
- title="Use this tab to change which data are used">Data Controls</a></li>
- <li><a href="#chart-control" data-toggle="tab"
- title="Use this tab to change how the chart is drawn">Chart Controls</a></li>
- <li><a href="#stats-display" data-toggle="tab"
- title="This tab will display overall statistics for your data">Statistics</a></li>
- <li><a href="#chart-display" data-toggle="tab"
- title="This tab will display the chart">Chart</a>
- {{! loading indicator - initially hidden }}
- <div id="loading-indicator" style="display: none;">
- <img class="loading-img" src="{{loadingIndicatorImagePath}}" />
- <span class="loading-message">{{message}}</span>
- </div>
- </li>
- </ul>
-
- {{! data form, chart config form, stats, and chart all get their own tab }}
- <div class="tab-content">
- {{! ---------------------------- tab for data settings form }}
- <div id="data-control" class="tab-pane active">
- {{! rendered separately }}
- </div>
-
- {{! ---------------------------- tab for chart graphics control form }}
- <div id="chart-control" class="tab-pane">
- {{! rendered separately }}
- </div>
-
- {{! ---------------------------- tab for data statistics }}
- <div id="stats-display" class="tab-pane">
- {{! rendered separately }}
- </div>
-
- {{! ---------------------------- tab for actual chart }}
- <div id="chart-display" class="tab-pane">
- {{! chart rendered separately }}
- </div>
-
- </div>{{! end .tab-content }}
-</div>{{! end .chart-control }}
-</script>
-
-<script type="text/template" class="template-visualization" id="template-visualization-dataControl">
-
- <p class="help-text">
- Use the following controls to change the data used by the chart.
- Use the 'Draw' button to render (or re-render) the chart with the current settings.
- </p>
-
- {{! column selector containers }}
- <div class="column-select">
- <label for="X-select">Data column for X: </label>
- <select name="X" id="X-select">
- {{#each numericColumns}}
- <option value="{{index}}">{{name}}</option>
- {{/each}}
- </select>
- </div>
- <div class="column-select">
- <label for="Y-select">Data column for Y: </label>
- <select name="Y" id="Y-select">
- {{#each numericColumns}}
- <option value="{{index}}">{{name}}</option>
- {{/each}}
- </select>
- </div>
-
- {{! optional id column }}
- <div id="include-id">
- <label for="include-id-checkbox">Include a third column as data point IDs?</label>
- <input type="checkbox" name="include-id" id="include-id-checkbox" />
- <p class="help-text-small">
- These will be displayed (along with the x and y values) when you hover over
- a data point.
- </p>
- </div>
- <div class="column-select" style="display: none">
- <label for="ID-select">Data column for IDs: </label>
- <select name="ID" id="ID-select">
- {{#each allColumns}}
- <option value="{{index}}">{{name}}</option>
- {{/each}}
- </select>
- </div>
-
- {{! if we're using generic column selection names ('column 1') - allow the user to use the first line }}
- <div id="first-line-header" style="display: none;">
- <p>Possible headers: {{ possibleHeaders }}
- </p>
- <label for="first-line-header-checkbox">Use the above as column headers?</label>
- <input type="checkbox" name="include-id" id="first-line-header-checkbox"
- {{#if usePossibleHeaders }}checked="true"{{/if}}/>
- <p class="help-text-small">
- It looks like Galaxy couldn't get proper column headers for this data.
- Would you like to use the column headers above as column names to select columns?
- </p>
- </div>
-
- <input id="render-button" type="button" value="Draw" />
- <div class="clear"></div>
-</script>
-
-<script type="text/template" class="template-visualization" id="template-visualization-chartControl">
- <p class="help-text">
- Use the following controls to how the chart is displayed.
- The slide controls can be moved by the mouse or, if the 'handle' is in focus, your keyboard's arrow keys.
- Move the focus between controls by using the tab or shift+tab keys on your keyboard.
- Use the 'Draw' button to render (or re-render) the chart with the current settings.
- </p>
-
- <div id="datapointSize" class="form-input numeric-slider-input">
- <label for="datapointSize">Size of data point: </label>
- <div class="slider-output">{{datapointSize}}</div>
- <div class="slider"></div>
- <p class="form-help help-text-small">
- Size of the graphic representation of each data point
- </p>
- </div>
-
- <div id="animDuration" class="form-input checkbox-input">
- <label for="animate-chart">Animate chart transitions?: </label>
- <input type="checkbox" id="animate-chart"
- class="checkbox control"{{#if animDuration}} checked="true"{{/if}} />
- <p class="form-help help-text-small">
- Uncheck this to disable the animations used on the chart
- </p>
- </div>
-
- <div id="width" class="form-input numeric-slider-input">
- <label for="width">Chart width: </label>
- <div class="slider-output">{{width}}</div>
- <div class="slider"></div>
- <p class="form-help help-text-small">
- (not including chart margins and axes)
- </p>
- </div>
-
- <div id="height" class="form-input numeric-slider-input">
- <label for="height">Chart height: </label>
- <div class="slider-output">{{height}}</div>
- <div class="slider"></div>
- <p class="form-help help-text-small">
- (not including chart margins and axes)
- </p>
- </div>
-
- <div id="X-axis-label"class="text-input form-input">
- <label for="X-axis-label">Re-label the X axis: </label>
- <input type="text" name="X-axis-label" id="X-axis-label" value="{{xLabel}}" />
- <p class="form-help help-text-small"></p>
- </div>
-
- <div id="Y-axis-label" class="text-input form-input">
- <label for="Y-axis-label">Re-label the Y axis: </label>
- <input type="text" name="Y-axis-label" id="Y-axis-label" value="{{yLabel}}" />
- <p class="form-help help-text-small"></p>
- </div>
-
- <input id="render-button" type="button" value="Draw" />
-</script>
-
-<script type="text/template" class="template-visualization" id="template-visualization-statsDisplay">
- <p class="help-text">By column:</p>
- <table id="chart-stats-table">
- <thead><th></th><th>X</th><th>Y</th></thead>
- {{#each stats}}
- <tr><td>{{name}}</td><td>{{xval}}</td><td>{{yval}}</td></tr>
- </tr>
- {{/each}}
- </table>
-</script>
-
-<script type="text/template" class="template-visualization" id="template-visualization-chartDisplay">
- <svg width="{{width}}" height="{{height}}"></svg>
-</script>
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a static/scripts/viz/scatterplot.js
--- a/static/scripts/viz/scatterplot.js
+++ /dev/null
@@ -1,488 +0,0 @@
-/* =============================================================================
-todo:
- outside this:
- BUG: setting width, height in plot controls doesn't re-interpolate data locations!!
- BUG?: get metadata_column_names (from datatype if necessary)
- BUG: single vis in popupmenu should have tooltip with that name NOT 'Visualizations'
-
- wire label setters, anim setter
-
- TwoVarScatterplot:
- ??: maybe better to do this with a canvas...
- save as visualization
- to seperate file?
- remove underscore dependencies
- add interface to change values (seperate)?
- download svg -> base64 encode
- incorporate glyphs, glyph state renderers
-
- ScatterplotSettingsForm:
- some css bug that lowers the width of settings form when plot-controls tab is open
- causes chart to shift
- what can be abstracted/reused for other graphs?
- avoid direct manipulation of this.plot
- allow option to put plot into seperate tab of interface (for small multiples)
-
- provide callback in view to load data incrementally - for large sets
- paginate
- handle rerender
- use endpoint (here and on the server (fileptr))
- fetch (new?) data
- handle rerender
- use d3.TSV?
- render warning on long data (> maxDataPoints)
- adjust endpoint
-
- selectable list of preset column comparisons (rnaseq etc.)
- how to know what sort of Tabular the data is?
- smarter about headers
- validate columns selection (here or server)
-
- set stats column names by selected columns
- move chart into tabbed area...
-
- Scatterplot.mako:
- multiple plots on one page (small multiples)
- ?? ensure svg styles thru d3 or css?
- d3: configable (easily)
- css: standard - better maintenance
- ? override at config
-
-============================================================================= */
-/**
- * Two Variable scatterplot visualization using d3
- * Uses semi transparent circles to show density of data in x, y grid
- * usage :
- * var plot = new TwoVarScatterplot({ containerSelector : 'div#my-plot', ... })
- * plot.render( xColumnData, yColumnData );
- *
- * depends on: d3, underscore
- */
-function TwoVarScatterplot( config ){
- var TICK_LINE_AND_PADDING = 10,
- GUESS_AT_SVG_CHAR_WIDTH = 7,
- GUESS_AT_SVG_CHAR_HEIGHT = 10,
- PADDING = 8,
- X_LABEL_TOO_LONG_AT = 5;
-
- // set up logging
- //this.debugging = true;
- this.log = function(){
- if( this.debugging && console && console.debug ){
- var args = Array.prototype.slice.call( arguments );
- args.unshift( this.toString() );
- console.debug.apply( console, args );
- }
- };
- this.log( 'new TwoVarScatterplot:', config );
-
- // ........................................................ set up chart config
- // config will default to these values when not passed in
- //NOTE: called on new
- this.defaults = {
- id : 'TwoVarScatterplot',
- containerSelector : 'body',
- //TODO??: needed?
- maxDataPoints : 30000,
- datapointSize : 4,
- animDuration : 500,
- //TODO: variable effect (not always exactly # of ticks set to)
- xNumTicks : 10,
- yNumTicks : 10,
- xAxisLabelBumpY : 40,
- yAxisLabelBumpX : -40,
- width : 400,
- height : 400,
- //TODO: anyway to make this a sub-obj?
- marginTop : 50,
- marginRight : 50,
- marginBottom : 50,
- marginLeft : 50,
-
- xMin : null,
- xMax : null,
- yMin : null,
- yMax : null,
-
- xLabel : "X",
- yLabel : "Y"
- };
- this.config = _.extend( {}, this.defaults, config );
- this.log( 'intial config:', this.config );
-
- this.updateConfig = function( newConfig, rerender ){
- // setter for chart config
- //TODO: validate here
- _.extend( this.config, newConfig );
- this.log( this + '.updateConfig:', this.config );
- //TODO: implement rerender flag
- };
-
- // ........................................................ helpers
- this.toString = function(){
- return this.config.id;
- };
- // conv. methods for svg transforms
- this.translateStr = function( x, y ){
- return 'translate(' + x + ',' + y + ')';
- };
- this.rotateStr = function( d, x, y ){
- return 'rotate(' + d + ',' + x + ',' + y + ')';
- };
-
- // ........................................................ initial element creation
- this.adjustChartDimensions = function( top, right, bottom, left ){
- //this.log( this + '.adjustChartDimensions', arguments );
- top = top || 0;
- right = right || 0;
- bottom = bottom || 0;
- left = left || 0;
- this.svg
- .attr( "width", this.config.width + ( this.config.marginRight + right )
- + ( this.config.marginLeft + left ) )
- .attr( "height", this.config.height + ( this.config.marginTop + top )
- + ( this.config.marginBottom + bottom ) )
- // initial is hidden - show it
- .style( 'display', 'block' );
-
- // move content group away from margins
- //TODO: allow top, right axis
- this.content = this.svg.select( "g.content" )
- .attr( "transform", this.translateStr( this.config.marginLeft + left, this.config.marginTop + top ) );
- };
-
- // ........................................................ data and scales
- this.preprocessData = function( data, min, max ){
- //this.log( this + '.preprocessData', arguments );
- //TODO: filter by min, max if set
-
- // set a cap on the data, limit to first n points
- return ( data.length > this.config.maxDataPoints )? ( data.slice( 0, this.config.maxDataPoints ) ): ( data );
- };
-
- this.findMinMaxes = function( xCol, yCol, meta ){
- //this.log( this + '.findMinMaxes', arguments );
- // configuration takes priority, otherwise meta (from the server) if passed, last-resort: compute it here
- this.xMin = this.config.xMin || ( meta )?( meta[0].min ):( d3.min( xCol ) );
- this.xMax = this.config.xMax || ( meta )?( meta[0].max ):( d3.max( xCol ) );
- this.yMin = this.config.yMin || ( meta )?( meta[1].min ):( d3.min( yCol ) );
- this.yMax = this.config.yMax || ( meta )?( meta[1].max ):( d3.max( yCol ) );
- };
-
- this.setUpScales = function(){
- //this.log( this + '.setUpScales', arguments );
- // Interpolation for x, y based on data domains
- this.xScale = d3.scale.linear()
- .domain([ this.xMin, this.xMax ])
- .range([ 0, this.config.width ]),
- this.yScale = d3.scale.linear()
- .domain([ this.yMin, this.yMax ])
- .range([ this.config.height, 0 ]);
- };
-
- // ........................................................ axis and ticks
- this.setUpXAxis = function(){
- //this.log( this + '.setUpXAxis', arguments );
- // origin: bottom, left
- //TODO: incoporate top, right
- this.xAxisFn = d3.svg.axis()
- .scale( this.xScale )
- .ticks( this.config.xNumTicks )
- .orient( 'bottom' );
- this.xAxis// = content.select( 'g#x-axis' )
- .attr( 'transform', this.translateStr( 0, this.config.height ) )
- .call( this.xAxisFn );
- //this.log( 'xAxis:', this.xAxis );
-
- //TODO: adjust ticks when tick labels are long - move odds down and extend tick line
- // (for now) hide them
- var xLongestTickLabel = d3.max( _.map( [ this.xMin, this.xMax ],
- function( number ){ return ( String( number ) ).length; } ) );
- //this.log( 'xLongestTickLabel:', xLongestTickLabel );
- if( xLongestTickLabel >= X_LABEL_TOO_LONG_AT ){
- this.xAxis.selectAll( 'g' ).filter( ':nth-child(odd)' ).style( 'display', 'none' );
- }
-
- this.log( 'this.config.xLabel:', this.config.xLabel );
- this.xAxisLabel// = xAxis.select( 'text#x-axis-label' )
- .attr( 'x', this.config.width / 2 )
- .attr( 'y', this.config.xAxisLabelBumpY )
- .attr( 'text-anchor', 'middle' )
- .text( this.config.xLabel );
- this.log( 'xAxisLabel:', this.xAxisLabel );
- };
-
- this.setUpYAxis = function(){
- //this.log( this + '.setUpYAxis', arguments );
- this.yAxisFn = d3.svg.axis()
- .scale( this.yScale )
- .ticks( this.config.yNumTicks )
- .orient( 'left' );
- this.yAxis// = content.select( 'g#y-axis' )
- .call( this.yAxisFn );
- //this.log( 'yAxis:', this.yAxis );
-
- // a too complicated section for increasing the left margin when tick labels are long
- // get the tick labels for the y axis
- var yTickLabels = this.yAxis.selectAll( 'text' ).filter( function( e, i ){ return i !== 0; } );
- this.log( 'yTickLabels:', yTickLabels );
-
- // get the longest label length (or 0 if no labels)
- this.yLongestLabel = d3.max(
- //NOTE: d3 returns an nested array - use the plain array inside ([0])
- yTickLabels[0].map( function( e, i ){
- return ( d3.select( e ).text() ).length;
- })
- ) || 0;
- //this.log( 'yLongestLabel:', this.yLongestLabel );
- //TODO: lose the guessing if possible
- var neededY = TICK_LINE_AND_PADDING + ( this.yLongestLabel * GUESS_AT_SVG_CHAR_WIDTH )
- + PADDING + GUESS_AT_SVG_CHAR_HEIGHT;
- //this.log( 'neededY:', neededY );
-
- // increase width for yLongerStr, increase margin for y
- //TODO??: (or transform each number: 2k)
- this.config.yAxisLabelBumpX = -( neededY - GUESS_AT_SVG_CHAR_HEIGHT );
- if( this.config.marginLeft < neededY ){
- var adjusting = ( neededY ) - this.config.marginLeft;
- adjusting = ( adjusting < 0 )?( 0 ):( adjusting );
- //this.log( 'adjusting:', adjusting );
-
- // update dimensions, translations
- this.adjustChartDimensions( 0, 0, 0, adjusting );
- }
- //this.log( 'this.config.yAxisLableBumpx, this.config.marginLeft:',
- // this.config.yAxisLabelBumpX, this.config.marginLeft );
-
- this.yAxisLabel// = yAxis.select( 'text#y-axis-label' )
- .attr( 'x', this.config.yAxisLabelBumpX )
- .attr( 'y', this.config.height / 2 )
- .attr( 'text-anchor', 'middle' )
- .attr( 'transform', this.rotateStr( -90, this.config.yAxisLabelBumpX, this.config.height / 2 ) )
- .text( this.config.yLabel );
- //this.log( 'yAxisLabel:', this.yAxisLabel );
- };
-
- // ........................................................ grid lines
- this.renderGrid = function(){
- //this.log( this + '.renderGrid', arguments );
- // VERTICAL
- // select existing
- this.vGridLines = this.content.selectAll( 'line.v-grid-line' )
- .data( this.xScale.ticks( this.xAxisFn.ticks()[0] ) );
-
- // append any extra lines needed (more ticks)
- this.vGridLines.enter().append( 'svg:line' )
- .classed( 'grid-line v-grid-line', true );
-
- // update the attributes of existing and appended
- this.vGridLines
- .attr( 'x1', this.xScale )
- .attr( 'y1', 0 )
- .attr( 'x2', this.xScale )
- .attr( 'y2', this.config.height );
-
- // remove unneeded (less ticks)
- this.vGridLines.exit().remove();
- //this.log( 'vGridLines:', this.vGridLines );
-
- // HORIZONTAL
- this.hGridLines = this.content.selectAll( 'line.h-grid-line' )
- .data( this.yScale.ticks( this.yAxisFn.ticks()[0] ) );
-
- this.hGridLines.enter().append( 'svg:line' )
- .classed( 'grid-line h-grid-line', true );
-
- this.hGridLines
- .attr( 'x1', 0 )
- .attr( 'y1', this.yScale )
- .attr( 'x2', this.config.width )
- .attr( 'y2', this.yScale );
-
- this.hGridLines.exit().remove();
- //this.log( 'hGridLines:', this.hGridLines );
- };
-
- // ........................................................ data points
- this.renderDatapoints = function( xCol, yCol, ids ){
- this.log( this + '.renderDatapoints', arguments );
- var count = 0,
- plot = this,
- xPosFn = function( d, i ){
- //if( d ){ this.log( 'x.data:', newXCol[ i ], 'plotted:', plot.xScale( newXCol[ i ] ) ); }
- return plot.xScale( xCol[ i ] );
- },
- yPosFn = function( d, i ){
- //if( d ){ this.log( 'y.data:', newYCol[ i ], 'plotted:', plot.yScale( newYCol[ i ] ) ); }
- return plot.yScale( yCol[ i ] );
- };
-
- //this.datapoints = this.addDatapoints( xCol, yCol, ids, ".glyph" );
- var datapoints = this.content.selectAll( '.glyph' ).data( xCol );
-
- // enter - NEW data to be added as glyphs: give them a 'entry' position and style
- count = 0;
- datapoints.enter()
- .append( 'svg:circle' )
- .each( function(){ count += 1; } )
- .classed( "glyph", true )
- .attr( "cx", 0 )
- .attr( "cy", this.config.height )
- // start all bubbles small...
- .attr( "r", 0 );
- this.log( count, ' new glyphs created' );
-
- // for all EXISTING glyphs and those that need to be added: transition anim to final state
- count = 0;
- datapoints
- // ...animate to final position
- .transition().duration( this.config.animDuration )
- .each( function(){ count += 1; } )
- .attr( "cx", xPosFn )
- .attr( "cy", yPosFn )
- .attr( "r", plot.config.datapointSize );
- this.log( count, ' existing glyphs transitioned' );
-
- // events
- // glyphs that need to be removed: transition to from normal state to 'exit' state, remove from DOM
- datapoints.exit()
- .each( function(){ count += 1; } )
- .transition().duration( this.config.animDuration )
- .attr( "cy", this.config.height )
- .attr( "r", 0 )
- .remove();
- this.log( count, ' glyphs removed' );
-
- this._addDatapointEventhandlers( datapoints, xCol, yCol, ids );
- };
-
- this._addDatapointEventhandlers = function( datapoints, xCol, yCol, ids ){
- var plot = this;
- datapoints
- //TODO: remove magic numbers
- .on( 'mouseover', function( d, i ){
- var datapoint = d3.select( this );
- datapoint
- .style( 'fill', 'red' )
- .style( 'fill-opacity', 1 );
-
- // create horiz, vert lines to axis
- plot.content.append( 'line' )
- .attr( 'stroke', 'red' )
- .attr( 'stroke-width', 1 )
- // start not at center, but at the edge of the circle - to prevent mouseover thrashing
- .attr( 'x1', datapoint.attr( 'cx' ) - plot.config.datapointSize )
- .attr( 'y1', datapoint.attr( 'cy' ) )
- .attr( 'x2', 0 )
- .attr( 'y2', datapoint.attr( 'cy' ) )
- .classed( 'hoverline', true );
-
- // if the vertical hoverline
- if( datapoint.attr( 'cy' ) < plot.config.height ){
- plot.content.append( 'line' )
- .attr( 'stroke', 'red' )
- .attr( 'stroke-width', 1 )
- .attr( 'x1', datapoint.attr( 'cx' ) )
- .attr( 'y1', datapoint.attr( 'cy' ) + plot.config.datapointSize )
- .attr( 'x2', datapoint.attr( 'cx' ) )
- .attr( 'y2', plot.config.height )
- .classed( 'hoverline', true );
- }
-
- var datapointWindowPos = $( this ).offset();
- plot.datapointInfoBox = plot.infoBox(
- datapointWindowPos.top, datapointWindowPos.left,
- plot.infoHtml( xCol[ i ], yCol[ i ], ( ids )?( ids[ i ] ):( undefined ) )
- );
- $( 'body' ).append( plot.datapointInfoBox );
- })
- .on( 'mouseout', function(){
- d3.select( this )
- .style( 'fill', 'black' )
- .style( 'fill-opacity', 0.2 );
- plot.content.selectAll( '.hoverline' ).remove();
- if( plot.datapointInfoBox ){
- plot.datapointInfoBox.remove();
- }
- });
- },
-
- this.render = function( columnData, meta ){
- this.log( this + '.render', arguments );
- this.log( '\t config:', this.config );
-
- // prepare the data
- //pre: columns passed are numeric
- //pre: at least two columns are passed
- //assume: first column is x, second column is y, any remaining aren't used
- var xCol = columnData[0],
- yCol = columnData[1],
- ids = ( columnData.length > 2 )?( columnData[2] ):( undefined );
- //this.log( this + '.render', xCol.length, yCol.length, this.config );
-
- //pre: xCol.len == yCol.len
- xCol = this.preprocessData( xCol );
- yCol = this.preprocessData( yCol );
- this.log( 'xCol len', xCol.length, 'yCol len', yCol.length );
-
- this.findMinMaxes( xCol, yCol, meta );
- //this.log( 'xMin, xMax, yMin, yMax:', this.xMin, this.xMax, this.yMin, this.yMax );
- this.setUpScales();
-
- // find (or build if it doesn't exist) the svg dom infrastructure
- if( !this.svg ){ this.svg = d3.select( 'svg' ).attr( "class", "chart" ); }
- if( !this.content ){
- this.content = this.svg.append( "svg:g" ).attr( "class", "content" ).attr( 'id', this.config.id );
- }
- //this.log( 'svg:', this.svg );
- //this.log( 'content:', this.content );
-
- this.adjustChartDimensions();
-
- if( !this.xAxis ){ this.xAxis = this.content.append( 'g' ).attr( 'class', 'axis' ).attr( 'id', 'x-axis' ); }
- if( !this.xAxisLabel ){
- this.xAxisLabel = this.xAxis.append( 'text' ).attr( 'class', 'axis-label' ).attr( 'id', 'x-axis-label' );
- }
- //this.log( 'xAxis:', this.xAxis, 'xAxisLabel:', this.xAxisLabel );
-
- if( !this.yAxis ){ this.yAxis = this.content.append( 'g' ).attr( 'class', 'axis' ).attr( 'id', 'y-axis' ); }
- if( !this.yAxisLabel ){
- this.yAxisLabel = this.yAxis.append( 'text' ).attr( 'class', 'axis-label' ).attr( 'id', 'y-axis-label' );
- }
- //this.log( 'yAxis:', this.yAxis, 'yAxisLabel:', this.yAxisLabel );
-
- this.setUpXAxis();
- this.setUpYAxis();
-
- this.renderGrid();
- this.renderDatapoints( xCol, yCol, ids );
- };
-
- this.infoHtml = function( x, y, id ){
- var retDiv = $( '<div/>' );
- if( id ){
- $( '<div/>' ).text( id ).css( 'font-weight', 'bold' ).appendTo( retDiv );
- }
- $( '<div/>' ).text( x ).appendTo( retDiv );
- $( '<div/>' ).text( y ).appendTo( retDiv );
- return retDiv.html();
- };
-
- //TODO: html for now
- this.infoBox = function( top, left, html, adjTop, adjLeft ){
- adjTop = adjTop || 0;
- adjLeft = adjLeft || 20;
- var infoBox = $( '<div />' )
- .addClass( 'chart-info-box' )
- .css({
- 'position' : 'absolute',
- 'top' : top + adjTop,
- 'left' : left + adjLeft
- });
- infoBox.html( html );
- return infoBox;
- };
-
-}
-
-//==============================================================================
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a templates/webapps/galaxy/visualization/scatterplot.mako
--- a/templates/webapps/galaxy/visualization/scatterplot.mako
+++ /dev/null
@@ -1,256 +0,0 @@
-<%inherit file="/base.mako"/>
-
-<%def name="stylesheets()">
-${parent.stylesheets()}
-${h.css(
- "base",
- "autocomplete_tagging",
- "jquery-ui/smoothness/jquery-ui"
-)}
-
-<style type="text/css">
-/*TODO: use/move into base.less*/
-* { margin: 0px; padding: 0px; }
-
-/* -------------------------------------------- general layout */
-div.tab-pane {
- padding: 8px;
-}
-
-/* -------------------------------------------- header */
-.header {
- margin-bottom: 8px;
-}
-
-#chart-header {
- padding : 8px;
- background-color: #ebd9b2;
- margin-bottom: 16px;
- overflow: auto;
-}
-
-#chart-header .subtitle {
- margin: -4px 0px 0px 4px;
- padding : 0;
- color: white;
- font-size: small;
-}
-
-/* -------------------------------------------- main layout */
-#scatterplot {
- /*from width + margin of chart?*/
-}
-
-.scatterplot-container .tab-pane {
-}
-
-/* -------------------------------------------- all controls */
-
-#scatterplot input[type=button],
-#scatterplot select {
- width: 100%;
- max-width: 256px;
- margin-bottom: 8px;
-}
-
-#scatterplot .help-text,
-#scatterplot .help-text-small {
- color: grey;
-}
-
-#scatterplot .help-text {
- padding-bottom: 16px;
-}
-
-#scatterplot .help-text-small {
- padding: 4px;
- font-size: smaller;
-}
-
-#scatterplot > * {
-}
-
-#scatterplot input[value=Draw] {
- display: block;
- margin-top: 16px;
-}
-
-#scatterplot .numeric-slider-input {
- max-width: 70%;
-}
-
-/* -------------------------------------------- data controls */
-
-/* -------------------------------------------- chart controls */
-#chart-control .form-input {
- /*display: table-row;*/
-}
-
-#chart-control label {
- /*text-align: right;*/
- margin-bottom: 8px;
- /*display: table-cell;*/
-}
-
-#chart-control .slider {
- /*display: table-cell;*/
- height: 8px;
- display: block;
- margin: 8px 0px 0px 8px;
-}
-
-#chart-control .slider-output {
- /*display: table-cell;*/
- float: right;
-}
-
-#chart-control input[type="text"] {
- border: 1px solid lightgrey;
-}
-
-
-/* -------------------------------------------- statistics */
-#stats-display table#chart-stats-table {
- width: 100%;
-}
-
-#stats-display #chart-stats-table th {
- width: 30%;
- padding: 4px;
- font-weight: bold;
- color: grey;
-}
-
-#stats-display #chart-stats-table td {
- border: solid lightgrey;
- border-width: 1px 0px 0px 1px;
- padding: 4px;
-}
-
-#stats-display #chart-stats-table td:nth-child(1) {
- border-width: 1px 0px 0px 0px;
- padding-right: 1em;
- text-align: right;
- font-weight: bold;
- color: grey;
-}
-
-/* -------------------------------------------- load indicators */
-#loading-indicator {
- margin: 12px 0px 0px 8px;
-}
-
-#scatterplot #loading-indicator .loading-message {
- font-style: italic;
- font-size: smaller;
- color: grey;
-}
-
-/* -------------------------------------------- chart area */
-#chart-holder {
- overflow: auto;
- margin-left: 8px;
-}
-
-svg .grid-line {
- fill: none;
- stroke: lightgrey;
- stroke-opacity: 0.5;
- shape-rendering: crispEdges;
- stroke-dasharray: 3, 3;
-}
-
-svg .axis path, svg .axis line {
- fill: none;
- stroke: black;
- shape-rendering: crispEdges;
-}
-
-svg .axis text {
- font-family: monospace;
- font-size: 12px;
-}
-
-svg #x-axis-label, svg #y-axis-label {
- font-family: sans-serif;
- font-size: 10px;
-}
-
-svg .glyph {
- stroke: none;
- fill: black;
- fill-opacity: 0.2;
-}
-
-/* -------------------------------------------- info box */
-.chart-info-box {
- border-radius: 4px;
- padding: 4px;
- background-color: white;
- border: 1px solid black;
-}
-
-</style>
-
-</%def>
-
-<%def name="javascripts()">
-${parent.javascripts()}
-${h.js(
-
- "libs/underscore",
- "libs/jquery/jquery-ui",
- "libs/d3",
-
- "mvc/base-mvc",
- "utils/LazyDataLoader",
- "viz/scatterplot"
-)}
-
-${h.templates(
- "../../templates/compiled/template-visualization-scatterplotControlForm",
- "../../templates/compiled/template-visualization-dataControl",
- "../../templates/compiled/template-visualization-chartControl",
- "../../templates/compiled/template-visualization-chartDisplay",
- "../../templates/compiled/template-visualization-statsDisplay"
-)}
-
-${h.js(
- "mvc/visualization/scatterplotControlForm",
-)}
-
-<script type="text/javascript">
-$(function(){
-
- var hda = ${h.to_json_string( trans.security.encode_dict_ids( hda.to_dict() ) )},
- querySettings = ${h.to_json_string( query_args )},
- chartConfig = _.extend( querySettings, {
- containerSelector : '#chart',
- //TODO: move to ScatterplotControlForm.initialize
- marginTop : ( querySettings.marginTop > 20 )?( querySettings.marginTop ):( 20 ),
-
- xColumn : querySettings.xColumn,
- yColumn : querySettings.yColumn,
- idColumn : querySettings.idColumn
- });
- //console.debug( querySettings );
-
- var settingsForm = new ScatterplotControlForm({
- dataset : hda,
- apiDatasetsURL : "${h.url_for( controller='/api/datasets', action='index' )}",
- el : $( '#scatterplot' ),
- chartConfig : chartConfig
- }).render();
-
-});
-</script>
-</%def>
-
-<%def name="body()">
- <!--dataset info-->
- <div id="chart-header" class="header">
- <h2 class="title">Scatterplot of '${hda.name}'</h2>
- <p class="subtitle">${hda.info}</p>
- </div>
- <div id="scatterplot" class="scatterplot-control-form"></div>
-</%def>
diff -r b71c9af7c17c48e8ed1c45918a459f5b2c0167e4 -r 044ead55435801561acdf72fe225209239202a5a templates/webapps/galaxy/visualization/v_fwork_test.mako
--- a/templates/webapps/galaxy/visualization/v_fwork_test.mako
+++ /dev/null
@@ -1,132 +0,0 @@
-<%inherit file="/base.mako"/>
-<%def name="title()">
-${visualization_name}
-</%def>
-
-
-<%def name="stylesheets()">
-${parent.stylesheets()}
-${h.css(
- "base",
-)}
-
-<style type="text/css">
-/*TODO: use/move into base.less*/
-* { margin: 0px; padding: 0px; }
-</style>
-
-</%def>
-
-<%def name="process_hda( hda )">
-<%
- hda_dict = hda.to_dict()
- hda_dict[ 'id' ] = trans.security.encode_id( hda_dict[ 'id' ] )
- hda_dict[ 'history_id' ] = trans.security.encode_id( hda_dict[ 'history_id' ] )
- del hda_dict[ 'peek' ]
- return hda_dict
-%>
-</%def>
-
-<%def name="javascripts()">
-${parent.javascripts()}
-<script type="text/javascript">
-$(function(){
-
-//var data = {
-// title : 'shared with user visualization',
-// type : 'test',
-// slug : 'shared',
-// annotation : 'a visualization shared with a specific user',
-// config : {
-// x : 10,
-// y : 10
-// }
-// };
-
-//var creationPromise = jQuery.ajax( '/api/visualizations', {
-// type : 'POST',
-// contentType : 'application/json',
-// data : JSON.stringify( data )
-// });
-//creationPromise.success(function(){
-// console.debug( 'success' );
-//});
-//creationPromise.error(function(){
-// console.debug( 'error' );
-//});
-
-
-});
-</script>
-</%def>
-
-<%def name="print_var( name, var )">
-%if var is not None:
- <% t = str( type( var ) )[1:-1] %>
- <p>${name}: ${t}, ${var}</p>
-%else:
- <p>No ${name}</p>
-%endif
-</%def>
-
-<%def name="body()">
- <%
- import pprint
- print self
- print self.context
- pprint.pprint( self.context.kwargs, indent=4 )
- %>
- <%
- vars_to_print = [
- ( 'default', default ),
- ( 'string', string ),
- ( 'boolean', boolean ),
- ( 'integer', integer ),
- ( 'float', float ),
- ( 'json', json ),
- ]
- %>
- %for name, var in vars_to_print:
- ${print_var( name, var )}
- %endfor
-
- %if visualization:
- <h1>${visualization.title}</h1>
- <p>id: ${trans.security.encode_id( visualization.id )}</p>
- <p>dbkey: ${visualization.dbkey}</p>
- <p>config:
- <pre>${h.to_json_string( visualization.latest_revision.config, sort_keys=True, indent=( 4 * ' ' ) )}</pre>
- </p>
- %endif
-
- %if dataset:
- <h1>${dataset.name}</h1>
- <p>id: ${trans.security.encode_id( dataset.id )}</p>
- <p>history id: ${trans.security.encode_id( dataset.history.id )}</p>
- <pre>
- ${h.to_json_string( process_hda( dataset ), sort_keys=True, indent=( 4 * ' ' ) )}
- </pre>
- %endif
-
- %if dataset_instance:
- <h1>${dataset_instance.name}</h1>
- <p>id: ${trans.security.encode_id( dataset_instance.id )}</p>
- %if hda_ldda == 'hda':
- <p>history id: ${trans.security.encode_id( dataset_instance.history.id )}</p>
- <pre>
- ${h.to_json_string( process_hda( dataset_instance ), sort_keys=True, indent=( 4 * ' ' ) )}
- </pre>
- %else:
- <p>(LibraryDatasetDatasetAssociation)</p>
- %endif
- %endif
-
- %if query_args:
- <ul>
- %for key, val in query_args.items():
- <li>${key} : ${val}</li>
- %endfor
- </ul>
- %endif
-
-</%def>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6f9059801faf/
Changeset: 6f9059801faf
Branch: stable
User: greg
Date: 2014-02-14 16:40:31
Summary: Change log.warning to log.debug for messages regarding conflicting datatypes since recent changes in the Galaxy framework now result in job errors when using log.warning.
Affected #: 1 file
diff -r e088f2dc8b070d13e9fb7319463786d7ff4f5024 -r 6f9059801fafb3b7ae2cf844b07848beab0846fa lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py
+++ b/lib/galaxy/datatypes/registry.py
@@ -223,7 +223,7 @@
if extension in self.datatypes_by_extension:
# Because of the way that the value of can_process_datatype was set above, we know that the value of
# override is True.
- self.log.warning( "Overriding conflicting datatype with extension '%s', using datatype from %s." % \
+ self.log.debug( "Overriding conflicting datatype with extension '%s', using datatype from %s." % \
( str( extension ), str( config ) ) )
if make_subclass:
datatype_class = type( datatype_class_name, ( datatype_class, ), {} )
@@ -277,7 +277,7 @@
if not override:
# Do not load the datatype since it conflicts with an existing datatype which we are not supposed
# to override.
- self.log.warning( "Ignoring conflicting datatype with extension '%s' from %s." % ( extension, config ) )
+ self.log.debug( "Ignoring conflicting datatype with extension '%s' from %s." % ( extension, config ) )
# Load datatype sniffers from the config - we'll do this even if one or more datatypes were not properly processed in the config
# since sniffers are not tightly coupled with datatypes.
self.load_datatype_sniffers( root,
https://bitbucket.org/galaxy/galaxy-central/commits/b71c9af7c17c/
Changeset: b71c9af7c17c
User: inithello
Date: 2014-02-14 16:43:10
Summary: Merge grafted bugfix from stable.
Affected #: 0 files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Change log.warning to log.debug for messages regarding conflicting datatypes since recent changes in the Galaxy framework now result in job errors when using log.warning.
by commits-noreply@bitbucket.org 14 Feb '14
by commits-noreply@bitbucket.org 14 Feb '14
14 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/0b0018fa5d20/
Changeset: 0b0018fa5d20
User: greg
Date: 2014-02-14 16:40:31
Summary: Change log.warning to log.debug for messages regarding conflicting datatypes since recent changes in the Galaxy framework now result in job errors when using log.warning.
Affected #: 1 file
diff -r 955e973c5b33eba4e0e68979a7c20c0bd0558e37 -r 0b0018fa5d20228bb7a8c0dc6566b8239873610d lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py
+++ b/lib/galaxy/datatypes/registry.py
@@ -223,7 +223,7 @@
if extension in self.datatypes_by_extension:
# Because of the way that the value of can_process_datatype was set above, we know that the value of
# override is True.
- self.log.warning( "Overriding conflicting datatype with extension '%s', using datatype from %s." % \
+ self.log.debug( "Overriding conflicting datatype with extension '%s', using datatype from %s." % \
( str( extension ), str( config ) ) )
if make_subclass:
datatype_class = type( datatype_class_name, ( datatype_class, ), {} )
@@ -277,7 +277,7 @@
if not override:
# Do not load the datatype since it conflicts with an existing datatype which we are not supposed
# to override.
- self.log.warning( "Ignoring conflicting datatype with extension '%s' from %s." % ( extension, config ) )
+ self.log.debug( "Ignoring conflicting datatype with extension '%s' from %s." % ( extension, config ) )
# Load datatype sniffers from the config - we'll do this even if one or more datatypes were not properly processed in the config
# since sniffers are not tightly coupled with datatypes.
self.load_datatype_sniffers( root,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0