/**
* @author Dimitry Kudrayvtsev * @version 2.1 */
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 selector = 'body'; var timeDomainStart = d3.time.day.offset(new Date(), -3); var timeDomainEnd = d3.time.hour.offset(new Date(), +3); var timeDomainMode = FIT_TIME_DOMAIN_MODE;// fixed or fit var taskTypes = []; 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 = d3.time.scale().domain([timeDomainStart, timeDomainEnd]).range([0, width]).clamp(true); var y = d3.scale.ordinal().domain(taskTypes).rangeRoundBands([0, height - margin.top - margin.bottom], .1); var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format(tickFormat)).tickSubdivide(true) .tickSize(8).tickPadding(8); var yAxis = d3.svg.axis().scale(y).orient("left").tickSize(0); var initTimeDomain = function (tasks) { 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; } }; var initAxis = function () { x = d3.time.scale().domain([timeDomainStart, timeDomainEnd]).range([0, width]).clamp(true); y = d3.scale.ordinal().domain(taskTypes).rangeRoundBands([0, height - margin.top - margin.bottom], .1); xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format(tickFormat)).tickSubdivide(true) .tickSize(8).tickPadding(8); yAxis = d3.svg.axis().scale(y).orient("left").tickSize(0); }; function gantt(tasks, legend) { initTimeDomain(tasks); initAxis(); var svg = d3.select(selector) .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("fill", function (d) { return d.color }) .attr("y", 0) .attr("transform", rectTransform) .attr("height", function (d) { return y.rangeBand(); }) .attr("width", function (d) { return Math.max(1, (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); var legendWidth = 400; var legendHeight = 75; var svgLegend = d3.select(".legend1").append("svg") .attr("width", legendWidth).attr("height", legendHeight) legend.forEach(function(legendPart, idx) { svgLegend.append('text') .attr("x", 380) .attr("y", 10) .attr("dy", idx + "em") .text(legendPart) .style("text-anchor", "end") .style("font-size", 15) }); return gantt; }; gantt.redraw = function (tasks) { initTimeDomain(tasks); initAxis(); var svg = d3.select(".chart"); svg.attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom); 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("fill", function (d) { return d.color }) .transition() .attr("y", 0) .attr("transform", rectTransform) .attr("height", function (d) { return y.rangeBand(); }) .attr("width", function (d) { return Math.max(1, (x(d.endDate) - x(d.startDate))); }); rect.transition() .attr("transform", rectTransform) .attr("height", function (d) { return y.rangeBand(); }) .attr("width", function (d) { return Math.max(1, (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.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; }; gantt.selector = function (value) { if (!arguments.length) return selector; selector = value; return gantt; }; return gantt;
};