<html>

<!--
  Copyright (c) 2012 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
-->

<!--

  This page plots data loaded from Chrome performance tests listed in
  chrome_config.js for specified version numbers in URL parameter.

  Example:
    build-comparison.html?versions=17.1.963.11,17.1.963.12,17.1.963.13
-->
<head>
<style type="text/css">
{
  margin: 0;
  padding: 0;
  list-style-type: none;
}
body {
  font-family: Helvetica, Arial, sans-serif;
  color: #333;
}
a {
  color: #2D7BB2;
  text-decoration: none;
  font-weight: bold;
}
a:hover {
  color: #333;
}
h2, h3, h4 {
  clear: both;
  margin: 0 0 0.6em 0;
}
h3 {
  color: #666;
}
button {
  padding: 2px 6px 3px;
}
label {
  font-size: 11px;
  color: #666;
}
</style>

<title>Chrome Perf Platform Comparison</title>
<script src="chrome_config.js"></script>
<script src="ui/js/common.js"></script>
<script src="https://www.google.com/jsapi"></script>

<script type="text/javascript">
var params = ParseParams();
var versions = {};
var allRowData = [];
var isDataFetched = false;

google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(init);

function init() {
  if (params.versions) {
    split_ver = params.versions.split(/[\s,]+/);
    for (var i = 0; i < split_ver.length; i++)
      versions[split_ver[i]] = 1;
    FetchGraphList();
    
    document.getElementById('versions').defaultValue = params.versions;
  }
}

/**
 * On plot clicked, parse text area for version numbers and plot.
 */
function setVersion() {
  var ver = document.getElementById('versions').value;
  clearDiv('output');
  clearDiv('log');
  if (ver) {
    versions = {};
    split_ver = ver.split(/[\s,\n]+/);
    for (var i = 0; i < split_ver.length; i++)
      versions[split_ver[i]] = 1;
    if (isDataFetched)
      plot();
    else
      FetchGraphList();

    var stateObj = { foo: 'bar'};
    history.pushState(stateObj, "", MakeURL({'versions': ver}));
  }
}

/**
 * Fetch all the graphs.dat file on all systems and test directories.
 */
function FetchGraphList() {
  // Fetch graphs.dat from all machines and tests.
  var graphFiles = [];
  var graphPaths = [];
  for (var system in ChromeConfig.systemTitles) {
    for (var testName in ChromeConfig.testTitles) {
      var path = '../' + system + '/' + testName;
      graphFiles.push(path + '/' + 'graphs.dat');
      var p = {
        path: path,
        testName: testName,
        machine: ChromeConfig.systemTitles[system],
      }
      graphPaths.push(p);
    }
  }
  new FetchList(graphFiles, onGraphListReceived, graphPaths);
}

/**
 * Fetch all *-summary.dat.
 */
function onGraphListReceived(data, graphPaths) {
  // Select graph from graph list.
  var summaryFiles = [];
  for (var i = 0; i < data.length; i++) {
    var graphList = JsonToJs(data[i]);
    if (graphList) {
      for (var j = 0; j < graphList.length; j++) {
        if (graphList[j].important) {
          var gList = graphList[j];
          summaryFiles.push(graphPaths[i].path + '/' + graphList[j].name +
                            '-summary.dat');
          var row = {
            machine: graphPaths[i].machine,
            units: graphList[j].units,
            testName: graphPaths[i].testName,
            graphName: graphList[j].graphName,
          }
          allRowData.push(row);
          break;
        }
      }
    }
  }
  new FetchList(summaryFiles, onGraphDataReceived);
}

function onGraphDataReceived(data) {
  // Parse the summary data file.
  for (var i = 0; i < data.length; i++) {
    if (data[i]) {
      var rows = new Rows(data[i]);
      allRowData[i].rows = rows;
    }
  }
  isDataFetched = true;
  plot();
}

/**
 * Order data and add charts.
 */
function plot() {
  // Order row data by test names and machine names.
  var graphData = {};
  var foundVersions = {};
  for (var i = 0; i < allRowData.length; i++) {
    var rowData = allRowData[i];
    var rows = rowData.rows;
    if (!rows)
      continue;
    for (var j = 0; j < rows.length; j++) {
      var row = rows.get(j);
      if (!row)
        continue;
      if (row.version in versions) {
        foundVersions[row.version] = 1;
        var traces = row['traces'];
        if (!graphData[rowData.testName])
          graphData[rowData.testName] = {};
        if (!graphData[rowData.testName][rowData.machine]) {
          var data = {
            traceList: [traces],
            versions: [row.version],
            units: rowData.units,
          }
          graphData[rowData.testName][rowData.machine] = data;
        } else {
          var data = graphData[rowData.testName][rowData.machine];
          data.traceList.push(traces);
          data.versions.push(row.version);
        }
      }
    }
  }

  // Prepare traces for plotting.
  for (var testName in graphData) {
    var dataByMachine = graphData[testName];
    for (var machine in dataByMachine) {
      var data = dataByMachine[machine];
      var traceNames = {};
      for (var i = 0; i < data.traceList.length; i++) {
        for (var traceName in data.traceList[i]) {
          traceNames[traceName] = 1;
        }
      }

      var traceNameList = [];
      for (var traceName in traceNames)
        traceNameList.push(traceName);

      var traces = [];
      for (var i = 0; i < data.traceList.length; i++) {
        trace = [data.versions[i]];
        for (var traceName in traceNames) {
          if (data.traceList[i][traceName])
            trace.push(parseFloat(data.traceList[i][traceName][0]));
          else
            trace.push(0);
        }
        traces.push(trace);
      }
      data.traces = traces;
      data.traceNames = traceNameList;
    }
  }

  var versionExist = false;
  for (version in versions) {
    if (version) {
      if (!(version in foundVersions))
        reportError('No data for: ' + version);
      else
        versionExist = true;
    }
  }
  if (!versionExist)
    return;

  var output = document.getElementById('output');
  var htmlTable = new HTMLTable(output);

  // Add machine titles.
  var machineNames = [];
  for (var system in ChromeConfig.systemTitles) {
    htmlTable.addHeader(ChromeConfig.systemTitles[system]);
    machineNames.push(ChromeConfig.systemTitles[system]);
  }

  // Plot graph for each test and machine.
  for (var testName in graphData) {
    var dataByMachine = graphData[testName];
    htmlTable.addRow();

    for (var i = 0; i < machineNames.length; i++) {
      var data = dataByMachine[machineNames[i]];
      if (data) {
        var dataTable = new google.visualization.DataTable();
        dataTable.addColumn('string', 'Version');

        for (var j = 0; j < data.traceNames.length; j++)
          dataTable.addColumn('number', data.traceNames[j]);
        dataTable.addRows(data.traces);

        var options = {
          width: 400, height: 240,
          title: ChromeConfig.testTitles[testName],
          vAxis: {title: data.units, titleTextStyle: {color: 'red'}},
          colors:['#0000FF','#E69F00'],
        };

        var charDiv = document.createElement('div');
        htmlTable.addElement(charDiv);
        var chart = new google.visualization.ColumnChart(charDiv);
        chart.draw(dataTable, options);
      } else {
        var charDiv = document.createElement('div');
        htmlTable.addElement(charDiv);
      }
    }
  }
}

/**
 * Class for creating HTML table.
 * @constructor
 */
function HTMLTable(div) {
  this.div_ = div;
  this.table_ = document.createElement('table');
  this.div_.appendChild(this.table_);
  this.tr_ = null;
  this.headerTr_ = null;
}

HTMLTable.prototype.addHeader = function(title) {
  if (!this.headerTr_) {
    this.headerTr_ = document.createElement('tr');
    this.table_.appendChild(this.headerTr_);
  }
  var th = document.createElement('th');
  this.headerTr_.appendChild(th);
  th.innerHTML = title;
}

HTMLTable.prototype.addRow = function() {
  this.tr_ = document.createElement('tr');
  this.table_.appendChild(this.tr_);
}

HTMLTable.prototype.addElement = function(div) {
  var td = document.createElement('td');
  this.tr_.appendChild(td);
  td.appendChild(div);
}

function JsonToJs(data) {
  return eval('(' + data + ')');
}

function cleanId(str) {
 return str.replace(/\s/g, '_').toLowerCase();
}

function clearDiv(id) {
  var div = document.getElementById(id);
  while (div.hasChildNodes()) {
     div.removeChild(div.lastChild);
  }
}

function reportError(error) {
  document.getElementById('log').innerHTML = '<p>' + error + '</p>';
}

/**
 * Encapsulates a *-summary.dat file.
 * @constructor
 */
function Rows(data) {
  this.rows_ = (data) ? data.split('\n') : [];
  this.length = this.rows_.length;
}

/**
 * Returns the row at the given index.
 */
Rows.prototype.get = function(i) {
  if (!this.rows_[i].length) return null;
  var row = JsonToJs(this.rows_[i]);
  row.revision = isNaN(row['rev']) ? row['rev'] : parseInt(row['rev']);
  row.version = row['ver'];
  return row;
};
</script>
</head>
<body>
  <br />
  <center>
    <h2>Chrome Perf</h2>
  </center>
  <p><b>Build versions: </b><br/>
  <label for="direction">Enter version numbers with comma delimiter.</label>
  <br/>
  <textarea cols="40" rows="5" id="versions"></textarea>
  <p><button value="Plot" onClick="setVersion()">Plot</button></p>
  <pre id="log"></pre>
  <div id="output"></div>
</body>
</html>
