Le repo des sources pour le site web des JM2L
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

246 lignes
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. }