Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Unified Diff: perf/dashboard/ui/js/graph.js

Issue 1654813003: Remove old dead perf dashboard pages and js (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « perf/dashboard/ui/js/coordinates.js ('k') | perf/dashboard/ui/js/plotter.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: perf/dashboard/ui/js/graph.js
===================================================================
--- perf/dashboard/ui/js/graph.js (revision 298504)
+++ perf/dashboard/ui/js/graph.js (working copy)
@@ -1,645 +0,0 @@
-/*
- 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.
-*/
-
-/*
- Fetch all graph data files, prepare the data, and create Plotter() to
- generate a graph.
-
- To use:
- var graph = new Graph('output_div', graphList)
- graph.setTitle('Title');
- graph.graph();
-*/
-
-function JsonToJs(data) {
- return eval('(' + data + ')');
-}
-
-/**
- * Insert element a after element b.
- */
-function AppendChild(a, b) {
- var elementA = (typeof(a) == 'object') ? a : document.getElementById(a);
- var elementB = (typeof(b) == 'object') ? b : document.getElementById(b);
- elementB.appendChild(elementA);
-}
-
-/**
- * Insert element a before element b.
- */
-function InsertBefore(a, b) {
- var elementA = (typeof(a) == 'object') ? a : document.getElementById(a);
- var elementB = (typeof(b) == 'object') ? b : document.getElementById(b);
- elementB.insertBefore(elementA);
-}
-
-
-/**
- * Graph class.
- * @constructor
- *
- * Fetch each graph in |graphList| and create Plotter(). Create Graph()
- * and call graph() to display graph.
- *
- * @param div {String|DOMElement} The container that the graph should be
- * rendered to.
- * @param graphList {Array} List of graphs to be plotted.
- * @param options {Object} Options to configure graph.
- * - width {int} Width of graph.
- * - height {int} Height of graph.
- * - history {int} Number of row to show.
- * - showDetail {Boolean} Specifies whether or not to display detail.
- * Default false.
- * - showTabs {Boolean} Specifies whether or not to show tabs.
- * Default false.
- * - enableMouseScroll {Boolean} Specifies whether or not to enable
- * mouse wheel zooming. Default false.
- * - channels {Array} Display graph by channels.
- * - orderDataByVersion {Boolean} Order plot data by version number.
- * Default false.
- *
- * Example of the graphList:
- * [
- * {"units": "ms", "important": false, "name": "SunSpider-individual",
- * "SunSpider-individual-summary.dat"},
- * ]
- */
-function Graph(div, graphList, opt_options) {
- this.graphList_ = graphList;
- this.options_ = (opt_options) ? opt_options : {};
- this.history_ = (this.options_.history) ? this.options_.history : 150;
- this.rev_ = (this.options_.rev) ? this.options_.rev : -1;
- this.channels_ = (this.options_.channels) ? this.options_.channels : [];
- this.firstTrace_ = '';
- this.rows_ = [];
- this.isDetailViewAdded_ = false;
- this.selectedGraph_ = null;
- this.plotterDiv_ = null;
- this.tabs_ = [];
- this.width = this.options_.width;
- this.height = this.options_.height;
-
- this.graphContainer = document.createElement('div');
- this.graphContainer.setAttribute(
- 'style', 'display: block; overflow: hidden; ' +
- 'margin: 5px; padding: 5px; width:' + this.width);
- AppendChild(this.graphContainer, div);
-
- this.title = document.createElement('div');
- this.title.setAttribute('style', 'text-align: center');
- AppendChild(this.title, this.graphContainer);
-}
-
-/**
- * Start fetching graph data.
- */
-Graph.prototype.graph = function() {
- this.fetchSummary_();
-
- if (this.options_.showTabs)
- this.addTabs_();
-}
-
-/**
- * Set graph title.
- */
-Graph.prototype.setTitle = function(title) {
- this.title.innerHTML = title;
-}
-
-/**
- * Display tabs for each graph.
- */
-Graph.prototype.addTabs_ = function() {
- this.tabs_ = [];
- var tabPane = document.createElement('div');
- tabPane.setAttribute('class', 'switcher');
- AppendChild(tabPane, this.graphContainer);
-
- var graphNames = []
- var inserted = {};
- for (var i = 0; i < this.graphList_.length; i++) {
- if (!inserted[this.graphList_[i].name]) {
- graphNames.push(this.graphList_[i].name);
- inserted[this.graphList_[i].name] = 1;
- }
- }
-
- var obj = this;
- for (var i = 0; i < graphNames.length; i++) {
- var name = graphNames[i];
- var tab = document.createElement('span');
- if (name != this.selectedGraph_.name) {
- tab.setAttribute('class', 'select');
- }
- tab.addEventListener(
- "click",
- (function(){
- var cur = name; return function() {obj.switchGraph_(cur)}
- })(),
- false);
- tab.appendChild(document.createTextNode(name + " "));
- AppendChild(tab, tabPane);
- this.tabs_.push(tab);
- }
-}
-
-/**
- * Fetch graph summary data files.
- */
-Graph.prototype.fetchSummary_ = function() {
- this.rows_ = [];
- if (!this.selectedGraph_) {
- this.selectedGraph_ = this.graphList_[0];
- }
- var graphFiles = [];
- this.selectedGraphList_ = [];
- for (var i = 0; i < this.graphList_.length; i++) {
- if (this.graphList_[i].name == this.selectedGraph_.name) {
- graphFiles.push(this.graphList_[i].loc);
- this.selectedGraphList_.push(this.graphList_[i]);
- }
- }
- var obj = this;
- new FetchList(graphFiles, function(data) {obj.onSummaryReceived_(data)});
-}
-
-/**
- * Call addPlot_ once all graph summary data are received.
- */
-Graph.prototype.onSummaryReceived_ = function(data) {
- // Parse the summary data file.
- for (var i = 0; i < data.length; i++) {
- if (data[i]) {
- var rows = new Rows(data[i]);
- this.rows_[i] = rows;
- }
- }
- this.addPlot_();
-}
-
-/**
- * Merge all data rows by channel and version. This is use in platform
- * comparison graph.
- *
- * Example:
- * Two rows:
- * {"traces": {"score": ["777", "0.0"]}, "rev": "9",
- * "ver": "17.1.963.19", "chan": "stable"}
- * {"traces": {"score": ["888", "0.0"]}, "rev": "10",
- * "ver": "17.1.963.19", "chan": "stable"}
- * Become:
- * {"traces": {"score_windows": ["777", "0.0"],
- * "score_linux": ["888", "0.0"]},
- * "rev": "9", "ver": "17.1.963.19", "chan": "stable"}
- *
- * @return {Array} Array of rows.
- */
-Graph.prototype.getMergedRowsByVersion_ = function() {
- var channels = {};
- for (var i = 0; i < this.channels_.length; i++)
- channels[this.channels_[i]] = 1;
- var allRows = [];
- // Combind all rows to one list.
- for (var i = 0; i < this.rows_.length; i++) {
- if (this.rows_[i]) {
- for (var j = 0; j < this.rows_[i].length; j++) {
- var row = this.rows_[i].get(j);
- if (row && row.chan in channels) {
- row.machine = this.selectedGraphList_[i].machine;
- allRows.push(row);
- }
- }
- }
- }
-
- // Sort by version number.
- allRows.sort(
- function(a, b) {
- var a_arr = a.version.split('.');
- var b_arr = b.version.split('.');
- var len = Math.min(b_arr.length, b_arr.length);
- for (var i = 0; i < len; i++) {
- if (parseInt(a_arr[i], 10) > parseInt(b_arr[i], 10))
- return 1;
- else if (parseInt(a_arr[i], 10) < parseInt(b_arr[i], 10))
- return -1;
- }
- return a_arr.length - b_arr.length;
- });
-
- // Merge all rows by version number.
- var combindedRows = [];
- var index = 0;
- while (index < allRows.length) {
- var currentRow = allRows[index];
- var traces = currentRow['traces'];
- for (var traceName in traces) {
- var traceRenamed = traceName + '_' + currentRow.machine.toLowerCase();
- traces[traceRenamed] = traces[traceName];
- delete(traces[traceName]);
- }
- while (index < allRows.length - 1 &&
- allRows[index + 1].version == currentRow.version) {
- var row = allRows[index + 1];
- var traces = row['traces'];
- for (var traceName in traces) {
- var traceRenamed = traceName + '_' + row.machine.toLowerCase();
- currentRow['traces'][traceRenamed] = traces[traceName];
- }
- index++;
- }
- combindedRows.push(currentRow);
- index++;
- }
- return combindedRows;
-}
-
-/**
- * Merge all channel data by their index in file. This is use in channel
- * comparison graph.
- *
- * @return {Array} Array of rows.
- */
-Graph.prototype.getMergedRowByIndex_ = function() {
- var rowByChannel = {};
- for (var i = 0; i < this.channels_.length; i++)
- rowByChannel[this.channels_[i]] = [];
-
- // Order by channel.
- for (var i = 0; i < this.rows_.length; i++) {
- if (this.rows_[i]) {
- for (var j = 0; j < this.rows_[i].length; j++) {
- var row = this.rows_[i].get(j);
- if (row && row.chan in rowByChannel) {
- rowByChannel[row.chan].push(row);
- }
- }
- }
- }
-
- var max = 0;
- for (var channel in rowByChannel)
- max = Math.max(rowByChannel[channel].length, max);
-
- // Merge data.
- var combindedRows = [];
- for (var i = 0; i < max; i++) {
- var currentRow = null;
- for (var channel in rowByChannel) {
- if (rowByChannel[channel].length > i) {
- var row = rowByChannel[channel][i];
- var traces = row['traces'];
- for (var traceName in traces) {
- traces[traceName + '_' + channel] = traces[traceName];
- delete(traces[traceName]);
- }
- if (!currentRow) {
- currentRow = row;
- } else {
- for (var traceName in traces)
- currentRow['traces'][traceName] = traces[traceName];
- currentRow.version += ', ' + row.version;
- }
- }
- }
- combindedRows.push(currentRow);
- }
- return combindedRows;
-}
-
-/**
- * Get rows for a specific channel.
- *
- * @return {Array} Array of rows.
- */
-Graph.prototype.getRowByChannel_ = function() {
- // Combind channel data.
- var rows = [];
- for (var i = 0; i < this.rows_.length; i++) {
- if (this.rows_[i]) {
- for (var j = 0; j < this.rows_[i].length; j++) {
- var row = this.rows_[i].get(j);
- if (row && row.chan == this.channels_[0])
- rows.push(row);
- }
- }
- }
- return rows;
-}
-
-/**
- * Prepare the data and create Plotter() to generate a graph.
- */
-Graph.prototype.addPlot_ = function() {
- var rows = [];
- if (this.options_.orderDataByVersion)
- rows = this.getMergedRowsByVersion_();
- else if (this.channels_.length > 1)
- rows = this.getMergedRowByIndex_();
- else
- rows = this.getRowByChannel_();
-
- var maxRows = rows.length;
- if (maxRows > this.history_)
- maxRows = this.history_;
-
- // Find the start and end of the data slice we will focus on.
- var startRow = 0;
- if (this.rev_ > 0) {
- var i = 0;
- while (i < rows.length) {
- var row = rows[i];
- // If the current row's revision is higher than the desired revision,
- // continue searching.
- if (row.revision > this.rev_) {
- i++;
- continue;
- }
- // We're either just under or at the desired revision.
- startRow = i;
- // If the desired revision does not exist, use the row before it.
- if (row.revision < this.rev_ && startRow > 0)
- startRow -= 1;
- break;
- }
- }
-
- // Some summary files contain data not listed in rev-descending order. For
- // those cases, it is possible we will find a start row in the middle of the
- // data whose neighboring data is not nearby. See xp-release-dual-core
- // moz rev 265 => no graph.
- var endRow = startRow + maxRows;
-
- // Build and order a list of revision numbers.
- var allTraces = {};
- var revisionNumbers = [];
- var versionMap = {};
- var hasNumericRevisions = true;
- // graphData[rev] = {trace1:[value, stddev], trace2:[value, stddev], ...}
- var graphData = {};
- for (var i = startRow; i < endRow; ++i) {
- var row = rows[i];
- if (!row)
- continue;
- var traces = row['traces'];
- for (var j = 0; j < traces.length; ++j)
- traces[j] = parseFloat(traces[j]);
-
- graphData[row.revision] = traces;
- if (isNaN(row.revision)) {
- hasNumericRevisions = false;
- }
- revisionNumbers.push(row.revision);
-
- versionMap[row.revision] = row.version;
-
- // Collect unique trace names. If traces are explicitly specified in
- // params, delete unspecified trace data.
- for (var traceName in traces) {
- if (typeof(params['trace']) != 'undefined' &&
- params['trace'][traceName] != 1) {
- delete(traces[traceName]);
- }
- allTraces[traceName] = 1;
- }
- }
-
- // Build a list of all the trace names we've seen, in the order in which
- // they appear in the data file. Although JS objects are not required by
- // the spec to iterate their properties in order, in practice they do,
- // because it causes compatibility problems otherwise.
- var traceNames = [];
- for (var traceName in allTraces)
- traceNames.push(traceName);
- this.firstTrace_ = traceNames[0];
-
- // If the revisions are numeric (svn), sort them numerically to ensure they
- // are in ascending order. Otherwise, if the revisions aren't numeric (git),
- // reverse them under the assumption the rows were prepended to the file.
- if (hasNumericRevisions) {
- revisionNumbers.sort(
- function(a, b) { return parseInt(a, 10) - parseInt(b, 10) });
- } else {
- revisionNumbers.reverse();
- }
-
- // Build separate ordered lists of trace data.
- var traceData = {};
- var versionList = [];
- for (var revIndex = 0; revIndex < revisionNumbers.length; ++revIndex) {
- var rev = revisionNumbers[revIndex];
- var revisionData = graphData[rev];
- for (var nameIndex = 0; nameIndex < traceNames.length; ++nameIndex) {
- var traceName = traceNames[nameIndex];
- if (!traceData[traceName])
- traceData[traceName] = [];
- if (!revisionData[traceName])
- traceData[traceName].push([NaN, NaN]);
- else
- traceData[traceName].push([parseFloat(revisionData[traceName][0]),
- parseFloat(revisionData[traceName][1])]);
- }
- versionList.push(versionMap[rev]);
- }
-
- var plotData = [];
- for (var traceName in traceData)
- plotData.push(traceData[traceName]);
-
- var plotterDiv = document.createElement('div');
- if (!this.plotterDiv_)
- AppendChild(plotterDiv, this.graphContainer)
- else
- this.graphContainer.replaceChild(plotterDiv, this.plotterDiv_);
- this.plotterDiv_ = plotterDiv;
-
- var plotter = new Plotter(
- versionList, plotData, traceNames, this.selectedGraph_.units,
- this.plotterDiv_, this.width, this.height);
-
- var obj = this;
- plotter.onclick = function(){obj.onPlotClicked.apply(obj, arguments)};
- plotter.enableMouseScroll = this.options_.enableMouseScroll;
- plotter.plot();
-}
-
-/**
- * Handle switching graph when tab is clicked.
- */
-Graph.prototype.switchGraph_ = function(graphName) {
- if (graphName == this.selectedGraph_.name)
- return;
-
- for (var i = 0; i < this.tabs_.length; i++) {
- var name = this.tabs_[i].innerHTML;
- if (graphName + ' ' == name) {
- this.tabs_[i].removeAttribute('class');
- } else {
- this.tabs_[i].setAttribute('class', 'select');
- }
- }
-
- for (var i = 0; i < this.graphList_.length; i++) {
- if (this.graphList_[i].name == graphName) {
- this.selectedGraph_ = this.graphList_[i];
- break;
- }
- }
-
- this.fetchSummary_();
-}
-
-/**
- * On plot clicked, display detail view.
- */
-Graph.prototype.onPlotClicked = function(prev_cl, cl) {
- if (!this.options_.showDetail)
- return;
- this.addDetailView_();
-
- var getChildByName = function(div, name) {
- var children = div.childNodes;
- for (var i = 0; i < children.length; i++)
- if (children[i].getAttribute('name') == name)
- return children[i];
- }
- // Define sources for detail tabs
- if ('view-change' in Config.detailTabs) {
- // If the changeLinkPrefix has {PREV_CL}/{CL} markers, replace them.
- // Otherwise, append to the URL.
- var url = Config.changeLinkPrefix;
- if (url.indexOf('{PREV_CL}') >= 0 || url.indexOf('{CL}') >= 0) {
- url = url.replace('{PREV_CL}', prev_cl);
- url = url.replace('{CL}', cl);
- } else {
- url += prev_cl + ':' + cl;
- }
- getChildByName(this.detailPane, 'view-change').setAttribute('src', url);
- }
-
- if ('view-pages' in Config.detailTabs) {
- getChildByName(this.detailPane, 'view-pages').
- setAttribute('src', 'details.html?cl=' + cl +
- '&graph=' + this.milestone + '-' + this.selectedGraph_.name +
- '&trace=' + this.firstTrace_);
- }
- if ('view-coverage' in Config.detailTabs) {
- getChildByName(this.detailPane, 'view-coverage').setAttribute(
- 'src',Config.coverageLinkPrefix + cl);
- }
-
- if (!this.didPositionDetail) {
- this.positionDetails_();
- this.didPositionDetail = true;
- }
-}
-
-/**
- * Display detail view.
- */
-Graph.prototype.addDetailView_ = function() {
- if (this.isDetailViewAdded_)
- return;
- this.isDetailViewAdded_ = true;
- // Add detail page.
- this.detailPane = document.createElement('div');
- AppendChild(this.detailPane, this.graphContainer);
-
- for (var tab in Config.detailTabs) {
- var detail = document.createElement('iframe');
- detail.setAttribute('class', 'detail');
- detail.setAttribute('name', tab);
- AppendChild(detail, this.detailPane);
- }
-
- this.selectorPane = document.createElement('div');
- this.selectorPane.setAttribute('class', 'selectors');
- this.selectorPane.setAttribute(
- 'style', 'display: block; 1px solid black; position: absolute;');
- AppendChild(this.selectorPane, this.graphContainer);
-
- var firstTab = true;
- for (var tab in Config.detailTabs) {
- var selector = document.createElement('div');
- selector.setAttribute('class', 'selector');
- var obj = this;
- selector.onclick = (
- function(){
- var cur = tab; return function() {obj.changeDetailTab(cur)}})();
- if (firstTab)
- firstTab = false;
- else
- selector.setAttribute('style', 'border-top: none');
- selector.innerHTML = Config.detailTabs[tab];
- AppendChild(selector, this.selectorPane);
- }
-}
-
-Graph.prototype.positionDetails_ = function() {
- var win_height = window.innerHeight;
-
- var views_width = this.graphContainer.offsetWidth -
- this.selectorPane.offsetWidth;
-
- this.detailPane.style.width = views_width + "px";
- this.detailPane.style.height = (
- win_height - this.graphContainer.offsetHeight -
- this.graphContainer.offsetTop - 30) + "px";
-
- this.selectorPane.style.left = (
- this.detailPane.offsetLeft + views_width + 1) + "px";
- this.selectorPane.style.top = this.detailPane.offsetTop + "px";
-
- // Change to the first detail tab
- for (var tab in Config.detailTabs) {
- this.changeDetailTab_(tab);
- break;
- }
-}
-
-Graph.prototype.changeDetailTab_ = function(target) {
- var detailArr = this.detailPane.getElementsByTagName('iframe');
- var i = 0;
- for (var tab in Config.detailTabs) {
- detailArr[i++].style.display = (tab == target ? 'block' : 'none');
- }
-}
-
-Graph.prototype.goTo = function(graph) {
- params.graph = graph;
- if (params.graph == '')
- delete params.graph;
- window.location.href = MakeURL(params);
-}
-
-Graph.prototype.getURL = function() {
- new_url = window.location.href;
- new_url = new_url.replace(/50/, "150");
- new_url = new_url.replace(/\&lookout=1/, "");
- return new_url;
-}
-
-
-/**
- * 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;
-};
« no previous file with comments | « perf/dashboard/ui/js/coordinates.js ('k') | perf/dashboard/ui/js/plotter.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698