| <!DOCTYPE html> |
| <html> |
| <head> |
| <link type="text/css" rel="stylesheet" href="/dashboard/static/base.css"> |
| <link rel="import" href="/components/polymer/polymer.html"> |
| |
| <script src="/jquery/jquery-2.1.4.min.js"></script> |
| <script src="/flot/jquery.flot.min.js"></script> |
| <script src="/flot/jquery.flot.pie.min.js"></script> |
| <script src="/flot/jquery.flot.stack.min.js"></script> |
| |
| <style> |
| form, ul { |
| margin-left: 20px; |
| } |
| |
| .sub-form { |
| margin-bottom: 20px; |
| margin-left: 30px; |
| margin-top: 10px; |
| } |
| |
| input[type=submit] { |
| background-color: #4d90fe; |
| background-image: -webkit-linear-gradient(top, #4d90fe, #4787ed); |
| background-image: linear-gradient(to bottom, #4d90fe, #4787ed); |
| border: 1px solid #3079ed; |
| border-radius: 2px; |
| color: #fff; |
| font-size: 11px; |
| font-weight: bold; |
| height: 27px; |
| line-height: 27px; |
| min-width: 54px; |
| padding: 0px 8px; |
| -webkit-user-select: none; |
| } |
| |
| input[type=checkbox] { |
| margin-right: 10px; |
| } |
| |
| hr { |
| border-top: solid 1px #ebebeb; |
| margin: 16px 0; |
| width: 100%; |
| } |
| |
| .piechart { |
| height: 400px; |
| width: 800px; |
| } |
| </style> |
| </head> |
| <body> |
| {% include 'nav.html' %} |
| <h1>Chrome Performance Statistics</h1> |
| {% if waiting %} |
| Waiting ({{processed}} of {{total}})... |
| <script> |
| 'use strict'; |
| window.setTimeout(function() { |
| location.reload(); |
| }, 5000); |
| </script> |
| {% elif have_stats %} |
| <h2>{{title}}:</h2> |
| {% if type == "around_revision" %} |
| <table> |
| <tr> |
| <th>Test</th> |
| <th>Revision tested</th> |
| <th>Median % change</th> |
| <th>Median before</th> |
| <th>Median after</th> |
| <th>Mean % change</th> |
| <th>Mean before</th> |
| <th>Mean after</th> |
| <th>Standard Deviation</th> |
| </tr> |
| {% for test in stats.tests %} |
| <tr> |
| <td>{{test.test_path}}</td> |
| <td>{{test.actual_revision}}</td> |
| <td>{{test.median_percent_improved}}</td> |
| <td>{{test.median_before}}</td> |
| <td>{{test.median_after}}</td> |
| <td>{{test.mean_percent_improved}}</td> |
| <td>{{test.mean_before}}</td> |
| <td>{{test.mean_after}}</td> |
| <td>{{test.std}}</td> |
| </tr> |
| {% endfor %} |
| </table> |
| {% elif type == "alert_summary" %} |
| <div class="alert_summary_group"> |
| <h3>Overall Alert Stats</h3> |
| |
| <h4>Bots</h4> |
| <div id="bots-pie" class="piechart"></div> |
| |
| <h4>Test Suites</h4> |
| <div id="test_suites-pie" class="piechart"></div> |
| |
| <h4>Individual Traces</h4> |
| <div id="traces-pie" class="piechart"></div> |
| |
| <h4>Bug IDs</h4> |
| <div id="bug_ids-pie" class="piechart"></div> |
| |
| <h4>Percent Changed</h4> |
| <div id="percent_changed_buckets-pie" class="piechart"></div> |
| |
| </div> |
| <div class="alert_summary_group"> |
| <h3>Daily Alert Stats</h3> |
| |
| <h4>Bots</h4> |
| <div id="bots-daily" class="piechart"></div> |
| |
| <h4>Test Suites</h4> |
| <div id="test_suites-daily" class="piechart"></div> |
| |
| <h4>Individual Traces</h4> |
| <div id="traces-daily" class="piechart"></div> |
| |
| <h4>Bug IDs</h4> |
| <div id="bug_ids-daily" class="piechart"></div> |
| |
| <h4>Percent Changed</h4> |
| <div id="percent_changed_buckets-daily" class="piechart"></div> |
| <div id="chart-tooltip" style="position: absolute; display:none; |
| background-color:white; color: black;"> |
| </div> |
| </div> |
| |
| <script> |
| 'use strict'; |
| |
| function labelFormatter(label, series) { |
| return ('<div style="font-size:8pt; text-align:center; ' + |
| 'padding:2px; color:white;">' + label + '<br>' + |
| Math.round(series.percent) + '%</div>'); |
| } |
| |
| var axis_map = {{stats.axis_map | safe}}; |
| var summaries = {{stats.overall_summaries | safe}}; |
| |
| for (var key in summaries) { |
| $.plot('#' + key + '-pie', summaries[key], { |
| series: { |
| pie: { |
| show: true, |
| radius: 1, |
| label: { |
| show: true, |
| radius: 2 / 3, |
| formatter: labelFormatter, |
| threshold: 0.1 |
| } |
| } |
| }, |
| legend: { |
| show: false |
| }, |
| grid: { |
| hoverable: true |
| } |
| }); |
| |
| $('#' + key + '-pie').bind('plothover', function(event, pos, item) { |
| var tooltip = document.getElementById('chart-tooltip'); |
| if (item) { |
| tooltip.textContent = ( |
| item.series.label + ': ' + item.datapoint[0].toFixed(2)); |
| tooltip.style.left = (pos.pageX + 15) + 'px'; |
| tooltip.style.top = pos.pageY + 'px'; |
| tooltip.style.display = ''; |
| } else { |
| tooltip.style.display = 'none'; |
| } |
| }); |
| } |
| |
| var daily = {{stats.daily_summaries | safe}}; |
| for (var d in daily) { |
| $.plot('#' + d + '-daily', daily[d], { |
| series: { |
| stack: true, |
| lines: { |
| show: true, |
| fill: true, |
| steps: false |
| }, |
| bars: { |
| show: false, |
| barWidth: 0.6 |
| } |
| }, |
| legend: { |
| show: false |
| }, |
| xaxis: { |
| tickFormatter: function(num) { return axis_map[num] || ''; } |
| }, |
| grid: { |
| hoverable: true |
| } |
| }); |
| |
| $('#' + d + '-daily').bind('plothover', function(event, pos, item) { |
| var tooltip = document.getElementById('chart-tooltip'); |
| var x = Math.round(pos.x); |
| if (x < 0 || x >= this[0].length) { |
| tooltip.style.display = 'none'; |
| return; |
| } |
| var y = pos.y; |
| var label = null; |
| var sum = 0, lastSum = 0; |
| for (var i = 0; i < this.length; i++) { |
| sum += this[i].data[x][1]; |
| if (lastSum <= y && y < sum) { |
| label = this[i].label; |
| break; |
| } |
| lastSum = sum; |
| } |
| if (label) { |
| tooltip.textContent = label + ': ' + this[i].data[x][1]; |
| tooltip.style.left = (pos.pageX + 15) + 'px'; |
| tooltip.style.top = pos.pageY + 'px'; |
| tooltip.style.display = ''; |
| } else { |
| tooltip.style.display = 'none'; |
| } |
| }.bind(daily[d])); |
| } |
| </script> |
| {% endif %} |
| {% else %} |
| <script> |
| 'use strict'; |
| |
| function updateSubForm() { |
| var sel = document.getElementById('type-select'); |
| var val = sel.options[sel.selectedIndex].value; |
| var revForm = document.getElementById('around_revision_form'); |
| var alertForm = document.getElementById('alert_summary_form'); |
| if (val == 'around_revision') { |
| revForm.style.display = ''; |
| alertForm.style.display = 'none'; |
| } else { |
| revForm.style.display = 'none'; |
| alertForm.style.display = ''; |
| } |
| } |
| </script> |
| <form method="POST"> |
| {{xsrf_input|safe}} |
| <b>Select the type of stats to calculate:</b> |
| <select name="type" id="type-select" onchange="updateSubForm();"> |
| <option value="around_revision">Performance Before/After Revision</option> |
| <option value="alert_summary">Summary of alerts over time</option> |
| </select><br><br> |
| Name for this run:<br> |
| <input type="text" name="name"><br> |
| <div class="sub-form" id="around_revision_form"> |
| Bots:<br> |
| {% for bot in bots %} |
| <label> |
| <input type="checkbox" checked name="bots" value="{{bot}}"> |
| {{bot}} |
| </label><br> |
| {% endfor %} |
| <br> |
| Revision to check:<br> |
| <input type="text" placeholder="1234567" name="rev"><br><br> |
| Number of revisions before/after to check:<br> |
| <input type="text" name="num_around" value="10"><br><br> |
| </div> |
| <div class="sub-form" id="alert_summary_form" style="display:none"> |
| Sheriff: |
| <select name="sheriff"> |
| {% for sheriff in sheriffs %} |
| <option value="{{sheriff}}">{{sheriff}}</option> |
| {% endfor %} |
| </select><br><br> |
| Start date: <input type="date" name="start_date"><br><br> |
| End date: <input type="date" name="end_date"><br><br> |
| </div> |
| <input type="submit" value="Submit"> |
| </form> |
| <hr> |
| <b>Or select recent stats to view:</b> |
| <ul> |
| {% for s in recent %} |
| <li><a href="/stats?key={{s.key}}">{{s.title}}</a> |
| {% endfor %} |
| </ul> |
| {% endif %} |
| </body> |
| </html> |