Le repo des sources pour le site web des JM2L
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

246 lines
8.2 KiB

  1. var taskStatus = {'Stand':'Stand',
  2. 'Table ronde':'Table-ronde',
  3. 'Atelier':'Atelier',
  4. 'Concert':'Concert',
  5. 'Conference':'Conference',
  6. 'Repas':'Repas'};
  7. var tickFormat = "%H:%M";
  8. var margin = {
  9. top : 15,
  10. right : 0,
  11. bottom : 0,
  12. left : 50
  13. };
  14. var height = 500;
  15. var width = 730;
  16. var Keys = Array();
  17. var Salles = Array();
  18. var Areas = Array();
  19. var Tasks = Array();
  20. d3.json("le-prog-json",
  21. function(error, json) {
  22. if (error) return console.warn(error);
  23. var Keys = Object.keys(json["all"])
  24. // Build set of data in memory
  25. for (var k = 0; k < Keys.length; k++) {
  26. Salles[Keys[k]] = Array();
  27. Areas[Keys[k]] = Array();
  28. Tasks[Keys[k]] = json["all"][Keys[k]]
  29. // Fix Json to make date objects
  30. Tasks[Keys[k]].forEach(function(d) {
  31. d.startDate = new Date(d.startDate);
  32. d.endDate = new Date(d.endDate);
  33. })
  34. // Build the list of Salles and Areas
  35. Tasks[Keys[k]].forEach(function(d) {
  36. Salles[Keys[k]].push( d.placeName );
  37. Areas[Keys[k]].push( d.status );
  38. } )
  39. Salles[Keys[k]] = d3.set(Salles[Keys[k]]).values();
  40. Areas[Keys[k]] = d3.set(Areas[Keys[k]]).values();
  41. // Create Controls to Handle user selection
  42. Areas[Keys[k]].forEach(function(TypeArea) {
  43. d3.select("#Schedule_SVG_"+Keys[k])
  44. .append("input")
  45. .attr("type", "checkbox")
  46. .attr("name", "OptTimetable-"+Keys[k])
  47. .attr("id", TypeArea+"-"+Keys[k])
  48. .attr("area", TypeArea)
  49. .style("float", "left")
  50. .style("margin-left", "20px")
  51. .style("margin-right", "3px")
  52. .property("checked",true);
  53. d3.select("#Schedule_SVG_"+Keys[k])
  54. .append("label")
  55. .attr("for", TypeArea+"-"+Keys[k])
  56. .style("float", "left")
  57. .style("margin-left", "5px")
  58. .text(TypeArea);
  59. });
  60. // Create a dedicated SVG for it
  61. svg = d3.select("#Schedule_SVG_"+Keys[k])
  62. .append("svg")
  63. .attr("id", "TimeTable-"+Keys[k])
  64. .attr("width", "100%") //width + margin.right + margin.left)
  65. //.attr("height", height + margin.top + margin.bottom)
  66. .attr("viewBox", "0 0 " + (width + margin.right + margin.left) + " " + (height + margin.top + margin.bottom) )
  67. .attr("preserveAspectRatio", "xMidYMid meet");
  68. svg.append("g")
  69. .attr("class", "xAxis axis");
  70. svg.append("g")
  71. .attr("class", "yAxis axis");
  72. var chart = svg.append("g")
  73. .attr("class", "timetable");
  74. HandleEvents(Keys[k]);
  75. displayit(json["all"][Keys[k]], Salles[Keys[k]], Keys[k]);
  76. }
  77. });
  78. var keyFunction = function(d) {
  79. return d.startDate + d.placeName + d.endDate;
  80. };
  81. function HandleEvents(Ctrl) {
  82. d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")
  83. .data(Areas[Ctrl])
  84. .on("change", function(TypeData) {
  85. ArrayChoice = Array()
  86. checked = d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")[0]
  87. .forEach( function(v)
  88. {
  89. if (d3.select(v).node().checked)
  90. ArrayChoice.push(v.attributes['area'].value)
  91. }
  92. )
  93. area_select = Array();
  94. selection = Tasks[Ctrl].filter(function(v) {
  95. return ArrayChoice.indexOf(v.status)>=0;
  96. });
  97. if (selection.length) {
  98. selection.forEach(function(d)
  99. { area_select.push( d.placeName ); }
  100. );
  101. area_select = d3.set(area_select).values();
  102. displayit(selection, area_select, Ctrl);
  103. d3.select("#TimeTable-"+Ctrl)[0][0].style.opacity = 1;
  104. } else {
  105. d3.select("#TimeTable-"+Ctrl)[0][0].style.opacity = 0;
  106. }
  107. });
  108. }
  109. function displayit(Set_of_Task, Set_of_Area, key) {
  110. // Try to compute time range
  111. Set_of_Task.sort(function(a, b) {
  112. return a.startDate - b.startDate;
  113. });
  114. timeDomainStart = Set_of_Task[0].startDate;
  115. Set_of_Task.sort(function(a, b) {
  116. return a.endDate - b.endDate;
  117. });
  118. timeDomainEnd = Set_of_Task[Set_of_Task.length - 1].endDate;
  119. // Prepare scales
  120. xScale = d3.scale.ordinal()
  121. .domain(Set_of_Area)
  122. .rangeRoundBands([ 0, width ], .1);
  123. yScale = d3.time.scale()
  124. .domain([ timeDomainStart, timeDomainEnd ])
  125. .range([ 0, height - margin.top - margin.bottom ])
  126. .clamp(true);
  127. xAxis = d3.svg.axis()
  128. .scale(xScale)
  129. .orient("top")
  130. .tickSize(1);
  131. yAxis = d3.svg.axis()
  132. .scale(yScale)
  133. .orient("left")
  134. .tickFormat(d3.time.format(tickFormat))
  135. .tickSubdivide(true)
  136. .tickSize(8)
  137. .tickPadding(8);
  138. var svg = d3.select("#TimeTable-"+key);
  139. var chart = svg.select(".timetable")
  140. var content = chart.selectAll("foreignObject")
  141. .data(Set_of_Task, keyFunction);
  142. content.enter()
  143. .insert("foreignObject",":first-child")
  144. .append("xhtml:body")
  145. .attr("class", "SvgBody")
  146. .html(function(d) {
  147. return '<div class="EvtBox '+ taskStatus[d.status] +'"><a href="/event/'+ d.uid +
  148. '">' + d.desc + '</a></div>'
  149. })
  150. .transition()
  151. .duration(750);
  152. content.transition()
  153. .duration(750)
  154. .attr("x", function(d){
  155. return xScale(d.placeName || "unk");
  156. })
  157. .attr("y", function(d){
  158. return yScale( d.startDate );
  159. })
  160. .attr("width", function(d) {
  161. return xScale.rangeBand();
  162. })
  163. .attr("height", function(d) {
  164. return (yScale( d.endDate ) - yScale( d.startDate ));
  165. });
  166. content.exit()
  167. .transition()
  168. .duration(300)
  169. .style("opacity", 1e-6)
  170. .remove();
  171. var rect = chart.selectAll("rect")
  172. .data(Set_of_Task, keyFunction);
  173. rect.enter()
  174. .insert("rect",":first-child")
  175. .attr("rx", 5)
  176. .attr("ry", 5)
  177. .attr("filter", "url(/img/shadow.svg#dropshadow)")
  178. .attr("style", function(d){
  179. return "fill:url(/img/shadow.svg#BoxGradient-"+ taskStatus[d.status] +")"
  180. })
  181. .attr("class", function(d){
  182. if(taskStatus[d.status] == null)
  183. { return "bar";}
  184. return taskStatus[d.status];
  185. })
  186. .transition()
  187. .duration(750)
  188. rect.transition()
  189. .duration(750)
  190. .attr("x", function(d){
  191. return xScale(d.placeName || "unk");
  192. })
  193. .attr("y", function(d){
  194. return yScale( d.startDate )+1;
  195. })
  196. .attr("width", function(d) {
  197. return xScale.rangeBand();
  198. })
  199. .attr("height", function(d) {
  200. return (yScale( d.endDate ) - yScale( d.startDate )-2);
  201. });
  202. rect.exit()
  203. .transition()
  204. .duration(300)
  205. .style("opacity", 1e-6)
  206. .remove();
  207. svg.select(".yAxis")
  208. .attr("transform", "translate("+ margin.left +","+ margin.top +")")
  209. .transition()
  210. .call(yAxis);
  211. svg.select(".xAxis")
  212. .attr("transform", "translate("+ margin.left +","+ margin.top +")")
  213. .transition()
  214. .call(xAxis);
  215. chart.attr("transform", "translate("+ margin.left +","+ margin.top +")");
  216. }