|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- var taskStatus = {'Stand':'Stand',
- 'Table ronde':'Table-ronde',
- 'Atelier':'Atelier',
- 'Concert':'Concert',
- 'Conference':'Conference',
- 'Repas':'Repas'};
- var tickFormat = "%H:%M";
- var margin = {
- top : 15,
- right : 0,
- bottom : 0,
- left : 50
- };
- var height = 500;
- var width = 730;
- var Keys = Array();
- var Salles = Array();
- var Areas = Array();
- var Tasks = Array();
-
-
- d3.json("le-prog-json",
- function(error, json) {
- if (error) return console.warn(error);
- var Keys = Object.keys(json["all"]);
- // Build set of data in memory
- for (var k = 0; k < Keys.length; k++) {
- Salles[Keys[k]] = Array();
- Areas[Keys[k]] = Array();
- Tasks[Keys[k]] = json["all"][Keys[k]];
- // Fix Json to make date objects
- Tasks[Keys[k]].forEach(function(d) {
- d.startDate = new Date(d.startDate);
- d.endDate = new Date(d.endDate);
- });
-
- // Build the list of Salles and Areas
- Tasks[Keys[k]].forEach(function(d) {
- Salles[Keys[k]].push( d.placeName );
- Areas[Keys[k]].push( d.status );
- } );
- Salles[Keys[k]] = d3.set(Salles[Keys[k]]).values();
- Areas[Keys[k]] = d3.set(Areas[Keys[k]]).values();
- // Create Controls to Handle user selection
- Areas[Keys[k]].forEach(function(TypeArea) {
- d3.select("#Schedule_SVG_"+Keys[k])
- .append("input")
- .attr("type", "checkbox")
- .attr("name", "OptTimetable-"+Keys[k])
- .attr("id", TypeArea+"-"+Keys[k])
- .attr("area", TypeArea)
- .style("float", "left")
- .style("margin-left", "20px")
- .style("margin-right", "3px")
- .property("checked",true);
-
- d3.select("#Schedule_SVG_"+Keys[k])
- .append("label")
- .attr("for", TypeArea+"-"+Keys[k])
- .style("float", "left")
- .style("margin-left", "5px")
- .text(TypeArea);
- });
-
- d3.select("#Schedule_SVG_"+Keys[k])
- .append("br");
-
- // Create a dedicated SVG for it
- svg = d3.select("#Schedule_SVG_"+Keys[k])
- .append("svg")
- .attr("id", "TimeTable-"+Keys[k])
- .attr("width", "100%") //width + margin.right + margin.left)
- //.attr("height", height + margin.top + margin.bottom)
- .attr("viewBox", "0 0 " + (width + margin.right + margin.left) + " " + (height + margin.top + margin.bottom) )
- .attr("preserveAspectRatio", "xMidYMid meet");
- // Add some gradient
- header(svg);
- // Create axis
- svg.append("g")
- .attr("class", "xAxis axis");
-
- svg.append("g")
- .attr("class", "yAxis axis");
-
- var chart = svg.append("g")
- .attr("class", "timetable");
-
- HandleEvents(Keys[k]);
- displayit(json["all"][Keys[k]], Salles[Keys[k]], Keys[k]);
- }
- });
-
- function header(svg) {
- defs = svg.append("svg:defs");
-
- conf = defs.append("svg:linearGradient")
- .attr("id", "BoxGradient-Conference")
- .attr("x1", "100%")
- .attr("y1", "0%")
- .attr("x2", "50%")
- .attr("y2", "100%")
- .attr("spreadMethod", "pad");
-
- conf.append("svg:stop")
- .attr("offset", "0%")
- .attr("stop-color", "#EEE")
- .attr("stop-opacity", 0);
-
- conf.append("svg:stop")
- .attr("offset", "15%")
- .attr("stop-color", "#BDF86B")
- .attr("stop-opacity", .5);
-
- atlier = defs.append("svg:linearGradient")
- .attr("id", "BoxGradient-Atelier")
- .attr("x1", "100%")
- .attr("y1", "0%")
- .attr("x2", "50%")
- .attr("y2", "100%")
- .attr("spreadMethod", "pad");
-
- atlier.append("svg:stop")
- .attr("offset", "0%")
- .attr("stop-color", "#EEE")
- .attr("stop-opacity", 0);
-
- atlier.append("svg:stop")
- .attr("offset", "15%")
- .attr("stop-color", "#FF856E")
- .attr("stop-opacity", .5);
-
- // append filter element
- var filter = defs.append( 'filter' )
- .attr( 'id', 'dropshadow' ); /// !!! important - define id to reference it later
-
- // append gaussian blur to filter
- filter.append( 'feGaussianBlur' )
- .attr( 'in', 'SourceAlpha' )
- .attr( 'stdDeviation', 3 ) // !!! important parameter - blur
- .attr( 'result', 'blur' );
-
- // append offset filter to result of gaussion blur filter
- filter.append( 'feOffset' )
- .attr( 'in', 'blur' )
- .attr( 'dx', 2 ) // !!! important parameter - x-offset
- .attr( 'dy', 2 ) // !!! important parameter - y-offset
- .attr( 'result', 'offsetBlur' );
-
- filter.append( 'feComponentTransfer' )
- .append( 'feFuncA' )
- .attr( "type", "linear" )
- .attr( "slope", "0.4" );
-
- // merge result with original image
- var feMerge = filter.append( 'feMerge' );
-
- // first layer result of blur and offset
- feMerge.append( 'feMergeNode' )
- .attr( 'in", "offsetBlur' );
-
- // original image on top
- feMerge.append( 'feMergeNode' )
- .attr( 'in', 'SourceGraphic' );
- // end filter stuff
-
- }
-
-
- var keyFunction = function(d) {
- return d.startDate + d.placeName + d.endDate;
- };
-
- function HandleEvents(Ctrl) {
- d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")
- .data(Areas[Ctrl])
- .on("change", function(TypeData) {
- ArrayChoice = Array();
- checked = d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")[0]
- .forEach( function(v)
- {
- if (d3.select(v).node().checked)
- ArrayChoice.push(v.attributes['area'].value);
- }
- );
- area_select = Array();
- selection = Tasks[Ctrl].filter(function(v) {
- return ArrayChoice.indexOf(v.status)>=0;
- });
- if (selection.length) {
- selection.forEach(function(d)
- { area_select.push( d.placeName ); }
- );
- area_select = d3.set(area_select).values();
- displayit(selection, area_select, Ctrl);
- d3.select("#TimeTable-"+Ctrl)[0][0].style.opacity = 1;
- } else {
- d3.select("#TimeTable-"+Ctrl)[0][0].style.opacity = 0;
- }
- });
- }
-
-
- function displayit(Set_of_Task, Set_of_Area, key) {
- // Try to compute time range
- Set_of_Task.sort(function(a, b) {
- return a.startDate - b.startDate;
- });
- timeDomainStart = Set_of_Task[0].startDate;
- Set_of_Task.sort(function(a, b) {
- return a.endDate - b.endDate;
- });
- timeDomainEnd = Set_of_Task[Set_of_Task.length - 1].endDate;
-
- // Prepare scales
- xScale = d3.scale.ordinal()
- .domain(Set_of_Area)
- .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);
-
- var svg = d3.select("#TimeTable-"+key);
-
- var chart = svg.select(".timetable");
-
- var rect = chart.selectAll("rect")
- .data(Set_of_Task, keyFunction);
-
- rect.enter()
- .insert("rect")
- .attr("rx", 5)
- .attr("ry", 5)
- .attr("filter", "url(#dropshadow)")
- .style("fill", function(d){
- return "url(#BoxGradient-"+ taskStatus[d.status] +")";
- })
- .attr("class", function(d){
- if(taskStatus[d.status] == null)
- { return "bar";}
- return taskStatus[d.status];
- })
- .transition()
- .duration(750);
-
-
- rect.transition()
- .duration(750)
- .attr("x", function(d){
- return xScale(d.placeName || "unk");
- })
- .attr("y", function(d){
- return yScale( d.startDate )+1;
- })
- .attr("width", function(d) {
- return xScale.rangeBand();
- })
- .attr("height", function(d) {
- return (yScale( d.endDate ) - yScale( d.startDate )-2);
- });
-
- rect.exit()
- .transition()
- .duration(300)
- .style("opacity", 1e-6)
- .remove();
-
- var content = chart.selectAll("foreignObject")
- .data(Set_of_Task, keyFunction);
-
- content.enter()
- .insert("foreignObject")
- .append("xhtml:div")
- .attr("class", "SvgBody")
- .html(function(d) {
- return '<div class="EvtBox '+ taskStatus[d.status] +'"><a href="/event/'+ d.uid +
- '">' + d.desc + '</a></div>';
- })
- .transition()
- .duration(750);
-
- content.transition()
- .duration(750)
- .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 ));
- });
- // .attr("transform" ,"scale(1)");
-
- content.exit()
- .transition()
- .duration(300)
- .style("opacity", 1e-6)
- .remove();
-
- svg.select(".yAxis")
- .attr("transform", "translate("+ margin.left +","+ margin.top +")")
- .transition()
- .call(yAxis);
-
- svg.select(".xAxis")
- .attr("transform", "translate("+ margin.left +","+ margin.top +")")
- .transition()
- .call(xAxis);
-
- chart.attr("transform", "translate("+ margin.left +","+ margin.top +")");
- }
|