{% extends "tables/base.html" %}
{% comment %}

Copyright 2012 Google Inc. All Rights Reserved.

This template builds page with performance details of one build.
{% endcomment %}
{% block title %}ChromeOS Performance{% endblock %}
{% block html_block %}
<div>
<span style="text-align: left">
<a href="../../../index.html" target="_top">HOME</a>
&nbsp;|&nbsp;
<a href="../../../{{ tpl_netbook }}/{{ tpl_board }}/perf_index.html">
chromeos performance test dashboard</a>
&nbsp;|&nbsp;
</span>
<span style="float: right">
  <i>last updated: {{ tpl_last_updated }}</i>
</span>

<center>
<h3>{{ tpl_board }} - {{ tpl_netbook }} - {{ tpl_build }}</h3>

{% autoescape off %}
{{ tpl_preprocessed_html }}<p>
{% endautoescape %}

{# ** Separate the email by test names ** #}
{% for test in tpl_regressed_tests|dictsort:"test_name" %}
<hr>
  {# ** Organize the keys according to common plot ** #}
  {% regroup test.test_keys|dictsort:"test_key" by key_plot as keys_by_plot %}
  {% for plot in keys_by_plot %}
    <h3>Summary for
    <a class="info"
       href="https://chromium.googlesource.com/chromiumos/third_party/autotest.git/+/master/{{ test.test_path }}"
       target="_blank">
       {{ test.test_name }}
    </a>
    {% if plot.grouper %}
    &nbsp;-&nbsp;
    <a href="../../../{{ tpl_netbook }}/{{ tpl_board }}/{{ plot.grouper }}.html" target="_blank">
      View Recent Plot
    </a>
    &nbsp;-&nbsp;
    <a href="../../../../historydash/{{ tpl_netbook }}/{{ tpl_board }}/{{ plot.grouper }}.html" target="_blank">
      View Historical Plot
    </a>
    {% endif %}
    </h3>
    <table cellspacing="1" cellpadding="2" style="margin-right:200px;">
    <tr>
      <td align="center"Key</td>
      {% for stat_name in plot.list.0.key_headers %}
        {% ifnotequal stat_name 'histogram' %}
        {% ifnotequal stat_name 'values' %}
        <td align="center">{{ stat_name|capfirst }}</td>
        {% endifnotequal %}
        {% endifnotequal %}
      {% endfor %}
    </tr>
    {# ** Each item is a single key with stats. ** #}
    {% for item in plot.list|dictsort:"sort_key" %}
      <tr>
        <td align="center"><b><tt>{{ item.test_key }}</tt></b></td>
        {% for key_stat in item.key_stats|dictsort:"stat_name" %}
          {% ifnotequal key_stat.stat_name 'histogram' %}
          {% ifnotequal key_stat.stat_name 'values' %}
          <td align="center"><b><tt>{{ key_stat.stat_val }}</tt></b></td>
          {% endifnotequal %}
          {% endifnotequal %}
        {% endfor %}
      </tr>
    {% endfor %}
    </table>
    {% for item in plot.list|dictsort:"sort_key" %}
      {% for key_stat in item.key_stats|dictsort:"stat_name" %}
        {% ifequal key_stat.stat_name 'histogram' %}
        <!--Load the AJAX API-->
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
        <script type="text/javascript">
          // Load the Visualization API and the piechart package.
          google.load('visualization', '1', {'packages':['corechart']});

          // Set a callback to run when the Google Visualization API is loaded.
          google.setOnLoadCallback(drawCharts_histogram);

          // Callback that creates and populates a data table,
          // instantiates the charts, passes in the data and
          // draws them.
          function drawCharts_histogram() {
          var data = new google.visualization.DataTable();
          data.addColumn('string', 'Bin');
          data.addColumn('number', 'Bin Count');
          data.addRows({{ key_stat.stat_val.data|length }});
          // Add x-axis.
          {% for bin, binlow, binhigh in key_stat.stat_val.data %}
          data.setValue({{ forloop.counter0 }}, 0, '{{ binlow }}-{{ binhigh }}');
          data.setValue({{ forloop.counter0 }}, 1, {{ bin }});
          {% endfor %}

          var chart = new google.visualization.ColumnChart(
              document.getElementById('{{ item.test_key }}_histogram_div'));
          chart.draw(data, {
              hAxis: {title: '{{ test.test_name }} - {{ item.test_key }}'},
              height: {{ key_stat.stat_val.height }},
              title: 'Histogram for Build: {{ tpl_build }}',
              width: {{ key_stat.stat_val.width }}});
          }
        </script>

        <div id="{{ item.test_key }}_histogram_div"></div>

        {% endifequal %}
        {% ifequal key_stat.stat_name 'values' %}
        <!--Load the AJAX API-->
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
        <script type="text/javascript">
          // Load the Visualization API and the piechart package.
          google.load('visualization', '1', {'packages':['corechart']});

          // Set a callback to run when the Google Visualization API is loaded.
          google.setOnLoadCallback(drawCharts_values);

          // Callback that creates and populates a data table,
          // instantiates the charts, passes in the data and
          // draws them.
          function drawCharts_values() {
          var data = new google.visualization.DataTable();
          data.addColumn('number', 'Iteration');
          {% for column_name, job_tag in key_stat.stat_val.column_names %}
          data.addColumn('number', '{{ column_name }}');
          {% endfor %}
          data.addRows({{ key_stat.stat_val.rowcount }});
          // Add x-axis.
          {% for xindex, yindex, value in key_stat.stat_val.data %}
          data.setValue({{ xindex }}, {{ yindex }}, {{ value }});
          {% endfor %}

          var chart = new google.visualization.ScatterChart(
              document.getElementById('{{ item.test_key }}_values_div'));
          google.visualization.events.addListener(chart, 'select', function(){
            var job_tags = new Array();
            {% for column_name, job_tag in key_stat.stat_val.column_names %}
              job_tags[{{ forloop.counter0 }}] = '{{ job_tag }}';
            {% endfor %}
            window.open(
                'http://cautotest/results/' +
                job_tags[chart.getSelection()[0].column-1] +
                '/' + '{{ test.test_name }}' +
                '/results/keyval')
            });
          chart.draw(data, {
              hAxis: {title: '{{ test.test_name }} - {{ item.test_key }}'},
              height: {{ key_stat.stat_val.height }},
              pointSize: 3,
              title: 'Iteration Values for Build: {{ tpl_build }}',
              width: {{ key_stat.stat_val.width }}});
          }
        </script>

        <div id="{{ item.test_key }}_values_div"></div>

        {% endifequal %}
      {% endfor %}
    {% endfor %}
    <hr>
  {% endfor %}
{% endfor %}
</center>

{% autoescape off %}
{{ tpl_build_log }}<p>
{% endautoescape %}
{% endblock %}
