Merge "Improve projects list UI in the home page"

This commit is contained in:
Jenkins 2016-02-22 18:52:47 +00:00 committed by Gerrit Code Review
commit a087cfd8d0
4 changed files with 142 additions and 12 deletions

View File

@ -58,7 +58,7 @@ function HomeController($scope, healthService, projectService, viewService, $loc
vm.chartDataRate = [{ key: '% Failures', values: entries.failRate }];
vm.projects = projects
.sort(byFailRateDesc)
.map(function(project) { return generateGaugeData(project); });
.map(function(project) { return generateHorizontalBarData(project); });
};
var getChartEntries = function(dateStats, blanks) {
@ -84,12 +84,20 @@ function HomeController($scope, healthService, projectService, viewService, $loc
return { x: date.getTime(), y: value };
};
var generateGaugeData = function(project) {
var generateHorizontalBarData = function(project) {
return {
name: project.name,
passRate: 1 - project.metrics.failRate,
failRate: project.metrics.failRate,
passes: project.metrics.passes,
failures: project.metrics.failures,
data: [
{ key: 'Passes', value: project.metrics.passes, color: 'blue' },
{ key: 'Failures', value: project.metrics.failures, color: 'red' }
{ key: 'Passes Rate',
values: [{label:'',
value: 1 - project.metrics.failRate}], color: 'blue' },
{ key: 'Failures Rate',
values: [{label:'',
value: project.metrics.failRate}], color: 'red' }
]
};
};

View File

@ -0,0 +1,88 @@
'use strict';
var directivesModule = require('./_index.js');
var d3 = require('d3');
var nv = require('nvd3');
/**
* @ngInject
*/
function chartBarHorizontal() {
var link = function(scope, el, attrs) {
scope.$on('loading-started', function() {
el.css({'display' : 'none'});
});
scope.$on('loading-complete', function() {
el.css({'display' : 'block'});
if (chart !== null) {
chart.update();
}
});
var chart = null;
var svg = d3.select(el[0]).append('svg')
.attr('width', attrs.width)
.attr('height', attrs.height);
var update = function(data) {
if (typeof data === 'undefined') {
return;
}
chart = nv.models.multiBarHorizontalChart();
chart.x(function(d) {
return d.label;
});
chart.y(function(d) {
return d.value;
});
chart.margin({top: 0, right: 5, bottom: 1, left: 5});
chart.width(300); // FIXME: this is workaround the for unstable width
chart.duration(0);
chart.groupSpacing(0);
chart.showControls(false);
chart.showLegend(false);
chart.showValues(false);
chart.showXAxis(false);
chart.showYAxis(false);
chart.stacked(true);
chart.yAxis.axisLabel(false);
chart.yAxis.showMaxMin(false);
chart.yAxis.tickFormat(d3.format('.2%'));
chart.yAxis.tickValues(0);
chart.xAxis.axisLabel(false);
chart.xAxis.tickValues(0);
svg.datum(data).call(chart);
chart.update();
};
scope.$on('windowResize', function() {
if (chart !== null) {
chart.update();
}
});
scope.$on('viewContentLoaded', function() {
if (chart !== null) {
chart.update();
}
});
scope.$watch('data', update);
};
return {
restrict: 'EA',
scope: {
'data': '=',
'width': '@',
'height': '@'
},
link: link
};
}
directivesModule.directive('chartBarHorizontal', chartBarHorizontal);

View File

@ -50,15 +50,44 @@
</div>
</form>
</div>
<div class="col-lg-4" ng-repeat="project in home.projects | filter:home.searchProject">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
<a ui-sref="groupedRuns({ runMetadataKey: home.groupKey, name: project.name })">
<h3 class="panel-title">{{project.name}}</h3>
</a>
<h3 class="panel-title">Project status</h3>
</div>
<div class="panel-body">
<chart-gauge data="project.data" width="100%" height="250"></chart-gauge>
<table table-sort class="table table-hover" data="home.projects">
<thead>
<tr>
<th field="number" class="text-center">#</th>
<th sort-field="name" class="text-center">Project Name</a></th>
<th sort-field="passes" class="text-center">Passes</th>
<th sort-field="failures" class="text-center">Failures</th>
<th sort-field="passRate" class="text-center">% Passes</th>
<th sort-default sort-field="failRate" class="text-center">% Failures</th>
<th field="barGraph" class="text-center" style="min-width:320px">Bar Graph</th>
</tr>
</thead>
<tbody>
<tr table-ref="table" ng-repeat="p in home.projects | filter:home.searchProject"
ng-class="p.failRate > 0.15 ? 'danger' : p.failRate > 0.08 ? 'warning' : p.failRate > 0 ? 'info' : 'success'">
<td class="text-right">{{$index+1}}</td>
<td class="text-left">
<a ui-sref="groupedRuns({ runMetadataKey: home.groupKey, name: p.name })">{{p.name}}</a>
</td>
<td class="text-right">{{p.passes|number}}</td>
<td class="text-right">{{p.failures|number}}</td>
<td class="text-right">{{p.passRate*100|number:2}}</td>
<td class="text-right">{{p.failRate*100|number:2}}</td>
<td>
<div id="chart">
<chart-bar-horizontal data="p.data" height="20">
</chart-bar-horizontal>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -75,15 +75,20 @@ describe('HomeController', function() {
it('should generate project data', function() {
projectService.createProjects = function() {
return [{ name: 'p1', metrics: { passes: 1, failures: 2 }}];
return [{ name: 'p1',
metrics: { passes: 1, failures: 2, failRate: 0.4 }}];
};
homeController.loadData();
var project = homeController.projects[0];
expect(project.name).toEqual('p1');
expect(project.data.length).toEqual(2);
expect(project.data).toContain({ key: 'Passes', value: 1, color: 'blue'});
expect(project.data).toContain({ key: 'Failures', value: 2, color: 'red'});
expect(project.data).toContain({ key: 'Passes Rate',
values: [{label: '', value: 0.6}],
color: 'blue'});
expect(project.data).toContain({ key: 'Failures Rate',
values: [{label: '', value: 0.4}],
color: 'red'});
});
it('should sort projects by descending percentage of failures', function() {