Skip to content

Instantly share code, notes, and snippets.

@davidrichards
Last active August 29, 2015 14:01
Show Gist options
  • Save davidrichards/28c39939540bcf1e96cb to your computer and use it in GitHub Desktop.
Save davidrichards/28c39939540bcf1e96cb to your computer and use it in GitHub Desktop.
Some Monitoring Details

Basic Concept

I've been working on organizing our delivery. The following is an experiment and will change quite a bit.

We have hundreds of story details that are now being integrated into these reports on a daily basis. This is an incomplete view of what I'm working on. There are many estimates in this story that will get better refined with just a few days' more work. Of course, we'll get better at this as the weeks pass by.

seq description startAt dueAt beginAt expectedAt
0 Access Lab 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-05-28T06:00:00+00:00
1 Deploy Lab Nagios 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-18T06:00:00+00:00
2 Core Host Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-18T06:00:00+00:00
3 Deploy Lab Openstack 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-29T06:00:00+00:00
4 Deploy Lab Apigee 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-29T06:00:00+00:00
5 Deploy Lab Perconadb 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-29T06:00:00+00:00
6 Update Devops Chef Repositories 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-29T06:00:00+00:00
7 Deploy Lab Oracle 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-08-29T06:00:00+00:00
8 Core Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-09-22T06:00:00+00:00
9 Request Lab Eforcs 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-11-19T07:00:00+00:00
10 Core Openstack Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-12-01T07:00:00+00:00
11 Core Perconadb Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-12-01T07:00:00+00:00
12 Core Apigee Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-12-01T07:00:00+00:00
13 Core Oracle Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2014-12-01T07:00:00+00:00
14 Receive Eforcs 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2015-02-20T07:00:00+00:00
15 Test Lab Netcool Connectivity 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2015-05-25T06:00:00+00:00
16 Refine Monitoring 2014-01-29 2014-06-20 2014-05-28T06:00:00+00:00 2015-08-26T06:00:00+00:00
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>Estimated Timeline</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" href="http://billmill.org/css/style.css" />
<style>
body {
font-family: Georgia,"Times New Roman",Times,serif;
font-size: 14px;
background-color: white;
width: 1020px;
}
table {
border-collapse: collapse;
}
th {
border-bottom: 2px solid #ddd;
padding: 8px;
font-weight: bold;
}
td {
padding: 8px;
border-top: 1px solid #ddd;
}
#chart {
padding: 0px;
}
.xaxislabel {
font-size: 9px;
}
</style>
</head>
<body>
<div id="datatable"></div>
<script>
var rows = []
var formatdate = d3.time.format("%b %d %Y");
d3.csv("estimates.csv", function(error, csv) {
csv.forEach(function(row) {
row.startAt = new Date(Date.parse(row.startAt));
row.dueAt = new Date(Date.parse(row.dueAt));
row.expectedAt = new Date(Date.parse(row.expectedAt));
rows.push(row);
});
var table = d3.select("#datatable").append("table");
thead = table.append("thead");
tbody = table.append("tbody");
thead.append("th").text("Description");
thead.append("th").text("Start At");
thead.append("th").text("Due At");
thead.append("th").text("Expected At");
thead.append("th").text("");
var tr = tbody.selectAll("tr")
.data(rows)
.enter().append("tr");
var td = tr.selectAll("td")
.data(function(d) { return [d.description, formatdate(d.startAt), formatdate(d.dueAt), formatdate(d.expectedAt)]; })
.enter().append("td")
.text(function(d) { return d; });
var width = 160,
height = d3.select("table")[0][0].clientHeight,
mx = 10,
radius = 4;
// Now add the chart column
d3.select("#datatable tbody tr").append("td")
.attr("id", "chart")
.attr("width", width + "px")
.attr("rowspan", rows.length);
var chart = d3.select("#chart").append("svg")
.attr("class", "chart")
.attr("width", width)
.attr("height", height);
var maxDate = new Date(Date.parse("January 1, 2014"));
var minDate = new Date(Date.parse("December 31, 2016"));
for (i=0; i < rows.length; i++) {
if (rows[i].expectedAt > maxDate) { maxDate = rows[i].expectedAt; }
if (rows[i].dueAt > maxDate) { maxDate = rows[i].dueAt; }
if (rows[i].startAt < minDate) { minDate = rows[i].startAt; }
}
var seqs = rows.map(function(t) { return t.seq; });
var xscale = d3.time.scale()
.domain([minDate, maxDate])
.range([mx, width-mx])
.nice();
var yscale = d3.scale.ordinal()
.domain(seqs)
.rangeBands([0, height]);
// FIXME: Get a better x axis
// chart.selectAll(".xaxislabel")
// .data(xscale.ticks(2))
// .enter().append("text")
// .attr("class", "xaxislabel")
// .attr("x", function(d) { return xscale(d); })
// .attr("y", 10)
// .attr("text-anchor", "middle")
// .text(String)
chart.selectAll(".xaxistick")
.data(xscale.ticks(2))
.enter().append("line")
.attr("x1", function(d) { return xscale(d); })
.attr("x2", function(d) { return xscale(d); })
.attr("y1", 10)
.attr("y2", height)
.attr("stroke", "#eee")
.attr("stroke-width", 1);
chart.selectAll(".line")
.data(rows)
.enter().append("line")
.attr("x1", function(d) { return xscale(d.startAt); })
.attr("y1", function(d) { return yscale(d.seq) + yscale.rangeBand()/2; })
.attr("x2", function(d) { return xscale(d.expectedAt); })
.attr("y2", function(d) { return yscale(d.seq) + yscale.rangeBand()/2; })
.attr("stroke", "#888")
.attr("stroke-width", 8);
var pt = chart.selectAll(".pt")
.data(rows)
.enter().append("g")
.attr("class", "pt")
.attr("transform", function(d) { return "translate(" + xscale(d.startAt) + "," + (yscale(d.seq) + yscale.rangeBand()/2) + ")"; });
pt.append("circle")
.attr("cx", -5)
.attr("cy", 0)
.attr("r", radius)
.attr("opacity", function(d) { return d.expectedAt > d.dueAt ? .6 : 0 })
.attr("fill", "#ff0000");
chart.selectAll(".due-tick")
.data(rows)
.enter().append("line")
.attr("x1", function(d) { return xscale(d.dueAt); })
.attr("y1", function(d) { return yscale(d.seq) + yscale.rangeBand()/2 - 6; })
.attr("x2", function(d) { return xscale(d.dueAt); })
.attr("y2", function(d) { return yscale(d.seq) + yscale.rangeBand()/2 + 6; })
.attr("stroke", "#555")
.attr("stroke-width", 3);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment