• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE HTML>
2
3<html id="t">
4  <head>
5    <title>About Stats</title>
6
7<style>
8body {
9  border-top: 10px solid #3B85E3;
10  color: #333;
11  font-family: Verdana, Helvetica, Arial, sans-serif;
12}
13body, td {
14  font-size: 11px;
15}
16a:link, a:visited {
17  color: #2C3EBA;
18  text-decoration: none;
19}
20a:hover {
21  color: red;
22  text-decoration: underline;
23}
24h1 {
25  border-left: 10px solid #FFF;
26  font-size: 16px;
27  font-weight: bold;
28  margin: 0;
29  padding: 0.2em;
30  color: #3B85E3;
31}
32h2 {
33  border-left: 10px solid #FFF;
34  font-size: 11px;
35  font-weight: normal;
36  margin: 0;
37  padding: 0 6em 0.2em 0.2em;
38}
39.details {
40  margin: 0.4em 1.9em 0 1.2em;
41  padding: 0 0.4em 0.3em 0;
42  white-space: nowrap;
43}
44.details .outer {
45  padding-right: 0;
46  vertical-align: top;
47}
48.details .top {
49  border-top: 2px solid #333;
50  font-weight: bold;
51  margin-top: 0.4em;
52}
53.details .header2 {
54  font-weight: bold;
55  padding-left: 0.9em;
56}
57.details .key {
58  padding-left: 1.1em;
59  vertical-align: top;
60}
61.details .value {
62  text-align: right;
63  color: #333;
64  font-weight: bold;
65}
66.details .zebra {
67  background: #EEE;
68}
69.lower {
70  text-transform: lowercase;
71}
72</style>
73<script>
74
75/* Counter accessor for Name Node. */
76function getCounterNameFromCounterNode(node) {
77  return node.childNodes[1];
78}
79
80/* Counter accessor for Value Node. */
81function getCounterValueFromCounterNode(node) {
82  return node.childNodes[3];
83}
84
85/* Counter accessor for Delta Node. */
86function getCounterDeltaFromCounterNode(node) {
87  return node.childNodes[5];
88}
89
90/* Timer accessor for Name Node. */
91function getTimerNameFromTimerNode(node) {
92  return node.childNodes[1];
93}
94
95/* Timer accessor for Value Node. */
96function getTimerValueFromTimerNode(node) {
97  return node.childNodes[3];
98}
99
100/* Timer accessor for Time Node. */
101function getTimerTimeFromTimerNode(node) {
102  return node.childNodes[5];
103}
104
105/* Timer accessor for Average Time Node. */
106function getTimerAvgTimeFromTimerNode(node) {
107  return node.childNodes[7];
108}
109
110/* Do the filter work.  Hide all nodes matching node.*/
111function filterMatching(text, nodelist, functionToGetNameNode) {
112  var showAll = text.length == 0;
113  for (var i = 0, node; node = nodelist[i]; i++) {
114    var name = functionToGetNameNode(node).innerHTML.toLowerCase();
115    if (showAll || name.indexOf(text) >= 0) {
116      node.style.display = "table-row";
117    } else {
118      node.style.display = "none";
119    }
120  }
121}
122
123/* Hides or shows counters based on the user's current filter selection. */
124function doFilter() {
125  var filter = document.getElementById("filter");
126  var text = filter.value.toLowerCase();
127  var nodes = document.getElementsByName("counter");
128  filterMatching(text, nodes, getCounterNameFromCounterNode);
129  var nodes = document.getElementsByName("timer");
130  filterMatching(text, nodes, getTimerNameFromTimerNode);
131}
132
133/* Colors the counters based on increasing or decreasing value. */
134function doColor() {
135  var nodes = document.getElementsByName("counter");
136  for (var i = 0, node; node = nodes[i]; i++) {
137    var child = getCounterDeltaFromCounterNode(node);
138    var delta = child.innerHTML;
139    if (delta > 0) {
140      child.style.color = "Green";
141    } else if (delta == 0) {
142      child.style.color = "Black";
143    } else {
144      child.style.color = "Red";
145    }
146  }
147}
148
149/* Counters with no values are null. Remove them. */
150function removeNullValues() {
151  var nodes = document.getElementsByName("counter");
152  for (var i = nodes.length - 1; i >= 0; i--) {
153    var node = nodes[i];
154    var value = getCounterValueFromCounterNode(node).innerHTML;
155    if (value == "null") {
156      node.parentNode.removeChild(node);
157    }
158  }
159  var nodes = document.getElementsByName("timer");
160  for (var i = 0, node; node = nodes[i]; i++) {
161    var value_node = getTimerValueFromTimerNode(node);
162    if (value_node.innerHTML == "null") {
163      value_node.innerHTML = "";
164    }
165  }
166}
167
168/* Compute the average time for timers */
169function computeTimes() {
170  var nodes = document.getElementsByName("timer");
171  for (var i = 0, node; node = nodes[i]; i++) {
172    var count = getTimerValueFromTimerNode(node).innerHTML;
173    if (count.length > 0) {
174      var time = getTimerTimeFromTimerNode(node).innerHTML;
175      var avg = getTimerAvgTimeFromTimerNode(node);
176      avg.innerHTML = Math.round(time / count * 100) / 100;
177    }
178  }
179}
180
181/* All the work we do onload. */
182function onLoadWork() {
183  doColor();
184  removeNullValues();
185  computeTimes();
186  document.getElementById("filter").focus();
187}
188
189// The function should only be used as the event handler
190// on a table cell element. To use it, put it in a <td> element:
191//  <td onclick="sort('string')" ...>
192//
193// The function sorts rows after the row with onclick event handler.
194//
195// type: the data type, 'string', 'number'
196function sort_table(type){
197  var cell = event.target;
198  var cnum = cell.cellIndex;
199
200  var row = cell.parentNode;
201  var start_index = row.rowIndex + 1;
202
203  var tbody = row.parentNode;
204  var table = tbody.parentNode;
205
206  var rows = new Array();
207
208  var indexes = new Array();
209  // skip the first row
210  for (var i = start_index; i < table.rows.length; i++)
211    rows.push(table.rows[i]);
212
213  // a, b are strings
214  function compare_strings(a,b) {
215    if (a == b) return 0;
216    if (a < b) return -1;
217    return 1;
218  }
219
220  // a, b are numbers
221  function compare_numbers(a,b) {
222    var x = isNaN(a) ? 0 : a;
223    var y = isNaN(b) ? 0 : b;
224    return x - y;
225  }
226
227  var sort_func = undefined;
228  if (type === 'string') {
229    sort_func = function(a, b) {
230      var x = a.cells[cnum].innerText;
231      var y = b.cells[cnum].innerText;
232      return compare_strings(x, y);
233    } ;
234
235  } else if (type === 'number') {
236    sort_func = function(a, b) {
237      var x = parseFloat(a.cells[cnum].innerText);
238      var y = parseFloat(b.cells[cnum].innerText);
239      return compare_numbers(x, y);
240    }
241  }
242
243  rows.sort(sort_func);
244
245  // change tables
246  if (cell._reverse) {
247    for (var i = rows.length - 1; i >= 0; i--)
248      tbody.appendChild(rows[i]);
249    cell._reverse = false;
250  } else {
251    for (var i = 0; i < rows.length; i++)
252      tbody.appendChild(rows[i]);
253    cell._reverse = true;
254  }
255}
256
257</script>
258</head>
259<body onload="onLoadWork()">
260  <div style="float: right">
261    <br>Filter: <input id="filter" type="text" value="" onkeyup="doFilter()">
262  </div>
263  <h1 class="lower">About Stats</h1>
264  <h2>Shhh!  This page is secret!</h2><br/>
265  <table class="details" cellspacing="0" cellpadding="0" border="0">
266    <tbody>
267      <tr>
268        <td class="outer">
269          <table cellspacing="0" cellpadding="0" border="0">
270            <tbody>
271              <tr>
272                <td class="top" width="100">Counters</td>
273                <td class="top value" colspan=2></td>
274              </tr>
275              <tr>
276                <td class="header2 lower" width="200" onclick="sort_table('string')">name</td>
277                <td class="header2 lower" onclick="sort_table('number')">value</td>
278                <td class="header2 lower" onclick="sort_table('number')">delta</td>
279              </tr>
280              <tr jsselect="counters" name="counter">
281                <td class="key" width="200" jscontent="name"></td>
282                <td class="value" jscontent="value"></td>
283                <td class="value" jscontent="delta"></td>
284              </tr>
285            </tbody>
286          </table>
287        </td>
288        <td width="15"/>
289        <td class="outer">
290          <table cellspacing="0" cellpadding="0" border="0">
291            <tbody>
292              <tr>
293                <td class="top" width="100">Timers</td>
294                <td class="top value"></td>
295                <td class="top value" colspan=3></td>
296              </tr>
297              <tr>
298                <td class="header2 lower" width="200" onclick="sort_table('string')">name</td>
299                <td class="header2 lower" onclick="sort_table('number')">count</td>
300                <td class="header2 lower" onclick="sort_table('number')">time (ms)</td>
301                <td class="header2 lower" onclick="sort_table('number')">avg time (ms)</td>
302              </tr>
303              <tr jsselect="timers" name="timer">
304                <td class="key" width="200" jscontent="name"></td>
305                <td class="value" jscontent="value"></td>
306                <td class="value" jscontent="time"></td>
307                <td class="value"></td>
308              </tr>
309            </tbody>
310          </table>
311        </td>
312      </tr>
313    </tbody>
314  </table><br/>
315</body>
316</html>
317