Commit 3d5c5758 authored by Jerome Mariette's avatar Jerome Mariette
Browse files

add upload functionality to the Jvenn application

parent 7a93d3a6
#
# Copyright (C) 2015 INRA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import cherrypy
import argparse
import textwrap
import string
import json
import os
WEB_DIR = os.path.abspath(os.path.join(__file__, "../../docs"))
class AppServer(object):
OUTPUT_DIRECTORY = "/tmp"
@cherrypy.expose
def index(self):
raise cherrypy.HTTPRedirect("/app/index.html")
@cherrypy.expose
def process_venn(self, **kwargs):
file_path = self.__upload(**kwargs)
return self.__compare_lists(file_path, True, "\t")
def __upload(self, **kwargs):
# the file transfer can take a long time; by default cherrypy
# limits responses to 300s; we increase it to 1h
cherrypy.response.timeout = 3600
# upload file by chunks
filepath = os.path.join(self.OUTPUT_DIRECTORY, kwargs["browse_upload"].filename)
FH_sever_file = open(filepath, "w")
while True:
data = kwargs["browse_upload"].file.read(8192)
if not data:
break
if isinstance(data, bytes):
FH_sever_file.write(data.decode())
else:
FH_sever_file.write(data)
FH_sever_file.close()
return(filepath)
def __compare_lists ( self, file , header, spliter):
FH = open(file,'r')
names = {}
samples = {}
for i, line in enumerate(FH.readlines()):
if i == 0 and header:
for j, val in enumerate(line.split(spliter)):
names[string.ascii_uppercase[j]] = val
else:
for j, val in enumerate(line.split(spliter)):
if j in samples:
samples[j].append(val)
else:
samples[j] = [val]
d = {}
j = 1
for s in samples:
for line in samples[s]:
if line.rstrip('\n\r') in d:
#already view in the current file (duplicate) ?
if d[line.rstrip('\n\r')] - j < 0:
d[line.rstrip('\n\r')] += j
else:
d[line.rstrip('\n\r')] = j
j *= 10
d2 = {}
for key, val in d.items():
if str(val).zfill(len(samples)) in d2:
d2[str(val).zfill(len(samples))].append(key)
else:
d2[str(val).zfill(len(samples))] = [key]
values = {}
data = {}
for key in sorted(d2):
k = ""
for i in range(len(key)):
if key[len(key)-(i+1)] == "1":
k = k + string.ascii_uppercase[i]
values[k] = len(d2[key])
data[k] = []
data[k].append(','.join(d2[key]))
return json.dumps([{'name': names, 'values' : values, 'data':data}], indent=4, sort_keys=True)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--daemon", action="store_true", dest="daemon", default=False, help="Run the server as daemon")
args = vars(parser.parse_args())
app_conf = {
'/':
{'tools.staticdir.root': WEB_DIR},
os.path.join('/', 'css'):
{'tools.staticdir.on' : True, 'tools.staticdir.dir' : './css/'},
os.path.join('/', 'js'):
{'tools.staticdir.on' : True, 'tools.staticdir.dir' : './js/'},
os.path.join('/', 'img'):
{'tools.staticdir.on' : True, 'tools.staticdir.dir' : './img/'},
os.path.join('/', 'app'):
{'tools.staticdir.on' : True, 'tools.staticdir.dir' : './'}
}
cherrypy.quickstart(AppServer(), config=app_conf)
\ No newline at end of file
......@@ -66,7 +66,7 @@
<p>In order to use jvenn, you need to import within your web page: </p>
<ul>
<li><a href="http://jquery.com/">jQuery v1.6.x or higher</a></li>
<li><a href="src/jvenn.min.js">jvenn.min.js</a></li>
<li><a href="js/jvenn.min.js">jvenn.min.js</a></li>
</ul>
<p>Take a peek at the code below, a single function call to initialise the venn diagram is all it takes:</p>
<pre class="prettyprint linenums">
......
......@@ -21,8 +21,12 @@
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/bootstrap-colorpicker.min.js"></script>
<script type="text/javascript" src="src/canvas2svg.js"></script>
<script type="text/javascript" src="src/jvenn.min.js"></script>
<script type="text/javascript" src="js/canvas2svg.js"></script>
<script type="text/javascript" src="js/jvenn.min.js"></script>
<script type="text/javascript" src="js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="js/jquery.fileupload.js"></script>
<script language="Javascript">
$(document).ready(function () {
......@@ -32,40 +36,43 @@
displaySwitch= true,
shortNumber = true,
fontSize = "12px",
fontFamily = "Arial";
fontFamily = "Arial",
uploadSeries = new Array();
function getArrayFromArea(areaID) {
var lines = $("#"+areaID).val().split("\n");
var table = new Array();
for (var lindex in lines) {
table.push(lines[lindex].trim());
}
return (table);
}
function updateJvenn() {
var seriesTable = new Array();
var num = 0;
for(var i=6; i>=1; i--) {
if($("#area"+i).val() != "") {
num = i;
break;
if ($("#paste-tab").hasClass("active")) {
var type = "pa",
seriesTable = new Array(),
num = 0;
for(var i=6; i>=1; i--) {
if($("#area_pa_"+i).val() != "") {
num = i;
break;
}
}
for(var i=1; i<=num; i++) {
seriesTable.push({
name: $("#name_pa_"+i).val(),
data: getArrayFromArea("area_pa_"+i)
});
}
} else {
var type = "up",
seriesTable = uploadSeries;
}
for(var i=1; i<=num; i++) {
seriesTable.push({
name: $("#name"+i).val(),
data: getArrayFromArea("area"+i)
});
}
var colorsTable = new Array();
colorsTable.push($('#name1').css("color"));
colorsTable.push($('#name2').css("color"));
colorsTable.push($('#name3').css("color"));
colorsTable.push($('#name4').css("color"));
colorsTable.push($('#name5').css("color"));
colorsTable.push($('#name6').css("color"));
var colorsTable = new Array();
colorsTable.push($('#name_'+type+'_1').css("color"));
colorsTable.push($('#name_'+type+'_2').css("color"));
colorsTable.push($('#name_'+type+'_3').css("color"));
colorsTable.push($('#name_'+type+'_4').css("color"));
colorsTable.push($('#name_'+type+'_5').css("color"));
colorsTable.push($('#name_'+type+'_6').css("color"));
$("#jvenn-container").jvenn({
series: seriesTable,
......@@ -97,9 +104,158 @@
});
}
// update the view when any fields change
$("[id^=name]").change(function() {
updateJvenn();
});
$("[id^=area]").change(function() {
updateJvenn();
});
$("#venn-type").change(function() {
updateJvenn();
});
$("#qm_yes").click(function() {
shortNumber = true;
updateJvenn();
});
$("#qm_no").click(function() {
shortNumber = false;
updateJvenn();
});
$("#ds_yes").click(function() {
displayStat = true;
updateJvenn();
});
$("#ds_no").click(function() {
displayStat = false;
updateJvenn();
});
$("#dsw_yes").click(function() {
displaySwitch = true;
updateJvenn();
});
$("#dsw_no").click(function() {
displaySwitch = false;
updateJvenn();
});
$("#dm_classic").click(function() {
displayMode = "classic";
updateJvenn();
});
$("#dm_edwards").click(function() {
displayMode = "edwards";
updateJvenn();
});
$('[id^="ff"]').click(function() {
fontFamily = $(this).html();
updateJvenn();
});
$('[id^="fs"]').click(function() {
fontSize = $(this).html();
updateJvenn();
});
$('[id^="colorp"]').colorpicker().on('changeColor.colorpicker', function(event) {
var type = $(this).attr("id").split("_")[1],
index = $(this).attr("id").split("_")[2];
$("#name_" + type + "_" + index).css("color", event.color.toHex());
$("#name_" + type + "_" + index).css("border-color", event.color.toHex());
if (type == "pa") {
$("#area_" + type + "_" + index).css("color", event.color.toHex());
$("#area_" + type + "_" + index).css("border-color", event.color.toHex());
}
updateJvenn();
});
$('[id^="colord"]').click(function() {
var type = $(this).attr("id").split("_")[1],
index = $(this).attr("id").split("_")[2];
$("#name_" + type + "_" + index).css("color", colorDefault[index-1]);
$("#name_" + type + "_" + index).css("border-color", colorDefault[index-1]);
if (type == "pa") {
$("#area_" + type + "_" + index).css("color", colorDefault[index-1]);
$("#area_" + type + "_" + index).css("border-color", colorDefault[index-1]);
}
$("#colorp_" + type + "_" + index).colorpicker('setValue', colorDefault[index-1]);
updateJvenn();
});
$('[id^="clear"]').click(function() {
var type = $(this).attr("id").split("_")[1],
index = $(this).attr("id").split("_")[2];
if (type == "pa") {
$("#area_" + type + "_" + index).val("");
}
$("#name_" + type + "_" + index).val("List " + index);
updateJvenn();
});
$('#clear-all').click(function() {
$('[id^="name_"]').each(function() {
var type = $(this).attr("id").split("_")[1],
index = $(this).attr("id").split("_")[2];
if (type == "pa") {
$("#area_" + type + "_" + index).val("");
}
$("#name_" + type + "_" + index).val("List " + index);
});
$('#search-field').val("");
$('#search-status').html("");
$('#venn-type').val("classic");
updateJvenn();
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
updateJvenn();
$("#names").val("");
});
$("#upload_and_draw").click(function(){
$("#browse_upload").click();
});
$('#browse_upload').fileupload({
dataType: 'json',
add: function (e, data) {
data.submit();
},
done: function (e, data) {
uploadSeries = new Array({name: data.result[0].name, data: data.result[0].data, values: data.result[0].values});
$("#name_up_1").val(data.result[0].name["A"]);
$("#name_up_2").val(data.result[0].name["B"]);
$("#name_up_3").val(data.result[0].name["C"]);
$("#name_up_4").val(data.result[0].name["D"]);
$("#name_up_5").val(data.result[0].name["E"]);
$("#name_up_6").val(data.result[0].name["F"]);
updateJvenn();
}/*,
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}*/
});
function getArrayFromArea(areaID) {
var lines = $("#"+areaID).val().split("\n");
var table = new Array();
for (var lindex in lines) {
table.push(lines[lindex].trim());
}
return (table);
}
$("#example").click(function() {
$("#name1").val("DESeq");
$("#area1").val(
$("#paste-tab a").tab("show");
$("#name_pa_1").val("DESeq");
$("#area_pa_1").val(
'G000002\nG000005\nG000008\nG000009\nG000012\nG000022\nG000023\nG000024\nG000026\nG000027\nG000028\nG000029\nG000030\nG000031\nG000041\n'+
'G000046\nG000053\nG000061\nG000078\nG000080\nG000082\nG000095\nG000098\nG000101\nG000114\nG000116\nG000129\nG000130\nG000144\nG000147\n'+
'G000164\nG000165\nG000167\nG000177\nG000180\nG000181\nG000185\nG000186\nG000189\nG000194\nG000195\nG000197\nG000200\nG000203\nG000215\n'+
......@@ -185,8 +341,8 @@
'G005234\nG005237\nG005241\nG005243\nG005248\nG005250\nG005254\nG005255\nG005259\nG005262\nG005263\nG005264\nG005265\nG005266\nG005268\n'+
'G005269\nG005273\nG005274\nG005276\n'
);
$("#name2").val("FQ");
$("#area2").val(
$("#name_pa_2").val("FQ");
$("#area_pa_2").val(
'G000002\nG000005\nG000008\nG000009\nG000012\nG000022\nG000023\nG000024\nG000026\nG000027\nG000028\nG000029\nG000030\nG000031\nG000041\n'+
'G000046\nG000061\nG000078\nG000082\nG000098\nG000101\nG000116\nG000144\nG000147\nG000164\nG000165\nG000167\nG000177\nG000180\nG000181\n'+
'G000185\nG000186\nG000194\nG000195\nG000203\nG000218\nG000231\nG000232\nG000236\nG000237\nG000238\nG000253\nG000254\nG000256\nG000259\n'+
......@@ -261,8 +417,8 @@
'G005202\nG005203\nG005204\nG005212\nG005214\nG005220\nG005222\nG005227\nG005231\nG005234\nG005237\nG005241\nG005243\nG005248\nG005250\n'+
'G005254\nG005255\nG005259\nG005263\nG005264\nG005265\nG005266\nG005268\nG005269\nG005273\nG005274\nG005276\n'
);
$("#name3").val("RPKM");
$("#area3").val(
$("#name_pa_3").val("RPKM");
$("#area_pa_3").val(
'G000005\nG000008\nG000009\nG000012\nG000028\nG000029\nG000030\nG000061\nG000101\nG000147\nG000165\nG000177\nG000185\nG000195\nG000237\n'+
'G000259\nG000262\nG000302\nG000305\nG000306\nG000311\nG000316\nG000355\nG000356\nG000370\nG000376\nG000377\nG000381\nG000412\nG000418\n'+
'G000420\nG000426\nG000447\nG000490\nG000514\nG000517\nG000547\nG000581\nG000665\nG000696\nG000701\nG000704\nG000705\nG000711\nG000714\n'+
......@@ -292,8 +448,8 @@
'G005176\nG005180\nG005185\nG005188\nG005192\nG005198\nG005201\nG005202\nG005203\nG005212\nG005214\nG005222\nG005241\nG005243\nG005246\n'+
'G005248\nG005250\nG005254\nG005255\nG005259\nG005263\nG005264\nG005266\nG005268\nG005269\nG005273\nG005276\n'
);
$("#name4").val("TC");
$("#area4").val(
$("#name_pa_4").val("TC");
$("#area_pa_4").val(
'G000005\nG000008\nG000009\nG000012\nG000026\nG000028\nG000029\nG000030\nG000061\nG000082\nG000101\nG000147\nG000165\nG000167\nG000177\n'+
'G000185\nG000195\nG000236\nG000237\nG000256\nG000259\nG000262\nG000276\nG000302\nG000305\nG000306\nG000311\nG000316\nG000318\nG000355\n'+
'G000356\nG000365\nG000376\nG000377\nG000381\nG000391\nG000412\nG000418\nG000420\nG000426\nG000431\nG000447\nG000490\nG000493\nG000514\n'+
......@@ -332,8 +488,8 @@
'G005188\nG005192\nG005198\nG005201\nG005202\nG005203\nG005212\nG005214\nG005222\nG005241\nG005243\nG005246\nG005248\nG005250\nG005254\n'+
'G005255\nG005263\nG005264\nG005266\nG005268\nG005269\nG005273\nG005276\n'
);
$("#name5").val("TMM");
$("#area5").val(
$("#name_pa_5").val("TMM");
$("#area_pa_5").val(
'G000002\nG000005\nG000008\nG000009\nG000012\nG000022\nG000023\nG000024\nG000026\nG000027\nG000028\nG000029\nG000030\nG000031\nG000041\n'+
'G000061\nG000078\nG000080\nG000082\nG000095\nG000098\nG000101\nG000114\nG000116\nG000129\nG000144\nG000147\nG000165\nG000167\nG000177\n'+
'G000180\nG000181\nG000185\nG000186\nG000194\nG000195\nG000197\nG000203\nG000215\nG000218\nG000231\nG000232\nG000236\nG000237\nG000238\n'+
......@@ -415,8 +571,8 @@
'G005234\nG005237\nG005241\nG005243\nG005246\nG005248\nG005250\nG005254\nG005255\nG005259\nG005262\nG005263\nG005264\nG005265\nG005266\n'+
'G005268\nG005269\nG005273\nG005274\nG005276\n'
);
$("#name6").val("UQ");
$("#area6").val(
$("#name_pa_6").val("UQ");
$("#area_pa_6").val(
'G000002\nG000005\nG000008\nG000009\nG000012\nG000022\nG000023\nG000026\nG000027\nG000028\nG000029\nG000030\nG000031\nG000041\nG000046\n'+
'G000061\nG000078\nG000082\nG000095\nG000098\nG000101\nG000114\nG000116\nG000129\nG000144\nG000147\nG000165\nG000167\nG000177\nG000180\n'+
'G000181\nG000185\nG000186\nG000194\nG000195\nG000197\nG000203\nG000215\nG000218\nG000231\nG000232\nG000236\nG000237\nG000238\nG000242\n'+
......@@ -502,110 +658,23 @@
updateJvenn();
});
$('[id^="clear"]').click(function() {
var index = $(this).attr("id").split("_")[1];
$("#area" + index).val("");
$("#name" + index).val("List " + index);
updateJvenn();
});
$('#clear-all').click(function() {
$('[id^="clear"]').each(function() {
var index = $(this).attr("id").split("_")[1];
$("#area" + index).val("");
$("#name" + index).val("List " + index);
});
$('#search-field').val("");
$('#search-status').html("");
$('#venn-type').val("classic");
updateJvenn();
});
$('#colorp_pa_1').children("span").children("i").css("background-color", colorDefault[0]);
$('#colorp_pa_2').children("span").children("i").css("background-color", colorDefault[1]);
$('#colorp_pa_3').children("span").children("i").css("background-color", colorDefault[2]);
$('#colorp_pa_4').children("span").children("i").css("background-color", colorDefault[3]);
$('#colorp_pa_5').children("span").children("i").css("background-color", colorDefault[4]);
$('#colorp_pa_6').children("span").children("i").css("background-color", colorDefault[5]);
$('#colorp_up_1').children("span").children("i").css("background-color", colorDefault[0]);
$('#colorp_up_2').children("span").children("i").css("background-color", colorDefault[1]);
$('#colorp_up_3').children("span").children("i").css("background-color", colorDefault[2]);
$('#colorp_up_4').children("span").children("i").css("background-color", colorDefault[3]);
$('#colorp_up_5').children("span").children("i").css("background-color", colorDefault[4]);
$('#colorp_up_6').children("span").children("i").css("background-color", colorDefault[5]);
updateJvenn();
// update the view when any fields change
$("[id^=name]").change(function() {
updateJvenn();
});
$("[id^=area]").change(function() {
updateJvenn();
});
$("#venn-type").change(function() {
updateJvenn();
});
$('[id^="colorp"]').colorpicker().on('changeColor.colorpicker', function(event) {
var index = $(this).attr("id").split("_")[1];
$("#name" + index).css("color", event.color.toHex());
$("#name" + index).css("border-color", event.color.toHex());
$("#area" + index).css("color", event.color.toHex());
$("#area" + index).css("border-color", event.color.toHex());
updateJvenn();
});
$('[id^="colord"]').click(function() {
var index = $(this).attr("id").split("_")[1];
$("#name" + index).css("color", colorDefault[index-1]);
$("#name" + index).css("border-color", colorDefault[index-1]);
$("#area" + index).css("color", colorDefault[index-1]);
$("#area" + index).css("border-color", colorDefault[index-1]);
$("#colorp_" + index).colorpicker('setValue', colorDefault[index-1]);
updateJvenn();
});
$("#qm_yes").click(function() {
shortNumber = true;
updateJvenn();
});
$("#qm_no").click(function() {
shortNumber = false;
updateJvenn();
});
$("#ds_yes").click(function() {
displayStat = true;
updateJvenn();
});
$("#ds_no").click(function() {
displayStat = false;
updateJvenn();
});
$("#dsw_yes").click(function() {
displaySwitch = true;
updateJvenn();
});
$("#dsw_no").click(function() {
displaySwitch = false;
updateJvenn();
});
$("#dm_classic").click(function() {
displayMode = "classic";
updateJvenn();
});
$("#dm_edwards").click(function() {
displayMode = "edwards";
updateJvenn();
});
$('[id^="ff"]').click(function() {
fontFamily = $(this).html();
updateJvenn();
});
$('[id^="fs"]').click(function() {
fontSize = $(this).html();
updateJvenn();
});
// first init of the jvenn plugin
$('#colorp_1').children("span").children("i").css("background-color", colorDefault[0]);
$('#colorp_2').children("span").children("i").css("background-color", colorDefault[1]);
$('#colorp_3').children("span").children("i").css("background-color", colorDefault[2]);
$('#colorp_4').children("span").children("i").css("background-color", colorDefault[3]);
$('#colorp_5').children("span").children("i").css("background-color", colorDefault[4]);
$('#colorp_6').children("span").children("i").css("background-color", colorDefault[5]);
updateJvenn();
});
</script>
<style type="text/css">
/* add classes control-group.color */
.control-group.color1 input,
......@@ -838,112 +907,213 @@
<span id="search-status" class="label label-info" style="vertical-align: 16px; margin-left: -35px;"></span>
</div>
</div>