2 * correlation coefficients plotting using d3
3 * Isaak Y Tecle <iyt2@cornell.edu>
8 jQuery(document).ready( function() {
9 var page = document.URL;
11 if (page.match(/solgs\/traits\/all\//) != null ||
12 page.match(/solgs\/models\/combined\/trials\//) != null) {
14 setTimeout(function() {listGenCorPopulations()}, 5000);
18 var url = window.location.pathname;
20 if (url.match(/[solgs\/population|breeders_toolbox\/trial]/)) {
21 checkPhenoCorreResult();
28 function checkPhenoCorreResult () {
30 var popDetails = getPopulationDetails();
31 var popId = popDetails.population_id;
36 url: '/phenotype/correlation/check/result/' + popId,
37 success: function(response) {
38 if (response.result === 'yes') {
39 phenotypicCorrelation();
41 jQuery("#run_pheno_correlation").show();
49 jQuery(document).ready( function() {
51 jQuery("#run_pheno_correlation").click(function() {
52 phenotypicCorrelation();
60 jQuery("#run_genetic_correlation").live("click", function() {
61 var popId = jQuery("#corre_selected_population_id").val();
62 var popType = jQuery("#corre_selected_population_type").val();
64 jQuery("#correlation_canvas").empty();
66 jQuery("#correlation_message")
67 .css({"padding-left": '0px'})
68 .html("Running genetic correlation analysis...");
70 formatGenCorInputData(popId, popType);
75 function listGenCorPopulations () {
76 var modelData = getTrainingPopulationData();
78 var trainingPopIdName = JSON.stringify(modelData);
80 var popsList = '<dl id="corre_selected_population" class="corre_dropdown">'
81 + '<dt> <a href="#"><span>Choose a population</span></a></dt>'
85 + '<a href="#">' + modelData.name + '<span class=value>' + trainingPopIdName + '</span></a>'
88 popsList += '</ul></dd></dl>';
90 jQuery("#corre_select_a_population_div").empty().append(popsList).show();
93 if (modelData.id.match(/uploaded/) == null) {
94 dbSelPopsList = addSelectionPopulations();
98 jQuery("#corre_select_a_population_div ul").append(dbSelPopsList);
101 var userUploadedSelExists = jQuery("#uploaded_selection_pops_table").doesExist();
102 if (userUploadedSelExists == true) {
104 var userSelPops = listUploadedSelPopulations();
107 jQuery("#corre_select_a_population_div ul").append(userSelPops);
111 jQuery(".corre_dropdown dt a").click(function() {
112 jQuery(".corre_dropdown dd ul").toggle();
115 jQuery(".corre_dropdown dd ul li a").click(function() {
117 var text = jQuery(this).html();
119 jQuery(".corre_dropdown dt a span").html(text);
120 jQuery(".corre_dropdown dd ul").hide();
122 var idPopName = jQuery("#corre_selected_population").find("dt a span.value").html();
123 idPopName = JSON.parse(idPopName);
124 modelId = jQuery("#model_id").val();
126 selectedPopId = idPopName.id;
127 selectedPopName = idPopName.name;
128 selectedPopType = idPopName.pop_type;
130 jQuery("#corre_selected_population_name").val(selectedPopName);
131 jQuery("#corre_selected_population_id").val(selectedPopId);
132 jQuery("#corre_selected_population_type").val(selectedPopType);
136 jQuery(".corre_dropdown").bind('click', function(e) {
137 var clicked = jQuery(e.target);
139 if (! clicked.parents().hasClass("corre_dropdown"))
140 jQuery(".corre_dropdown dd ul").hide();
148 function formatGenCorInputData (popId, type, indexFile) {
149 var modelDetail = getPopulationDetails();
154 data: {'model_id': modelDetail.population_id, 'corr_population_id': popId, 'type' : type, 'index_file': indexFile},
155 url: '/correlation/genetic/data/',
156 success: function(response) {
158 if(response.status == 'success') {
159 gebvsFile = response.gebvs_file;
163 divPlace = '#si_correlation_canvas';
167 'model_id': modelDetail.population_id,
168 'corr_population_id': popId,
170 'gebvs_file': gebvsFile,
171 'div_place' : divPlace,
174 runGenCorrelationAnalysis(args);
177 jQuery("#correlation_message")
178 .css({"padding-left": '0px'})
179 .html("This population has no valid traits to correlate.");
182 error: function(response) {
183 jQuery("#correlation_message")
184 .css({"padding-left": '0px'})
185 .html("Error occured preparing the additive genetic data for correlation analysis.");
193 function getPopulationDetails () {
195 var populationId = jQuery("#population_id").val();
196 var populationName = jQuery("#population_name").val();
198 if (populationId == 'undefined') {
199 populationId = jQuery("#model_id").val();
200 populationName = jQuery("#model_name").val();
203 return {'population_id' : populationId,
204 'population_name' : populationName
209 function phenotypicCorrelation () {
211 var population = getPopulationDetails();
213 jQuery("#correlation_message").html("Running correlation... please wait...");
218 data: {'population_id': population.population_id },
219 url: '/correlation/phenotype/data/',
220 success: function(response) {
221 if (response.status == 'success') {
222 runPhenoCorrelationAnalysis();
224 jQuery("#correlation_message")
225 .css({"padding-left": '0px'})
226 .html("This population has no phenotype data.");
229 error: function(response) {
230 jQuery("#correlation_message")
231 .css({"padding-left": '0px'})
232 .html("Error occured preparing the phenotype data for correlation analysis.");
238 function runPhenoCorrelationAnalysis () {
239 var population = getPopulationDetails();
240 var popId = population.population_id;
245 data: {'population_id': popId },
246 url: '/phenotypic/correlation/analysis/output',
247 success: function(response) {
248 if (response.status == 'success') {
249 plotCorrelation(response.data);
251 var corrDownload = "<a href=\"/download/phenotypic/correlation/population/"
252 + popId + "\">Download correlation coefficients</a>";
254 jQuery("#correlation_canvas").append("<br />[ " + corrDownload + " ]").show();
255 jQuery("#correlation_message").empty();
256 jQuery("#run_pheno_correlation").hide();
258 jQuery("#correlation_message")
259 .css({"padding-left": '0px'})
260 .html("There is no correlation output for this dataset.");
263 error: function(response) {
264 jQuery("#correlation_message")
265 .css({"padding-left": '0px'})
266 .html("Error occured running the correlation analysis.");
272 function runGenCorrelationAnalysis (args) {
278 url: '/genetic/correlation/analysis/output',
279 success: function(response) {
280 if (response.status == 'success') {
282 divPlace = args.div_place;
284 if (divPlace === '#si_correlation_canvas') {
285 jQuery("#si_correlation_section").show();
288 plotCorrelation(response.data, divPlace);
289 jQuery("#correlation_message").empty();
290 jQuery("#si_correlation_message").empty();
292 if (divPlace === '#si_correlation_canvas') {
294 var popName = jQuery("#selected_population_name").val();
295 var corLegDiv = "<div id=\"si_correlation_"
296 + popName.replace(/\s/g, "")
299 var legendValues = legendParams();
300 var corLegDivVal = jQuery(corLegDiv).html(legendValues.legend);
302 jQuery("#si_correlation_canvas").append(corLegDivVal).show();
306 var popName = jQuery("#corre_selected_population_name").val();
307 var corLegDiv = "<div id=\"corre_correlation_"
308 + popName.replace(/\s/g, "")
311 var corLegDivVal = jQuery(corLegDiv).html(popName);
312 jQuery("#correlation_canvas").append(corLegDivVal).show();
316 jQuery("#correlation_message")
317 .css({"padding-left": '0px'})
318 .html("There is no genetic correlation output for this dataset.");
323 error: function(response) {
324 jQuery("#correlation_message")
325 .css({"padding-left": '0px'})
326 .html("Error occured running the genetic correlation analysis.");
334 function plotCorrelation (data, divPlace) {
336 data = data.replace(/\s/g, '');
337 data = data.replace(/\\/g, '');
338 data = data.replace(/^\"/, '');
339 data = data.replace(/\"$/, '');
340 data = data.replace(/\"NA\"/g, 100);
342 data = JSON.parse(data);
347 var nTraits = data.traits.length;
350 height = height * 0.5;
354 var pad = {left:70, top:20, right:100, bottom: 70};
355 var totalH = height + pad.top + pad.bottom;
356 var totalW = width + pad.left + pad.right;
358 var corXscale = d3.scale.ordinal().domain(d3.range(nTraits)).rangeBands([0, width]);
359 var corYscale = d3.scale.ordinal().domain(d3.range(nTraits)).rangeBands([height, 0]);
360 var corZscale = d3.scale.linear().domain([-1, 0, 1]).range(["#6A0888","white", "#86B404"]);
362 var xAxisScale = d3.scale.ordinal()
364 .rangeBands([0, width]);
366 var yAxisScale = d3.scale.ordinal()
368 .rangeRoundBands([height, 0]);
370 if ( divPlace == null) {
371 divPlace = '#correlation_canvas';
374 var svg = d3.select(divPlace)
376 .attr("height", totalH)
377 .attr("width", totalW);
379 var xAxis = d3.svg.axis()
383 var yAxis = d3.svg.axis()
387 var corrplot = svg.append("g")
388 .attr("id", "correlation_plot")
389 .attr("transform", "translate(" + pad.left + "," + pad.top + ")");
392 .attr("class", "x axis")
393 .attr("transform", "translate(0," + height +")")
399 .attr("transform", "rotate(90)")
400 .attr("fill", "#523CB5")
401 .style({"text-anchor":"start", "fill": "#523CB5"});
404 .attr("class", "y axis")
405 .attr("transform", "translate(0,0)")
411 .attr("fill", "#523CB5")
412 .style("fill", "#523CB5");
416 for (var i=0; i<data.coefficients.length; i++) {
417 for (var j=0; j<data.coefficients[i].length; j++) {
418 corr.push({"row":i, "col":j, "value": data.coefficients[i][j]});
420 if (data.coefficients[i][j] != 100) {
421 coefs.push(data.coefficients[i][j]);
426 var cell = corrplot.selectAll("rect")
428 .enter().append("rect")
429 .attr("class", "cell")
430 .attr("x", function (d) { return corXscale(d.col)})
431 .attr("y", function (d) { return corYscale(d.row)})
432 .attr("width", corXscale.rangeBand())
433 .attr("height", corYscale.rangeBand())
434 .attr("fill", function (d) {
435 if (d.value === 100) {return "white";}
436 else {return corZscale(d.value)}
438 .attr("stroke", "white")
439 .attr("stroke-width", 1)
440 .on("mouseover", function (d) {
443 .attr("stroke", "green")
444 corrplot.append("text")
445 .attr("id", "corrtext")
446 .text("[" + data.traits[d.row]
447 + " vs. " + data.traits[d.col]
448 + ": " + d3.format(".2f")(d.value)
450 .style("fill", function () {
452 { return "#86B404"; }
453 else if (d.value < 0)
454 { return "#6A0888"; }
456 .attr("x", totalW * 0.5)
457 .attr("y", totalH * 0.5)
458 .attr("font-weight", "bold")
459 .attr("dominant-baseline", "middle")
460 .attr("text-anchor", "middle")
463 .on("mouseout", function() {
464 d3.selectAll("text.corrlabel").remove()
465 d3.selectAll("text#corrtext").remove()
466 d3.select(this).attr("stroke","white")
469 corrplot.append("rect")
470 .attr("height", height)
471 .attr("width", width)
472 .attr("fill", "none")
473 .attr("stroke", "#523CB5")
474 .attr("stroke-width", 1)
475 .attr("pointer-events", "none");
477 var legendValues = [];
479 if (d3.min(coefs) > 0 && d3.max(coefs) > 0 ) {
480 legendValues = [[0, 0], [1, d3.max(coefs)]];
481 } else if (d3.min(coefs) < 0 && d3.max(coefs) < 0 ) {
482 legendValues = [[0, d3.min(coefs)], [1, 0]];
484 legendValues = [[0, d3.min(coefs)], [1, 0], [2, d3.max(coefs)]];
487 var legend = corrplot.append("g")
488 .attr("class", "cell")
489 .attr("transform", "translate(" + (width + 10) + "," + (height * 0.25) + ")")
496 legend = legend.selectAll("rect")
500 .attr("x", function (d) { return 1;})
501 .attr("y", function (d) {return 1 + (d[0] * recLH) + (d[0] * 5); })
502 .attr("width", recLH)
503 .attr("height", recLW)
504 .style("stroke", "black")
505 .attr("fill", function (d) {
506 if (d === 100) {return "white"}
507 else {return corZscale(d[1])}
510 var legendTxt = corrplot.append("g")
511 .attr("transform", "translate(" + (width + 40) + "," + ((height * 0.25) + (0.5 * recLW)) + ")")
512 .attr("id", "legendtext");
514 legendTxt.selectAll("text")
518 .attr("fill", "#523CB5")
519 .style("fill", "#523CB5")
521 .attr("y", function (d) { return 1 + (d[0] * recLH) + (d[0] * 5); })
523 if (d[1] > 0) { return "Positive"; }
524 else if (d[1] < 0) { return "Negative"; }
525 else if (d[1] === 0) { return "Neutral"; }
527 .attr("dominant-baseline", "middle")
528 .attr("text-anchor", "start");