Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: sky/tools/webkitpy/tool/commands/data/summary.html

Issue 675343003: Prune a bunch of webkitpy. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>ChangeLog Analysis</title>
5 <style type="text/css">
6
7 body {
8 font-family: 'Helvetica' 'Segoe UI Light' sans-serif;
9 font-weight: 200;
10 padding: 20px;
11 min-width: 1200px;
12 }
13
14 * {
15 padding: 0px;
16 margin: 0px;
17 border: 0px;
18 }
19
20 h1, h2, h3 {
21 font-weight: 200;
22 }
23
24 h1 {
25 margin: 0 0 1em 0;
26 }
27
28 h2 {
29 font-size: 1.2em;
30 text-align: center;
31 margin-bottom: 1em;
32 }
33
34 h3 {
35 font-size: 1em;
36 }
37
38 .view {
39 margin: 0px;
40 width: 600px;
41 float: left;
42 }
43
44 .graph-container p {
45 width: 200px;
46 text-align: right;
47 margin: 20px 0 20px 0;
48 padding: 5px;
49 border-right: solid 1px black;
50 }
51
52 .graph-container table {
53 width: 100%;
54 }
55
56 .graph-container table, .graph-container td {
57 border-collapse: collapse;
58 border: none;
59 }
60
61 .graph-container td {
62 padding: 5px;
63 vertical-align: center;
64 }
65
66 .graph-container td:first-child {
67 width: 200px;
68 text-align: right;
69 border-right: solid 1px black;
70 }
71
72 .graph-container .selected {
73 background: #eee;
74 }
75
76 #reviewers .selected td:first-child {
77 border-radius: 10px 0px 0px 10px;
78 }
79
80 #areas .selected td:last-child {
81 border-radius: 0px 10px 10px 0px;
82 }
83
84 .graph-container .bar {
85 display: inline-block;
86 min-height: 1em;
87 background: #9f6;
88 margin-right: 0.4ex;
89 }
90
91 .graph-container .reviewed-patches {
92 background: #3cf;
93 margin-right: 1px;
94 }
95
96 .graph-container .unreviewed-patches {
97 background: #f99;
98 }
99
100 .constrained {
101 background: #eee;
102 border-radius: 10px;
103 }
104
105 .constrained .vertical-bar {
106 border-right: solid 1px #eee;
107 }
108
109 #header {
110 border-spacing: 5px;
111 }
112
113 #header section {
114 display: table-cell;
115 width: 200px;
116 vertical-align: top;
117 border: solid 2px #ccc;
118 border-collapse: collapse;
119 padding: 5px;
120 font-size: 0.8em;
121 }
122
123 #header dt {
124 float: left;
125 }
126
127 #header dt:after {
128 content: ': ';
129 }
130
131 #header .legend {
132 width: 600px;
133 }
134
135 .legend .bar {
136 width: 15ex;
137 padding: 2px;
138 }
139
140 .legend .reviews {
141 width: 25ex;
142 }
143
144 .legend td:first-child {
145 width: 18ex;
146 }
147
148 </style>
149 </head>
150 <body>
151 <h1>ChangeLog Analysis</h1>
152
153 <section id="header">
154 <section id="summary">
155 <h2>Summary</h2>
156 </section>
157
158 <section class="legend">
159 <h2>Legend</h2>
160 <div class="graph-container">
161 <table>
162 <tbody>
163 <tr><td>Contributor's name</td>
164 <td><span class="bar reviews">Reviews</span> <span class="value-container">(# of reviews)</span><br>
165 <span class="bar reviewed-patches">Reviewed</span><span class="bar unreviewed-pa tches">Unreviewed</span>
166 <span class="value-container">(# of reviewed):(# of unreviewed)</span></td></tr>
167 </tbody>
168 </table>
169 </div>
170 </section>
171 </section>
172
173 <section id="contributors" class="view">
174 <h2 id="contributors-title">Contributors</h2>
175 <div class="graph-container"></div>
176 </section>
177
178 <section id="areas" class="view">
179 <h2 id="areas-title">Areas of contributions</h2>
180 <div class="graph-container"></div>
181 </section>
182
183 <script>
184
185 // Naive implementation of element extensions discussed on public-webapps
186
187 if (!Element.prototype.append) {
188 Element.prototype.append = function () {
189 for (var i = 0; i < arguments.length; i++) {
190 // FIXME: Take care of other node types
191 if (arguments[i] instanceof Element || arguments[i] instanceof Chara cterData)
192 this.appendChild(arguments[i]);
193 else
194 this.appendChild(document.createTextNode(arguments[i]));
195 }
196 return this;
197 }
198 }
199
200 if (!Node.prototype.remove) {
201 Node.prototype.remove = function () {
202 this.parentNode.removeChild(this);
203 return this;
204 }
205 }
206
207 if (!Element.create) {
208 Element.create = function () {
209 if (arguments.length < 1)
210 return null;
211 var element = document.createElement(arguments[0]);
212 if (arguments.length == 1)
213 return element;
214
215 // FIXME: the second argument can be content or IDL attributes
216 var attributes = arguments[1];
217 for (attribute in attributes)
218 element.setAttribute(attribute, attributes[attribute]);
219
220 if (arguments.length >= 3)
221 element.append.apply(element, arguments[2]);
222
223 return element;
224 }
225 }
226
227 if (!Node.prototype.removeAllChildren) {
228 Node.prototype.removeAllChildren = function () {
229 while (this.firstChild)
230 this.firstChild.remove();
231 return this;
232 }
233 }
234
235 Element.prototype.removeClassNameFromAllElements = function (className) {
236 var elements = this.getElementsByClassName(className);
237 for (var i = 0; i < elements.length; i++)
238 elements[i].classList.remove(className);
239 }
240
241 function getJSON(url, callback) {
242 var xhr = new XMLHttpRequest();
243 xhr.open('GET', url, true);
244 xhr.onreadystatechange = function () {
245 if (this.readyState == 4)
246 callback(JSON.parse(xhr.responseText));
247 }
248 xhr.send();
249 }
250
251 function GraphView(container) {
252 this._container = container;
253 this._defaultData = null;
254 }
255
256 GraphView.prototype.setData = function(data, constrained) {
257 if (constrained)
258 this._container.classList.add('constrained');
259 else
260 this._container.classList.remove('constrained');
261 this._clearGraph();
262 this._constructGraph(data);
263 }
264
265 GraphView.prototype.setDefaultData = function(data) {
266 this._defaultData = data;
267 this.setData(data);
268 }
269
270 GraphView.prototype.reset = function () {
271 this.setMarginTop();
272 this.setData(this._defaultData);
273 }
274
275 GraphView.prototype.isConstrained = function () { return this._container.classLi st.contains('constrained'); }
276
277 GraphView.prototype.targetRow = function (node) {
278 var target = null;
279
280 while (node && node != this._container) {
281 if (node.localName == 'tr')
282 target = node;
283 node = node.parentNode;
284 }
285
286 return node && target;
287 }
288
289 GraphView.prototype.selectRow = function (row) {
290 this._container.removeClassNameFromAllElements('selected');
291 row.classList.add('selected');
292 }
293
294 GraphView.prototype.setMarginTop = function (y) { this._container.style.marginTo p = y ? y + 'px' : null; }
295 GraphView.prototype._graphContainer = function () { return this._container.getEl ementsByClassName('graph-container')[0]; }
296 GraphView.prototype._clearGraph = function () { return this._graphContainer().re moveAllChildren(); }
297
298 GraphView.prototype._numberOfPatches = function (dataItem) {
299 return dataItem.numberOfReviewedPatches + (dataItem.numberOfUnreviewedPatche s !== undefined ? dataItem.numberOfUnreviewedPatches : 0);
300 }
301
302 GraphView.prototype._maximumValue = function (labels, data) {
303 var numberOfPatches = this._numberOfPatches;
304 return Math.max.apply(null, labels.map(function (label) {
305 return Math.max(numberOfPatches(data[label]), data[label].numberOfReview s !== undefined ? data[label].numberOfReviews : 0);
306 }));
307 }
308
309 GraphView.prototype._sortLabelsByNumberOfReviwsAndReviewedPatches = function(dat a) {
310 var labels = Object.keys(data);
311 if (!labels.length)
312 return null;
313 var numberOfPatches = this._numberOfPatches;
314 var computeValue = function (dataItem) {
315 return numberOfPatches(dataItem) + (dataItem.numberOfReviews !== undefin ed ? dataItem.numberOfReviews : 0);
316 }
317 labels.sort(function (a, b) { return computeValue(data[b]) - computeValue(da ta[a]); });
318 return labels;
319 }
320
321 GraphView.prototype._constructGraph = function (data) {
322 var element = this._graphContainer();
323 var labels = this._sortLabelsByNumberOfReviwsAndReviewedPatches(data);
324 if (!labels) {
325 element.append(Element.create('p', {}, ['None']));
326 return;
327 }
328
329 var maxValue = this._maximumValue(labels, data);
330 var computeStyleForBar = function (value) { return 'width:' + (value * 85.0 / maxValue) + '%' }
331
332 var table = Element.create('table', {}, [Element.create('tbody')]);
333 for (var i = 0; i < labels.length; i++) {
334 var label = labels[i];
335 var item = data[label];
336 var row = Element.create('tr', {}, [Element.create('td', {}, [label]), E lement.create('td', {})]);
337 var valueCell = row.lastChild;
338
339 if (item.numberOfReviews != undefined) {
340 valueCell.append(
341 Element.create('span', {'class': 'bar reviews', 'style': compute StyleForBar(item.numberOfReviews) }),
342 Element.create('span', {'class': 'value-container'}, [item.numbe rOfReviews]),
343 Element.create('br')
344 );
345 }
346
347 valueCell.append(Element.create('span', {'class': 'bar reviewed-patches' , 'style': computeStyleForBar(item.numberOfReviewedPatches) }));
348 if (item.numberOfUnreviewedPatches !== undefined)
349 valueCell.append(Element.create('span', {'class': 'bar unreviewed-pa tches', 'style': computeStyleForBar(item.numberOfUnreviewedPatches) }));
350
351 valueCell.append(Element.create('span', {'class': 'value-container'},
352 [item.numberOfReviewedPatches + (item.numberOfUnreviewedPatches !== undefined ? ':' + item.numberOfUnreviewedPatches : '')]));
353
354 table.firstChild.append(row);
355 row.label = label;
356 row.data = item;
357 }
358 element.append(table);
359 }
360
361 var contributorsView = new GraphView(document.querySelector('#contributors'));
362 var areasView = new GraphView(document.querySelector('#areas'));
363
364 getJSON('summary.json',
365 function (summary) {
366 var summaryContainer = document.querySelector('#summary');
367 summaryContainer.append(Element.create('dl', {}, [
368 Element.create('dt', {}, ['Total entries (reviewed)']),
369 Element.create('dd', {}, [(summary['reviewed'] + summary['unreviewed ']) + ' (' + summary['reviewed'] + ')']),
370 Element.create('dt', {}, ['Total contributors']),
371 Element.create('dd', {}, [summary['contributors']]),
372 Element.create('dt', {}, ['Contributors who reviewed']),
373 Element.create('dd', {}, [summary['contributors_with_reviews']]),
374 ]));
375 });
376
377 getJSON('contributors.json',
378 function (contributors) {
379 for (var contributor in contributors) {
380 contributor = contributors[contributor];
381 contributor.numberOfReviews = contributor.reviews ? contributor.revi ews.total : 0;
382 contributor.numberOfReviewedPatches = contributor.patches ? contribu tor.patches.reviewed : 0;
383 contributor.numberOfUnreviewedPatches = contributor.patches ? contri butor.patches.unreviewed : 0;
384 }
385 contributorsView.setDefaultData(contributors);
386 });
387
388 getJSON('areas.json',
389 function (areas) {
390 for (var area in areas) {
391 areas[area].numberOfReviewedPatches = areas[area].reviewed;
392 areas[area].numberOfUnreviewedPatches = areas[area].unreviewed;
393 }
394 areasView.setDefaultData(areas);
395 });
396
397 function contributorAreas(contributorData) {
398 var areas = new Object;
399 for (var area in contributorData.reviews.areas) {
400 if (!areas[area])
401 areas[area] = {'numberOfReviewedPatches': 0};
402 areas[area].numberOfReviews = contributorData.reviews.areas[area];
403 }
404 for (var area in contributorData.patches.areas) {
405 if (!areas[area])
406 areas[area] = {'numberOfReviews': 0};
407 areas[area].numberOfReviewedPatches = contributorData.patches.areas[area ];
408 }
409 return areas;
410 }
411
412 function areaContributors(areaData) {
413 var contributors = areaData['contributors'];
414 for (var contributor in contributors) {
415 contributor = contributors[contributor];
416 contributor.numberOfReviews = contributor.reviews;
417 contributor.numberOfReviewedPatches = contributor.reviewed;
418 contributor.numberOfUnreviewedPatches = contributor.unreviewed;
419 }
420 return contributors;
421 }
422
423 var mouseTimer = 0;
424 window.onmouseover = function (event) {
425 clearTimeout(mouseTimer);
426
427 var row = contributorsView.targetRow(event.target);
428 if (row) {
429 if (!contributorsView.isConstrained()) {
430 contributorsView.selectRow(row);
431 areasView.setMarginTop(row.firstChild.offsetTop);
432 areasView.setData(contributorAreas(row.data), 'constrained');
433 }
434 return;
435 }
436
437 row = areasView.targetRow(event.target);
438 if (row) {
439 if (!areasView.isConstrained()) {
440 areasView.selectRow(row);
441 contributorsView.setMarginTop(row.firstChild.offsetTop);
442 contributorsView.setData(areaContributors(row.data), 'constrained');
443 }
444 return;
445 }
446
447 mouseTimer = setTimeout(function () {
448 contributorsView.reset();
449 areasView.reset();
450 }, 500);
451 }
452
453 </script>
454 </body>
455 </html>
OLDNEW
« no previous file with comments | « sky/tools/webkitpy/tool/commands/adduserstogroups.py ('k') | sky/tools/webkitpy/tool/commands/findusers.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698