comparison jqBarGraph.2.1.js @ 0:3ba5983012cf draft

Uploaded
author mzeidler
date Tue, 24 Sep 2013 10:19:40 -0400
parents
children cbd4d7e3f155
comparison
equal deleted inserted replaced
-1:000000000000 0:3ba5983012cf
1 /**
2 * jqBarGraph - jQuery plugin
3 * @version: 1.1 (2011/04/03)
4 * @requires jQuery v1.2.2 or later
5 * @author Ivan Lazarevic
6 * Examples and documentation at: http://www.workshop.rs/jqbargraph/
7 *
8 * Dual licensed under the MIT and GPL licenses:
9 * http://www.opensource.org/licenses/mit-license.php
10 * http://www.gnu.org/licenses/gpl.html
11 *
12 * @param data: arrayOfData // array of data for your graph
13 * @param title: false // title of your graph, accept HTML
14 * @param barSpace: 10 // this is default space between bars in pixels
15 * @param width: 400 // default width of your graph ghhjgjhg
16 * @param height: 200 //default height of your graph
17 * @param color: '#000000' // if you don't send colors for your data this will be default bars color
18 * @param colors: false // array of colors that will be used for your bars and legends
19 * @param lbl: '' // if there is no label in your array
20 * @param sort: false // sort your data before displaying graph, you can sort as 'asc' or 'desc'
21 * @param position: 'bottom' // position of your bars, can be 'bottom' or 'top'. 'top' doesn't work for multi type
22 * @param prefix: '' // text that will be shown before every label
23 * @param postfix: '' // text that will be shown after every label
24 * @param animate: true // if you don't need animated appereance change to false
25 * @param speed: 2 // speed of animation in seconds
26 * @param legendWidth: 100 // width of your legend box
27 * @param legend: false // if you want legend change to true
28 * @param legends: false // array for legend. for simple graph type legend will be extracted from labels if you don't set this
29 * @param type: false // for multi array data default graph type is stacked, you can change to 'multi' for multi bar type
30 * @param showValues: true // you can use this for multi and stacked type and it will show values of every bar part
31 * @param showValuesColor: '#fff' // color of font for values
32
33 * @example $('#divForGraph').jqBarGraph({ data: arrayOfData });
34
35 **/
36
37 (function($) {
38 var opts = new Array;
39 var level = new Array;
40
41 $.fn.jqBarGraph = $.fn.jqbargraph = function(options){
42
43 init = function(el){
44
45 opts[el.id] = $.extend({}, $.fn.jqBarGraph.defaults, options);
46 $(el).css({ 'width': opts[el.id].width, 'height': opts[el.id].height, 'position':'relative', 'text-align':'center' });
47
48
49 doGraph(el);
50 $("a").css({'color':'black'});
51
52 };
53
54 // sum of array elements
55 sum = function(ar,index){
56 total = 0;
57 for(val in ar){
58 total += ar[val][index];
59 }
60 return total.toFixed(2);
61 };
62
63 // count max value of array
64 max = function(ar,index){
65 maxvalue = 0;
66 for(var val in ar){
67 value = ar[val][0];
68 if(value instanceof Array) value = sum(value,index);
69 if (parseFloat(value) > parseFloat(maxvalue)) maxvalue=value;
70 }
71 return maxvalue;
72 };
73
74 // max value of multi array
75 maxMulti = function(ar,index){
76 maxvalue = 0;
77 maxvalue2 = 0;
78
79 for(var val in ar){
80 ar2 = ar[val][0];
81
82 for(var val2 in ar2){
83 if(ar2[val2][index]>maxvalue2) maxvalue2 = ar2[val2][index];
84 }
85
86 if (maxvalue2>maxvalue) maxvalue=maxvalue2;
87 }
88 console.log(maxvalue);
89 return maxvalue;
90 };
91
92
93 doGraph = function(el){
94
95 arr = opts[el.id];
96 data = arr.data;
97
98 //check if array is bad or empty
99 if(data == undefined) {
100 $(el).html('There is not enought data for graph');
101 return;
102 }
103 //sorting ascending or descending
104 if(arr.sort == 'asc') data.sort(sortNumberAsc);
105 if(arr.sort == 'desc') data.sort(sortNumberDesc);
106 if(arr.sortBar == 'asc') sortBars(data, barAsc);
107 if(arr.sortBar == 'desc')sortBars(data,barDesc);
108 if(arr.tab=='reads'){
109 val_index=0;
110 }
111 else{
112 val_index=1;
113
114 }
115
116 legend = '';
117 prefix = arr.prefix;
118 postfix = arr.postfix;
119 space = arr.barSpace; //space between bars
120 legendWidth = arr.legend ? arr.legendWidth : 0; //width of legend box
121 fieldWidth = ($(el).width()-legendWidth)/data.length; //width of bar
122 totalHeight = $(el).height(); //total height of graph box
123 var leg = new Array(); //legends array
124
125 //max value in data, I use this to calculate height of bar
126 max = max(data,val_index);
127
128 color_map={};
129 color_map["pathogen"]=arr.colors[0];
130 color_map["ambiguous"]=arr.colors[1];
131 color_map["human"]=arr.colors[2];
132
133 if(arr.tab=='reads'){
134 val_index=0;
135 }
136 else{
137 val_index=1;
138
139 }
140 for(var val in data){
141
142 valueData = data[val][0];
143 if (valueData instanceof Array)
144 value = sum(valueData,val_index);
145 else
146 value = valueData;
147
148 lbl = data[val][1];
149 unique = val+el.id; //unique identifier
150 divid=""+el.id;
151
152 if(arr.type == 'multi') color = 'none';
153
154 if (lbl == undefined) lbl = arr.lbl;
155
156 margin_top=14/(data.length);
157
158
159 out = "<div class='graphField"+el.id+"' id='graphField"+unique+"' style='position: absolute'>";
160 out += "<div class='graphValue"+el.id+"' id='graphValue"+unique+"'>"+parseInt(value)+"</div>";
161
162 out += "<div class='graphBar"+el.id+"' id='graphFieldBar"+unique+"' style='background-color:#fff;position: relative; overflow: hidden;'></div>";
163 //console.log(color)
164 // if there is no legend or exist legends display lbl at the bottom
165
166 out += "<a class='graphLabelLink' href=#files"+el.id+" onclick=fillDiv('"+el.id+"','"+valueData[0][3]+"_"+lbl+"')><div class='graphLabel"+el.id+"' id='graphLabel"+unique+"'style='margin-top:"+margin_top+"px;'>"+lbl+"</div></a>";
167 out += "</div>";
168
169
170
171 $(el).append(out);
172 $(".graphLabel"+el.id).css({'-webkit-transform': 'rotate(30deg)', '-moz-transform': 'rotate(30deg)','-o-transform': 'rotate(30deg)', '-ms-transform': 'rotate(30deg)','transform': 'rotate(30deg)', 'height':'100'});
173 $('a.graphLabel').css({
174 'text-decoration': 'none',
175 'color':'black'
176 });
177
178 //$('#graphLabel'+el.id).rotateLeft();
179
180 //size of bar
181 totalHeightBar = totalHeight - $('.graphLabel'+el.id).height() - $('.graphValue'+el.id).height()-margin_top;
182 fieldHeight = (totalHeightBar*value)/max;
183 $('#graphField'+unique).css({
184 'left': (fieldWidth)*val,
185 'width': fieldWidth-space,
186 'margin-left': space});
187
188 // multi array
189 if(valueData instanceof Array){
190
191 if(arr.type=="multi"){
192 console.log("multi");
193 maxe = maxMulti(data,val_index);
194 totalHeightBar = fieldHeight = totalHeight - $('.graphLabel'+el.id).height()-margin_top;
195 $('.graphValue'+el.id).remove();
196 } else {
197 console.log(max);
198 maxe = max;
199 }
200
201 for (i in valueData){
202 heig = (totalHeightBar*valueData[i][val_index]/maxe);
203 if(navigator.userAgent.match('Safari') && !navigator.userAgent.match('Chrom')){
204
205 heig = heig + (arr.borderSize/1.85);
206 }
207
208 wid = parseInt((fieldWidth-space)/valueData.length);
209
210 sv = ''; // show values
211 fs = 0; // font size
212 if (arr.showValues){
213 sv = arr.prefix+valueData[i][0]+arr.postfix;
214 fs = 12; // font-size is 0 if showValues = false
215 }
216 o = "<a class='subBarLink' href=#files"+el.id+" onclick=fillDiv('"+el.id+"','"+valueData[i][3]+"_"+lbl+"','"+valueData[i][5]+"')><div class='subBars"+el.id+"' style=' box-sizing:border-box; -moz-box-sizing:border-box; -ms-box-sizing:border-box; -webkit-box-sizing:border-box; height:"+heig+"px; border-top:"+arr.borderSize+"px solid; border-color: "+arr.showValuesColor+"; background-color: "+color_map[valueData[i][2]]+"; left:"+wid*i+"px; color:"+arr.showValuesColor+"; font-size:"+fs+"px' >"+sv+"</div></a>";
217 $('#graphFieldBar'+unique).prepend(o);
218 }
219 }
220
221 if(arr.type=='multi')
222 $('.subBars'+el.id).css({ 'width': wid, 'position': 'absolute', 'bottom': 0 });
223
224 //position of bars
225 if(arr.position == 'bottom') $('.graphField'+el.id).css('bottom',0);
226
227
228
229
230
231 // animated apearing
232 if(arr.animate){
233 $('#graphFieldBar'+unique).css({ 'height' : 0 });
234 $('#graphFieldBar'+unique).animate({'height': fieldHeight},arr.speed*1000);
235 } else {
236 $('#graphFieldBar'+unique).css({'height': fieldHeight});
237 }
238
239 }
240
241
242
243 createLegend(color_map,el.id); // create legend from array
244 createLinks(el.id);
245 //position of legend
246
247 $(el).append("<div id='legendHolder"+unique+"'></div>");
248 $('#legendHolder'+unique).css({ 'width': legendWidth, 'float': 'right', 'margin-left':'100px','text-align' : 'left'});
249 $('#legendHolder'+unique).append(legend);
250 $('#legendHolder'+unique).append(links);
251 $('.legendBar'+el.id).css({ 'float':'left', 'margin': 3, 'margin-left':'10','height': 12, 'width': 20, 'font-size': 0});
252 $('.linkBar'+el.id).css({'margin-left':'10'});
253
254
255 $("#sortAsc"+el.id).click(function(){
256 if(opts[el.id].sort!='asc'){
257 opts[el.id].sort='asc';
258 $('#graphHolder'+el.id).html('');
259 $('#graphHolder'+el.id).jqbargraph(opts[el.id]);
260 }
261
262 });
263 $("#sortDesc"+el.id).click(function(){
264 if(opts[el.id].sort!='desc'){
265 opts[el.id].sort='desc';
266 $('#'+el.id).html('');
267 $('#'+el.id).jqbargraph(opts[el.id]);
268 }
269
270 });
271 $("#sortBarAsc"+el.id).click(function(){
272 if(opts[el.id].sortBar!='asc'){
273 opts[el.id].sortBar='asc';
274 $('#graphHolder'+el.id).html('');
275 $('#graphHolder'+el.id).jqbargraph(opts[el.id]);
276 }
277
278 });
279 $("#sortBarDesc"+el.id).click(function(){
280 if(opts[el.id].sortBar!='desc'){
281 opts[el.id].sortBar='desc';
282 $('#graphHolder'+el.id).html('');
283 $('#graphHolder'+el.id).jqbargraph(opts[el.id]);
284 }
285
286 });
287
288 $("#showBasepairs"+el.id).click(function(){
289 opts[el.id].tab='basepairs';
290 $("#label"+el.id).html('Cumulative basepairs assigned to family');
291 $('#graphHolder'+el.id).html('');
292 $('#graphHolder'+el.id).jqbargraph(opts[el.id]);
293
294
295
296 });
297 $("#showReads"+el.id).click(function(){
298 opts[el.id].tab='reads';
299 $("#label"+el.id).html('Cumulative reads assigned to family');
300 $('#graphHolder'+el.id).html('');
301 $('#graphHolder'+el.id).jqbargraph(opts[el.id]);
302
303
304
305 });
306
307
308
309 //position of title
310 if(arr.title){
311 $(el).wrap("<div id='graphHolder"+el.id+"'></div>");
312 $('#graphHolder'+el.id).prepend("<div id='label"+el.id+"'>Cumulative reads assigned to family</div>").css({ 'width' : arr.width+'px', 'text-align' : 'center' });
313 $('#graphHolder'+el.id).prepend("<a href=#files"+el.id+" onclick=fillDiv('"+el.id+"')>"+arr.title+"</a>").css({ 'width' : arr.width+'px', 'text-align' : 'center' });
314
315 }
316 $("#graphHolder"+el.id).append("<div class='files"+el.id+"' id='files"+el.id+"' ></div><p/>");
317 $('.files'+el.id).css({'width' : arr.width+'px','background-color':'silver', 'border':'2px solid gray', 'display':'none'})
318
319 $("#graphHolder"+el.id).append("<div class='image"+el.id+"' id='image"+el.id+"' ></div>");
320 $('.image'+el.id).css({'width' : arr.width+'px','background-color':'silver', 'border':'2px solid gray', 'display':'none'})
321
322 };
323
324
325 //creating legend from array
326 createLegend = function(color_map,id){
327 legend = '';
328 for(var val in color_map){
329 legend += "<div id='legend"+val+"' style='overflow: hidden; zoom: 1;'>";
330 legend += "<div class='legendBar"+id+"' id='legendColor"+val+"' style='background-color:"+color_map[val]+"'></div>";
331 legend += "<div class='legendLabel"+id+"' id='graphLabel"+unique+"'>"+val+"</div>";
332 legend += "</div>";
333 }
334 };
335
336 createLinks = function(id){
337 links="<div class='linkBar"+id+"'>";
338 links+="<div ><a href='javascript:void(0);' id='sortAsc"+id+"' >sort asceding</a></div>"
339 links+="<div ><a href='javascript:void(0);' id='sortDesc"+id+"'>sort desceding</a></div>"
340 links+="<div ><a href='javascript:void(0);' id='sortBarAsc"+id+"'>sort bars asceding</a></div>"
341 links+="<div ><a href='javascript:void(0);' id='sortBarDesc"+id+"'>sort bars desceding</a></div>"
342 if(opts[id].tab=='reads'){
343 links+="<div ><a href='javascript:void(0);' id='showBasepairs"+id+"'>show baispair chart </a></div>"
344 }else{
345 links+="<div ><a href='javascript:void(0);' id='showReads"+id+"'>show read chart </a></div>"
346 }
347 links+="</div>"
348
349
350 };
351
352 fillDiv = function (elid, dir, region) {
353
354
355
356 arr=opts[elid];
357
358 dict=arr.files;
359
360 generateDownloadLink = function(family,region,filetype){
361 out="no file";
362 if(searchArray("region_"+region+"_"+filetype,dict[family][region])!=-1){
363 out="<a href="+family+"/region_"+region+"_"+filetype+">download</a>";
364 }
365 return out;
366
367 };
368 generateShowLink = function(family,region){
369 out="no image";
370
371 if(searchArray("region_"+region+"_consensus.png",dict[family][region])!=-1){
372 out="<a href=#image"+elid+" onclick=showImage('"+elid+"','"+region+"','"+ family +"/"+dict[family][region][3]+"')>show</a>";
373 }
374 return out;
375
376 };
377
378
379 data = arr.data
380 for(var val in data){
381 for(var element in data[val][0]){
382 dict[data[val][0][0][3]+"_"+data[val][1]][data[val][0][element][5]].push(data[val][0][element][0],data[val][0][element][1],data[val][0][element][4]);
383
384 }
385 }
386 var div = document.getElementById("files" + elid);
387 div.innerHTML="";
388 out = "<div><b>Files for Sample "+arr.sample+"</b></div><p/>";
389
390 out += "<div class='" + elid + "_files' id='" + elid + "_files'><table id='"+elid+"table' class='"+elid+"table' border=1 cellpadding=3 cellspacing=0 style=' border: 1pt solid #000000; border-Collapse: collapse'>";
391 out += "<tr><th>family</th><th>region</th><th>#reads</th><th>#basepairs</th><th>region length</th><th>unaligned fasta</th><th>bam alignment</th><th>consensus fasta</th><th>consensus diagram</th></tr>"
392 if (!dir) {
393 for (var directory in dict) {
394 //out += "<b>"+directory+"</b>";
395 //out += "<div class='dirlist' id='" + directory + "_files'";
396 for (var region in dict[directory]) {
397 if(dict[directory][region][5]){
398 out += "<tr><td>"+directory+"</td><td>"+region+"</td><td>"+dict[directory][region][5]+"</td><td>"+dict[directory][region][6]+"</td><td>"+dict[directory][region][7]+"</td><td>"+generateDownloadLink(directory,region,"unaligned.fa.bzip2")+"</td><td>"+generateDownloadLink(directory,region,"alignment.bam")+"</td><td>"+generateDownloadLink(directory,region,"consensus.fa")+"</td><td>"+generateShowLink(directory,region)+" "+generateDownloadLink(directory,region,"consensus.png")+"</td></tr>";
399 }
400 }
401 out += "</div>";
402 }
403 } else {
404 out += "<b>"+ dir+"</b>" ;
405
406 if (!region) {
407 for (var region in dict[dir]) {
408 if(dict[dir][region][5]){
409 out += "<tr><td>"+dir+"</td><td>"+region+"</td><td>"+dict[dir][region][5]+"</td><td>"+dict[dir][region][6]+"</td><td>"+dict[dir][region][7]+"</td><td>"+generateDownloadLink(dir,region,"unaligned.fa.bzip2")+"</td><td>"+generateDownloadLink(dir,region,"alignment.bam")+"</td><td>"+generateDownloadLink(dir,region,"consensus.fa")+"</td><td>"+generateShowLink(dir,region)+" "+generateDownloadLink(dir,region,"consensus.png")+"</td></tr>";
410 }
411 }
412 } else {
413
414 if(dict[dir][region][5]){
415 out += "<tr><td>"+dir+"</td><td>"+region+"</td><td>"+dict[dir][region][5]+"</td><td>"+dict[dir][region][6]+"</td><td>"+dict[dir][region][7]+"</td><td>"+generateDownloadLink(dir,region,"unaligned.fa.bzip2")+"</td><td>"+generateDownloadLink(dir,region,"alignment.bam")+"</td><td>"+generateDownloadLink(dir,region,"consensus.fa")+"</td><td>"+generateShowLink(dir,region)+" "+generateDownloadLink(dir,region,"consensus.png")+"</td></tr>";
416 }
417 }
418 }
419 out += "</div>";
420
421 $(div).append(out);
422 $("a").css({'color':'black'});
423 $("table").css({'border':'collapse'});
424 $(div).append("<div class='close_files"+elid+"'style='cursor:pointer;'>x</div>");
425 $(".close_files"+elid).click(function(){
426 $('.files'+elid).animate({'height':'0px'},1000,'',function(){
427 $('.files'+elid).css({'display':'none'});
428 $('.files'+elid).removeClass("selected");
429 });
430
431
432 });
433 $("div.close_files"+elid).css({'color':'white','position':'absolute','top':5,'left':5,'background-color':arr.colors[1],'border':'1px solid white','border-radius':'20px','height':'20px','width':'20px','text-align': 'center'});
434 $("a.close_files"+elid).css({'color':'white', 'text-decoration': 'none'});
435 $('.files'+elid).css({'width': 'auto','display':'none'});
436 wi=$('.files'+elid).width()+15;
437
438
439 if(!$('.files'+elid).hasClass("selected")){
440 $('.files'+elid).css({'height': 'auto','display':'none'});
441 hei=$('.files'+elid).height();
442 hei=parseInt(hei)+10;
443 hei=hei>400? hei=400 : hei;
444 $('.files'+elid).css({'width':wi+'px','position':'relative','height':'0px', 'overflow' : 'auto','background-color':'#D0D0D0', 'border':'2px solid silver','border-radius':'10px','display':'block' });
445 $('.files'+elid).animate({'height':hei+'px'}, 1000,'',function(){
446
447 $('.files'+elid).addClass("selected");
448 });
449 }
450 else{
451
452 curr_hei=$('.files'+elid).height();
453 $('.files'+elid).css({'height': 'auto','display':'none'});
454 hei=$('.files'+elid).height();
455 hei=parseInt(hei)+10;
456 hei=hei>400? hei=400 : hei;
457 $('.files'+elid).css({'height': curr_hei+'px', 'width':'915px','position':'relative', 'overflow' : 'auto','background-color':'#D0D0D0', 'border':'2px solid silver','border-radius':'10px','display':'block' }).animate({'height':hei+'px'}, 1000);
458 }
459 };
460 searchArray = function(str, strArray){
461 for (var j=0; j<strArray.length; j++) {
462 if (strArray[j].indexOf(str)!=-1) return j;
463 }
464 return -1;
465 };
466
467 showImage = function (elid,region, consensus_image,wi) {
468 var div = document.getElementById("image" + elid);
469 div.innerHTML="";
470 this.img = new Image();
471 this.img.src = consensus_image;
472 hei=this.img.height;
473 out="<img src="+consensus_image+" alt="+consensus_image+">";
474 $(div).append(out)
475
476
477
478 $(div).append("<div class='close_image"+elid+"'style='cursor:pointer;'>x</div>");
479 $(".close_image"+elid).click(function(){
480 $('.image'+elid).animate({'height':'0px'},1000,'',function(){
481 $('.image'+elid).css({'display':'none'});
482 $('.image'+elid).removeClass("selected");
483 });
484
485
486 });
487 $("div.close_image"+elid).css({'color':'white','position':'absolute','bottom':5,'left':5,'background-color':arr.colors[1],'border':'1px solid white','border-radius':'20px','height':'20px','width':'20px','text-align': 'center'});
488 $("a.close_image"+elid).css({'color':'white', 'text-decoration': 'none'});
489
490 wi=$('.files'+elid).width();
491
492
493 if(!$('.image'+elid).hasClass("selected")){
494 $('.image'+elid).css({'width':wi+'px','position':'relative','height':'0px', 'overflow' : 'auto','background-color':'#D0D0D0', 'border':'2px solid silver','border-radius':'10px','display':'block' });
495 $('.image'+elid).animate({'height':hei}, 1000,'',function(){
496
497 $('.image'+elid).addClass("selected");
498 });
499 }
500
501 };
502
503
504 this.each (
505 function()
506 { init(this); }
507 )
508
509 };
510
511 // default values
512 $.fn.jqBarGraph.defaults = {
513 sample: 'no_sample_id',
514 barSpace: 10,
515 width: 400,
516 height: 600,
517 color: '#000000',
518 colors: false,
519 lbl: '',
520 sort: false, // 'asc' or 'desc'
521 sortBar: false,
522 tab: 'reads',
523 position: 'bottom', // or 'top' doesn't work for multi type
524 prefix: '',
525 postfix: '',
526 animate: true,
527 speed: 3.0,
528 legendWidth: 150,
529 legend: false,
530 type: false, // or 'multi'
531 showValues: false,
532 borderSize: 1,
533 showValuesColor: '#fff',
534 title: false
535 };
536
537
538 //sorting functions
539 function sortNumberAsc(a,b){
540 sum_a=0
541 for(var values in a){
542 if(a[values] instanceof Array){
543 for(var val in a[values]){
544 sum_a+=a[values][val][0];
545 }
546 }
547 }
548 sum_b=0
549 for(var values in b){
550 if(b[values] instanceof Array){
551 for(var val in b[values]){
552 sum_b+=b[values][val][0];
553 }
554 }
555 }
556
557 if (sum_a<sum_b) return -1;
558 if (sum_a>sum_b) return 1;
559 return 0;
560 }
561
562 function sortNumberDesc(a,b){
563 sum_a=0
564 for(var values in a){
565 if(a[values] instanceof Array){
566 for(var val in a[values]){
567 sum_a+=a[values][val][0];
568 }
569 }
570 }
571 sum_b=0
572 for(var values in b){
573 if(b[values] instanceof Array){
574 for(var val in b[values]){
575 sum_b+=b[values][val][0];
576 }
577 }
578 }
579
580 if (sum_a<sum_b) return 1;
581 if (sum_a>sum_b) return -1;
582 return 0;
583 }
584
585 function sortBars(data,fun){
586 for(var values in data){
587 last = data[values].pop();
588 for(var val in data[values]){
589 data[values][val].sort(fun);
590 }
591 data[values].push(last);
592 }
593 }
594
595 function barAsc(a,b){
596 if(a[0]<b[0]) return -1;
597 if(a[0]>b[0]) return 1;
598 return 0;
599 }
600
601 function barDesc(a,b){
602 if(a[0]<b[0]) return 1;
603 if(a[0]>b[0]) return -1;
604 return 0;
605 }
606
607 })(jQuery);