burnchart/templates/burndown.eco

157 lines
4.8 KiB
Plaintext

<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Burndown App</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/rickshaw.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/d3.min.js"></script>
<script src="js/d3.layout.min.js"></script>
<script src="js/rickshaw.min.js"></script>
</head>
<body>
<header class="navbar blue navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<ul class="nav pull-left">
<li><a><i class="icon-white icon-fire"></i> Burndown App</a></li>
</ul>
<ul class="nav pull-right">
<li><a><i class="icon-white icon-book"></i> <%= @project %></a></li>
</ul>
</div>
</div>
</header>
<section class="container-fluid pad40">
<section class="row-fluid">
<div class="span2 sideBar">
<br>
<ul>
<li class="active">
<figure>
<a href="/burndown"><i class="icon-signal"></i> Burndown Chart</a>
</figure>
</li>
<li>
<figure>
<a href="/issues"><i class="icon-tasks"></i> Issues</a>
</figure>
</li>
</ul>
</div>
<section class="span10 content borBox">
<div class="row-fluid">
<div class="page-header">
<h1>Burndown chart <small>showing actual vs. ideal velocity on each day</small></h1>
</div>
</div>
<br>
<div class="row-fluid">
<div class="span12">
<div id="chart"></div>
<div id="timeline"></div>
</div>
</div>
</section>
</section>
</section>
<script>
(function() {
var now = new Date().getTime();
var ideal = [], actual = [], issues = {}, i = 0;
<% for day, data of @days: %>
ideal.push({ 'x': <%= day / 1000 %>, 'y': <%= data['ideal'] %> });
actual.push({ 'x': <%= day / 1000 %>, 'y': <%= data['actual'] %> });
// Fill up issues object.
<% if data['issues'].length > 0: %>
issues[<%= day %>] = [];
<% for issue in data['issues']: %>
issues[<%= day %>].push('<%= issue['title'] %>');
<% end %>
<% end %>
i++;
<% end %>
// The line graph.
var graph = new Rickshaw.Graph({
element: document.querySelector("#chart"),
height: 600,
renderer: 'line',
series: [{
data: ideal,
color: '#75ABC5',
name: 'Ideal'
}, {
data: actual,
color: '#F89406',
name: 'Actual'
}]
});
graph.render();
// Onhover.
var hoverDetail = new Rickshaw.Graph.HoverDetail({
graph: graph,
xFormatter: function(d) { return new Date(d * 1000).toUTCString().substring(0, 11) },
formatter: function(series, stamp, points) {
if (series.name == 'Ideal') {
return '<p>Ideally ' + Math.round(points) + ' points left</p>'
} else {
var left = '<p>' + Math.round(points) + ' points left</p>';
// Have we closed any issues today?
var iss = issues[stamp * 1000];
if (iss) {
var string = '<ul>';
for (var i = 0; i < iss.length; i++) {
string += '<li><span class="icon-ok icon-white"></span>&nbsp;&nbsp;' + unescape(iss[i]) + '</li>';
}
string += '</ul>';
return left + string;
} else {
return left;
}
}
}
});
// Axes.
var xAxis = new Rickshaw.Graph.Axis.Time({
graph: graph,
ticksTreatment: 'glow'
});
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph,
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
ticksTreatment: 'glow'
});
xAxis.render();
yAxis.render();
// Annotations.
var annotator = new Rickshaw.Graph.Annotate({
graph: graph,
element: document.getElementById('timeline')
});
annotator.add(now / 1000, 'Now');
annotator.update();
})();
</script>
</body>
</html>