|
|
@@ -1,437 +0,0 @@ |
|
|
|
/** |
|
|
|
* inspired from @author Dimitry Kudrayvtsev |
|
|
|
* @author tr4ck3ur |
|
|
|
*/ |
|
|
|
|
|
|
|
d3.sched = function(EventType) { |
|
|
|
var FIT_TIME_DOMAIN_MODE = "fit"; |
|
|
|
var FIXED_TIME_DOMAIN_MODE = "fixed"; |
|
|
|
var myname = EventType; |
|
|
|
var margin = { |
|
|
|
top : 15, |
|
|
|
right : 10, |
|
|
|
bottom : 10, |
|
|
|
left : 50 |
|
|
|
}; |
|
|
|
var timeDomainStart = d3.time.hour.offset(new Date(),-2); |
|
|
|
var timeDomainEnd = d3.time.hour.offset(new Date(),+2); |
|
|
|
var timeDomainMode = FIT_TIME_DOMAIN_MODE;// fixed or fit |
|
|
|
var taskTypes = []; |
|
|
|
var taskStatus = []; |
|
|
|
//var height = document.body.clientHeight - margin.top - margin.bottom-5; |
|
|
|
height = 700; |
|
|
|
//var width = document.body.clientWidth - margin.right - margin.left-5; |
|
|
|
var width = 700;// - margin.right - margin.left; |
|
|
|
var tickFormat = "%H:%M"; |
|
|
|
var lastscale = -1; |
|
|
|
|
|
|
|
var xScale = d3.scale.ordinal() |
|
|
|
.domain(taskTypes) |
|
|
|
.rangeRoundBands([ 0, width - margin.left], .1); |
|
|
|
|
|
|
|
var yScale = d3.time.scale() |
|
|
|
.domain([ timeDomainStart, timeDomainEnd ]) |
|
|
|
.range([ 0, height - margin.top ]) //- margin.bottom ]); |
|
|
|
.clamp(true); |
|
|
|
|
|
|
|
var xAxis = d3.svg.axis() |
|
|
|
.scale(xScale) |
|
|
|
.orient("left") |
|
|
|
.tickSize(1); |
|
|
|
|
|
|
|
var yAxis = d3.svg.axis() |
|
|
|
.scale(yScale) |
|
|
|
.orient("bottom") |
|
|
|
.tickFormat(d3.time.format(tickFormat)) |
|
|
|
.tickSubdivide(true) |
|
|
|
.tickSize(8).tickPadding(8); |
|
|
|
|
|
|
|
var keyFunction = function(d) { |
|
|
|
return d.startDate + d.placeName + d.endDate; |
|
|
|
}; |
|
|
|
|
|
|
|
var rectTransform = function(d) { |
|
|
|
return "translate(" + xScale(d.placeName) + "," + yScale(d.startDate) + ")"; |
|
|
|
}; |
|
|
|
|
|
|
|
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() { |
|
|
|
|
|
|
|
xScale = d3.scale.ordinal() |
|
|
|
.domain(taskTypes) |
|
|
|
.rangeRoundBands([ 0, width ], .1); |
|
|
|
|
|
|
|
yScale = d3.time.scale() |
|
|
|
.domain([ timeDomainStart, timeDomainEnd ]) |
|
|
|
.range([ 0, height - margin.top - margin.bottom ]) |
|
|
|
.clamp(true); |
|
|
|
|
|
|
|
xAxis = d3.svg.axis() |
|
|
|
.scale(xScale) |
|
|
|
.orient("top") |
|
|
|
.tickSize(1); |
|
|
|
|
|
|
|
yAxis = d3.svg.axis() |
|
|
|
.scale(yScale) |
|
|
|
.orient("left") |
|
|
|
.tickFormat(d3.time.format(tickFormat)) |
|
|
|
.tickSubdivide(true) |
|
|
|
.tickSize(8) |
|
|
|
.tickPadding(8); |
|
|
|
}; |
|
|
|
|
|
|
|
function sched(tasks) { |
|
|
|
|
|
|
|
initTimeDomain(tasks); |
|
|
|
initAxis(); |
|
|
|
|
|
|
|
function zoomed() { |
|
|
|
var px = d3.event.translate[0]; |
|
|
|
var py = d3.event.translate[1]; |
|
|
|
var dx = 0; |
|
|
|
timeDomainStart = d3.time.hour.offset( timeDomainStart, 0) |
|
|
|
if (py>0) { |
|
|
|
dx = timeDomainStart.getTime()-yScale.invert(py).getTime() |
|
|
|
} else { |
|
|
|
dx = -timeDomainStart.getTime()+yScale.invert(-py).getTime() |
|
|
|
} |
|
|
|
NewStart = d3.time.hour.offset( timeDomainStart.getTime()+dx, 0) |
|
|
|
//NewEnd = d3.time.hour.offset( timeDomainStart.getTime()+dx, 0) //.3*d3.event.scale) |
|
|
|
//yScale.domain([ NewStart , NewEnd ]) |
|
|
|
|
|
|
|
sched.timeDomainMode("fit") |
|
|
|
//sched.timeDomain([ NewStart , NewEnd ]); |
|
|
|
//timeDomainStart = NewStart |
|
|
|
//timeDomainEnd = NewEnd |
|
|
|
|
|
|
|
var dy = py; |
|
|
|
var dz = timeDomainEnd-timeDomainStart |
|
|
|
if (py>0) |
|
|
|
var dx = timeDomainStart-yScale.invert(py).getTime() |
|
|
|
else |
|
|
|
var dx = -timeDomainStart+yScale.invert(-py).getTime() |
|
|
|
|
|
|
|
//yScale.domain([ timeDomainStart, d3.time.hour.offset(timeDomainStart, d3.event.scale*4) ]) |
|
|
|
// .range([ 0, height - margin.top - margin.bottom ]) |
|
|
|
// .clamp(true); |
|
|
|
|
|
|
|
//yScale2.domain([ NewStart, d3.time.hour.offset(NewStart, d3.event.scale*4) ]) |
|
|
|
// .range([ 0, height - margin.top - margin.bottom ]) |
|
|
|
// .clamp(true); |
|
|
|
|
|
|
|
// |
|
|
|
if (0 && lastscale!=d3.event.scale) { |
|
|
|
lastscale = d3.event.scale; |
|
|
|
yScale.domain([ timeDomainStart, d3.time.hour.offset(timeDomainStart, d3.event.scale*4) ]) |
|
|
|
.range([ 0, height - margin.top - margin.bottom ]) |
|
|
|
.clamp(true); |
|
|
|
//Saved = chart.attr("transform"); |
|
|
|
//coords = Saved.slice(Saved.search(/([0-9]+)/g),Saved.length-1).split(','); |
|
|
|
//chart.attr("transform", "translate(" + px + "," + py + ")"); |
|
|
|
//zoom.translate((80,120)) |
|
|
|
//zoom.center([121, 21]) |
|
|
|
//sched.redraw(this.id, tasks); |
|
|
|
//zoom.translate() |
|
|
|
|
|
|
|
//chart.attr("transform", "translate(" + parseInt(coords[0])+px + "," + parseInt(coords[1])+py + ")"); |
|
|
|
//chart.attr("transform", "translate(" + 121 + "," + 21 + ")"); |
|
|
|
chart.attr("transform", "translate(" + px + "," + py + ")"); |
|
|
|
} |
|
|
|
// else { |
|
|
|
// chart.attr("transform", "translate(" + px + "," + py + ")"); |
|
|
|
//} |
|
|
|
|
|
|
|
var dxr = d3.time.hour.offset( timeDomainStart+dx, 0) |
|
|
|
//ind.text( py +" "+ dz +" => "+ d3.event.scale ) |
|
|
|
//if ( DragLimit.xmin < (-px) && (-px) < DragLimit.xmax ) { |
|
|
|
// } else { |
|
|
|
// d3.event.sourceEvent.stopPropagation(); |
|
|
|
// } |
|
|
|
|
|
|
|
//sched.redraw(tasks); |
|
|
|
|
|
|
|
|
|
|
|
//sched.timeDomain([ d3.time.hour.offset(mystart,0), d3.time.hour.offset(mystart, d3.event.scale) ]); |
|
|
|
if (1) { |
|
|
|
svg.select(".yAxis") |
|
|
|
.attr("transform", "translate("+ margin.left +","+ margin.top +")")// + py + ")") |
|
|
|
.transition() |
|
|
|
.call(yAxis); |
|
|
|
|
|
|
|
//svg.select(".yAxis2") |
|
|
|
// .attr("transform", "translate(80,0)") |
|
|
|
// .call(yAxis2); |
|
|
|
|
|
|
|
svg.select(".xAxis") |
|
|
|
.attr("transform", "translate("+ margin.left +","+ margin.top +")") |
|
|
|
.transition() |
|
|
|
.call(xAxis); |
|
|
|
|
|
|
|
chart.attr("transform", "translate("+ margin.left +","+ margin.top +")"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var zoom = d3.behavior.zoom() |
|
|
|
.scaleExtent([1, 4]) |
|
|
|
.on("zoom", zoomed); |
|
|
|
|
|
|
|
var svg = d3.select("#Schedule_"+EventType) |
|
|
|
.append("svg") |
|
|
|
.attr("id", EventType) |
|
|
|
.attr("class", "chart") |
|
|
|
.attr("width", width + margin.left + margin.right) |
|
|
|
.attr("height", height + margin.top + margin.bottom) |
|
|
|
.call(zoom); |
|
|
|
|
|
|
|
var chart = svg.append("g") |
|
|
|
.attr("class", "sched-chart"); |
|
|
|
|
|
|
|
chart.selectAll(".sched-chart") |
|
|
|
.data(tasks, keyFunction).enter() |
|
|
|
.append("rect") |
|
|
|
.attr("class", function(d){ |
|
|
|
if(taskStatus[d.status] == null) |
|
|
|
{ return "bar";} |
|
|
|
return taskStatus[d.status]; |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (0) { |
|
|
|
chart.selectAll('.foreignObject') |
|
|
|
.data(tasks, keyFunction).enter() |
|
|
|
.append('foreignObject') |
|
|
|
.attr("x", function(d){ |
|
|
|
return xScale(d.placeName || "unk"); |
|
|
|
}) |
|
|
|
.attr("y", function(d){ |
|
|
|
return yScale(d.startDate); |
|
|
|
}) |
|
|
|
//.attr("y", 0) |
|
|
|
//.attr("x", 2) |
|
|
|
//.attr("transform", rectTransform) |
|
|
|
.attr("width", function(d) { |
|
|
|
return xScale.rangeBand(); |
|
|
|
}) |
|
|
|
.attr("height", function(d) { |
|
|
|
return (yScale(d.endDate) - yScale(d.startDate)); |
|
|
|
}) |
|
|
|
.append("xhtml:div") |
|
|
|
.html(function(d) { |
|
|
|
return '<div style="padding:2px;height:100%"><a href="/event/'+ d.uid + |
|
|
|
'">' + d.desc + '</a></div>' |
|
|
|
}); |
|
|
|
} |
|
|
|
/* svg.selectAll("text") |
|
|
|
.data(tasks, keyFunction).enter() |
|
|
|
.append("text") |
|
|
|
.text(function(d) { return d.desc; }) |
|
|
|
.attr("x", 2) |
|
|
|
.attr("y", 16) |
|
|
|
.attr("transform", rectTransform) |
|
|
|
.attr("width", function(d) { |
|
|
|
return x.rangeBand(); |
|
|
|
}) |
|
|
|
.fill('blue'); |
|
|
|
*/ |
|
|
|
|
|
|
|
svg.append("g") |
|
|
|
.attr("class", "xAxis axis"); |
|
|
|
|
|
|
|
svg.append("g") |
|
|
|
.attr("class", "yAxis axis"); |
|
|
|
|
|
|
|
//zoomed(); |
|
|
|
//sched.redraw(tasks); |
|
|
|
return sched; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
sched.redraw = function(who, tasks) { |
|
|
|
|
|
|
|
//initTimeDomain(tasks); |
|
|
|
//initAxis(); |
|
|
|
var svg = d3.select("#"+who); |
|
|
|
|
|
|
|
var schedChartGroup = svg.select(".sched-chart"); |
|
|
|
|
|
|
|
var rect = schedChartGroup.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("x", function(d){ |
|
|
|
return xScale(d.placeName || "unk"); |
|
|
|
}) |
|
|
|
.attr("y", function(d){ |
|
|
|
return yScale(d.startDate); |
|
|
|
}) |
|
|
|
//.attr("transform", rectTransform) |
|
|
|
.attr("width", function(d) { |
|
|
|
return xScale.rangeBand(); |
|
|
|
}) |
|
|
|
.attr("height", function(d) { |
|
|
|
return (yScale(d.endDate) - yScale(d.startDate)); |
|
|
|
}); |
|
|
|
|
|
|
|
rect.transition() |
|
|
|
//.attr("transform", rectTransform) |
|
|
|
.attr("x", function(d){ |
|
|
|
return xScale(d.placeName || "unk"); |
|
|
|
}) |
|
|
|
.attr("y", function(d){ |
|
|
|
return yScale(d.startDate); |
|
|
|
}) |
|
|
|
.attr("width", function(d) { |
|
|
|
return xScale.rangeBand(); |
|
|
|
}) |
|
|
|
.attr("height", function(d) { |
|
|
|
return (yScale(d.endDate) - yScale(d.startDate)); |
|
|
|
}); |
|
|
|
|
|
|
|
rect.exit() |
|
|
|
.remove(); |
|
|
|
|
|
|
|
var content = schedChartGroup.selectAll("foreignObject") |
|
|
|
.data(tasks, keyFunction); |
|
|
|
|
|
|
|
content.enter() |
|
|
|
.insert("foreignObject",":first-child") |
|
|
|
//.transition() |
|
|
|
.attr("x", function(d){ |
|
|
|
return xScale(d.placeName || "unk"); |
|
|
|
}) |
|
|
|
.attr("y", function(d){ |
|
|
|
return yScale(d.startDate); |
|
|
|
}) |
|
|
|
//.attr("transform", rectTransform) |
|
|
|
.attr("width", function(d) { |
|
|
|
return xScale.rangeBand(); |
|
|
|
}) |
|
|
|
.attr("height", function(d) { |
|
|
|
return (yScale(d.endDate) - yScale(d.startDate)); |
|
|
|
}) |
|
|
|
.append("xhtml:div") |
|
|
|
.html(function(d) { |
|
|
|
return '<div style="padding:2px;height:100%"><a href="/event/'+ d.uid + |
|
|
|
'">' + d.desc + '</a></div>' |
|
|
|
}); |
|
|
|
|
|
|
|
content.transition() |
|
|
|
//.attr("transform", rectTransform) |
|
|
|
.attr("x", function(d){ |
|
|
|
return xScale(d.placeName || "unk"); |
|
|
|
}) |
|
|
|
.attr("y", function(d){ |
|
|
|
return yScale(d.startDate); |
|
|
|
}) |
|
|
|
.attr("width", function(d) { |
|
|
|
return xScale.rangeBand(); |
|
|
|
}) |
|
|
|
.attr("height", function(d) { |
|
|
|
return (yScale(d.endDate) - yScale(d.startDate)); |
|
|
|
}); |
|
|
|
|
|
|
|
content.exit() |
|
|
|
.remove(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.margin = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return margin; |
|
|
|
margin = value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.timeDomain = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return [ timeDomainStart, timeDomainEnd ]; |
|
|
|
timeDomainStart = +value[0], timeDomainEnd = +value[1]; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* @param {string} |
|
|
|
* vale The value can be "fit" - the domain fits the data or |
|
|
|
* "fixed" - fixed domain. |
|
|
|
*/ |
|
|
|
sched.timeDomainMode = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return timeDomainMode; |
|
|
|
timeDomainMode = value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.taskTypes = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return taskTypes; |
|
|
|
taskTypes = value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.taskStatus = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return taskStatus; |
|
|
|
taskStatus = value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.width = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return width; |
|
|
|
width = +value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.height = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return height; |
|
|
|
height = +value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.tickFormat = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return tickFormat; |
|
|
|
tickFormat = value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
sched.name = function(value) { |
|
|
|
if (!arguments.length) |
|
|
|
return myname; |
|
|
|
myname = value; |
|
|
|
return sched; |
|
|
|
}; |
|
|
|
|
|
|
|
return sched; |
|
|
|
}; |