forked from dk8996's block: D3.js Gantt Chart basic example.
forked from baramuyu's block: D3.js v4 Gantt Chart basic example.
license: mit |
forked from dk8996's block: D3.js Gantt Chart basic example.
forked from baramuyu's block: D3.js v4 Gantt Chart basic example.
html,body,#wrapper { | |
width: 100%; | |
height: 100%; | |
margin: 0px; | |
} | |
.chart { | |
font-family: Arial, sans-serif; | |
font-size: 12px; | |
} | |
.axis path,.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.bar { | |
fill: #33b5e5; | |
} | |
.bar-failed { | |
fill: #CC0000; | |
} | |
.bar-running { | |
fill: #669900; | |
} | |
.bar-succeeded { | |
fill: #33b5e5; | |
} | |
.bar-killed { | |
fill: #ffbb33; | |
} | |
#forkme_banner { | |
display: block; | |
position: absolute; | |
top: 0; | |
right: 10px; | |
z-index: 10; | |
padding: 10px 50px 10px 10px; | |
color: #fff; | |
background: | |
url('http://dk8996.github.io/Gantt-Chart/images/blacktocat.png') | |
#0090ff no-repeat 95% 50%; | |
font-weight: 700; | |
box-shadow: 0 0 10px rgba(0, 0, 0, .5); | |
border-bottom-left-radius: 2px; | |
border-bottom-right-radius: 2px; | |
text-decoration: none; | |
} |
var tasks = [ | |
{"startDate":new Date("Sun Dec 09 01:36:45 EST 2012"),"endDate":new Date("Sun Dec 09 02:36:45 EST 2012"),"taskName":"E Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 04:56:32 EST 2012"),"endDate":new Date("Sun Dec 09 06:35:47 EST 2012"),"taskName":"A Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 06:29:53 EST 2012"),"endDate":new Date("Sun Dec 09 06:34:04 EST 2012"),"taskName":"D Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 05:35:21 EST 2012"),"endDate":new Date("Sun Dec 09 06:21:22 EST 2012"),"taskName":"P Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 05:00:06 EST 2012"),"endDate":new Date("Sun Dec 09 05:05:07 EST 2012"),"taskName":"D Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 03:46:59 EST 2012"),"endDate":new Date("Sun Dec 09 04:54:19 EST 2012"),"taskName":"P Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 04:02:45 EST 2012"),"endDate":new Date("Sun Dec 09 04:48:56 EST 2012"),"taskName":"N Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 03:27:35 EST 2012"),"endDate":new Date("Sun Dec 09 03:58:43 EST 2012"),"taskName":"E Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 01:40:11 EST 2012"),"endDate":new Date("Sun Dec 09 03:26:35 EST 2012"),"taskName":"A Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 03:00:03 EST 2012"),"endDate":new Date("Sun Dec 09 03:09:51 EST 2012"),"taskName":"D Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 01:21:00 EST 2012"),"endDate":new Date("Sun Dec 09 02:51:42 EST 2012"),"taskName":"P Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 01:08:42 EST 2012"),"endDate":new Date("Sun Dec 09 01:33:42 EST 2012"),"taskName":"N Job","status":"FAILED"}, | |
{"startDate":new Date("Sun Dec 09 00:27:15 EST 2012"),"endDate":new Date("Sun Dec 09 00:54:56 EST 2012"),"taskName":"E Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 00:29:48 EST 2012"),"endDate":new Date("Sun Dec 09 00:44:50 EST 2012"),"taskName":"D Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 07:39:21 EST 2012"),"endDate":new Date("Sun Dec 09 07:43:22 EST 2012"),"taskName":"P Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 07:00:06 EST 2012"),"endDate":new Date("Sun Dec 09 07:05:07 EST 2012"),"taskName":"D Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 08:46:59 EST 2012"),"endDate":new Date("Sun Dec 09 09:54:19 EST 2012"),"taskName":"P Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 09:02:45 EST 2012"),"endDate":new Date("Sun Dec 09 09:48:56 EST 2012"),"taskName":"N Job","status":"RUNNING"}, | |
{"startDate":new Date("Sun Dec 09 08:27:35 EST 2012"),"endDate":new Date("Sun Dec 09 08:58:43 EST 2012"),"taskName":"E Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 08:40:11 EST 2012"),"endDate":new Date("Sun Dec 09 08:46:35 EST 2012"),"taskName":"A Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 08:00:03 EST 2012"),"endDate":new Date("Sun Dec 09 08:09:51 EST 2012"),"taskName":"D Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 10:21:00 EST 2012"),"endDate":new Date("Sun Dec 09 10:51:42 EST 2012"),"taskName":"P Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sun Dec 09 11:08:42 EST 2012"),"endDate":new Date("Sun Dec 09 11:33:42 EST 2012"),"taskName":"N Job","status":"FAILED"}, | |
{"startDate":new Date("Sun Dec 09 12:27:15 EST 2012"),"endDate":new Date("Sun Dec 09 12:54:56 EST 2012"),"taskName":"E Job","status":"SUCCEEDED"}, | |
{"startDate":new Date("Sat Dec 08 23:12:24 EST 2012"),"endDate":new Date("Sun Dec 09 00:26:13 EST 2012"),"taskName":"A Job","status":"KILLED"}]; | |
var taskStatus = { | |
"SUCCEEDED" : "bar", | |
"FAILED" : "bar-failed", | |
"RUNNING" : "bar-running", | |
"KILLED" : "bar-killed" | |
}; | |
var taskNames = [ "D Job", "P Job", "E Job", "A Job", "N Job" ]; | |
tasks.sort(function(a, b) { | |
return a.endDate - b.endDate; | |
}); | |
var maxDate = tasks[tasks.length - 1].endDate; | |
tasks.sort(function(a, b) { | |
return a.startDate - b.startDate; | |
}); | |
var minDate = tasks[0].startDate; | |
var format = "%H:%M"; | |
var gantt = d3.gantt().taskTypes(taskNames).taskStatus(taskStatus).tickFormat(format); | |
gantt(tasks); |
/** | |
* @author Dimitry Kudrayvtsev | |
* @version 2.0 | |
* | |
* Ported to d3 v4 by Keyvan Fatehi on October 16th, 2016 | |
*/ | |
d3.gantt = function() { | |
var FIT_TIME_DOMAIN_MODE = "fit"; | |
var FIXED_TIME_DOMAIN_MODE = "fixed"; | |
var margin = { | |
top : 20, | |
right : 40, | |
bottom : 20, | |
left : 150 | |
}; | |
var timeDomainStart = d3.timeDay.offset(new Date(),-3); | |
var timeDomainEnd = d3.timeHour.offset(new Date(),+3); | |
var timeDomainMode = FIT_TIME_DOMAIN_MODE;// fixed or fit | |
var taskTypes = []; | |
var taskStatus = []; | |
var height = document.body.clientHeight - margin.top - margin.bottom-5; | |
var width = document.body.clientWidth - margin.right - margin.left-5; | |
var tickFormat = "%H:%M"; | |
var keyFunction = function(d) { | |
return d.startDate + d.taskName + d.endDate; | |
}; | |
var rectTransform = function(d) { | |
return "translate(" + x(d.startDate) + "," + y(d.taskName) + ")"; | |
}; | |
var x,y,xAxis,yAxis; | |
initAxis(); | |
var initTimeDomain = function() { | |
if (timeDomainMode === FIT_TIME_DOMAIN_MODE) { | |
if (tasks === undefined || tasks.length < 1) { | |
timeDomainStart = d3.time.day.offset(new Date(), -3); | |
timeDomainEnd = d3.time.hour.offset(new Date(), +3); | |
return; | |
} | |
tasks.sort(function(a, b) { | |
return a.endDate - b.endDate; | |
}); | |
timeDomainEnd = tasks[tasks.length - 1].endDate; | |
tasks.sort(function(a, b) { | |
return a.startDate - b.startDate; | |
}); | |
timeDomainStart = tasks[0].startDate; | |
} | |
}; | |
function initAxis() { | |
x = d3.scaleTime().domain([ timeDomainStart, timeDomainEnd ]).range([ 0, width ]).clamp(true); | |
y = d3.scaleBand().domain(taskTypes).rangeRound([ 0, height - margin.top - margin.bottom ], .1); | |
xAxis = d3.axisBottom().scale(x).tickFormat(d3.timeFormat(tickFormat)) | |
.tickSize(8).tickPadding(8); | |
yAxis = d3.axisLeft().scale(y).tickSize(0); | |
}; | |
function gantt(tasks) { | |
initTimeDomain(); | |
initAxis(); | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("class", "chart") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("class", "gantt-chart") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")"); | |
svg.selectAll(".chart") | |
.data(tasks, keyFunction).enter() | |
.append("rect") | |
.attr("rx", 5) | |
.attr("ry", 5) | |
.attr("class", function(d){ | |
if(taskStatus[d.status] == null){ return "bar";} | |
return taskStatus[d.status]; | |
}) | |
.attr("y", 0) | |
.attr("transform", rectTransform) | |
.attr("height", function(d) { return 70; }) | |
.attr("width", function(d) { | |
return (x(d.endDate) - x(d.startDate)); | |
}); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")") | |
.transition() | |
.call(xAxis); | |
svg.append("g").attr("class", "y axis").transition().call(yAxis); | |
return gantt; | |
}; | |
gantt.redraw = function(tasks) { | |
initTimeDomain(); | |
initAxis(); | |
var svg = d3.select("svg"); | |
var ganttChartGroup = svg.select(".gantt-chart"); | |
var rect = ganttChartGroup.selectAll("rect").data(tasks, keyFunction); | |
rect.enter() | |
.insert("rect",":first-child") | |
.attr("rx", 5) | |
.attr("ry", 5) | |
.attr("class", function(d){ | |
if(taskStatus[d.status] == null){ return "bar";} | |
return taskStatus[d.status]; | |
}) | |
.transition() | |
.attr("y", 0) | |
.attr("transform", rectTransform) | |
.attr("height", function(d) { return y.range()[1]; }) | |
.attr("width", function(d) { | |
return (x(d.endDate) - x(d.startDate)); | |
}); | |
rect.transition() | |
.attr("transform", rectTransform) | |
.attr("height", function(d) { return y.range()[1]; }) | |
.attr("width", function(d) { | |
return (x(d.endDate) - x(d.startDate)); | |
}); | |
rect.exit().remove(); | |
svg.select(".x").transition().call(xAxis); | |
svg.select(".y").transition().call(yAxis); | |
return gantt; | |
}; | |
gantt.margin = function(value) { | |
if (!arguments.length) | |
return margin; | |
margin = value; | |
return gantt; | |
}; | |
gantt.timeDomain = function(value) { | |
if (!arguments.length) | |
return [ timeDomainStart, timeDomainEnd ]; | |
timeDomainStart = +value[0], timeDomainEnd = +value[1]; | |
return gantt; | |
}; | |
/** | |
* @param {string} | |
* vale The value can be "fit" - the domain fits the data or | |
* "fixed" - fixed domain. | |
*/ | |
gantt.timeDomainMode = function(value) { | |
if (!arguments.length) | |
return timeDomainMode; | |
timeDomainMode = value; | |
return gantt; | |
}; | |
gantt.taskTypes = function(value) { | |
if (!arguments.length) | |
return taskTypes; | |
taskTypes = value; | |
return gantt; | |
}; | |
gantt.taskStatus = function(value) { | |
if (!arguments.length) | |
return taskStatus; | |
taskStatus = value; | |
return gantt; | |
}; | |
gantt.width = function(value) { | |
if (!arguments.length) | |
return width; | |
width = +value; | |
return gantt; | |
}; | |
gantt.height = function(value) { | |
if (!arguments.length) | |
return height; | |
height = +value; | |
return gantt; | |
}; | |
gantt.tickFormat = function(value) { | |
if (!arguments.length) | |
return tickFormat; | |
tickFormat = value; | |
return gantt; | |
}; | |
return gantt; | |
}; | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Gantt Chart Example 1</title> | |
<!-- <link type="text/css" href="http://mbostock.github.io/d3/style.css" rel="stylesheet" /> --> | |
<link type="text/css" href="example.css" rel="stylesheet" /> | |
</head> | |
<body> | |
<script type="text/javascript" src="http://d3js.org/d3.v4.min.js"></script> | |
<script type="text/javascript" src="gantt.js"></script> | |
<script type="text/javascript" src="example.js"></script> | |
</body> | |
</html> |