genevalidatorapp 1.4.13 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +5 -1
  4. data/bin/genevalidatorapp +227 -73
  5. data/config.ru +1 -1
  6. data/genevalidatorapp.gemspec +7 -6
  7. data/lib/genevalidatorapp.rb +247 -0
  8. data/lib/{GeneValidatorApp → genevalidatorapp}/config.rb +7 -6
  9. data/lib/{GeneValidatorApp → genevalidatorapp}/database.rb +8 -13
  10. data/lib/genevalidatorapp/exceptions.rb +162 -0
  11. data/lib/{GeneValidatorApp → genevalidatorapp}/genevalidator.rb +52 -58
  12. data/lib/{GeneValidatorApp → genevalidatorapp}/logger.rb +0 -0
  13. data/lib/genevalidatorapp/routes.rb +81 -0
  14. data/lib/genevalidatorapp/server.rb +63 -0
  15. data/lib/{GeneValidatorApp → genevalidatorapp}/version.rb +1 -1
  16. data/public/{web_files → src}/css/bootstrap1.min.css +0 -0
  17. data/public/{web_files → src}/css/custom.css +8 -13
  18. data/public/{web_files → src}/css/custom.min.css +0 -0
  19. data/public/{web_files → src}/css/font-awesome.min.css +0 -0
  20. data/public/{web_files → src}/js/bionode-seq.min.js +0 -0
  21. data/public/{web_files → src}/js/bootstrap.min.js +0 -0
  22. data/public/{web_files → src}/js/d3.v3.min.js +0 -0
  23. data/public/{web_files → src}/js/genevalidator.js +44 -49
  24. data/public/{web_files → src}/js/jquery.cookie.min.js +0 -0
  25. data/public/{web_files → src}/js/jquery.min.js +0 -0
  26. data/public/{web_files → src}/js/jquery.tablesorter.min.js +0 -0
  27. data/public/{web_files → src}/js/jquery.validate.min.js +0 -0
  28. data/public/src/js/plots.js +814 -0
  29. data/public/web_files/css/GV_compiled_css.min.css +15 -0
  30. data/public/web_files/js/GV_compiled_js.min.js +34 -0
  31. data/spec/app_spec.rb +1 -1
  32. data/spec/database_spec.rb +2 -2
  33. data/views/index.slim +1 -1
  34. data/views/layout.slim +15 -24
  35. data/views/results.slim +54 -0
  36. metadata +39 -35
  37. data/lib/GeneValidatorApp.rb +0 -321
  38. data/public/web_files/css/bootstrap.min.css +0 -7
  39. data/public/web_files/js/genevalidator.min.js +0 -1
  40. data/public/web_files/js/plots.js +0 -744
  41. data/public/web_files/js/plots.min.js +0 -1
@@ -0,0 +1,814 @@
1
+ /*
2
+ GV - GeneValidator's JavaScript module
3
+
4
+ Define a global GV (acronym for GeneValidator) object containing all
5
+ GV associated methods:
6
+ */
7
+
8
+ //define global GV object
9
+ var GV;
10
+ if (!GV) {
11
+ GV = {};
12
+ }
13
+
14
+ //GV module
15
+ (function () {
16
+ 'use strict';
17
+ /*global window:false, $:false, d3:false*/
18
+ // SHOW ALL PLOTS button
19
+ GV.toggleAllPlots = function (btn) {
20
+ if (window.chrome && (window.location.protocol === 'file:')){
21
+ $('#browseralert').modal();
22
+ } else {
23
+ var plotBtns = $('.plot_btn');
24
+ if (plotBtns.length > 30){
25
+ $('#alert').modal();
26
+ } else {
27
+ $('#spinner1').modal({ backdrop: 'static', keyboard: 'false' });
28
+ if (btn.status !== 'pressed'){
29
+ btn.status = 'pressed';
30
+ $('#show_all_plots').html('Hide All Charts');
31
+ GV.showAllPlots();
32
+ } else {
33
+ btn.status = 'released';
34
+ $('#show_all_plots').html('Show All Charts');
35
+ GV.removeAllPlots();
36
+ }
37
+ $('#spinner1').modal('hide'); // remove activity spinner
38
+ }
39
+ }
40
+ };
41
+
42
+ //iterate over the plot_btns and add data to each childRow
43
+ GV.showAllPlots = function () {
44
+ $('.plot_btn').each (function(){
45
+ if (this.status !== 'pressed') {
46
+ GV.addData(this, 'all');
47
+ }
48
+ });
49
+ };
50
+
51
+ GV.removeAllPlots = function () {
52
+ $('.tablesorter-childRow').each (function(){
53
+ $(this).remove();
54
+ });
55
+ $('.plot_btn').each (function(){
56
+ this.status = 'released';
57
+ });
58
+ };
59
+
60
+ GV.addData = function (source, val){
61
+ if (window.chrome && (window.location.protocol === 'file:')){
62
+ $('#browseralert').modal();
63
+ } else {
64
+ var $currentRow = $(source).closest('tr'),
65
+ target = $currentRow.attr("data-target"),
66
+ $childRow = $('#mainrow' + target);
67
+
68
+ if ($childRow.length && source.status !== 'pressed') {
69
+ // if you click on another td...
70
+ GV.emptyChildRow($currentRow, target, source);
71
+ GV.addDataToChildRow($currentRow, target, val);
72
+ } else if ($childRow.length === 0){
73
+ GV.createChildRow($currentRow, target, source);
74
+ GV.addDataToChildRow($currentRow, target, val);
75
+ } else if ($childRow.length) {
76
+ GV.removeChildRow($currentRow, $childRow, source);
77
+ }
78
+
79
+ $('table').trigger('update');
80
+ }
81
+ };
82
+
83
+ GV.toggleOverviewBtn = function () {
84
+ if (window.chrome && (window.location.protocol === 'file:')){
85
+ $('#overview').remove();
86
+ } else {
87
+ var jsonFile = 'web_files/json/overview.json';
88
+ $.getJSON(jsonFile, function( json ) {
89
+ var overview = $('<span>' + json.less + '</span><br>');
90
+ var full_overview = $('<span>' + json.evaluation + '</span><br>');
91
+ if ( $('#overview_btn').hasClass('active')){
92
+ $('#overview_text').html(full_overview);
93
+ $('#overview_btn').text('Show Less');
94
+ GV.addPlot(json.data, 'overview', json.type, json.title, json.footer, json.xtitle, json.ytitle);
95
+ } else {
96
+ $('#overview').find('svg').remove();
97
+ $('#overview_text').html(overview);
98
+ $('#overview_btn').text('Show More');
99
+ }
100
+ });
101
+ }
102
+ };
103
+
104
+ GV.createChildRow = function ($currentRow, target, source) {
105
+ var childRowHTML = '<tr class="tablesorter-childRow" id="mainrow' + target +
106
+ '"><td colspan="12" id="row' + target + '"><div id="' +
107
+ target + '" class="expanded-child"></div></td></tr>';
108
+ $currentRow.addClass('tablesorter-hasChildRow');
109
+ $currentRow.after(childRowHTML);
110
+ source.status = 'pressed';
111
+ };
112
+
113
+ GV.removeChildRow = function ($currentRow, $childRow, source) {
114
+ $currentRow.removeClass('tablesorter-hasChildRow');
115
+ $childRow.remove();
116
+ source.status = 'released';
117
+ };
118
+
119
+ GV.emptyChildRow = function ($currentRow, target, source) {
120
+ var targetId = '#' + target;
121
+ var explanationId = '#' + target + 'explanation';
122
+ $(targetId).empty();
123
+ $(explanationId).remove();
124
+ GV.resetStatusOfOtherButtons($currentRow);
125
+ source.status = 'pressed';
126
+ };
127
+
128
+ GV.resetStatusOfOtherButtons = function ($currentRow) {
129
+ $currentRow.find('td').each (function(){
130
+ if (this.status == 'pressed') { this.status = 'released'; }
131
+ });
132
+ $currentRow.find('.plot_btn').each (function(){
133
+ if (this.status == 'pressed') { this.status = 'released'; }
134
+ });
135
+ };
136
+
137
+ GV.addDataToChildRow = function ($currentRow, target, val) {
138
+ var file = $currentRow.attr("data-jsonFile");
139
+
140
+ $.getJSON(file, function( json ) {
141
+ if (val === 'all'){
142
+ for (var i in json.validations){
143
+ if (json.validations[i].graphs !== undefined) {
144
+ GV.generatePlotCommands(json.validations[i].graphs, target);
145
+ }
146
+ }
147
+ } else {
148
+ GV.addExplanation(target, json.validations[val]);
149
+ if (json.validations[val].graphs !== undefined) {
150
+ GV.generatePlotCommands(json.validations[val].graphs, target);
151
+ }
152
+ }
153
+ });
154
+ };
155
+
156
+ GV.generatePlotCommands = function (graphs, target) {
157
+ for (var g = 0; g < graphs.length; g++) {
158
+ var graphData = graphs[g];
159
+ GV.addPlot(graphData.data, target, graphData.type, graphData.title,
160
+ graphData.footer, graphData.xtitle, graphData.ytitle,
161
+ graphData.aux1, graphData.aux2);
162
+ }
163
+ };
164
+
165
+ GV.addExplanation = function (target, jsonData) {
166
+ var row = '#row' + target;
167
+ var approach_html = '<p><b>Approach:</b> ' + jsonData.approach + '</p>';
168
+ var explanation_html = '<p><b>Explanation:</b> ' + jsonData.explanation + '</p>';
169
+ var conclusion_html = '<p><b>Conclusion:</b> ' + jsonData.conclusion + '</p>';
170
+
171
+ var explain = $('<div id="' + target + 'explanation" class="alert alert-info explanation_alert" role="alert">' +
172
+ approach_html + explanation_html + conclusion_html + '</div>');
173
+ $(row).prepend(explain);
174
+ };
175
+
176
+
177
+ // Functions that produce the plots in D3
178
+ GV.addPlot = function (jsonData, target, type, title, footer, xtitle, ytitle, aux1, aux2) {
179
+ var legend;
180
+ if (footer === '') {
181
+ legend = [];
182
+ } else {
183
+ legend = footer.split(';');
184
+ }
185
+
186
+ switch(type) {
187
+ case 'scatter':
188
+ GV.plot_scatter(jsonData, target, title, footer, xtitle, ytitle, aux1, aux2);
189
+ break;
190
+ case 'bars':
191
+ GV.plot_bars(jsonData, target, title, legend, xtitle, ytitle, aux1);
192
+ break;
193
+ case 'simplebars':
194
+ GV.plot_simple_bars(jsonData, target, title, legend, xtitle, ytitle);
195
+ break;
196
+ case 'lines':
197
+ if (aux2 !== null) {
198
+ aux2 = aux2.split(',');
199
+ }
200
+ GV.plot_lines(jsonData, target, title, legend, xtitle, ytitle, aux1, aux2);
201
+ break;
202
+ case 'align':
203
+ if (aux2 !== null) {
204
+ aux2 = aux2.split(',');
205
+ }
206
+ GV.plot_align(jsonData, target, title, legend, xtitle, ytitle, aux1, aux2);
207
+ break;
208
+ default:
209
+ break;
210
+ }
211
+ };
212
+
213
+ GV.color_beautification = function (color) {
214
+ switch(color){
215
+ case 'red':
216
+ return d3.rgb(189,54,47);
217
+ case 'blue':
218
+ return d3.rgb(58,135,173);
219
+ case 'green':
220
+ return d3.rgb(70,136,71);
221
+ case 'yellow':
222
+ return d3.rgb(255,255,51);
223
+ case 'orange':
224
+ return d3.rgb(248,148,6);
225
+ case 'violet':
226
+ return d3.rgb(153,0,153);
227
+ case 'gray':
228
+ return d3.rgb(160,160,160);
229
+ default:
230
+ return color;
231
+ }
232
+ };
233
+
234
+ // bars plot
235
+ GV.plot_bars = function (alldata, target, title, footer, xTitle, yTitle, bar) {
236
+ var margin = {top: 70, right: 50, bottom: 75, left: 50},
237
+ width = 600 - margin.left - margin.right,
238
+ height = 500 - margin.top - margin.bottom;
239
+
240
+ var svg = d3.select("#".concat(target)).append("svg")
241
+ .attr("width", width + margin.left + margin.right)
242
+ .attr("height", height + margin.top + margin.bottom)
243
+ .append("g")
244
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
245
+
246
+ svg.append("text")
247
+ .attr("x", (width / 2))
248
+ .attr("y", -45)
249
+ .attr("text-anchor", "middle")
250
+ .style("font-size", "16px")
251
+ .text(title);
252
+
253
+ var padding = 100;
254
+
255
+ var flattened_data = [].concat.apply([], alldata);
256
+ var yMax = d3.max(flattened_data, function(d) { return d.value; }) + 3;
257
+ var y = d3.scale.linear()
258
+ .domain([0, yMax + yMax/10])
259
+ .range([height, 0]);
260
+
261
+ var xMin = d3.min(flattened_data, function(d) { return d.key; });
262
+ if (bar !== undefined){
263
+ xMin = Math.min(xMin, bar);
264
+ }
265
+
266
+ var xMax = d3.max(flattened_data, function(d) { return d.key; });
267
+ if (bar !== undefined){
268
+ xMax = Math.max(xMax, bar);
269
+ }
270
+
271
+ var x = d3.scale.linear()
272
+ .domain([xMin-padding, xMax+padding])
273
+ .range([13, width]);
274
+
275
+ var xAxis = d3.svg.axis()
276
+ .scale(x)
277
+ .orient("bottom")
278
+ .ticks(8);
279
+
280
+ var yAxis = d3.svg.axis()
281
+ .scale(y)
282
+ .orient("left")
283
+ .tickFormat(d3.format("d"))
284
+ .ticks(8);
285
+
286
+ svg.append("g")
287
+ .attr("class", "x axis")
288
+ .attr("transform", "translate(0," + height + ")")
289
+ .call(xAxis)
290
+ .append("text")
291
+ .attr("class", "label")
292
+ .attr("x", (width-xTitle.length)/2-50)
293
+ .attr("y", 35)
294
+ .style("text-anchor", "start")
295
+ .text(xTitle);
296
+
297
+ svg.append("g")
298
+ .attr("class", "y axis")
299
+ .call(yAxis)
300
+ .append("text")
301
+ .attr("class", "label")
302
+ .attr("transform", "rotate(-90)")
303
+ .attr("x", -(height+yTitle.length)/2-50)
304
+ .attr("y", -40)
305
+ .style("text-anchor", "start")
306
+ .text(yTitle);
307
+
308
+ alldata.map( function(data) {
309
+ svg.selectAll(".bar")
310
+ .data(data)
311
+ .enter().append("rect")
312
+ .attr("x", function(d) { return x(d.key); })
313
+ .attr("width", 6)
314
+ .attr("y", function(d) { return y(d.value); })
315
+ .attr("height", function(d) { return height - y(d.value); })
316
+ .attr("fill", function(d) { if (d.main === true) return GV.color_beautification("red"); return GV.color_beautification("blue");});
317
+ });
318
+
319
+ if (bar !== undefined){
320
+ svg.append("rect")
321
+ .attr("x", x(bar))
322
+ .attr("width", 4)
323
+ .attr("y", y(yMax + yMax/10))
324
+ .style("opacity",0.6)
325
+ .attr("height", height - y(yMax + yMax/8))
326
+ .attr("fill", GV.color_beautification("black"));
327
+
328
+ svg.append("text")
329
+ .attr("transform", "rotate(-90)")
330
+ .attr("x", -yMax/10 - 35)
331
+ .attr("y", x(bar) - 5)
332
+ .text("query");
333
+ }
334
+
335
+ var offset = 0;
336
+ var total_len = 0;
337
+ for (var i = 0; i < footer.length; i++) {
338
+ var array = footer[i].split(",");
339
+ total_len = total_len + array[0].length*8 + 15;
340
+ }
341
+
342
+ for (var j = 0; j < footer.length; j++) {
343
+
344
+ var footer_array = footer[j].split(",");
345
+ svg.append("rect")
346
+ .attr("x", (width-total_len)/2 + offset)
347
+ .attr("y", -30)
348
+ .attr("width", 10)
349
+ .attr("height", 10)
350
+ .style("fill", GV.color_beautification(footer_array[1].replace(/\s+/g, '')));
351
+
352
+ svg.append("text")
353
+ .attr("x", (width-total_len)/2 + offset + 15)
354
+ .attr("y", -20)
355
+ .text(footer_array[0]);
356
+ offset = offset + footer_array[0].length*8 + 15;
357
+ }
358
+ };
359
+
360
+ // bars plot
361
+ GV.plot_simple_bars = function (alldata, target, title, footer, xTitle, yTitle) {
362
+ var margin = {top: 70, right: 50, bottom: 75, left: 50},
363
+ width = 600 - margin.left - margin.right,
364
+ height = 500 - margin.top - margin.bottom;
365
+
366
+ var svg = d3.select("#".concat(target)).append("svg")
367
+ .attr("width", width + margin.left + margin.right)
368
+ .attr("height", height + margin.top + margin.bottom)
369
+ .append("g")
370
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
371
+
372
+ svg.append("text")
373
+ .attr("x", (width / 2))
374
+ .attr("y", -45)
375
+ .attr("text-anchor", "middle")
376
+ .style("font-size", "16px")
377
+ .text(title);
378
+
379
+ var padding = 0;
380
+
381
+ var flattened_data = [].concat.apply([], alldata);
382
+ var yMax = d3.max(flattened_data, function(d) { return d.value; }) + 3;
383
+ var y = d3.scale.linear()
384
+ .domain([0, yMax])
385
+ .range([height, 0]);
386
+
387
+ var xMin = d3.min(flattened_data, function(d) { return d.key; });
388
+ var xMax = d3.max(flattened_data, function(d) { return d.key; });
389
+
390
+ var x = d3.scale.linear()
391
+ .domain([xMin-padding, xMax+padding])
392
+ .range([13, width]);
393
+
394
+ var xAxis = d3.svg.axis()
395
+ .scale(x)
396
+ .orient("bottom")
397
+ .ticks(8);
398
+
399
+ var yAxis = d3.svg.axis()
400
+ .scale(y)
401
+ .orient("left")
402
+ .tickFormat(d3.format("d"))
403
+ .ticks(8);
404
+
405
+ svg.append("g")
406
+ .attr("class", "x axis")
407
+ .attr("transform", "translate(0," + height + ")")
408
+ .call(xAxis)
409
+ .append("text")
410
+ .attr("class", "label")
411
+ .attr("x", (width-xTitle.length)/2-50)
412
+ .attr("y", 35)
413
+ .style("text-anchor", "start")
414
+ .text(xTitle);
415
+
416
+ svg.append("g")
417
+ .attr("class", "y axis")
418
+ .call(yAxis)
419
+ .append("text")
420
+ .attr("class", "label")
421
+ .attr("transform", "rotate(-90)")
422
+ .attr("x", -(height+yTitle.length)/2-50)
423
+ .attr("y", -40)
424
+ .style("text-anchor", "start")
425
+ .text(yTitle);
426
+
427
+ alldata.map( function(data) {
428
+ svg.selectAll(".bar")
429
+ .data(data)
430
+ .enter().append("rect")
431
+ .attr("x", function(d) { return x(d.key); })
432
+ .attr("width", 6)
433
+ .attr("y", function(d) { return y(d.value); })
434
+ .attr("height", function(d) { return height - y(d.value); })
435
+ .attr("fill", function(d) { if (d.main === true) return GV.color_beautification("red"); return GV.color_beautification("blue");});
436
+ });
437
+ };
438
+
439
+
440
+ // scatter plot
441
+ // ecuation of the line: slope * x + yLine
442
+ GV.plot_scatter = function (data, target, title, footer, xTitle, yTitle, yLine, slope) {
443
+ var margin = {top: 50, right: 30, bottom: 75, left: 50},
444
+ width = 500 - margin.left - margin.right,
445
+ height = 500 - margin.top - margin.bottom;
446
+
447
+ var x = d3.scale.linear()
448
+ .range([0, width]);
449
+ var y = d3.scale.linear()
450
+ .range([height, 0]);
451
+
452
+ var color = d3.scale.category10();
453
+
454
+ var xAxis = d3.svg.axis()
455
+ .scale(x)
456
+ .orient("bottom")
457
+ .ticks(8);
458
+ var yAxis = d3.svg.axis()
459
+ .scale(y)
460
+ .orient("left")
461
+ .tickFormat(d3.format("d"))
462
+ .ticks(8);
463
+
464
+ var svg = d3.select("#".concat(target)).append("svg")
465
+ .attr("width", width + margin.left + margin.right)
466
+ .attr("height", height + margin.top + margin.bottom)
467
+ .append("g")
468
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
469
+
470
+ svg.append("text")
471
+ .attr("x", (width / 2))
472
+ .attr("y", -25)
473
+ .attr("text-anchor", "middle")
474
+ .style("font-size", "16px")
475
+ .text(title);
476
+
477
+ svg.append("text")
478
+ .attr("x", (width / 2))
479
+ .attr("y", height+ 55)
480
+ .attr("text-anchor", "middle")
481
+ .style("font-size", "12px")
482
+ .text(footer);
483
+
484
+ var xMax = d3.max(data, function(d) { return d.x; });
485
+ var xMin = d3.min(data, function(d) { return d.x; });
486
+ var yMax = d3.max(data, function(d) { return d.y; });
487
+ var yMin = d3.min(data, function(d) { return d.y; });
488
+ x.domain(d3.extent(data, function(d) { return d.x; })).nice();
489
+ y.domain(d3.extent(data, function(d) { return d.y; })).nice();
490
+
491
+ svg.append("g")
492
+ .attr("class", "x axis")
493
+ .attr("transform", "translate(0," + height + ")")
494
+ .call(xAxis)
495
+ .append("text")
496
+ .attr("class", "label")
497
+ .attr("x", (width-xTitle.length)/2-50)
498
+ .attr("y", 35)
499
+ .style("text-anchor", "start")
500
+ .text(xTitle);
501
+
502
+ svg.append("g")
503
+ .attr("class", "y axis")
504
+ .call(yAxis)
505
+ .append("text")
506
+ .attr("class", "label")
507
+ .attr("transform", "rotate(-90)")
508
+ .attr("x", -(height+yTitle.length)/2-50)
509
+ .attr("y", -40)
510
+ .style("text-anchor", "start")
511
+ .text(yTitle);
512
+
513
+ svg.selectAll(".dot")
514
+ .data(data)
515
+ .enter().append("circle")
516
+ .attr("r", 2)
517
+ .attr("cx", function(d) { return x(d.x); })
518
+ .attr("cy", function(d) { return y(d.y); })
519
+ .style("fill", function() { return GV.color_beautification("red"); })
520
+ .style("opacity",0.6);
521
+
522
+ if ((slope !== undefined && slope !== "") && (yLine !== undefined && yLine !== "")){
523
+ yLine = parseFloat(yLine.replace(",", "."));
524
+ var xMaxValue = xMax;
525
+ var yMaxValue = yLine + slope * xMax;
526
+ if (yMaxValue > yMax){
527
+ xMaxValue = (yMax-yLine)/slope;
528
+ yMaxValue = yMax;
529
+ }
530
+
531
+ if (yMaxValue < yMin){
532
+ xMaxValue = (yMin-yLine)/slope;
533
+ yMaxValue = yMin;
534
+ }
535
+
536
+ var xMinValue = xMin;
537
+ var yMinValue = yLine + slope * xMin;
538
+ if (yMinValue > yMax){
539
+ xMinValue = (yMax-yLine)/slope;
540
+ yMinValue = yMin;
541
+ }
542
+
543
+ if (yMinValue < yMin){
544
+ xMinValue = (yMin-yLine)/slope;
545
+ yMinValue = yMin;
546
+ }
547
+
548
+ svg.append("line")
549
+ .attr("x1", x(xMinValue))
550
+ .attr("y1", y(yMinValue))
551
+ .attr("x2", x(xMaxValue))
552
+ .attr("y2", y(yMaxValue))
553
+ .attr("stroke-width", 2)
554
+ .attr("stroke", "black");
555
+ }
556
+ };
557
+
558
+ // line plot
559
+ // maximum 80 lines
560
+ GV.plot_lines = function (data, target, title, footer, xTitle, yTitle, no_lines, yValues) {
561
+ var margin = {top: 70, right: 50, bottom: 75, left: 50},
562
+ width = 600 - margin.left - margin.right,
563
+ height = 500 - margin.top - margin.bottom;
564
+
565
+ var x = d3.scale.linear()
566
+ .range([0, width]);
567
+ var y = d3.scale.linear()
568
+ .range([height, 0]);
569
+
570
+ var color = d3.scale.category10();
571
+ var xAxis = '';
572
+ if (title === 'Open Reading Frames in all 6 Frames') {
573
+ xAxis = d3.svg.axis()
574
+ .scale(x)
575
+ .orient("bottom")
576
+ .ticks(0);
577
+ } else {
578
+ xAxis = d3.svg.axis()
579
+ .scale(x)
580
+ .orient("bottom")
581
+ .ticks(5);
582
+ }
583
+
584
+ var yAxis = d3.svg.axis()
585
+ .scale(y)
586
+ .orient("left")
587
+ .ticks(5);
588
+
589
+ var svg = d3.select("#".concat(target)).append("svg")
590
+ .attr("width", width + margin.left + margin.right)
591
+ .attr("height", height + margin.top + margin.bottom)
592
+ .append("g")
593
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
594
+
595
+ svg.append("text")
596
+ .attr("x", (width / 2))
597
+ .attr("y", -35)
598
+ .attr("text-anchor", "middle")
599
+ .style("font-size", "16px")
600
+ .text(title);
601
+
602
+ var idx = -1;
603
+
604
+ x.domain([0, d3.max(data, function(d) { return d.stop; })]);
605
+ y.domain(d3.extent(data, function(d) { return d.y; })).nice();
606
+
607
+ svg.append("g")
608
+ .attr("class", "x axis")
609
+ .attr("transform", "translate(0," + (height + height/no_lines) + ")")
610
+ .call(xAxis)
611
+ .append("text")
612
+ .attr("class", "label")
613
+ .attr("x", (width-xTitle.length)/2-50)
614
+ .attr("y", 35)
615
+ .style("text-anchor", "start")
616
+ .text(xTitle);
617
+
618
+ if (yValues !== null){
619
+ svg.append("g")
620
+ .attr("class", "y axis")
621
+ .call(yAxis.ticks(yValues.length)
622
+ .tickFormat(function() {
623
+ idx = idx + 1;
624
+ return yValues[idx];
625
+ }))
626
+ .append("text")
627
+ .attr("class", "label")
628
+ .attr("transform", "rotate(-90)")
629
+ .attr("x", -(height+yTitle.length)/2-50)
630
+ .attr("y", -40)
631
+ .style("text-anchor", "start")
632
+ .text(yTitle);
633
+ } else {
634
+ svg.append("g")
635
+ .attr("class", "y axis")
636
+ .call(yAxis)
637
+ .append("text")
638
+ .attr("class", "label")
639
+ .attr("transform", "rotate(-90)")
640
+ .attr("x", -(height+yTitle.length)/2)
641
+ .attr("y", -40)
642
+ .style("text-anchor", "start")
643
+ .text(yTitle);
644
+ }
645
+
646
+ svg.selectAll(".dot")
647
+ .data(data)
648
+ .enter().append("line")
649
+ .attr("x1", function(d) { return x(d.start); })
650
+ .attr("y1", function(d) { return y(d.y); })
651
+ .attr("x2", function(d) { return x(d.stop); })
652
+ .attr("x2", function(d) { return x(d.stop); })
653
+ .attr("y2", function(d) { return y(d.y); })
654
+ .attr("stroke-width", function(d) {
655
+ if (d.dotted === undefined) {
656
+ if (d.color == "red" ) {
657
+ return height/no_lines/2.5;
658
+ } else {
659
+ return height/no_lines;
660
+ }
661
+ } else {
662
+ return height/no_lines/5;
663
+ }
664
+ })
665
+ .style("stroke-dasharray", function(d) { if (d.dotted === undefined) return ("0, 0"); return ("2, 6");})
666
+ .attr("stroke", function(d) { return GV.color_beautification(d.color); });
667
+
668
+ // add legend
669
+ var legend = svg.append("g")
670
+ .attr("class", "legend")
671
+ .attr("height", 100)
672
+ .attr("width", 100)
673
+ .attr('transform', 'translate(-20,50)');
674
+
675
+ var offset = 40;
676
+ var total_len = 0;
677
+ for (var i = 0; i < footer.length; i++) {
678
+ var array = footer[i].split(",");
679
+ total_len = total_len + array[0].length*8 + 15;
680
+ }
681
+
682
+ for (var j = 0; j < footer.length; j++) {
683
+ var footer_array = footer[j].split(",");
684
+ svg.append("rect")
685
+ .attr("x", (width-total_len)/2 + offset)
686
+ .attr("y", -30)
687
+ .attr("width", 10)
688
+ .attr("height", 10)
689
+ .style("fill", GV.color_beautification(footer_array[1].replace(/\s+/g, '')));
690
+
691
+ svg.append("text")
692
+ .attr("x", (width-total_len)/2 + offset + 15)
693
+ .attr("y", -20)
694
+ .text(footer_array[0]);
695
+ offset = offset + footer_array[0].length*8 + 15;
696
+ }
697
+ };
698
+
699
+ // line plot
700
+ // maximum 80 lines
701
+ GV.plot_align = function (data, target, title, footer, xTitle, yTitle, no_lines, yValues) {
702
+ var margin = {top: 75, right: 50, bottom: 75, left: 150},
703
+ width = 600 - margin.left - margin.right,
704
+ height = 300 - margin.top - margin.bottom;
705
+
706
+ var x = d3.scale.linear()
707
+ .range([0, width]);
708
+ var y = d3.scale.linear()
709
+ .range([height, 0]);
710
+
711
+ var color = d3.scale.category10();
712
+
713
+ var xAxis = d3.svg.axis()
714
+ .scale(x)
715
+ .orient("bottom")
716
+ .ticks(5);
717
+
718
+ var yAxis = d3.svg.axis()
719
+ .scale(y)
720
+ .orient("left")
721
+ .ticks(5);
722
+
723
+ var svg = d3.select("#".concat(target)).append("svg")
724
+ .style("vertical-align", "top")
725
+ .attr("width", width + margin.left + margin.right)
726
+ .attr("height", height + margin.top + margin.bottom)
727
+ .append("g")
728
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
729
+
730
+ svg.append("text")
731
+ .attr("x", (width / 2))
732
+ .attr("y", -35)
733
+ .attr("text-anchor", "middle")
734
+ .style("font-size", "16px")
735
+ .text(title);
736
+
737
+ var idx = -1;
738
+
739
+ x.domain([0, d3.max(data, function(d) { return d.stop; })]);
740
+ y.domain(d3.extent(data, function(d) { return d.y; })).nice();
741
+
742
+ svg.append("g")
743
+ .attr("class", "x axis")
744
+ .attr("transform", "translate(0," + (height+height/no_lines) + ")")
745
+ .call(xAxis)
746
+ .append("text")
747
+ .attr("class", "label")
748
+ .attr("x", (width-xTitle.length)/2-50)
749
+ .attr("y", 35)
750
+ .style("text-anchor", "start")
751
+ .text(xTitle);
752
+
753
+ if (yValues !== null){
754
+ svg.append("g")
755
+ .attr("class", "y axis")
756
+ .call(yAxis.ticks(yValues.length)
757
+ .tickFormat(function() {
758
+ idx = idx + 1;
759
+ return yValues[idx];
760
+ }))
761
+ .append("text")
762
+ .attr("class", "label")
763
+ .attr("transform", "rotate(-90)")
764
+ .attr("x", -(height+yTitle.length)/2-50)
765
+ .attr("y", -40)
766
+ .style("text-anchor", "start")
767
+ .text(yTitle);
768
+ } else {
769
+ svg.append("g")
770
+ .attr("class", "y axis")
771
+ .call(yAxis)
772
+ .append("text")
773
+ .attr("class", "label")
774
+ .attr("transform", "rotate(-90)")
775
+ .attr("x", -(height+yTitle.length)/2-50)
776
+ .attr("y", -40)
777
+ .style("text-anchor", "start")
778
+ .text(yTitle);
779
+ }
780
+
781
+ svg.selectAll(".dot")
782
+ .data(data)
783
+ .enter().append("line")
784
+ .attr("x1", function(d) { return x(d.start); })
785
+ .attr("y1", function(d) { return y(d.y); })
786
+ .attr("x2", function(d) { return x(d.stop); })
787
+ .attr("y2", function(d) { return y(d.y); })
788
+ .attr("stroke-width", function(d) { if (d.height == -1) return height/no_lines; return (height/no_lines * d.height) ; })
789
+ .attr("stroke", function(d) { return GV.color_beautification(d.color); });
790
+
791
+ var offset = 0;
792
+ var total_len = 0;
793
+ for (var i = 0; i < footer.length; i++) {
794
+ var array = footer[i].split(",");
795
+ total_len = total_len + array[0].length*8 + 15;
796
+ }
797
+
798
+ for (var j = 0; j < footer.length; j++) {
799
+ var footer_array = footer[j].split(",");
800
+ svg.append("rect")
801
+ .attr("x", (width-total_len)/2 + offset)
802
+ .attr("y", -30)
803
+ .attr("width", 10)
804
+ .attr("height", 10)
805
+ .style("fill", GV.color_beautification(footer_array[1].replace(/\s+/g, '')));
806
+
807
+ svg.append("text")
808
+ .attr("x", (width-total_len)/2 + offset + 15)
809
+ .attr("y", -20)
810
+ .text(footer_array[0]);
811
+ offset = offset + footer_array[0].length*8 + 15;
812
+ }
813
+ };
814
+ }());