<!DOCTYPE HTML> <html id="t"> <head> <title>About Stats</title> <style> body { border-top: 10px solid #3B85E3; color: #333; font-family: Verdana, Helvetica, Arial, sans-serif; } body, td { font-size: 11px; } a:link, a:visited { color: #2C3EBA; text-decoration: none; } a:hover { color: red; text-decoration: underline; } h1 { border-left: 10px solid #FFF; font-size: 16px; font-weight: bold; margin: 0; padding: 0.2em; color: #3B85E3; } h2 { border-left: 10px solid #FFF; font-size: 11px; font-weight: normal; margin: 0; padding: 0 6em 0.2em 0.2em; } .details { margin: 0.4em 1.9em 0 1.2em; padding: 0 0.4em 0.3em 0; white-space: nowrap; } .details .outer { padding-right: 0; vertical-align: top; } .details .top { border-top: 2px solid #333; font-weight: bold; margin-top: 0.4em; } .details .header2 { font-weight: bold; padding-left: 0.9em; } .details .key { padding-left: 1.1em; vertical-align: top; } .details .value { text-align: right; color: #333; font-weight: bold; } .details .zebra { background: #EEE; } .lower { text-transform: lowercase; } </style> <script> /* Counter accessor for Name Node. */ function getCounterNameFromCounterNode(node) { return node.childNodes[1]; } /* Counter accessor for Value Node. */ function getCounterValueFromCounterNode(node) { return node.childNodes[3]; } /* Counter accessor for Delta Node. */ function getCounterDeltaFromCounterNode(node) { return node.childNodes[5]; } /* Timer accessor for Name Node. */ function getTimerNameFromTimerNode(node) { return node.childNodes[1]; } /* Timer accessor for Value Node. */ function getTimerValueFromTimerNode(node) { return node.childNodes[3]; } /* Timer accessor for Time Node. */ function getTimerTimeFromTimerNode(node) { return node.childNodes[5]; } /* Timer accessor for Average Time Node. */ function getTimerAvgTimeFromTimerNode(node) { return node.childNodes[7]; } /* Do the filter work. Hide all nodes matching node.*/ function filterMatching(text, nodelist, functionToGetNameNode) { var showAll = text.length == 0; for (var i = 0, node; node = nodelist[i]; i++) { var name = functionToGetNameNode(node).innerHTML.toLowerCase(); if (showAll || name.indexOf(text) >= 0) { node.style.display = "table-row"; } else { node.style.display = "none"; } } } /* Hides or shows counters based on the user's current filter selection. */ function doFilter() { var filter = document.getElementById("filter"); var text = filter.value.toLowerCase(); var nodes = document.getElementsByName("counter"); filterMatching(text, nodes, getCounterNameFromCounterNode); var nodes = document.getElementsByName("timer"); filterMatching(text, nodes, getTimerNameFromTimerNode); } /* Colors the counters based on increasing or decreasing value. */ function doColor() { var nodes = document.getElementsByName("counter"); for (var i = 0, node; node = nodes[i]; i++) { var child = getCounterDeltaFromCounterNode(node); var delta = child.innerHTML; if (delta > 0) { child.style.color = "Green"; } else if (delta == 0) { child.style.color = "Black"; } else { child.style.color = "Red"; } } } /* Counters with no values are null. Remove them. */ function removeNullValues() { var nodes = document.getElementsByName("counter"); for (var i = nodes.length - 1; i >= 0; i--) { var node = nodes[i]; var value = getCounterValueFromCounterNode(node).innerHTML; if (value == "null") { node.parentNode.removeChild(node); } } var nodes = document.getElementsByName("timer"); for (var i = 0, node; node = nodes[i]; i++) { var value_node = getTimerValueFromTimerNode(node); if (value_node.innerHTML == "null") { value_node.innerHTML = ""; } } } /* Compute the average time for timers */ function computeTimes() { var nodes = document.getElementsByName("timer"); for (var i = 0, node; node = nodes[i]; i++) { var count = getTimerValueFromTimerNode(node).innerHTML; if (count.length > 0) { var time = getTimerTimeFromTimerNode(node).innerHTML; var avg = getTimerAvgTimeFromTimerNode(node); avg.innerHTML = Math.round(time / count * 100) / 100; } } } /* All the work we do onload. */ function onLoadWork() { doColor(); removeNullValues(); computeTimes(); document.getElementById("filter").focus(); } // The function should only be used as the event handler // on a table cell element. To use it, put it in a <td> element: // <td onclick="sort('string')" ...> // // The function sorts rows after the row with onclick event handler. // // type: the data type, 'string', 'number' function sort_table(type){ var cell = event.target; var cnum = cell.cellIndex; var row = cell.parentNode; var start_index = row.rowIndex + 1; var tbody = row.parentNode; var table = tbody.parentNode; var rows = new Array(); var indexes = new Array(); // skip the first row for (var i = start_index; i < table.rows.length; i++) rows.push(table.rows[i]); // a, b are strings function compare_strings(a,b) { if (a == b) return 0; if (a < b) return -1; return 1; } // a, b are numbers function compare_numbers(a,b) { var x = isNaN(a) ? 0 : a; var y = isNaN(b) ? 0 : b; return x - y; } var sort_func = undefined; if (type === 'string') { sort_func = function(a, b) { var x = a.cells[cnum].innerText; var y = b.cells[cnum].innerText; return compare_strings(x, y); } ; } else if (type === 'number') { sort_func = function(a, b) { var x = parseFloat(a.cells[cnum].innerText); var y = parseFloat(b.cells[cnum].innerText); return compare_numbers(x, y); } } rows.sort(sort_func); // change tables if (cell._reverse) { for (var i = rows.length - 1; i >= 0; i--) tbody.appendChild(rows[i]); cell._reverse = false; } else { for (var i = 0; i < rows.length; i++) tbody.appendChild(rows[i]); cell._reverse = true; } } </script> </head> <body onload="onLoadWork()"> <div style="float: right"> <br>Filter: <input id="filter" type="text" value="" onkeyup="doFilter()"> </div> <h1 class="lower">About Stats</h1> <h2>Shhh! This page is secret!</h2><br/> <table class="details" cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td class="outer"> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td class="top" width="100">Counters</td> <td class="top value" colspan=2></td> </tr> <tr> <td class="header2 lower" width="200" onclick="sort_table('string')">name</td> <td class="header2 lower" onclick="sort_table('number')">value</td> <td class="header2 lower" onclick="sort_table('number')">delta</td> </tr> <tr jsselect="counters" name="counter"> <td class="key" width="200" jscontent="name"></td> <td class="value" jscontent="value"></td> <td class="value" jscontent="delta"></td> </tr> </tbody> </table> </td> <td width="15"/> <td class="outer"> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td class="top" width="100">Timers</td> <td class="top value"></td> <td class="top value" colspan=3></td> </tr> <tr> <td class="header2 lower" width="200" onclick="sort_table('string')">name</td> <td class="header2 lower" onclick="sort_table('number')">count</td> <td class="header2 lower" onclick="sort_table('number')">time (ms)</td> <td class="header2 lower" onclick="sort_table('number')">avg time (ms)</td> </tr> <tr jsselect="timers" name="timer"> <td class="key" width="200" jscontent="name"></td> <td class="value" jscontent="value"></td> <td class="value" jscontent="time"></td> <td class="value"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table><br/> </body> </html>