我知道这对你来说可能很简单,但这是我项目的最后一部分,我已经完成了,所以我已经想完成这个了。这是我的问题,当我第一次加载我的甘特图时,我首先绘制轴和网格线之前它自己所以看起来我希望网格线是我的图表的背景但是当我重绘我的图表时存在问题甘特图首先在网格线之前绘制,因此输出的网格线覆盖了看起来很糟糕的甘特图。我会发布我的代码,以便您检查。我无法确定我首先放置网格线的位置。我想我需要和额外的眼睛..........
d3.gantt = function() {
var FIT_TIME_DOMAIN_MODE = "fit";
var FIXED_TIME_DOMAIN_MODE = "fixed";
var margin = {
top : 50,
right : 40,
bottom : 20,
left : 120
};
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 = 500 - margin.top - margin.bottom-5;
var width = 1200 - 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 xAxisGrid = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height + margin.top + margin.bottom, 0, 0)
.tickFormat("");
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);
xAxisGrid = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height + margin.top + margin.bottom, 0, 0)
.tickFormat("");
};
/////////////////////////////////
//Creating the chart
////////////////////////////
function gantt(tasks) {
initTimeDomain(tasks);
initAxis();
var dateFormat = d3.time.format("%Y-%m-%d");
var svg = d3.select("#gantt_chart")
.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) / tasks[tasks.length - 1].endDate)
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
var div = d3.select("body").append("div")
.attr("class","tooltip")
.style("opacity",0);
//this is the x-axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")")
.transition()
.call(xAxis)
.selectAll("text")
.style("text-anchor","end")
.attr("dx", 35)
.attr("dy", 5);
//.attr("dx", "-.8em")
//.attr("dy", -10)
//.attr("transform", function(d){return "rotate(-90)"});
//this is the y-axis
svg.append("g").attr("class", "y axis").transition().call(yAxis);
// title of the gantt
svg.append("g")
.append("text")
.attr("x", 300)
.attr("y", -30)
.attr("class","title")
.style("font-size",20)
.text("MINI-PM SCHEDULER GANTT CHART");
// y title
svg.append("g")
.append("text")
.attr("transform", "rotate(-90)")
.attr("dx", -220)
.attr("dy", -100)
.style("font-size",16)
.text("HANDLER ID");
//this is the legend part
var colors = [["RUNNING", "#669900"],["WARNING", "#ffbb33"],["DOWN", "#FF0000"]];
var legend = svg.append("g")
.attr("class", "legend");
var circle = legend.selectAll('circle')
.data(colors)
.enter()
.append("circle")
.attr("cx", function (d, i) {
return (i * 80)+(width/2)-125;
})
.attr("cy", 405)
.attr("r", 5)
.style("fill", function (d) {
return d[1];
});
var legendText = legend.selectAll('text')
.data(colors)
.enter()
.append("text")
.attr("x", function (d, i) {
return (i * 80)+(width/2)-115;
})
.attr("y", 410)
.text(function (d) {
return d[0];
});
// Add X Axis grid lines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")")
.call(xAxisGrid);
//this is the actual gantt
svg.selectAll(".chart")
.data(tasks, keyFunction).enter()
.append("rect")
.attr("rx", 0)
.attr("ry", 0)
.attr("class", function(d){
if(d.status > 75)
{
return "bar-failed";
}
else if (d.status >= 55 && d.status <= 75){
return "bar-killed";
}
else{
return "bar-running";
}
})
.attr("y", 0)
.attr("transform", rectTransform)
.attr("height", function(d) { return y.rangeBand(); })
.attr("width", function(d) {
return (x(d.endDate) - x(d.startDate));
})
.on("mouseover", function(d){
div.transition()
.duration(200)
.style("opacity", .9);
div.html("HandlerID: " + d.taskName + "<br>" + "startDate: " + dateFormat(d.startDate) + "<br/>" + "endDate: " + dateFormat(d.endDate) + "<br/>" + "% Insertions: " + d3.round(d.status,2) + "%")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout",function(d){
div.transition()
.duration(500)
.style("opacity", 0);
});
/*
svg.append("g")
.append("text")
.attr("x", width / 2)
.attr("y", 380)
.style("font-size",12)
.text("PERIOD"); */
return gantt;
};
gantt.redraw = function(tasks) {
initTimeDomain(tasks);
initAxis();
var dateFormat = d3.time.format("%Y-%m-%d");
var div = d3.select("body").append("div")
.attr("class","tooltip")
.style("opacity",0);
var svg = d3.select("#gantt_chart");
var ganttChartGroup = svg.select(".gantt-chart");
var rect = ganttChartGroup.selectAll("rect").data(tasks, keyFunction);
rect.enter()
.insert("rect",":first-child")
.attr("rx", 0)
.attr("ry", 0)
.attr("class", function(d){
if(d.status > 75)
{
return "bar-failed";
}
else if (d.status >= 55 && d.status <= 75){
return "bar-killed";
}
else{
return "bar-running";
}
})
.transition()
.attr("y", 0)
.attr("transform", rectTransform)
.attr("height", function(d) { return y.rangeBand(); })
.attr("width", function(d) {
return (x(d.endDate) - x(d.startDate));
});
rect.transition()
.attr("transform", rectTransform)
.attr("height", function(d) { return y.rangeBand(); })
.attr("width", function(d) {
return (x(d.endDate) - x(d.startDate));
});
rect.exit().remove();
rect
.on("mouseover", function(d){
div.transition()
.duration(200)
.style("opacity", .9);
div.html("HandlerID: " + d.taskName + "<br>" + "startDate: " + dateFormat(d.startDate) + "<br/>" + "endDate: " + dateFormat(d.endDate) + "<br/>" + "% Insertions: " + d3.round(d.status,2) + "%")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout",function(d){
div.transition()
.duration(500)
.style("opacity", 0);
});
svg.select(".grid").transition().call(xAxisGrid);
svg.select(".x").transition().call(xAxis);
svg.select(".y").transition().call(yAxis);
return gantt;
}; // end of redraw
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;
};