Home | History | Annotate | Download | only in resources
      1 <!DOCTYPE HTML>
      2 
      3 <html id="t">
      4   <head>
      5     <title>About Stats</title>
      6 
      7 <style>
      8 body {
      9   border-top: 10px solid #3B85E3;
     10   color: #333;
     11   font-family: Verdana, Helvetica, Arial, sans-serif;
     12 }
     13 body, td {
     14   font-size: 11px;
     15 }
     16 a:link, a:visited {
     17   color: #2C3EBA;
     18   text-decoration: none;
     19 }
     20 a:hover {
     21   color: red;
     22   text-decoration: underline;
     23 }
     24 h1 {
     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 }
     32 h2 {
     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. */
     76 function getCounterNameFromCounterNode(node) {
     77   return node.childNodes[1];
     78 }
     79 
     80 /* Counter accessor for Value Node. */
     81 function getCounterValueFromCounterNode(node) {
     82   return node.childNodes[3];
     83 }
     84 
     85 /* Counter accessor for Delta Node. */
     86 function getCounterDeltaFromCounterNode(node) {
     87   return node.childNodes[5];
     88 }
     89 
     90 /* Timer accessor for Name Node. */
     91 function getTimerNameFromTimerNode(node) {
     92   return node.childNodes[1];
     93 }
     94 
     95 /* Timer accessor for Value Node. */
     96 function getTimerValueFromTimerNode(node) {
     97   return node.childNodes[3];
     98 }
     99 
    100 /* Timer accessor for Time Node. */
    101 function getTimerTimeFromTimerNode(node) {
    102   return node.childNodes[5];
    103 }
    104 
    105 /* Timer accessor for Average Time Node. */
    106 function getTimerAvgTimeFromTimerNode(node) {
    107   return node.childNodes[7];
    108 }
    109 
    110 /* Do the filter work.  Hide all nodes matching node.*/
    111 function 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. */
    124 function 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. */
    134 function 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. */
    150 function 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 */
    169 function 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. */
    182 function 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'
    196 function 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