| Index: sky/tools/webkitpy/tool/commands/data/summary.html
|
| diff --git a/sky/tools/webkitpy/tool/commands/data/summary.html b/sky/tools/webkitpy/tool/commands/data/summary.html
|
| deleted file mode 100644
|
| index abf80d84fd20be35b7e9fb06d35fdc6fa8a2e8cf..0000000000000000000000000000000000000000
|
| --- a/sky/tools/webkitpy/tool/commands/data/summary.html
|
| +++ /dev/null
|
| @@ -1,455 +0,0 @@
|
| -<!DOCTYPE html>
|
| -<html>
|
| -<head>
|
| -<title>ChangeLog Analysis</title>
|
| -<style type="text/css">
|
| -
|
| -body {
|
| - font-family: 'Helvetica' 'Segoe UI Light' sans-serif;
|
| - font-weight: 200;
|
| - padding: 20px;
|
| - min-width: 1200px;
|
| -}
|
| -
|
| -* {
|
| - padding: 0px;
|
| - margin: 0px;
|
| - border: 0px;
|
| -}
|
| -
|
| -h1, h2, h3 {
|
| - font-weight: 200;
|
| -}
|
| -
|
| -h1 {
|
| - margin: 0 0 1em 0;
|
| -}
|
| -
|
| -h2 {
|
| - font-size: 1.2em;
|
| - text-align: center;
|
| - margin-bottom: 1em;
|
| -}
|
| -
|
| -h3 {
|
| - font-size: 1em;
|
| -}
|
| -
|
| -.view {
|
| - margin: 0px;
|
| - width: 600px;
|
| - float: left;
|
| -}
|
| -
|
| -.graph-container p {
|
| - width: 200px;
|
| - text-align: right;
|
| - margin: 20px 0 20px 0;
|
| - padding: 5px;
|
| - border-right: solid 1px black;
|
| -}
|
| -
|
| -.graph-container table {
|
| - width: 100%;
|
| -}
|
| -
|
| -.graph-container table, .graph-container td {
|
| - border-collapse: collapse;
|
| - border: none;
|
| -}
|
| -
|
| -.graph-container td {
|
| - padding: 5px;
|
| - vertical-align: center;
|
| -}
|
| -
|
| -.graph-container td:first-child {
|
| - width: 200px;
|
| - text-align: right;
|
| - border-right: solid 1px black;
|
| -}
|
| -
|
| -.graph-container .selected {
|
| - background: #eee;
|
| -}
|
| -
|
| -#reviewers .selected td:first-child {
|
| - border-radius: 10px 0px 0px 10px;
|
| -}
|
| -
|
| -#areas .selected td:last-child {
|
| - border-radius: 0px 10px 10px 0px;
|
| -}
|
| -
|
| -.graph-container .bar {
|
| - display: inline-block;
|
| - min-height: 1em;
|
| - background: #9f6;
|
| - margin-right: 0.4ex;
|
| -}
|
| -
|
| -.graph-container .reviewed-patches {
|
| - background: #3cf;
|
| - margin-right: 1px;
|
| -}
|
| -
|
| -.graph-container .unreviewed-patches {
|
| - background: #f99;
|
| -}
|
| -
|
| -.constrained {
|
| - background: #eee;
|
| - border-radius: 10px;
|
| -}
|
| -
|
| -.constrained .vertical-bar {
|
| - border-right: solid 1px #eee;
|
| -}
|
| -
|
| -#header {
|
| - border-spacing: 5px;
|
| -}
|
| -
|
| -#header section {
|
| - display: table-cell;
|
| - width: 200px;
|
| - vertical-align: top;
|
| - border: solid 2px #ccc;
|
| - border-collapse: collapse;
|
| - padding: 5px;
|
| - font-size: 0.8em;
|
| -}
|
| -
|
| -#header dt {
|
| - float: left;
|
| -}
|
| -
|
| -#header dt:after {
|
| - content: ': ';
|
| -}
|
| -
|
| -#header .legend {
|
| - width: 600px;
|
| -}
|
| -
|
| -.legend .bar {
|
| - width: 15ex;
|
| - padding: 2px;
|
| -}
|
| -
|
| -.legend .reviews {
|
| - width: 25ex;
|
| -}
|
| -
|
| -.legend td:first-child {
|
| - width: 18ex;
|
| -}
|
| -
|
| -</style>
|
| -</head>
|
| -<body>
|
| -<h1>ChangeLog Analysis</h1>
|
| -
|
| -<section id="header">
|
| -<section id="summary">
|
| -<h2>Summary</h2>
|
| -</section>
|
| -
|
| -<section class="legend">
|
| -<h2>Legend</h2>
|
| -<div class="graph-container">
|
| -<table>
|
| -<tbody>
|
| -<tr><td>Contributor's name</td>
|
| -<td><span class="bar reviews">Reviews</span> <span class="value-container">(# of reviews)</span><br>
|
| -<span class="bar reviewed-patches">Reviewed</span><span class="bar unreviewed-patches">Unreviewed</span>
|
| -<span class="value-container">(# of reviewed):(# of unreviewed)</span></td></tr>
|
| -</tbody>
|
| -</table>
|
| -</div>
|
| -</section>
|
| -</section>
|
| -
|
| -<section id="contributors" class="view">
|
| -<h2 id="contributors-title">Contributors</h2>
|
| -<div class="graph-container"></div>
|
| -</section>
|
| -
|
| -<section id="areas" class="view">
|
| -<h2 id="areas-title">Areas of contributions</h2>
|
| -<div class="graph-container"></div>
|
| -</section>
|
| -
|
| -<script>
|
| -
|
| -// Naive implementation of element extensions discussed on public-webapps
|
| -
|
| -if (!Element.prototype.append) {
|
| - Element.prototype.append = function () {
|
| - for (var i = 0; i < arguments.length; i++) {
|
| - // FIXME: Take care of other node types
|
| - if (arguments[i] instanceof Element || arguments[i] instanceof CharacterData)
|
| - this.appendChild(arguments[i]);
|
| - else
|
| - this.appendChild(document.createTextNode(arguments[i]));
|
| - }
|
| - return this;
|
| - }
|
| -}
|
| -
|
| -if (!Node.prototype.remove) {
|
| - Node.prototype.remove = function () {
|
| - this.parentNode.removeChild(this);
|
| - return this;
|
| - }
|
| -}
|
| -
|
| -if (!Element.create) {
|
| - Element.create = function () {
|
| - if (arguments.length < 1)
|
| - return null;
|
| - var element = document.createElement(arguments[0]);
|
| - if (arguments.length == 1)
|
| - return element;
|
| -
|
| - // FIXME: the second argument can be content or IDL attributes
|
| - var attributes = arguments[1];
|
| - for (attribute in attributes)
|
| - element.setAttribute(attribute, attributes[attribute]);
|
| -
|
| - if (arguments.length >= 3)
|
| - element.append.apply(element, arguments[2]);
|
| -
|
| - return element;
|
| - }
|
| -}
|
| -
|
| -if (!Node.prototype.removeAllChildren) {
|
| - Node.prototype.removeAllChildren = function () {
|
| - while (this.firstChild)
|
| - this.firstChild.remove();
|
| - return this;
|
| - }
|
| -}
|
| -
|
| -Element.prototype.removeClassNameFromAllElements = function (className) {
|
| - var elements = this.getElementsByClassName(className);
|
| - for (var i = 0; i < elements.length; i++)
|
| - elements[i].classList.remove(className);
|
| -}
|
| -
|
| -function getJSON(url, callback) {
|
| - var xhr = new XMLHttpRequest();
|
| - xhr.open('GET', url, true);
|
| - xhr.onreadystatechange = function () {
|
| - if (this.readyState == 4)
|
| - callback(JSON.parse(xhr.responseText));
|
| - }
|
| - xhr.send();
|
| -}
|
| -
|
| -function GraphView(container) {
|
| - this._container = container;
|
| - this._defaultData = null;
|
| -}
|
| -
|
| -GraphView.prototype.setData = function(data, constrained) {
|
| - if (constrained)
|
| - this._container.classList.add('constrained');
|
| - else
|
| - this._container.classList.remove('constrained');
|
| - this._clearGraph();
|
| - this._constructGraph(data);
|
| -}
|
| -
|
| -GraphView.prototype.setDefaultData = function(data) {
|
| - this._defaultData = data;
|
| - this.setData(data);
|
| -}
|
| -
|
| -GraphView.prototype.reset = function () {
|
| - this.setMarginTop();
|
| - this.setData(this._defaultData);
|
| -}
|
| -
|
| -GraphView.prototype.isConstrained = function () { return this._container.classList.contains('constrained'); }
|
| -
|
| -GraphView.prototype.targetRow = function (node) {
|
| - var target = null;
|
| -
|
| - while (node && node != this._container) {
|
| - if (node.localName == 'tr')
|
| - target = node;
|
| - node = node.parentNode;
|
| - }
|
| -
|
| - return node && target;
|
| -}
|
| -
|
| -GraphView.prototype.selectRow = function (row) {
|
| - this._container.removeClassNameFromAllElements('selected');
|
| - row.classList.add('selected');
|
| -}
|
| -
|
| -GraphView.prototype.setMarginTop = function (y) { this._container.style.marginTop = y ? y + 'px' : null; }
|
| -GraphView.prototype._graphContainer = function () { return this._container.getElementsByClassName('graph-container')[0]; }
|
| -GraphView.prototype._clearGraph = function () { return this._graphContainer().removeAllChildren(); }
|
| -
|
| -GraphView.prototype._numberOfPatches = function (dataItem) {
|
| - return dataItem.numberOfReviewedPatches + (dataItem.numberOfUnreviewedPatches !== undefined ? dataItem.numberOfUnreviewedPatches : 0);
|
| -}
|
| -
|
| -GraphView.prototype._maximumValue = function (labels, data) {
|
| - var numberOfPatches = this._numberOfPatches;
|
| - return Math.max.apply(null, labels.map(function (label) {
|
| - return Math.max(numberOfPatches(data[label]), data[label].numberOfReviews !== undefined ? data[label].numberOfReviews : 0);
|
| - }));
|
| -}
|
| -
|
| -GraphView.prototype._sortLabelsByNumberOfReviwsAndReviewedPatches = function(data) {
|
| - var labels = Object.keys(data);
|
| - if (!labels.length)
|
| - return null;
|
| - var numberOfPatches = this._numberOfPatches;
|
| - var computeValue = function (dataItem) {
|
| - return numberOfPatches(dataItem) + (dataItem.numberOfReviews !== undefined ? dataItem.numberOfReviews : 0);
|
| - }
|
| - labels.sort(function (a, b) { return computeValue(data[b]) - computeValue(data[a]); });
|
| - return labels;
|
| -}
|
| -
|
| -GraphView.prototype._constructGraph = function (data) {
|
| - var element = this._graphContainer();
|
| - var labels = this._sortLabelsByNumberOfReviwsAndReviewedPatches(data);
|
| - if (!labels) {
|
| - element.append(Element.create('p', {}, ['None']));
|
| - return;
|
| - }
|
| -
|
| - var maxValue = this._maximumValue(labels, data);
|
| - var computeStyleForBar = function (value) { return 'width:' + (value * 85.0 / maxValue) + '%' }
|
| -
|
| - var table = Element.create('table', {}, [Element.create('tbody')]);
|
| - for (var i = 0; i < labels.length; i++) {
|
| - var label = labels[i];
|
| - var item = data[label];
|
| - var row = Element.create('tr', {}, [Element.create('td', {}, [label]), Element.create('td', {})]);
|
| - var valueCell = row.lastChild;
|
| -
|
| - if (item.numberOfReviews != undefined) {
|
| - valueCell.append(
|
| - Element.create('span', {'class': 'bar reviews', 'style': computeStyleForBar(item.numberOfReviews) }),
|
| - Element.create('span', {'class': 'value-container'}, [item.numberOfReviews]),
|
| - Element.create('br')
|
| - );
|
| - }
|
| -
|
| - valueCell.append(Element.create('span', {'class': 'bar reviewed-patches', 'style': computeStyleForBar(item.numberOfReviewedPatches) }));
|
| - if (item.numberOfUnreviewedPatches !== undefined)
|
| - valueCell.append(Element.create('span', {'class': 'bar unreviewed-patches', 'style': computeStyleForBar(item.numberOfUnreviewedPatches) }));
|
| -
|
| - valueCell.append(Element.create('span', {'class': 'value-container'},
|
| - [item.numberOfReviewedPatches + (item.numberOfUnreviewedPatches !== undefined ? ':' + item.numberOfUnreviewedPatches : '')]));
|
| -
|
| - table.firstChild.append(row);
|
| - row.label = label;
|
| - row.data = item;
|
| - }
|
| - element.append(table);
|
| -}
|
| -
|
| -var contributorsView = new GraphView(document.querySelector('#contributors'));
|
| -var areasView = new GraphView(document.querySelector('#areas'));
|
| -
|
| -getJSON('summary.json',
|
| - function (summary) {
|
| - var summaryContainer = document.querySelector('#summary');
|
| - summaryContainer.append(Element.create('dl', {}, [
|
| - Element.create('dt', {}, ['Total entries (reviewed)']),
|
| - Element.create('dd', {}, [(summary['reviewed'] + summary['unreviewed']) + ' (' + summary['reviewed'] + ')']),
|
| - Element.create('dt', {}, ['Total contributors']),
|
| - Element.create('dd', {}, [summary['contributors']]),
|
| - Element.create('dt', {}, ['Contributors who reviewed']),
|
| - Element.create('dd', {}, [summary['contributors_with_reviews']]),
|
| - ]));
|
| - });
|
| -
|
| -getJSON('contributors.json',
|
| - function (contributors) {
|
| - for (var contributor in contributors) {
|
| - contributor = contributors[contributor];
|
| - contributor.numberOfReviews = contributor.reviews ? contributor.reviews.total : 0;
|
| - contributor.numberOfReviewedPatches = contributor.patches ? contributor.patches.reviewed : 0;
|
| - contributor.numberOfUnreviewedPatches = contributor.patches ? contributor.patches.unreviewed : 0;
|
| - }
|
| - contributorsView.setDefaultData(contributors);
|
| - });
|
| -
|
| -getJSON('areas.json',
|
| - function (areas) {
|
| - for (var area in areas) {
|
| - areas[area].numberOfReviewedPatches = areas[area].reviewed;
|
| - areas[area].numberOfUnreviewedPatches = areas[area].unreviewed;
|
| - }
|
| - areasView.setDefaultData(areas);
|
| - });
|
| -
|
| -function contributorAreas(contributorData) {
|
| - var areas = new Object;
|
| - for (var area in contributorData.reviews.areas) {
|
| - if (!areas[area])
|
| - areas[area] = {'numberOfReviewedPatches': 0};
|
| - areas[area].numberOfReviews = contributorData.reviews.areas[area];
|
| - }
|
| - for (var area in contributorData.patches.areas) {
|
| - if (!areas[area])
|
| - areas[area] = {'numberOfReviews': 0};
|
| - areas[area].numberOfReviewedPatches = contributorData.patches.areas[area];
|
| - }
|
| - return areas;
|
| -}
|
| -
|
| -function areaContributors(areaData) {
|
| - var contributors = areaData['contributors'];
|
| - for (var contributor in contributors) {
|
| - contributor = contributors[contributor];
|
| - contributor.numberOfReviews = contributor.reviews;
|
| - contributor.numberOfReviewedPatches = contributor.reviewed;
|
| - contributor.numberOfUnreviewedPatches = contributor.unreviewed;
|
| - }
|
| - return contributors;
|
| -}
|
| -
|
| -var mouseTimer = 0;
|
| -window.onmouseover = function (event) {
|
| - clearTimeout(mouseTimer);
|
| -
|
| - var row = contributorsView.targetRow(event.target);
|
| - if (row) {
|
| - if (!contributorsView.isConstrained()) {
|
| - contributorsView.selectRow(row);
|
| - areasView.setMarginTop(row.firstChild.offsetTop);
|
| - areasView.setData(contributorAreas(row.data), 'constrained');
|
| - }
|
| - return;
|
| - }
|
| -
|
| - row = areasView.targetRow(event.target);
|
| - if (row) {
|
| - if (!areasView.isConstrained()) {
|
| - areasView.selectRow(row);
|
| - contributorsView.setMarginTop(row.firstChild.offsetTop);
|
| - contributorsView.setData(areaContributors(row.data), 'constrained');
|
| - }
|
| - return;
|
| - }
|
| -
|
| - mouseTimer = setTimeout(function () {
|
| - contributorsView.reset();
|
| - areasView.reset();
|
| - }, 500);
|
| -}
|
| -
|
| -</script>
|
| -</body>
|
| -</html>
|
|
|