<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.
-->

<!--
  Display all graphs for machines specified in chrome_config.js.
-->

<head>
<title>Chrome Perf Overview</title>
<style type="text/css">
a {
  color: #004277;
  text-decoration: none;
}

/* Containers */
#top {
  text-align: center;
  padding: 10px;
}
#top-left {
  float:left;
}
#top-right {
  float:right;
}
.clear {
   clear: both;
}
.header {
  font-family:Tahoma;
  text-align:left;
  font-size:12px;
  font-weight:bold;
  text-decoration:none;
}
.section-title {
  text-align: center;
  border-bottom: 1px solid #EFEFEF;
  margin: 0px 15px 0px 15px;
  font-size: 11px;
  align: center;
}

/* Graph */
div.plot {
  cursor: pointer;
}
div.switcher * {
  border: 1px solid black;
  border-radius: 4px 4px 0 0;
  padding-left: 0.5em;
  padding-right: 0.5em;
}
div.switcher .select {
  background: #ddd;
  cursor: pointer;
}
canvas.plot {
  border: 1px solid black;
  cursor: pointer;
}
div.plot-coordinates {
  font-family: monospace;
}
iframe.detail {
  display: none;
  width: 100%;
  height: 100%;
  border: none;
}
div.selector {
  border: solid 1px black;
  cursor: pointer;
  padding-left: 0.3em;
  background-color: white;
}
div.selector:hover {
  background-color: rgb(200,200,250);
}
div.selected {
  border-left: none;
}
div.selectors {
  width: 80px;
  display: none;
}
#explain {
  font-size: 0.75em;
  font-style: italic;
  color: rgb(100,100,100);
}

/* Header Tab. */
.header-tab .empty {
  clear: left;
}
.header-tab {
  border-bottom: 1px solid #6B90DA;
  padding-left: 5px;
}
.header-tab ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.header-tab li {
  float: left;
  border: 1px solid #bbb;
  border-bottom-width: 0;
  margin: 0;
}
.header-tab a {
  text-decoration: none;
  display: block;
  background: #eee;
  padding: 0.24em 1em;
  color: #004277;
  text-align: center;
}
.header-tab a:hover {
  background: #ddf;
}
.header-tab  .active {
  border-color: #6B90DA;
}
.header-tab  .active a {
  position: relative;
  top: 1px;
  background: white;
  font-weight: bold;
  color: black;
}
</style>

<script src="chrome_config.js"></script>
<script src="ui/js/common.js"></script>
<script src="ui/js/plotter.js"></script>
<script src="ui/js/coordinates.js"></script>
<script src="ui/js/graph.js"></script>

<script language="javascript">
var params = ParseParams();
var view = (params['view']) ? params['view'] : 'important';

var CHANNELS = ['canary', 'dev', 'beta', 'stable'];

function init() {
  // 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);
}

function onGraphListReceived(data, graphPaths) {
  // Order graphList by machine and test name.
  var graphMap = {};
  var testNames = [];
  for (var i = 0; i < data.length; i++) {
    var graphList = JsonToJs(data[i]);
    if (graphList) {
      if (!(graphPaths[i].machine in graphMap))
        graphMap[graphPaths[i].machine] = {};
      graphMap[graphPaths[i].machine][graphPaths[i].testName] =
          [graphList, graphPaths[i].path];
      if (testNames.indexOf(graphPaths[i].testName) < 0)
        testNames.push(graphPaths[i].testName);
    }
  }

  // Get all important graphs.
  var selectedGraphNames = {};
  for (var machine in graphMap) {
    var graphByTestName = graphMap[machine];
    for (var test in graphByTestName) {
      var gList = graphByTestName[test][0];
      for (var k = 0; k < gList.length; k++) {
        var g = gList[k];
        if (!(g.name in selectedGraphNames)) {
          if (g.important) {
            selectedGraphNames[g.name] = 1;
          }
        }
      }
    }
  }

  if (view == 'channel-comparison') {
    addGraphTable(graphMap, testNames, selectedGraphNames, CHANNELS);
  } else if (view == 'platform-comparison') {
    displayPlatformComparison(graphMap, testNames, selectedGraphNames);
  } else {
    displayImportantGraphs(graphMap, testNames, selectedGraphNames);
  }

}

function displayImportantGraphs(graphMap, testNames, selectedGraphNames) {
  // Add graph for each channels.  For total graph only.
  var output = document.getElementById('output');

  // Add section labels.
  var sectionBelow = document.createElement('p');
  sectionBelow.setAttribute('style', 'text-align: center;');
  output.appendChild(sectionBelow);
  sectionBelow.appendChild(document.createTextNode('[ '));
  for (var i = 0; i < CHANNELS.length; i++) {
    var a = document.createElement('a');
    a.innerHTML = CHANNELS[i];
    a.setAttribute('href', '#' + CHANNELS[i]);
    sectionBelow.appendChild(a);
    if (i < CHANNELS.length - 1)
      sectionBelow.appendChild(document.createTextNode(' | '));
  }
  sectionBelow.appendChild(document.createTextNode(' ]'));

  for (var i = 0; i < CHANNELS.length; i++) {
    var channel = CHANNELS[i];
    // Channel title.
    var channelTitle = document.createElement('div');
    output.appendChild(channelTitle);
    channelTitle.setAttribute('id', channel);
    channelTitle.setAttribute('class', 'section-title');
    channelTitle.innerHTML = '<h2>' + channel + '</h2>';
    addGraphTable(graphMap, testNames, selectedGraphNames, [channel]);
  }
}

function addGraphTable(graphMap, testNames, selectedGraphNames, channels) {
  var output = document.getElementById('output');
  var table = document.createElement('table');
  output.appendChild(table);

  // Add machine titles.
  var trMachineTitle = document.createElement('tr');
  table.appendChild(trMachineTitle);
  trMachineTitle.appendChild(document.createElement('th'));
  for (var system in ChromeConfig.systemTitles) {
    var th = document.createElement('th');
    trMachineTitle.appendChild(th);
    th.innerHTML = '<a href="#" >' + ChromeConfig.systemTitles[system] +
                   '</a>';
  }

  // For each tests.
  for (var j = 0; j < testNames.length; j++) {
    var testName = testNames[j];
    var tr = document.createElement('tr');
    table.appendChild(tr);

    // Add graph title.
    var tdGraphTitle = document.createElement('td');
    tdGraphTitle.setAttribute(
        'style', 'width: 50px; vertical-align:top; padding-top: 80px');
    tr.appendChild(tdGraphTitle);
    tdGraphTitle.innerHTML = ChromeConfig.testTitles[testName];

    // For each machine, add graph.
    for (var machine in graphMap) {
      var toBeGraphedList = [];
      if (testName in graphMap[machine]) {
        var gMap = graphMap[machine][testName];
        var graphList  = gMap[0];
        var graphPath = gMap[1];
        for (var m = 0; m < graphList.length; m++) {
          if (graphList[m].name in selectedGraphNames) {
            graphList[m].loc = graphPath + '/' + graphList[m].name +
                               '-summary.dat';
            toBeGraphedList.push(graphList[m]);
            break;
          }
        }
      }

      var td = document.createElement('td');
      td.setAttribute('style', 'vertical-align:top;');
      var div = document.createElement('div');
      td.appendChild(div);
      tr.appendChild(td);

      if (toBeGraphedList.length > 0) {
        var options = {
          channels: channels,
          width: 250,
          height: 250,
          showDetail: false,
          showTabs: false,
          history: 50,
          enableMouseScroll: false,
        };
        var graph = new Graph(div, toBeGraphedList, options)
        var reportURL = graphPath + '/' + 'report.html?channel=' +
                        channels.join(',') + '&graph=' +
                        toBeGraphedList[0].name;
        graph.onPlotClicked = function(url) {
          return function () {window.open(url)};
        }(reportURL);
        graph.graph();
      } else {
        div.setAttribute(
            'style', 'display: inline-block; width: 250px; height: 250px')
      }
    }
  }
}

function displayPlatformComparison(graphMap, testNames, selectedGraphNames) {
  var output = document.getElementById('output');

  var table = document.createElement('table');
  output.appendChild(table);

  // Add channel titles.
  var trChannelTitle = document.createElement('tr');
  table.appendChild(trChannelTitle);
  trChannelTitle.appendChild(document.createElement('th'));
  for (var i = 0; i < CHANNELS.length; i++) {
    var th = document.createElement('th');
    trChannelTitle.appendChild(th);
    th.innerHTML = '<a href="#" >' + CHANNELS[i] + '</a>';
  }

  var machines = [];
  for (var machine in graphMap)
    machines.push(machine);

  // For each tests.
  for (var j = 0; j < testNames.length; j++) {
    var testName = testNames[j];
    var tr = document.createElement('tr');
    table.appendChild(tr);

    // Add test title.
    var tdGraphTitle = document.createElement('td');
    tdGraphTitle.setAttribute(
        'style', 'width: 50px; vertical-align:top; padding-top: 80px');
    tr.appendChild(tdGraphTitle);
    tdGraphTitle.innerHTML = ChromeConfig.testTitles[testName];

    // For each channel, add graph.
    for (var i = 0; i < CHANNELS.length; i++) {
      var channel = CHANNELS[i];
      var toBeGraphedList = [];
      for (var machine in graphMap) {
        if (testName in graphMap[machine]) {
          var gMap = graphMap[machine][testName];
          var graphList  = gMap[0];
          var graphPath = gMap[1];
          for (var m = 0; m < graphList.length; m++) {
            if (graphList[m].name in selectedGraphNames) {
              graphList[m].loc = graphPath + '/' + graphList[m].name +
                                 '-summary.dat';
              graphList[m].machine = cleanId(machine);             
              toBeGraphedList.push(graphList[m]);
              break;
            }
          }
        }
      }

      var td = document.createElement('td');
      td.setAttribute('style', 'vertical-align:top;');
      var div = document.createElement('div');
      td.appendChild(div);
      tr.appendChild(td);

      if (toBeGraphedList.length > 0) {
        var options = {
          channels: [channel],
          width: 250,
          height: 250,
          showDetail: false,
          showTabs: false,
          history: 50,
          enableMouseScroll: false,
          orderDataByVersion: true,
        };
        var graph = new Graph(div, toBeGraphedList, options)
        var reportURL = 'platform-comparison.html?channel=' +
                        channel + '&graph=' + toBeGraphedList[0].name +
                        '&test=' + testNames[j] +
                        '&platforms=' + machines.join(',');
        graph.onPlotClicked = function(url) {
          return function () {window.open(url)};
        }(reportURL);
        graph.graph();
      } else {
        div.setAttribute(
            'style', 'display: inline-block; width: 250px; height: 250px')
      }
    }
  }
}

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

window.addEventListener('load', init, false);
</script>
</head>
<body>
  <div id="top">
    <h2 class="title">
      Chrome Perf:
      <script>
      document.write('<a href="overview-chrome.html'
                     + window.location.search
                     + '">overview</a>');
      </script>
    </h2>
   <div class="clear"></div>
  </div>
  <div class="header-tab" style="margin:0 auto;">
    <ul>
      <script language="javascript">
        var tabs = {
          'important': 'Important Graphs',
          'channel-comparison': 'Channel Comparison',
          'platform-comparison': 'Platform Comparison',
        }
        for (var key in tabs) {
          var selected = (view == key) ? 'class="active"' : '';
          document.write('<li ' + selected +
                         '><a href="overview-chrome.html?view=' + key +
                         '">' + tabs[key] + '</a></li>');
        }
      </script>
    </ul>
    <div class="empty"></div>
  </div>
  <br />
  <div id="output" style="margin:0 auto;"></div>
</body>
</html>
