1 <!DOCTYPE html> 2 <!-- 3 * Copyright (c) 2012 The Chromium Authors. All rights reserved. Use of this 4 * source code is governed by a BSD-style license that can be found in the 5 * LICENSE file. 6 --> 7 <html> 8 <head> 9 <title>Device Stats Monitor</title> 10 <script type="text/javascript" src="http://www.google.com/jsapi"></script> 11 <style> 12 body { 13 font-family: sans-serif 14 } 15 </style> 16 </head> 17 <body> 18 <h2>Device Stats Monitor</h2> 19 <ul> 20 <li>Pass path to trace data via the <code>results</code> querystring param. 21 <li>Combine charts with the <code>combine</code> querystring param (e.g. <code>&combine=sectors_read,sectors_written</code>). 22 <li>Use <code>stacked=true</code> to stack combined charts instead of overlaying (default). 23 </ul> 24 </body> 25 <script> 26 google.load("visualization", "1", {packages:["corechart"]}); 27 28 /** 29 * @returns The querystring param value for |name| or an empty string. 30 */ 31 function getQuerystringParam(name) { 32 name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); 33 var regexS = "[\\?&]" + name + "=([^&#]*)"; 34 var regex = new RegExp(regexS); 35 var results = regex.exec(window.location.search); 36 if (results == null) 37 return ""; 38 else 39 return decodeURIComponent(results[1].replace(/\+/g, " ")); 40 } 41 42 /** 43 * @returns An array of keys in |obj| sorted by value. 44 */ 45 function sortedKeys(obj) { 46 var keys = []; 47 for (var key in obj) { 48 keys.push(key); 49 } 50 keys.sort(); 51 return keys; 52 } 53 54 /** 55 * Removes by value all params from array. 56 */ 57 Array.prototype.remove = function() { 58 var what, a = arguments, l = a.length, ax; 59 while (l && this.length) { 60 what = a[--l]; 61 while ((ax = this.indexOf(what)) != -1) { 62 this.splice(ax, 1); 63 } 64 } 65 return this; 66 } 67 68 /** 69 * Displays a new chart. 70 * 71 * @param {Number} hz Number of sample per second of the data. 72 * @param {String} name Name to display on top of chart. 73 * @param {Number[][]} values Array of value arrays to display. 74 * @param {Boolean} stacked Whether to display values as stacked. 75 */ 76 function displayChart(hz, name, values, units, stacked) { 77 var data = new google.visualization.DataTable(); 78 data.addColumn('number', 'ms'); 79 var names = name.split(','); 80 for (var i = 0; i < names.length; i++) { 81 data.addColumn('number', names[i]); 82 } 83 84 var rows = []; 85 var interval = 1000.0 / hz; 86 for (var i = 0; i < values[0].length; i++) { 87 var row = [i*interval]; 88 for (var j = 0; j < values.length; j++) { 89 row.push(values[j][i]); 90 } 91 rows.push(row); 92 } 93 data.addRows(rows); 94 95 var options = { 96 hAxis: {title: 'ms (' + hz + 'hz)'}, 97 isStacked: stacked, 98 legend: {position: 'top'}, 99 vAxis: {title: units}, 100 }; 101 102 var elem = document.createElement('DIV'); 103 elem.style = 'width:100%;height:500px'; 104 document.body.appendChild(elem); 105 var chart = new google.visualization.AreaChart(elem); 106 chart.draw(data, options); 107 } 108 109 /** 110 * Displays all charts. 111 * 112 * Invoked by the results script. JSONP is used to avoid security 113 * restrictions on XHRs for file:// URLs. 114 */ 115 function display(hz, results, units) { 116 var combine = getQuerystringParam('combine'); 117 var keys = sortedKeys(results); 118 for (var i = 0; i < keys.length; i++) { 119 var key = keys[i]; 120 var name = key; 121 var values = [results[key]]; 122 var unit = units[key]; 123 if (combine.indexOf(key) >= 0) { 124 i--; 125 name = combine; 126 values = []; 127 var combined_keys = combine.split(','); 128 for (var j = 0; j < combined_keys.length; j++) { 129 values.push(results[combined_keys[j]]); 130 keys.remove(combined_keys[j]); 131 } 132 } 133 displayChart(hz, name, values, unit, !!getQuerystringParam('stacked')); 134 } 135 } 136 137 var resultsPath = getQuerystringParam('results'); 138 if (resultsPath) 139 document.write("<script src='" + resultsPath + "'></"+"script>"); 140 else 141 document.write("Please specify results querystring param."); 142 </script> 143 </html> 144