fix test with new description field.
[sgn.git] / mason / breeders_toolbox / db_stats.mas
blobb326028efdddaa2ad975742169178e274ca782bd
2 <%args>
3 $breeding_programs
4 </%args>
6 % use JSON;
8 <& /util/import_javascript.mas, classes => [ 'd3.d3v4Min.js', 'd3pie_min.js', 'moment_min',  'd3.graphers.stackedObservationPhenotypeHistogram' ] &>
10   <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
11   <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
12   
13 <& /page/page_title.mas, title => 'Database Stats' &>
15 <&| /page/info_section.mas, title => "Date Range" &>
17 Filter by date of addition to database<br /><br />
18 <table><tr><td>
20 Start Date: <input type="text" id="dbstats_start_date" title="dbstats_start_date"  />
21 <td>&nbsp;</td></td><td>
23 End Date: <input type="text" id="dbstats_end_date" title="dbstats_end_date"  />
24 </td><td>
25 &nbsp;
26 </td><td>
27 <input type="checkbox" id="include_dateless_items"> include items without a date</input>
28 </td><td>
29 &nbsp;
30 </td><td>
31 <button id="update_dbstats_by_date">Update</button>
33 </td>
34 </tr></table>
35 </&>
37 <script>
39 var dbstats_start_date_element = jQuery("#dbstats_start_date");
40 //set_daterangepicker_default(dbstats_start_date_element);
42 jQuery('input[title="dbstats_start_date"]').daterangepicker(
43    {
44        "singleDatePicker": true,
45        "showDropdowns": true,
46        "autoUpdateInput": true,
47        "startDate": "1970-01-01",
48        "yearSelect" : true,
49        "minDate": "1970-01-01",
50        "maxDate": "2030-12-31",
51        locale: { 
52         format: 'YYYY-MM-DD'
53       }
54    },
58 var dbstats_end_date_element = jQuery("#dbstats_end_date");
60 jQuery('input[title="dbstats_end_date"]').daterangepicker(
61     {
62        "singleDatePicker": true,
63        "autoUpdateInput": true,
64        "minDate": "1970-01-01",
65        "maxDate" : "2030-12-31", 
66        "yearSelect" : true,
67        locale: { 
68            format: 'YYYY-MM-DD'
69        },
70        "showDropdowns": true,
71     },
75 </script>
77 <&| /page/info_section.mas, title => "Data categories" &>
79 <table><tr><td>
81 <span id="trial_types_div"></span>
83 </td><td>
85 <span id="trials_by_breeding_programs_div"></span>
87 </td></tr>
88 <tr><td>
90 <span id="traits_div"></span>
92 </td><td>
94 <span id="stocks_div"></span>
96 </td></tr>
97 </table>
99 </&>
101 %# <&| /page/info_section.mas, title => "Activity - past 52 weeks" &>
103 %#    <svg class="bargraph" width="800" height="200"></svg>
104     
105 %#  </&>
107 %# <&| /page/info_section.mas, title => "Breeding Program Summaries", collapsible=>1 &>
109 %# <div id="program_stats">[loading program stats...]</div>
111 %# </&>
113 %# <&| /page/info_section.mas, title => "Breeding Program Summaries", collapsible=>1 &>
115 %#  %  foreach (@$breeding_programs){
117 %#    <div class="well">
119 %#        <h3>Breeding Program: <% $_->[1] %></h3>
121 %#        <&| /page/info_section.mas, title => "Trials" , collapsible=>1 &>
122 %#            <& /breeders_toolbox/program/trials.mas, program_id => $_->[0] &>
123 %#        </&>
125 %#        <&| /page/info_section.mas, title => "Traits" , collapsible=>1 &>
126 %#            <& /breeders_toolbox/program/traits.mas, program_id => $_->[0], collapse_phenotypes_section => 0  &>
127 %#        </&>
129 %#    </div>
131 %#  }
133 %#</&>
135 <script>
137 % my $breeding_program_json = encode_json($breeding_programs);
140 jQuery(document).ready( function() { 
142     draw_overview_charts();   
144     jQuery('#update_dbstats_by_date').click( function() {
145         draw_overview_charts();
146     });
148     var breeding_programs = JSON.parse('<% $breeding_program_json %>');
150     //   alert(JSON.stringify(breeding_programs));
152 //   var html = "";
154 //    for(let i=0; i<breeding_programs.length; i++) {
155 // //      alert('table loop '+i + ' for '+breeding_programs[i][1]);
156 //       html += "<h3>Breeding Program: "+ breeding_programs[i][1] + "</h3>";
158 //       html += trial_table(html, breeding_programs[i][0]);
159 //       html += trait_table(html, breeding_programs[i][0]);
160 //    }
162 //    jQuery('#program_stats').html(html);
164 // //   alert(JSON.stringify(breeding_programs));
166 //    for(let n=0; n<breeding_programs.length; n++) {
167 // //       alert('ajax loop '+ n + ' for '+breeding_programs[n][1]);
168 //        trial_queries(breeding_programs[n][0], start_date, end_date, include_dateless_items);
169 //        trait_queries(breeding_programs[n][0], start_date, end_date, include_dateless_items);
170 //    }
175 function draw_overview_charts() { 
176  var start_date = jQuery('#dbstats_start_date').val();
177     var end_date   = jQuery('#dbstats_end_date').val();
178     var include_dateless_items = jQuery('#include_dateless_items').prop('checked');
179 //       alert('Drawing charts with start date of '+start_date+' end date of '+end_date+' and '+include_dateless_items);
180      // remove old graphs if present
181        jQuery('#trial_types_div').html("");
182        jQuery('#trials_by_breeding_programs_div').html("");
183        jQuery('#traits_div').html("");
184        jQuery('#stocks_div').html("");
186         jQuery.ajax({
187         url: '/ajax/dbstats/trials_by_breeding_program_chart',
188         data: { 'start_date' : start_date, 'end_date' : end_date, 'include_dateless_items' : include_dateless_items },  
189         error: function(response) { alert('An error occurred' + JSON.stringify(response));  },
190         success: function(response)  { 
191             //alert('success' + JSON.stringify(response)); 
192             var types_pie = new d3pie('trials_by_breeding_programs_div', response);
193         }
194     });
196     jQuery.ajax({
197         url: '/ajax/dbstats/traits_chart',
198         data: { 'start_date' : start_date, 'end_date' : end_date, 'include_dateless_items' : include_dateless_items },  
199         error: function(response) { alert('An error occurred' + JSON.stringify(response));  },
200         success: function(response)  { 
201            //alert('success' + JSON.stringify(response)); 
202            var types_pie = new d3pie('traits_div', response);
203         }
204     });
205   
206     jQuery.ajax({
207         url: '/ajax/dbstats/stocks_chart',
208         data: { 'start_date' : start_date, 'end_date' : end_date, 'include_dateless_items' : include_dateless_items },
209         error: function(response) { alert('An error occurred' + JSON.stringify(response));  },
210         success: function(response)  { 
211             var types_pie = new d3pie('stocks_div', response);
212         }
213     });
215     jQuery.ajax({
216         url: '/ajax/dbstats/trial_types_chart',
217         data: { 'start_date' : start_date, 'end_date' : end_date, 'include_dateless_items' : include_dateless_items },
218         error: function(response) { alert('An error occurred' + JSON.stringify(response));  },
219         success: function(response)  { 
220             //alert('success' + JSON.stringify(response)); 
221             var types_pie = new d3pie('trial_types_div', response);      
222         }
223     });
225 //    jQuery.ajax( { 
226 //        url : '/ajax/dbstats/activity',
227 //        error: function(r) { alert('An error occurred.'); },
228 //        success:  function(d) {
229 //            d.frequency = +d.frequency;
230 //            bargraph(d);
231 //        }
232 //    });
236 function bargraph(data) { 
237     var svg = d3.select(".bargraph"),
238     margin = {top: 20, right: 20, bottom: 30, left: 40},
239     width = +svg.attr("width") - margin.left - margin.right,
240     height = +svg.attr("height") - margin.top - margin.bottom;
242     var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
243         y = d3.scaleLinear().rangeRound([height, 0]);
245     var g = svg.append("g")
246       .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
248     x.domain(data.map(function(d) { return d.letter; }));
250     y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
251   
252     g.append("g")
253       .attr("class", "axis axis--x")
254       .attr("transform", "translate(0," + height + ")")
255       .call(d3.axisBottom(x));
257     g.append("g")
258       .attr("class", "axis axis--y")
259       .call(d3.axisLeft(y).ticks(10, ""))
260       .append("text")
261       .attr("transform", "rotate(-90)")
262       .attr("y", 6)
263       .attr("dy", "0.71em")
264       .attr("text-anchor", "end")
265       .text("Frequency");
267   g.selectAll(".bar")
268     .data(data)
269     .enter().append("rect")
270       .attr("class", "bar")
271       .attr("x", function(d) { return x(d.letter); })
272       .attr("y", function(d) { return y(d.frequency); })
273       .attr("width", x.bandwidth())
274       .attr("height", function(d) { return height - y(d.frequency); })
275       .attr("fill", "#AAAAEE");
276   }
280 function trial_table(html, bp_id) {
282 html += `
283 <table id="trial_summary_data_`+bp_id+`" class="display">
284     <thead>
285         <tr>
286             <th>Trial name</th>
287             <th>Description</th>
288         </tr>
289     </thead>
290 </table>
293 //    alert(html);
295     return html;
298 function trait_table(html, bp_id) {
300 html = `
301 <div class="well well-sm table-responsive">
302   <center><h4>Raw Data Statistics</h4></center>
303   <br/>
306   <div id="pheno_summary_table_`+bp_id+`_div">
308     <table id="phenotype_summary_data_`+bp_id+`" class="display">
309       <thead>
310         <tr>
311           <th>Trait</th>
312           <th>Mean</th>
313           <th>Min</th>
314           <th>Max</th>
315           <th>Std Dev</th>
316           <th>CV</th>
317           <th>Count</th>
318           <th>Histogram</th>
319         </tr>
320       </thead>
321       <tbody>
322       </tbody>
323     </table>
324   </div>
325 </div>
326 <div class="well well-sm" id="raw_data_histogram_well_`+bp_id+`">
327   <center><h4>Raw Data Histogram</h4></center><hr>
328   <div id="program_summary_hist_`+bp_id+`_div">
329     <div class="row">
330       <div class="col-sm-8">
331         <form class="form-horizontal">
332           <div class="form-group form-group-sm">
333             <label for="program_summary_hist_dropdown_`+bp_id+`" class="col-sm-2 control-label">Select:</label>
334             <div class="col-sm-10">
335               <div id="traits_assayed_dropdown_`+bp_id+`">
336               </div>
337             </div>
338           </div>
339       </div>
340       <div class="col-sm-4" id="traits_assayed_histogram_cvterm_link_`+bp_id+`">
341       </div>
342     </div>
344     <div id="program_summary_hist_`+bp_id+`">
345     </div>
347   </div>
348 </div>
353 //   alert(html);
355    return html;
358 function trial_queries(bp_id, start_date, end_date, include_dateless_items) { 
359 //    alert('AJAX call for '+bp_id +' start_date = '+start_date);
360     jQuery('#trial_summary_data_'+bp_id).DataTable( {
361         'autoWidth': false,
362         'ajax': '/ajax/breeders/program/'+ bp_id + '/field_trials?start_date='+start_date+'&end_date='+end_date+'&include_dateless_items='+include_dateless_items,
363     });
366 function trait_queries(bp_id, start_date, end_date, include_dateless_items) { 
367 //    alert('getting trait data...');
368     jQuery("#phenotype_summary_data_"+bp_id).DataTable( {
369         'ajax': '/ajax/breeders/program/'+ bp_id + '/phenotypes?start_date='+start_date+'&end_date='+end_date+'&include_dateless_items='+include_dateless_items,
370     });
371     
372     trait_summary_hist_display_change(bp_id, start_date, end_date, include_dateless_items);
374     ///clicking on the histogram glyph from the dataTable
375     /// scrolls down to the histogram div
376     ///
377     jQuery('#phenotype_summary_data_'+bp_id).on('click', 'a[href^="#"]', function(event) {
378         var offset = jQuery(window).height() - jQuery('#raw_data_histogram_well_'+bp_id).height() - 40;
379         var target = jQuery(this.getAttribute('href'));
380         if( target.length ) {
381             event.preventDefault();
382             jQuery('html, body').stop().animate({
383                 scrollTop: target.offset().top - offset
384             }, 1500);
385         }
386     });
389 function trait_summary_hist_display_change(program_id, start_date, end_date, include_dateless_items) {
391     var d3 = d3v4;
392     var draw_histogram = stackedObservationPhenotypeHistogram.draw;
394 //    alert('trait_summary_hist_display_change!');
396     jQuery.ajax ( {
397         url : '/ajax/breeders/program/'+ program_id + '/traits_assayed?start_date='+start_date+'&end_date='+end_date+'&include_dateless_items='+include_dateless_items,
398         beforeSend: function() {
399         //            jQuery("#working_modal").modal("show");
400         },
401         success: function(response){
402             //console.log(response);
403             if (response.traits_assayed[0][0]) {
404                 var traits_assayed_html = "<select class='form-control' id='program_summary_hist_dropdown_"+program_id+"'>";
405 //              alert('select: '+traits_assayed_html);
406                 for (i=0; i<response.traits_assayed[0].length; i++) {
407                     traits_assayed_html = traits_assayed_html + "<option value="+ response.traits_assayed[0][i][0] + " >" + response.traits_assayed[0][i][1] + "</option>";
408                 }
409                 traits_assayed_html = traits_assayed_html +"</select>";
411 //              alert(traits_assayed_html);
412                 jQuery("#traits_assayed_dropdown_"+program_id).html(traits_assayed_html);
413 //              alert('done with dropdown!');
414                 jQuery("#traits_assayed_dropdown_"+program_id).change(function(){
415                     var new_trait_id = jQuery('#traits_assayed_dropdown_'+program_id).find(":selected").val();
416 //                    alert("NEW TRAIT ID: "+new_trait_id);
417                     trait_summary_hist_change(program_id, new_trait_id);
418                 });
420                 jQuery('#traits_assayed_histogram_cvterm_link_'+program_id).html("<a href='/cvterm/"+response.traits_assayed[0][0][0]+"/view'>Definition</a>");
422                 var trait_id = jQuery("#program_summary_hist_dropdown_"+program_id).val();
423 //              alert('TRAIT_ID: '+trait_id);
424                 jQuery.ajax( {
425                     url : '/ajax/breeders/program/'+ program_id +'/trait_phenotypes/?trait='+trait_id,
426                     type: 'POST',
427                     success: function(response){
428                         jQuery("#working_modal").modal("hide");
429                         var draw_histogram = stackedObservationPhenotypeHistogram.draw;
430                         if (response.error) {
431                             alert(response.error);
432                         }
433                         else if (response.status!="success"){
434                             alert("Problem loading plant/plot data: "+response.status);
435                         }
436                         else {
437                             draw_histogram(response.data, d3.select("#program_summary_hist_"+program_id).node());
438                         }
439                     },
440                     error: function(response) {
441                         jQuery("#working_modal").modal("hide");
442                         alert('An error occured retrieving trait histogram data.');
443                     }
444                 });
445             } else {
446                 jQuery("#working_modal").modal("hide");
447                 jQuery("#program_summary_hist_"+program_id).html("<center><h4>There is no data to plot.</h4></center>");
448             }
450         },
451         error: function(response){
452             alert('Error retrieving traits assayed in this breeding program');
453         }
455     });
458 function trait_summary_hist_change(program_id, value) {
459          
460     jQuery('#traits_assayed_histogram_cvterm_link_'+program_id).html("<a href='/cvterm/"+value+"/view'>Definition</a>");
461     jQuery("#program_summary_hist_dropdown_"+program_id).val(value);
462     jQuery.ajax( {
463         url : '/ajax/breeders/program/'+ program_id +'/trait_phenotypes/?trait='+value+'',
464         type: 'POST',
465         beforeSend: function() {
466             jQuery("#working_modal").modal("show");
467         },
468         success: function(response){
469             jQuery("#working_modal").modal("hide");
470             var draw_histogram = stackedObservationPhenotypeHistogram.draw;
471             if (response.error) {
472                 alert(response.error);
473             }
474             else if (response.status!="success"){
475                 alert("Problem loading plant/plot data: "+response.status);
476             }
477             else {
478                 draw_histogram(response.data, d3.select("#program_summary_hist_"+program_id).node());
479             }
480         },
481         error: function(response) {
482             jQuery("#working_modal").modal("hide");
483             alert('An error occured retrieving trait histogram data.');
484         }
485     });
488 </script>