button to generate plot pheno from plants
[sgn.git] / js / solGS / gebvPhenoRegression.js
blobfa68a6de4041f947e27937874d30a22f0c90280f
1 /** 
2 * breeding values vs phenotypic deviation 
3 * plotting using d3js
4 * Isaak Y Tecle <iyt2@cornell.edu>
6 */
9 jQuery(document).ready( function() { 
10    
11     checkDataExists();   
13 });
16 function checkDataExists () {
17     var dataDetails  = getDataDetails();
18     var traitId      = dataDetails.trait_id;
19     var populationId = dataDetails.population_id;
21     jQuery.ajax({
22         type: 'POST',
23         dataType: 'json',
24         data: {'population_id': populationId, 'trait_id': traitId},
25         url: '/heritability/check/data/',
26         success: function(response) {
27             if(response.exists === 'yes') {
28                 getRegressionData();
30             } else {                
31                 calculateVarianceComponents();
32             }
33         },
34         error: function(response) {                    
35             // alert('there is error in checking the dataset for heritability analysis.');     
36         }  
37     });
38   
42 function getDataDetails () {
44     var populationId   = jQuery("#population_id").val();
45     var traitId        = jQuery("#trait_id").val();
46    
47     if (!populationId) {       
48         populationId = jQuery("#model_id").val();
49     }
51     if (!populationId) {
52         populationId = jQuery("#combo_pops_id").val();
53     }
55     return {'population_id' : populationId, 
56             'trait_id' : traitId
57             };
58         
62 function calculateVarianceComponents () {
63     var dataDetails  = getDataDetails();
64     var traitId      = dataDetails.trait_id;
65     var populationId = dataDetails.population_id;
66     
67     var gebvUrl = '/solgs/trait/' + traitId  + '/population/' + populationId;
68     
69     jQuery.ajax({
70         type: 'POST',
71         dataType: 'json',
72         data: {'source' : 'heritability'},
73         url: gebvUrl,
74         success: function(response) {
75             if(response.status === 'success') {
76                 getRegressionData();
77             } else {
78               jQuery("#heritability_message").html('Error occured estimating breeding values for this trait.');   
79             }
80         },
81         error: function(response) { 
82             jQuery("#heritability_message").html('Error occured estimating breeding values for this trait.');            
83         }  
84     });
88 function getRegressionData () { 
89     var dataDetails  = getDataDetails();
90     var traitId      = dataDetails.trait_id;
91     var populationId = dataDetails.population_id;
92     
93     jQuery.ajax({
94         type: 'POST',
95         dataType: 'json',
96         data: {'population_id': populationId, 'trait_id': traitId},
97         url: '/heritability/regression/data/',
98         success: function(response) {
99             if(response.status === 'success') {
100                 var regressionData = {
101                     'breeding_values'     : response.gebv_data,
102                     'phenotype_values'    : response.pheno_data,
103                     'phenotype_deviations': response.pheno_deviations,
104                     'heritability'        : response.heritability  
105                 };
106                     
107                 jQuery("#heritability_message").empty();
108                 plotRegressionData(regressionData);
109             }
110         },
111         error: function(response) {                    
112           jQuery("#heritability_message").html('Error occured getting regression data.');
113         }
114     });
118 function plotRegressionData(regressionData){
119   
120     var breedingValues      = regressionData.breeding_values;
121     var phenotypeDeviations = regressionData.phenotype_deviations;
122     var heritability        = regressionData.heritability;
123     var phenotypeValues     = regressionData.phenotype_values;
125      var phenoRawValues = phenotypeValues.map( function (d) {
126             d = d[1]; 
127             return parseFloat(d); 
128         });
130     var phenoXValues = phenotypeDeviations.map( function (d) {
131             d = d[1]; 
132             return parseFloat(d); 
133         });
135      var breedingYValues = breedingValues.map( function (d) {
136             d = d[1]; 
137             return parseFloat(d); 
138         });
139   
140     var lsData      = [];
141     var scatterData = [];
142    
143     phenotypeDeviations.map( function (pv) {
144       
145         var sD = [];
146         var lD = []; 
147         jQuery.each(breedingValues, function(i, gv) {
148             
149             if ( pv[0] === gv[0] ) {
150          
151                 sD.push({'name' : gv[0], 'gebv' : gv[1], 'pheno_dev': pv[1]} );
152                 
153                 var ptY = parseFloat(gv[1]);
154                 var ptX = parseFloat(pv[1]);
155                 lD.push(ptX, ptY);
156                 
157                 return false;
158             }
159             
160         });
161         lsData.push(lD);
162         scatterData.push(sD);       
163     });
164      
165     var height = 300;
166     var width  = 500;
167     var pad    = {left:20, top:20, right:20, bottom: 20}; 
168     var totalH = height + pad.top + pad.bottom;
169     var totalW = width + pad.left + pad.right;
171     var svg = d3.select("#gebv_pheno_regression_canvas")
172         .append("svg")
173         .attr("width", totalW)
174         .attr("height", totalH);
176     var regressionPlot = svg.append("g")
177         .attr("id", "#gebv_pheno_regression_plot")
178         .attr("transform", "translate(" + (pad.left - 5) + "," + (pad.top - 5) + ")");
179    
180     var phenoMin = d3.min(phenoXValues);
181     var phenoMax = d3.max(phenoXValues); 
182     
183     var xLimits = d3.max([Math.abs(d3.min(phenoXValues)), d3.max(phenoXValues)]);
184     var yLimits = d3.max([Math.abs(d3.min(breedingYValues)), d3.max(breedingYValues)]);
185     
186     var xAxisScale = d3.scale.linear()
187         .domain([0, xLimits])
188         .range([0, width/2]);
189     
190     var xAxisLabel = d3.scale.linear()
191         .domain([(-1 * xLimits), xLimits])
192         .range([0, width]);
194     var yAxisScale = d3.scale.linear()
195         .domain([0, yLimits])
196         .range([0, (height/2)]);
198     var xAxis = d3.svg.axis()
199         .scale(xAxisLabel)
200         .tickSize(3)
201         .orient("bottom");
202           
203     var yAxisLabel = d3.scale.linear()
204         .domain([(-1 * yLimits), yLimits])
205         .range([height, 0]);
206     
207    var yAxis = d3.svg.axis()
208         .scale(yAxisLabel)
209         .tickSize(3)
210         .orient("left");
212     var xAxisMid = 0.5 * (totalH); 
213     var yAxisMid = 0.5 * (totalW);
215     regressionPlot.append("g")
216         .attr("class", "x axis")
217         .attr("transform", "translate(" + pad.left + "," + xAxisMid +")")
218         .call(xAxis)
219         .selectAll("text")
220         .attr("y", 0)
221         .attr("x", 10)
222         .attr("dy", ".1em")         
223         .attr("transform", "rotate(90)")
224         .attr("fill", "green")
225         .style({"text-anchor":"start", "fill": "#86B404"});
226        
227     regressionPlot.append("g")
228         .attr("class", "y axis")
229         .attr("transform", "translate(" + yAxisMid +  "," + pad.top  + ")")
230         .call(yAxis)
231         .selectAll("text")
232         .attr("y", 0)
233         .attr("x", -10)
234         .attr("fill", "green")
235         .style("fill", "#86B404");
237     regressionPlot.append("g")
238         .attr("id", "x_axis_label")
239         .append("text")
240         .text("Phenotype deviations (X)")
241         .attr("y", (pad.top + (height/2)) + 50)
242         .attr("x", (width - 110))
243         .attr("font-size", 10)
244         .style("fill", "#86B404")
246     regressionPlot.append("g")
247         .attr("id", "y_axis_label")
248         .append("text")
249         .text("Breeding values (Y)")
250         .attr("y", (pad.top -  10))
251         .attr("x", ((width/2) - 80))
252         .attr("font-size", 10)
253         .style("fill", "#86B404")
255     regressionPlot.append("g")
256         .selectAll("circle")
257         .data(scatterData)
258         .enter()
259         .append("circle")
260         .attr("fill", "#9A2EFE")
261         .attr("r", 3)
262         .attr("cx", function(d) {
263             var xVal = d[0].pheno_dev;
264            
265             if (xVal >= 0) {
266                 return  (pad.left + (width/2)) + xAxisScale(xVal);
267             } else {   
268                 return (pad.left + (width/2)) - (-1 * xAxisScale(xVal));
269            }
270         })
271         .attr("cy", function(d) {             
272             var yVal = d[0].gebv;
273             
274             if (yVal >= 0) {
275                 return ( pad.top + (height/2)) - yAxisScale(yVal);
276             } else {
277                 return (pad.top + (height/2)) +  (-1 * yAxisScale(yVal));                  
278             }
279         })        
280         .on("mouseover", function(d) {
281             d3.select(this)
282                 .attr("r", 5)
283                 .style("fill", "#86B404")
284             regressionPlot.append("text")
285                 .attr("id", "dLabel")
286                 .style("fill", "#86B404")              
287                 .text( d[0].name + "(" + d[0].pheno_dev + "," + d[0].gebv + ")")
288                 .attr("x", pad.left + 1)
289                 .attr("y", pad.top + 80);
290         })
291         .on("mouseout", function(d) { 
292             d3.select(this)
293                 .attr("r", 3)
294                 .style("fill", "#9A2EFE")
295             d3.selectAll("text#dLabel").remove();            
296         });
297   
298     var line = ss.linear_regression()
299         .data(lsData)
300         .line(); 
301    
302     var lineParams = ss.linear_regression()
303         .data(lsData)
304      
305     var alpha = lineParams.b();
306     alpha     =  Math.round(alpha*100) / 100;
307     
308     var beta = lineParams.m();
309     beta     = Math.round(beta*100) / 100;
310     
311     var sign; 
312     if (beta > 0) {
313         sign = ' + ';
314     } else {
315         sign = ' - ';
316     };
318     var equation = 'y = ' + alpha  + sign  +  beta + 'x'; 
320     var rq = ss.r_squared(lsData, line);
321     rq     = Math.round(rq*100) / 100;
322     rq     = 'R-squared = ' + rq;
324     var lsLine = d3.svg.line()
325         .x(function(d) {
326             if (d[0] >= 0) {
327                 return  (pad.left + (width/2)) + xAxisScale(d[0]);
328             } else {   
329                 return (pad.left + (width/2)) - (-1 * xAxisScale(d[0]));
330             }})
331         .y(function(d) { 
332             if (d[1] >= 0) {
333                 return ( pad.top + (height/2)) - yAxisScale(d[1]);
334             } else {
335                 return  (pad.top + (height/2)) +  (-1 * yAxisScale(d[1]));                  
336             }});
337      
338     
339    
340     var lsPoints = [];          
341     jQuery.each(phenotypeDeviations, function (i, x)  {
342        
343         var  y = line(parseFloat(x[1])); 
344         lsPoints.push([x[1], y]); 
345    
346     });
347       
348     regressionPlot.append("svg:path")
349         .attr("d", lsLine(lsPoints))
350         .attr('stroke', '#86B404')
351         .attr('stroke-width', 2)
352         .attr('fill', 'none');
354      regressionPlot.append("g")
355         .attr("id", "equation")
356         .append("text")
357         .text(equation)
358         .attr("x", 20)
359         .attr("y", 30)
360         .style("fill", "#86B404")
361         .style("font-weight", "bold");  
362     
363      regressionPlot.append("g")
364         .attr("id", "rsquare")
365         .append("text")
366         .text(rq)
367         .attr("x", 20)
368         .attr("y", 50)
369         .style("fill", "#86B404")
370         .style("font-weight", "bold");  
371