Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Add churn metric & churn vs complexity chart #121

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
119 changes: 108 additions & 11 deletions lib/assets/scripts/plato-overview.js
Expand Up @@ -4,17 +4,17 @@
$(function() {
'use strict';

// bootstrap popover
// bootstrap popover
$('[rel=popover]').popover();

// @todo put client side templates into a JST
// @todo put client side templates into a JST
var fileGraphTemplate = _.template(
'<div class="threshold-<%= threshold %>">' +
'<div class="threshold-<%= threshold %>">' +
'<label><%= label %></label>' +
'<span class="horizontal-bar" style="width:<%= width %>px"></span>' +
'<span class="chart-value"><%= value %></span>' +
'</div>'
);
);

var horizontalBar = function(orig, width, label, thresholds) {
var threshold = 0;
Expand All @@ -33,7 +33,7 @@ $(function() {
};

function drawFileCharts() {
// @todo make a jQuery plugin to accomodate the horizontalBar function
// @todo make a jQuery plugin to accomodate the horizontalBar function
$('.js-file-chart').each(function() {
var el = $(this),
width = el.width() - 130; // @todo establish max width of graph in plugin
Expand All @@ -53,6 +53,11 @@ $(function() {
value = el.data('lint');
el.append(horizontalBar(value, Math.min(value * 5, width), 'lint errors', [1, 10]));
}

if (__options.flags.churn) {
value = el.data('churn');
el.append(horizontalBar(value, Math.min(value * 5, width), 'churn', [10, 50]));
}
});
}

Expand Down Expand Up @@ -98,7 +103,7 @@ $(function() {

reports.forEach(function(report) {

// @todo shouldn't need this, 'auto [num]' doesn't seem to work : https://github.com/oesmith/morris.js/issues/201
// @todo shouldn't need this, 'auto [num]' doesn't seem to work : https://github.com/oesmith/morris.js/issues/201
sloc.ymax = Math.max(sloc.ymax, report.complexity.aggregate.complexity.sloc.physical);
bugs.ymax = Math.max(bugs.ymax, report.complexity.aggregate.complexity.halstead.bugs.toFixed(2));

Expand All @@ -125,9 +130,9 @@ $(function() {
});

function onGraphClick(i) {
// If the i is not set, we jump to the last file in the list. This
// preserves a behavior from Morris v1. I expect Plato V1 to be deprecated
// and this hack is mearly to preserve the casper tests.
// If the i is not set, we jump to the last file in the list. This
// preserves a behavior from Morris v1. I expect Plato V1 to be deprecated
// and this hack is mearly to preserve the casper tests.
if (i == null || isNaN(i)) {
i = __report.reports.length - 1;
}
Expand All @@ -140,7 +145,7 @@ $(function() {
Morris.Bar(maintainability)
];

if (__options.flags.eslint) charts.push(Morris.Bar(lint));
if (__options.flags.eslint) {charts.push(Morris.Bar(lint));}

charts.forEach(function(chart) {
chart.on('click', onGraphClick);
Expand Down Expand Up @@ -176,12 +181,104 @@ $(function() {
});
}

function drawCharts() {
var COLOR = {
'A' : '#00B50E',
'B': '#53D700',
'C': '#FDF400',
'D': '#FF6C00',
'F': '#C40009'
};

function getRating(score) {
switch (true) {
case score <= 2: return 'A';
case score <= 4: return 'B';
case score <= 8: return 'C';
case score <= 16: return 'D';
default: return 'F';
}
}

var wasChurnComplexityInitialized = false;

function drawChurnChart(reports) {
wasChurnComplexityInitialized = true;
$('#chart_churn-complexity').highcharts({
chart: {
type: 'scatter',
zoomType: 'xy'
},
title: {
text: ''
},
xAxis: {
title: {
enabled: true,
text: 'Churn'
},
floor: 0,
startOnTick: true,
endOnTick: true
},
yAxis: {
title: {
text: 'Complexity'
},
floor: 0,
startOnTick: true,
endOnTick: true
},
plotOptions: {
series: {
turboThreshold: 0,
cursor: 'pointer',
events: {
click: function(event) {
window.open(event.point.link, '_blank');
}
}
},
scatter: {
marker: {
radius: 5,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
tooltip: {
headerFormat: '<b>{point.key}</b><br>',
pointFormat: '<p>Changed {point.x} times, with Cyclomatic score of {point.y}</p><br>',
footerFormat: 'Click on point to view details'
}
}
},
series: [{
showInLegend: false,
color: 'steelblue',
data: reports.map(function(report) {
return {
name: report.info.fileShort,
x: report.churn,
y: report.complexity.aggregate.complexity.cyclomatic,
color: COLOR[getRating(report.complexity.aggregate.complexity.cyclomatic)],
link: report.info.link
};
})
}]
});
}

function drawCharts() {
$('.js-chart').empty();
drawHistoricalChart(__history);
drawOverviewCharts(__report.reports);
drawFileCharts(__report.reports);
if (__report.summary.total.churn && !wasChurnComplexityInitialized) {
drawChurnChart(__report.reports);
}
}

drawCharts();
Expand Down
10 changes: 10 additions & 0 deletions lib/assets/scripts/plato-sortable-file-list.js
Expand Up @@ -53,6 +53,10 @@ $(function sortable_file_list() {
return _sortBy('data-complexity');
};

var _sortByChurn = function _sortByComplexity() {
return _sortBy('data-churn');
};

// appends the 'list' of '<li>' elements
// to its parent '<ul>'.
// @param: a list of '<li>'' elements
Expand Down Expand Up @@ -98,6 +102,11 @@ $(function sortable_file_list() {
_update_metrics_order('lint errors');
};

var _byChurn = function() {
_update_list(_sortByChurn());
_update_metrics_order('churn');
};

// styling

var _update_state = function _update_state(target) {
Expand All @@ -115,6 +124,7 @@ $(function sortable_file_list() {
$('button#button-bugs').on('click', _byBugs);
$('button#button-sloc').on('click', _bySLOC);
$('button#button-lint').on('click', _byLint);
$('button#button-churn').on('click', _byChurn);

// styling update for buttons

Expand Down