| OLD | NEW |
| (Empty) |
| 1 <html> | |
| 2 <head> | |
| 3 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jq
uery/1.9.0/jquery.min.js"></script> | |
| 4 <script type="text/javascript" src="https://www.google.com/jsapi"></script> | |
| 5 <script type="text/javascript"> | |
| 6 var url = "https://www.googleapis.com/projecthosting/v2/projects/skia/issu
es"; | |
| 7 | |
| 8 var ph_params = { | |
| 9 sort: 'items(published)', | |
| 10 fields: 'items(published,closed),totalResults', | |
| 11 maxResults: 9999, | |
| 12 key: 'AIzaSyDq0bq2zkLR1WfmmGihHU6Vf6nG4msE-io', | |
| 13 startIndex: 0 | |
| 14 }; | |
| 15 | |
| 16 google.load('visualization', '1', {packages:['corechart']}); | |
| 17 google.setOnLoadCallback( drawChart ); | |
| 18 | |
| 19 all_items = []; | |
| 20 var totalResults; | |
| 21 | |
| 22 // The bug database API may not return all the requested bugs in a single
call. | |
| 23 // (data.totalResults will return the total number of bugs that meet the | |
| 24 // request parameters, but data.items may only include a subset.) | |
| 25 // Keep calling back to the API, and appending results to all_items, until | |
| 26 // we get as many results as promised in data.totalResults (which is, | |
| 27 // of course, actually a 1-indexed array index for the last value, not the | |
| 28 // actual number of results. Hence the minus-ones. | |
| 29 | |
| 30 function getBugData(callback) { | |
| 31 $.get( url, ph_params, function( data ) { | |
| 32 totalResults = data.totalResults | |
| 33 all_items = all_items.concat(data.items); | |
| 34 $("#stats").text("Received " + all_items.length + | |
| 35 " total Skia bugs of " + (totalResults-1) + "." ); | |
| 36 if (all_items.length == totalResults - 1) { | |
| 37 callback(); | |
| 38 } else { | |
| 39 ph_params['startIndex'] = all_items.length + 1; | |
| 40 getBugData(callback); | |
| 41 } | |
| 42 }); | |
| 43 } | |
| 44 | |
| 45 function drawChart() { | |
| 46 var bug_data = []; | |
| 47 | |
| 48 getBugData(function() { | |
| 49 | |
| 50 /* Data comes back from the Project Hosting API in JSON format like: | |
| 51 | |
| 52 { | |
| 53 "totalResults": 1057, | |
| 54 "items": [ | |
| 55 { | |
| 56 "published": "2008-12-23T18:57:06.000Z", | |
| 57 "closed": "2009-04-23T17:12:54.000Z" | |
| 58 }, | |
| 59 { | |
| 60 "published": "2008-12-23T18:58:08.000Z", | |
| 61 "closed": "2010-04-15T17:28:52.000Z" | |
| 62 }, | |
| 63 ... | |
| 64 } | |
| 65 | |
| 66 if the bug is still open, there will simply not be a 'closed' | |
| 67 attribute on the item. | |
| 68 | |
| 69 */ | |
| 70 | |
| 71 | |
| 72 // turn this into a list of [ date, +1/-1 ] pairs indicating | |
| 73 // whether or not we added or subtracted a bug on that day. | |
| 74 // Need this intermediate step because the list of actions | |
| 75 // are only sorted on publication date, but the close date | |
| 76 // can be any time in the future. | |
| 77 | |
| 78 actions = []; | |
| 79 for (var i = 0 ; i < all_items.length; i++) { | |
| 80 var publish = new Date(all_items[i].published); | |
| 81 actions.push( [publish, 1] ); | |
| 82 if (all_items[i].closed ) { | |
| 83 var closed = new Date(all_items[i].closed); | |
| 84 actions.push( [closed,-1] ); | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 // now that opening and closing bugs are on equal footing, | |
| 89 // we can sort the action array by the date. | |
| 90 | |
| 91 actions.sort( function(a,b) { return a[0] - b[0]; } ); | |
| 92 | |
| 93 // convert the action array to a running total, and format | |
| 94 // it for the google visualization API while we're at it. | |
| 95 | |
| 96 var bug_count = 0; | |
| 97 for (var i = 0 ; i < actions.length; i++) { | |
| 98 bug_count += actions[i][1]; | |
| 99 bug_data.push( {c: [{v: actions[i][0]}, {v: bug_count}]} ); | |
| 100 } | |
| 101 $("#stats").text("Found " + (totalResults-1) + | |
| 102 " total Skia bugs, with " + bug_count + | |
| 103 " remaining open." ); | |
| 104 | |
| 105 var data_table_init = { | |
| 106 'cols': [ | |
| 107 { | |
| 108 'label': 'Time', | |
| 109 'type': 'datetime' | |
| 110 }, | |
| 111 { | |
| 112 'label': 'Number of open Skia bugs', | |
| 113 'type': 'number' | |
| 114 } | |
| 115 ], | |
| 116 'rows': bug_data | |
| 117 }; | |
| 118 | |
| 119 var data_table = new google.visualization.DataTable(data_table_init); | |
| 120 | |
| 121 var options = { | |
| 122 'title': 'Number of open Skia bugs', | |
| 123 'width': 1024, | |
| 124 'height': 768 | |
| 125 }; | |
| 126 | |
| 127 var graph_container = document.getElementById('graph'); | |
| 128 var graph = new google.visualization.LineChart(graph_container); | |
| 129 graph.draw(data_table,options); | |
| 130 }); | |
| 131 } | |
| 132 </script> | |
| 133 | |
| 134 <style> | |
| 135 body { | |
| 136 font-size: 24pt; | |
| 137 text-align: center; | |
| 138 font-family: Verdana, Arial, Helvetica, sans-serif; | |
| 139 } | |
| 140 </style> | |
| 141 | |
| 142 <title>Skia bug motivator</title> | |
| 143 </head> | |
| 144 <body> | |
| 145 <div id="results_wrapper"> | |
| 146 Open Skia bugs over time | |
| 147 <div id="stats">Gettings bugs, please wait...</div> | |
| 148 <div id="graph"></div> | |
| 149 </div> | |
| 150 </body> | |
| 151 </html> | |
| OLD | NEW |