| {% set title = 'Swarming Server Stats' %} |
| {% extends "swarming/base.html" %} |
| |
| {% block headers %} |
| <script type="text/javascript" src="//www.google.com/jsapi"></script> |
| <script type="text/javascript"> |
| var local = (function() { |
| google.load( |
| "visualization", "1", |
| { |
| callback: loaded, |
| packages: ["corechart", "table"] |
| }); |
| |
| // Display parameters. |
| var current_resolution = '{{resolution}}'; |
| var duration = {{duration}}; |
| var show_as_raw = false; |
| // Common shared data. |
| var data_table = null; |
| // The three graphs. |
| var chart_work = null; |
| var chart_times = null; |
| var chart_table = null; |
| // Current on-going HTTP request. |
| var current_query = null; |
| |
| {% include 'swarming/stats_common.js' %} |
| |
| // Reloads the data with a new resolution. |
| function set_resolution(res) { |
| set_resolution_internal(res); |
| // Refresh the data even if the user requested the same res. |
| var url = '/swarming/api/v1/stats/users/{{user|urlquote}}/' + |
| current_resolution + '?duration=' + duration; |
| sendQuery(url, redrawCharts); |
| } |
| |
| // Updates cached js variable show_as_raw. Do not redraw unless necessary, |
| // unlike set_resolution(). |
| function set_show_as_raw() { |
| var new_val = document.getElementById('show_as_raw').checked; |
| if (new_val != show_as_raw) { |
| show_as_raw = new_val; |
| redrawCharts(data_table); |
| } |
| } |
| |
| // Redraws all the charts. This can happen in two situations; new data |
| // arrived via sendQuery() or the raw data toggle was changed. |
| function redrawCharts(new_table) { |
| // Update the global variable. |
| data_table = new_table; |
| if (data_table == null) { |
| return; |
| } |
| // Reformat some of the columns. |
| if (show_as_raw == true) { |
| resetFormattedData(data_table); |
| } |
| |
| var formatter_key = get_key_formatter(); |
| // These indexes are relative to stats_gviz._User.ORDER. |
| formatter_key.format(data_table, 0); |
| |
| var round3 = new google.visualization.NumberFormat( |
| {decimalSymbol:'.', fractionDigits:3}); |
| // These indexes are relative to stats_gviz._User.ORDER. |
| round3.format(data_table, 5); |
| round3.format(data_table, 6); |
| round3.format(data_table, 7); |
| |
| // Work graph. |
| clearCustomTicks(chart_work); |
| var view = new google.visualization.DataView(data_table); |
| // These indexes are relative to stats_gviz._User.ORDER. |
| view.setColumns([0, 1, 2, 3, 4, 8, 9]); |
| chart_work.setDataTable(view.toDataTable()); |
| if (show_as_raw == false) { |
| setAxisTicksToUnitsOnNextDraw(chart_work, false); |
| } |
| chart_work.draw(); |
| |
| // Times graph. |
| clearCustomTicks(chart_times); |
| var view = new google.visualization.DataView(data_table); |
| // These indexes are relative to stats_gviz._User.ORDER. |
| view.setColumns([0, 5, 6, 7]); |
| chart_times.setDataTable(view.toDataTable()); |
| if (show_as_raw == false) { |
| setAxisTicksToUnitsOnNextDraw(chart_times, false); |
| } |
| chart_times.draw(); |
| |
| // Bottom raw data table. |
| chart_table.setDataTable(data_table); |
| chart_table.draw(); |
| } |
| |
| // Now the actual work. |
| // Callback when google viz is ready. Loads each graph. |
| function loaded() { |
| data_table = new google.visualization.DataTable({{initial_data|safe}}); |
| chart_work = new google.visualization.ChartWrapper( |
| { |
| chartType: 'LineChart', |
| dataTable: data_table, |
| containerId: 'work_graph', |
| options: { |
| animation: { |
| duration: 500, |
| easing: 'out' |
| }, |
| height: '100%', |
| title: 'Shards activity', |
| width: '100%' |
| }, |
| }); |
| chart_times = new google.visualization.ChartWrapper( |
| { |
| chartType: 'LineChart', |
| dataTable: data_table, |
| containerId: 'times_graph', |
| options: { |
| animation: { |
| duration: 500, |
| easing: 'out' |
| }, |
| height: '100%', |
| title: 'Times (s)', |
| width: '100%' |
| }, |
| }); |
| chart_table = new google.visualization.ChartWrapper( |
| { |
| chartType: 'Table', |
| dataTable: data_table, |
| containerId: 'raw_data_table', |
| options: { |
| animation: { |
| duration: 500, |
| easing: 'out' |
| }, |
| height: '100%', |
| title: 'Raw data', |
| width: '100%' |
| }, |
| }); |
| |
| if (data_table != null) { |
| // Data was preloaded. Update the UI checkboxes. |
| set_resolution_internal(current_resolution); |
| redrawCharts(data_table); |
| } else { |
| // Do not draw yet, since it would fail because of the empty DataTable. |
| // sendQuery() will call .draw() on each chart. |
| set_resolution('hours'); |
| } |
| } |
| |
| // Public interface. |
| return { |
| set_resolution: set_resolution, |
| set_show_as_raw: set_show_as_raw, |
| |
| // For debugging. |
| chart_times: function() { return chart_times; }, |
| chart_work: function() { return chart_work; }, |
| chart_table: function() { return chart_table; }, |
| current_query: function() { return current_query; }, |
| current_resolution: function() { return current_resolution; }, |
| data_table: function() { return data_table; }, |
| duration: function() { return duration; }, |
| show_as_raw: function() { return show_as_raw; } |
| } |
| })(); |
| </script> |
| {% endblock %} |
| |
| |
| {% block body %} |
| |
| <h1>Statistics for user {{user}}</h1> |
| {# TODO(maruel): Keep duration, current_resolution and maybe 'now'. #} |
| <a href="/stats">Go back to summary</a> |
| <p> |
| |
| Resolution: |
| <input type="checkbox" id=resolution_days |
| onclick="local.set_resolution('days')">Day</input> |
| <input type="checkbox" id=resolution_hours |
| onclick="local.set_resolution('hours')">Hour</input> |
| <input type="checkbox" id=resolution_minutes |
| onclick="local.set_resolution('minutes')">Minute</input> |
| <br> |
| <input type="checkbox" id=show_as_raw onclick="local.set_show_as_raw()"> |
| Show as raw</input> |
| |
| <hr> |
| <div id="work_graph" class="graph">(Loading...)</div> |
| <hr> |
| <div id="times_graph" class="graph">(Loading...)</div> |
| <hr> |
| <div id="raw_data_table" class="data_table">(Loading...)</div> |
| |
| {% endblock %} |