Commit 3f14c714 authored by Floreal Cabanettes's avatar Floreal Cabanettes
Browse files

Add new export: web page allowing to have an interactive dot plot offline, Implements #100

parent e574fefd
......@@ -16,3 +16,4 @@ fi
cd src/dgenies/static/css
index.js -o dgenies.min.css dgenies.css
index.js -o dgenies-offline-result.min.css chosen.min.css animate.css jquery-ui.min.css bootstrap.min.css bootstrap-theme.min.css dgenies.min.css
......@@ -23,3 +23,5 @@ babel.js -o jquery.fileupload.min.js --compact --minified jquery.fileupload.js j
babel.js -o dgenies.run.min.js --compact --minified dgenies.run.js
babel.js -o dgenies.status.min.js --compact --minified dgenies.status.js
babel.js -o dgenies.documentation.min.js --compact --minified dgenies.documentation.js
babel.js -o dgenies-offline-result.min.js --compact --minified jquery-3.2.1.min.js popper.min.js bootstrap.min.js bootstrap-notify.min.js jquery-ui.min.js jquery.cookie-1.4.1.min.js dgenies.min.js chosen.jquery.min.js FileSaver.min.js canvg.min.js d3.min.js dgenies.result.min.js BootstrapMenu.min.js
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,6 +3,20 @@ if (!d3 || !d3.boxplot) {
}
d3.boxplot.events = {};
d3.boxplot.events.context_menu = {
actions: [{
name: 'Export SVG',
onClick: dgenies.result.export.export_svg
},{
name: 'Export PNG',
onClick: dgenies.result.export.export_png
},{
name: 'Reverse query',
isShown: function() {return d3.boxplot.name_x !== d3.boxplot.name_y},
onClick: dgenies.result.controls.launch_reverse_contig
}]
};
/**
* Initialise events
*/
......@@ -39,19 +53,7 @@ d3.boxplot.events.init_context_menu = function () {
d3.boxplot.query_selected = d3.boxplot.select_query(y);
});
let menu = new BootstrapMenu("svg.svgcontainer", {
actions: [{
name: 'Export SVG',
onClick: dgenies.result.export.export_svg
},{
name: 'Export PNG',
onClick: dgenies.result.export.export_png
},{
name: 'Reverse query',
isShown: function() {return d3.boxplot.name_x !== d3.boxplot.name_y},
onClick: dgenies.result.controls.launch_reverse_contig
}]
});
let menu = new BootstrapMenu("svg.svgcontainer", d3.boxplot.events.context_menu);
};
/**
......
This diff is collapsed.
......@@ -245,6 +245,37 @@ dgenies.result.export.export_query_as_reference_fasta_standalone = function () {
}, 0);
};
/**
* Download offline viewer
*/
dgenies.result.export.export_offline_viewer = function() {
dgenies.show_loading("Building file...", 180);
window.setTimeout(() => {
dgenies.post(`/summary/${dgenies.result.id_res}`,
{},
function (data) {
dgenies.hide_loading();
if (data["success"]) {
if (data["status"] === "done") {
let export_div = $("div#export-pict");
export_div.html("");
export_div.append($("<a>").attr("href", `/viewer/${dgenies.result.id_res}`)
.attr("download", dgenies.result.id_res + ".html").attr("id", "my-download")
.text("download"));
dgenies.hide_loading();
document.getElementById('my-download').click();
}
else if (data["status"] === "waiting") {
dgenies.result.export.export_offline_viewer();
}
}
else {
dgenies.notify(data["message"] || "An error occurred! Please contact us to report the bug", "danger");
}
})
}, 0);
};
/**
* Manage exports
*/
......@@ -292,6 +323,10 @@ dgenies.result.export.export = function () {
dgenies.result.export.export_backup_file();
async = true;
}
else if (selection === 10) {
dgenies.result.export.export_offline_viewer();
async = true;
}
else
dgenies.notify("Not supported yet!", "danger", 2000);
if (!async)
......
......@@ -62,8 +62,10 @@ dgenies.result.export.save_file(blob,"svg")},0)};/**
*/dgenies.result.export.export_query_as_reference_fasta_webserver=function(){dgenies.post(`/build-query-as-reference/${dgenies.result.id_res}`,{},function(data,success){if(data["success"]){dgenies.notify("You will receive a mail soon with the link to download your Fasta file","success")}else{dgenies.notify(`An error has occurred. Please contact the support`,"danger")}})};/**
* Export query like reference fasta file (standalone mode)
*/dgenies.result.export.export_query_as_reference_fasta_standalone=function(){dgenies.show_loading("Building file...",180);window.setTimeout(()=>{dgenies.post(`/build-query-as-reference/${dgenies.result.id_res}`,{},function(data,success){if(data["success"]){let export_div=$("div#export-pict");export_div.html("");export_div.append($("<a>").attr("href",`/get-query-as-reference/${dgenies.result.id_res}`).attr("download",`as_reference_${d3.boxplot.name_y}.fasta`).attr("id","my-download").text("download"));document.getElementById("my-download").click();dgenies.hide_loading()}else{dgenies.notify(`An error has occurred. Please contact the support`,"danger")}})},0)};/**
* Download offline viewer
*/dgenies.result.export.export_offline_viewer=function(){dgenies.show_loading("Building file...",180);window.setTimeout(()=>{let export_div=$("div#export-pict");export_div.html("");export_div.append($("<a>").attr("href",`/viewer/${dgenies.result.id_res}`).attr("download",dgenies.result.id_res+".html").attr("id","my-download").text("download"));dgenies.hide_loading();document.getElementById("my-download").click()})};/**
* Manage exports
*/dgenies.result.export.export=function(){let select=$("form#export select");let selection=parseInt(select.val());window.setTimeout(()=>{if(selection>0){let async=false;if(selection===1){dgenies.result.export.export_svg();async=true}else if(selection===2){dgenies.result.export.export_png();async=true}else if(selection===3)dgenies.result.export.export_paf();else if(selection===4){dgenies.result.export.ask_export_fasta();async=true}else if(selection===5){dgenies.result.export.export_association_table()}else if(selection===6){dgenies.result.export.export_no_association_file("query");async=true}else if(selection===7){dgenies.result.export.export_no_association_file("target");async=true}else if(selection===8){if(dgenies.mode==="webserver"){dgenies.result.export.export_query_as_reference_fasta_webserver()}else{dgenies.result.export.export_query_as_reference_fasta_standalone();async=true}}else if(selection===9){dgenies.result.export.export_backup_file();async=true}else dgenies.notify("Not supported yet!","danger",2000);if(!async)dgenies.hide_loading();select.val("0")}},0)};
*/dgenies.result.export.export=function(){let select=$("form#export select");let selection=parseInt(select.val());window.setTimeout(()=>{if(selection>0){let async=false;if(selection===1){dgenies.result.export.export_svg();async=true}else if(selection===2){dgenies.result.export.export_png();async=true}else if(selection===3)dgenies.result.export.export_paf();else if(selection===4){dgenies.result.export.ask_export_fasta();async=true}else if(selection===5){dgenies.result.export.export_association_table()}else if(selection===6){dgenies.result.export.export_no_association_file("query");async=true}else if(selection===7){dgenies.result.export.export_no_association_file("target");async=true}else if(selection===8){if(dgenies.mode==="webserver"){dgenies.result.export.export_query_as_reference_fasta_webserver()}else{dgenies.result.export.export_query_as_reference_fasta_standalone();async=true}}else if(selection===9){dgenies.result.export.export_backup_file();async=true}else if(selection===10){dgenies.result.export.export_offline_viewer();async=true}else dgenies.notify("Not supported yet!","danger",2000);if(!async)dgenies.hide_loading();select.val("0")}},0)};
if(!dgenies||!dgenies.result){throw"dgenies.result wasn't included!"}dgenies.result.summary={};dgenies.result.summary.percents={};/**
* Show summary window
* @param {object} percents: percents for each identity category
......@@ -246,31 +248,31 @@ for(let i=0;i<4;i++){d3.boxplot.__draw_idy_lines(i.toString(),lines,x_len,y_len)
d3.boxplot.x_zones={};let sum=0;for(let i=0;i<x_order.length-1;i++){let x_id=x_order[i];let x_contig_len=x_contigs[x_id]/d3.boxplot.x_len*d3.boxplot.scale;d3.boxplot.x_zones[x_id]=[sum,sum+x_contig_len];sum+=x_contig_len;d3.boxplot.container.append("line").attr("x1",sum).attr("y1",d3.boxplot.scale).attr("x2",sum).attr("y2",0).attr("class","break-lines").attr("stroke-width",d3.boxplot.break_lines_width).attr("stroke",d3.boxplot.break_lines_color).style("stroke-dasharray",d3.boxplot.break_lines_dash)}d3.boxplot.x_zones[x_order[x_order.length-1]]=[sum,d3.boxplot.scale];//Y axis:
d3.boxplot.y_zones={};sum=0;for(let i=0;i<y_order.length-1;i++){let y_id=y_order[i];let y_contig_len=y_contigs[y_id]/d3.boxplot.y_len*d3.boxplot.scale;d3.boxplot.y_zones[y_id]=[sum,sum+y_contig_len];sum+=y_contig_len;d3.boxplot.container.append("line").attr("x1",0).attr("y1",d3.boxplot.scale-sum).attr("x2",d3.boxplot.scale).attr("y2",d3.boxplot.scale-sum).attr("class","break-lines").attr("stroke-width",d3.boxplot.break_lines_width).attr("stroke",d3.boxplot.break_lines_color).style("stroke-dasharray",d3.boxplot.break_lines_dash)}d3.boxplot.y_zones[y_order[y_order.length-1]]=[sum,d3.boxplot.scale];if(!d3.boxplot.break_lines_show){d3.selectAll("line.break-lines").style("visibility","hidden")}d3.boxplot.draw_axis_bckgd();d3.boxplot.draw_left_axis(d3.boxplot.y_len);d3.boxplot.draw_bottom_axis(d3.boxplot.x_len);d3.boxplot.draw_top_axis(d3.boxplot.x_zones);d3.boxplot.draw_right_axis(d3.boxplot.y_zones);window.setTimeout(()=>{//Data:
d3.boxplot.draw_lines();$("#restore-all").click(function(){if(d3.boxplot.zoom.reset_scale(false,null,false)){$(this).hide()}});$(document).on("keyup",function(e){if(e.keyCode===27){if(d3.boxplot.zoom.reset_scale(false,null,false)){$("#restore-all").hide()}}});d3.boxplot.draw_legend();dgenies.hide_loading()},0);d3.boxplot.zoom.init();d3.boxplot.events.init_context_menu()};
if(!d3||!d3.boxplot){throw"d3.boxplot wasn't included!"}d3.boxplot.events={};/**
if(!d3||!d3.boxplot){throw'd3.boxplot wasn\'t included!'}d3.boxplot.events={};d3.boxplot.events.context_menu={actions:[{name:'Export SVG',onClick:dgenies.result.export.export_svg},{name:'Export PNG',onClick:dgenies.result.export.export_png},{name:'Reverse query',isShown:function(){return d3.boxplot.name_x!==d3.boxplot.name_y},onClick:dgenies.result.controls.launch_reverse_contig}]};/**
* Initialise events
*/d3.boxplot.events.init=function(){$("input#filter_size").change(function(){d3.boxplot.events.filter_size(d3.boxplot.min_sizes[this.value])});$("input#stroke-linecap").change(function(){d3.boxplot.events.stroke_linecap(!this.checked)});$("input#stroke-width").change(function(){d3.boxplot.events.stroke_width(this.value)});$("input#filter_identity").change(function(){d3.boxplot.events.filter_identity(this.value)});$("input#chroms-limits").change(function(){d3.boxplot.events.set_break_lines_visibility(this.value)});$("div#legend div.draw").on("click",d3.boxplot.switch_color_theme)};/**
*/d3.boxplot.events.init=function(){$('input#filter_size').change(function(){d3.boxplot.events.filter_size(d3.boxplot.min_sizes[this.value])});$('input#stroke-linecap').change(function(){d3.boxplot.events.stroke_linecap(!this.checked)});$('input#stroke-width').change(function(){d3.boxplot.events.stroke_width(this.value)});$('input#filter_identity').change(function(){d3.boxplot.events.filter_identity(this.value)});$('input#chroms-limits').change(function(){d3.boxplot.events.set_break_lines_visibility(this.value)});$('div#legend div.draw').on('click',d3.boxplot.switch_color_theme)};/**
* Initialise context menu
*/d3.boxplot.events.init_context_menu=function(){d3.boxplot.svgcontainer.on("mousedown",function(){let event=d3.event;let rect=$("g.container")[0].getBoundingClientRect();let posY=rect.top+window.scrollY,height_c=rect.height;let y=d3.boxplot.scale-(event.pageY-posY)/height_c*d3.boxplot.scale;d3.boxplot.query_selected=d3.boxplot.select_query(y)});let menu=new BootstrapMenu("svg.svgcontainer",{actions:[{name:"Export SVG",onClick:dgenies.result.export.export_svg},{name:"Export PNG",onClick:dgenies.result.export.export_png},{name:"Reverse query",isShown:function(){return d3.boxplot.name_x!==d3.boxplot.name_y},onClick:dgenies.result.controls.launch_reverse_contig}]})};/**
*/d3.boxplot.events.init_context_menu=function(){d3.boxplot.svgcontainer.on('mousedown',function(){let event=d3.event;let rect=$('g.container')[0].getBoundingClientRect();let posY=rect.top+window.scrollY,height_c=rect.height;let y=d3.boxplot.scale-(event.pageY-posY)/height_c*d3.boxplot.scale;d3.boxplot.query_selected=d3.boxplot.select_query(y)});let menu=new BootstrapMenu('svg.svgcontainer',d3.boxplot.events.context_menu)};/**
* Set break lines visibility: color and thickness, or hidden
*
* @param {string} value: visibility value: "0"-> hidden to "5" -> max visibility value
*/d3.boxplot.events.set_break_lines_visibility=function(value){if(value==="0"){d3.boxplot.break_lines_show=false;d3.boxplot.break_lines_dash="3, 3"}else if(value==="1"){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/2000;d3.boxplot.break_lines_color="#bfbfbf";d3.boxplot.break_lines_dash="3, 3"}else if(value==="2"){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/1500;d3.boxplot.break_lines_color="#7c7c7c";d3.boxplot.break_lines_dash="3, 3"}else if(value==="3"){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/1000;d3.boxplot.break_lines_color="#424242";d3.boxplot.break_lines_dash="3, 3"}else if(value==="4"){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/800;d3.boxplot.break_lines_color="#2b2b2b";d3.boxplot.break_lines_dash="3, 3"}else if(value==="5"){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/600;d3.boxplot.break_lines_color="#000000";d3.boxplot.break_lines_dash="none"}if(d3.boxplot.break_lines_show){d3.selectAll("line.break-lines").style("visibility","visible");d3.selectAll("line.break-lines").attr("stroke-width",d3.boxplot.break_lines_width/d3.boxplot.zoom_scale_lines);d3.selectAll("line.break-lines").attr("stroke",d3.boxplot.break_lines_color);d3.selectAll("line.break-lines").style("stroke-dasharray",d3.boxplot.break_lines_dash)}else{d3.selectAll("line.break-lines").style("visibility","hidden")}};/**
*/d3.boxplot.events.set_break_lines_visibility=function(value){if(value==='0'){d3.boxplot.break_lines_show=false;d3.boxplot.break_lines_dash='3, 3'}else if(value==='1'){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/2000;d3.boxplot.break_lines_color='#bfbfbf';d3.boxplot.break_lines_dash='3, 3'}else if(value==='2'){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/1500;d3.boxplot.break_lines_color='#7c7c7c';d3.boxplot.break_lines_dash='3, 3'}else if(value==='3'){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/1000;d3.boxplot.break_lines_color='#424242';d3.boxplot.break_lines_dash='3, 3'}else if(value==='4'){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/800;d3.boxplot.break_lines_color='#2b2b2b';d3.boxplot.break_lines_dash='3, 3'}else if(value==='5'){d3.boxplot.break_lines_show=true;d3.boxplot.break_lines_width=d3.boxplot.scale/600;d3.boxplot.break_lines_color='#000000';d3.boxplot.break_lines_dash='none'}if(d3.boxplot.break_lines_show){d3.selectAll('line.break-lines').style('visibility','visible');d3.selectAll('line.break-lines').attr('stroke-width',d3.boxplot.break_lines_width/d3.boxplot.zoom_scale_lines);d3.selectAll('line.break-lines').attr('stroke',d3.boxplot.break_lines_color);d3.selectAll('line.break-lines').style('stroke-dasharray',d3.boxplot.break_lines_dash)}else{d3.selectAll('line.break-lines').style('visibility','hidden')}};/**
* Remove too small matches
*
* @param {number} min_size minimum size. Beside it, hide matches
*/d3.boxplot.events.filter_size=function(min_size){for(let i=0;i<d3.boxplot.min_sizes.length;i++){let size=d3.boxplot.min_sizes[i];if(size<min_size){$("path.content-lines.s_"+size.toString().replace(".","_")).hide()}else{$("path.content-lines.s_"+size.toString().replace(".","_")).show()}}d3.boxplot.min_size=min_size};/**
*/d3.boxplot.events.filter_size=function(min_size){for(let i=0;i<d3.boxplot.min_sizes.length;i++){let size=d3.boxplot.min_sizes[i];if(size<min_size){$('path.content-lines.s_'+size.toString().replace('.','_')).hide()}else{$('path.content-lines.s_'+size.toString().replace('.','_')).show()}}d3.boxplot.min_size=min_size};/**
* Remove low identity matches
*
* @param {number} min_idy minimum of identity. Beside it, hide matches
*/d3.boxplot.events.filter_identity=function(min_idy){d3.boxplot.min_idy_draw=min_idy;dgenies.show_loading();window.setTimeout(()=>{d3.boxplot.draw_lines();d3.selectAll("path.content-lines").attr("stroke-width",d3.boxplot.content_lines_width/d3.boxplot.zoom_scale_lines);d3.boxplot.events.filter_size(d3.boxplot.min_size);dgenies.hide_loading()},0)};/**
*/d3.boxplot.events.filter_identity=function(min_idy){d3.boxplot.min_idy_draw=min_idy;dgenies.show_loading();window.setTimeout(()=>{d3.boxplot.draw_lines();d3.selectAll('path.content-lines').attr('stroke-width',d3.boxplot.content_lines_width/d3.boxplot.zoom_scale_lines);d3.boxplot.events.filter_size(d3.boxplot.min_size);dgenies.hide_loading()},0)};/**
* If stroke precision checked, strole-linecap is set to "butt". Else "round" to improve visibility of matches
*
* @param {boolean} rounded if true, improve bisibility by add round cap to lines
*/d3.boxplot.events.stroke_linecap=function(rounded){d3.boxplot.linecap=rounded?"round":"butt";$("path").attr("stroke-linecap",d3.boxplot.linecap)};/**
*/d3.boxplot.events.stroke_linecap=function(rounded){d3.boxplot.linecap=rounded?'round':'butt';$('path').attr('stroke-linecap',d3.boxplot.linecap)};/**
* Change matches lines stroke width
*
* @param {string} width new width class ("1", "2", or "3")
*/d3.boxplot.events.stroke_width=function(width){let stroke_width=d3.boxplot.scale/600;if(width==="1"){stroke_width=d3.boxplot.scale/400}else if(width==="2"){stroke_width=d3.boxplot.scale/200}else if(width==="3"){stroke_width=d3.boxplot.scale/100}d3.boxplot.content_lines_width=stroke_width;d3.selectAll("path.content-lines").attr("stroke-width",stroke_width/d3.boxplot.zoom_scale_lines)};
*/d3.boxplot.events.stroke_width=function(width){let stroke_width=d3.boxplot.scale/600;if(width==='1'){stroke_width=d3.boxplot.scale/400}else if(width==='2'){stroke_width=d3.boxplot.scale/200}else if(width==='3'){stroke_width=d3.boxplot.scale/100}d3.boxplot.content_lines_width=stroke_width;d3.selectAll('path.content-lines').attr('stroke-width',stroke_width/d3.boxplot.zoom_scale_lines)};
if(!d3||!d3.boxplot){throw'd3.boxplot wasn\'t included!'}d3.boxplot.mousetip={};/**
* Get color (black/white) depending on bgColor so it would be clearly seen.
* @param bgColor
......
This diff is collapsed.
......@@ -47,6 +47,7 @@
<option value="0" selected disabled hidden>Export...</option>
<option value="1">Svg</option>
<option value="2">Png</option>
<option value="10">Offline viewer</option>
<option value="3">Paf file</option>
{% if not is_gallery and fasta_file %}
<option value="4">Query Fasta</option>
......
......@@ -924,6 +924,33 @@ def get_filter_out_target(id_res):
return get_filter_out(id_res=id_res, type_f="target")
@app.route('/viewer/<id_res>')
def get_viewer_html(id_res):
"""
Get HTML file with offline interactive viewer inside
:param id_res: job id
:type id_res: str
"""
paf = os.path.join(APP_DATA, id_res, "map.paf")
idx1 = os.path.join(APP_DATA, id_res, "query.idx")
idx2 = os.path.join(APP_DATA, id_res, "target.idx")
paf = Paf(paf, idx1, idx2)
if paf.parsed:
res = paf.get_d3js_data()
res["success"] = True
percents = paf.get_summary_stats()
with open(os.path.join(app_folder, "static", "js", "dgenies-offline-result.min.js"), "r") as js_min:
js = js_min.read()
with open(os.path.join(app_folder, "static", "css", "dgenies-offline-result.min.css"), "r") as css_min:
css = css_min.read()
return render_template("map_offline.html", json=json.dumps(res), version=VERSION, js=js, css=css,
percents=percents)
return abort(403)
@app.route("/ask-upload", methods=['POST'])
def ask_upload():
"""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment