Skip to content

Instantly share code, notes, and snippets.

@boxdot
Last active July 6, 2016 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boxdot/51ae19e473772af40603d89f303c6f56 to your computer and use it in GitHub Desktop.
Save boxdot/51ae19e473772af40603d89f303c6f56 to your computer and use it in GitHub Desktop.
Gantt Chart
license: MIT
height: 500
<!DOCTYPE html>
<title>Gantt Diagram</title>
<style>
.axis path, .axis line, .grid path, .grid line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.grid line {
stroke: lightgrey;
}
.task {
stroke: black;
}
.task.failed {
fill: red;
}
.weekend {
fill: lightgrey;
opacity: 0.5;
}
</style>
<svg></svg>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
var margin = { top: 30, right: 10, bottom: 20, left: 70 };
var width = 960 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleBand();
var c10 = d3.scaleOrdinal(d3.schemeCategory10);
var svg = d3.select('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom);
var context = svg.append('g')
.attr('class', 'context')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
d3.json('tasks.json', function(error, data) {
data = parseDates(data);
x.domain([
d3.min(data.map(function(d) { return d.startDate; })),
d3.max(data.map(function(d) { return d.endDate; }))
]);
y.range([0, height])
.domain(data.map(function(d) { return d.taskName; }));
context.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(x));
var weekend = x.ticks(d3.timeDay.every(1))
.filter(function(d) { return d.getDay() == 0 || d.getDay() == 6; });
context.selectAll('.weekend').data(weekend).enter().append('rect')
.attr('class', 'weekend')
.attr('x', x)
.attr('y', 0)
.attr('width', function(d) {
return x(d3.timeDay.offset(d, 1)) - x(d); })
.attr('height', height);
context.append('g')
.attr('class', 'x grid')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisTop(x)
.ticks(d3.timeHour.every(6))
.tickSizeInner(height)
.tickSizeOuter(0)
.tickFormat(''));
context.append('g')
.attr('class', 'y axis')
.call(d3.axisLeft(y));
context.selectAll('.task').data(data).enter().append('rect')
.attr('class', 'task')
.attr('x', function(d) { return x(d.startDate); })
.attr('y', function(d) { return y(d.taskName); })
.attr('rx', 3)
.attr('ry', 3)
.attr('width', function(d) { return x(d.endDate) - x(d.startDate); })
.attr('height', y.bandwidth())
.attr('fill', function(d) { return c10(d.id); })
.classed('failed', function(d) { return d.failed; });
});
function parseDates(data) {
return data.map(function(d) {
d.startDate = new Date(d.startDate);
d.endDate = new Date(d.endDate);
return d;
});
}
</script>
[
{
"id": 899,
"startDate": "2016-06-23T05:36:09",
"endDate": "2016-06-23T11:40:15",
"failed": false,
"taskName": "publication"
},
{
"id": 899,
"startDate": "2016-06-23T11:40:32",
"endDate": "2016-06-23T12:27:58",
"failed": false,
"taskName": "publication"
},
{
"id": 904,
"startDate": "2016-06-29T07:06:17",
"endDate": "2016-06-29T09:02:35",
"failed": false,
"taskName": "build"
},
{
"id": 904,
"startDate": "2016-06-29T09:02:41",
"endDate": "2016-06-29T14:04:37",
"failed": false,
"taskName": "build"
},
{
"id": 904,
"startDate": "2016-06-29T14:04:54",
"endDate": "2016-06-29T17:51:03",
"failed": false,
"taskName": "build"
},
{
"id": 207,
"startDate": "2016-06-27T17:52:45",
"endDate": "2016-06-28T09:02:20",
"failed": false,
"taskName": "publication"
},
{
"id": 207,
"startDate": "2016-06-28T09:02:25",
"endDate": "2016-06-28T09:33:00",
"failed": false,
"taskName": "publication"
},
{
"id": 207,
"startDate": "2016-06-28T09:33:03",
"endDate": "2016-06-28T22:40:29",
"failed": false,
"taskName": "publication"
},
{
"id": 207,
"startDate": "2016-06-28T22:40:34",
"endDate": "2016-06-29T06:51:49",
"failed": false,
"taskName": "publication"
},
{
"id": 147,
"startDate": "2016-07-04T09:55:42",
"endDate": "2016-07-04T12:49:12",
"failed": false,
"taskName": "indexer"
},
{
"id": 147,
"startDate": "2016-07-04T12:49:17",
"endDate": "2016-07-04T20:02:29",
"failed": false,
"taskName": "indexer"
},
{
"id": 98,
"startDate": "2016-06-30T19:21:47",
"endDate": "2016-06-30T20:21:47",
"failed": true,
"taskName": "build"
},
{
"id": 98,
"startDate": "2016-07-01T21:57:58",
"endDate": "2016-07-02T22:30:31",
"failed": false,
"taskName": "build"
},
{
"id": 444,
"startDate": "2016-06-23T12:50:22",
"endDate": "2016-06-23T18:16:33",
"failed": false,
"taskName": "publication"
},
{
"id": 906,
"startDate": "2016-07-02T20:31:24",
"endDate": "2016-07-03T03:12:47",
"failed": false,
"taskName": "indexer"
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment