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.
 
 
 
 
 

438 lignes
13 KiB

  1. /**
  2. * inspired from @author Dimitry Kudrayvtsev
  3. * @author tr4ck3ur
  4. */
  5. d3.sched = function(EventType) {
  6. var FIT_TIME_DOMAIN_MODE = "fit";
  7. var FIXED_TIME_DOMAIN_MODE = "fixed";
  8. var myname = EventType;
  9. var margin = {
  10. top : 15,
  11. right : 10,
  12. bottom : 10,
  13. left : 50
  14. };
  15. var timeDomainStart = d3.time.hour.offset(new Date(),-2);
  16. var timeDomainEnd = d3.time.hour.offset(new Date(),+2);
  17. var timeDomainMode = FIT_TIME_DOMAIN_MODE;// fixed or fit
  18. var taskTypes = [];
  19. var taskStatus = [];
  20. //var height = document.body.clientHeight - margin.top - margin.bottom-5;
  21. height = 700;
  22. //var width = document.body.clientWidth - margin.right - margin.left-5;
  23. var width = 700;// - margin.right - margin.left;
  24. var tickFormat = "%H:%M";
  25. var lastscale = -1;
  26. var xScale = d3.scale.ordinal()
  27. .domain(taskTypes)
  28. .rangeRoundBands([ 0, width - margin.left], .1);
  29. var yScale = d3.time.scale()
  30. .domain([ timeDomainStart, timeDomainEnd ])
  31. .range([ 0, height - margin.top ]) //- margin.bottom ]);
  32. .clamp(true);
  33. var xAxis = d3.svg.axis()
  34. .scale(xScale)
  35. .orient("left")
  36. .tickSize(1);
  37. var yAxis = d3.svg.axis()
  38. .scale(yScale)
  39. .orient("bottom")
  40. .tickFormat(d3.time.format(tickFormat))
  41. .tickSubdivide(true)
  42. .tickSize(8).tickPadding(8);
  43. var keyFunction = function(d) {
  44. return d.startDate + d.placeName + d.endDate;
  45. };
  46. var rectTransform = function(d) {
  47. return "translate(" + xScale(d.placeName) + "," + yScale(d.startDate) + ")";
  48. };
  49. var initTimeDomain = function(tasks) {
  50. if (timeDomainMode === FIT_TIME_DOMAIN_MODE) {
  51. if (tasks === undefined || tasks.length < 1) {
  52. timeDomainStart = d3.time.day.offset(new Date(), -3);
  53. timeDomainEnd = d3.time.hour.offset(new Date(), +3);
  54. return;
  55. }
  56. tasks.sort(function(a, b) {
  57. return a.endDate - b.endDate;
  58. });
  59. timeDomainEnd = tasks[tasks.length - 1].endDate;
  60. tasks.sort(function(a, b) {
  61. return a.startDate - b.startDate;
  62. });
  63. timeDomainStart = tasks[0].startDate;
  64. }
  65. };
  66. var initAxis = function() {
  67. xScale = d3.scale.ordinal()
  68. .domain(taskTypes)
  69. .rangeRoundBands([ 0, width ], .1);
  70. yScale = d3.time.scale()
  71. .domain([ timeDomainStart, timeDomainEnd ])
  72. .range([ 0, height - margin.top - margin.bottom ])
  73. .clamp(true);
  74. xAxis = d3.svg.axis()
  75. .scale(xScale)
  76. .orient("top")
  77. .tickSize(1);
  78. yAxis = d3.svg.axis()
  79. .scale(yScale)
  80. .orient("left")
  81. .tickFormat(d3.time.format(tickFormat))
  82. .tickSubdivide(true)
  83. .tickSize(8)
  84. .tickPadding(8);
  85. };
  86. function sched(tasks) {
  87. initTimeDomain(tasks);
  88. initAxis();
  89. function zoomed() {
  90. var px = d3.event.translate[0];
  91. var py = d3.event.translate[1];
  92. var dx = 0;
  93. timeDomainStart = d3.time.hour.offset( timeDomainStart, 0)
  94. if (py>0) {
  95. dx = timeDomainStart.getTime()-yScale.invert(py).getTime()
  96. } else {
  97. dx = -timeDomainStart.getTime()+yScale.invert(-py).getTime()
  98. }
  99. NewStart = d3.time.hour.offset( timeDomainStart.getTime()+dx, 0)
  100. //NewEnd = d3.time.hour.offset( timeDomainStart.getTime()+dx, 0) //.3*d3.event.scale)
  101. //yScale.domain([ NewStart , NewEnd ])
  102. sched.timeDomainMode("fit")
  103. //sched.timeDomain([ NewStart , NewEnd ]);
  104. //timeDomainStart = NewStart
  105. //timeDomainEnd = NewEnd
  106. var dy = py;
  107. var dz = timeDomainEnd-timeDomainStart
  108. if (py>0)
  109. var dx = timeDomainStart-yScale.invert(py).getTime()
  110. else
  111. var dx = -timeDomainStart+yScale.invert(-py).getTime()
  112. //yScale.domain([ timeDomainStart, d3.time.hour.offset(timeDomainStart, d3.event.scale*4) ])
  113. // .range([ 0, height - margin.top - margin.bottom ])
  114. // .clamp(true);
  115. //yScale2.domain([ NewStart, d3.time.hour.offset(NewStart, d3.event.scale*4) ])
  116. // .range([ 0, height - margin.top - margin.bottom ])
  117. // .clamp(true);
  118. //
  119. if (0 && lastscale!=d3.event.scale) {
  120. lastscale = d3.event.scale;
  121. yScale.domain([ timeDomainStart, d3.time.hour.offset(timeDomainStart, d3.event.scale*4) ])
  122. .range([ 0, height - margin.top - margin.bottom ])
  123. .clamp(true);
  124. //Saved = chart.attr("transform");
  125. //coords = Saved.slice(Saved.search(/([0-9]+)/g),Saved.length-1).split(',');
  126. //chart.attr("transform", "translate(" + px + "," + py + ")");
  127. //zoom.translate((80,120))
  128. //zoom.center([121, 21])
  129. //sched.redraw(this.id, tasks);
  130. //zoom.translate()
  131. //chart.attr("transform", "translate(" + parseInt(coords[0])+px + "," + parseInt(coords[1])+py + ")");
  132. //chart.attr("transform", "translate(" + 121 + "," + 21 + ")");
  133. chart.attr("transform", "translate(" + px + "," + py + ")");
  134. }
  135. // else {
  136. // chart.attr("transform", "translate(" + px + "," + py + ")");
  137. //}
  138. var dxr = d3.time.hour.offset( timeDomainStart+dx, 0)
  139. //ind.text( py +" "+ dz +" => "+ d3.event.scale )
  140. //if ( DragLimit.xmin < (-px) && (-px) < DragLimit.xmax ) {
  141. // } else {
  142. // d3.event.sourceEvent.stopPropagation();
  143. // }
  144. //sched.redraw(tasks);
  145. //sched.timeDomain([ d3.time.hour.offset(mystart,0), d3.time.hour.offset(mystart, d3.event.scale) ]);
  146. if (1) {
  147. svg.select(".yAxis")
  148. .attr("transform", "translate("+ margin.left +","+ margin.top +")")// + py + ")")
  149. .transition()
  150. .call(yAxis);
  151. //svg.select(".yAxis2")
  152. // .attr("transform", "translate(80,0)")
  153. // .call(yAxis2);
  154. svg.select(".xAxis")
  155. .attr("transform", "translate("+ margin.left +","+ margin.top +")")
  156. .transition()
  157. .call(xAxis);
  158. chart.attr("transform", "translate("+ margin.left +","+ margin.top +")");
  159. }
  160. }
  161. var zoom = d3.behavior.zoom()
  162. .scaleExtent([1, 4])
  163. .on("zoom", zoomed);
  164. var svg = d3.select("#Schedule_"+EventType)
  165. .append("svg")
  166. .attr("id", EventType)
  167. .attr("class", "chart")
  168. .attr("width", width + margin.left + margin.right)
  169. .attr("height", height + margin.top + margin.bottom)
  170. .call(zoom);
  171. var chart = svg.append("g")
  172. .attr("class", "sched-chart");
  173. chart.selectAll(".sched-chart")
  174. .data(tasks, keyFunction).enter()
  175. .append("rect")
  176. .attr("class", function(d){
  177. if(taskStatus[d.status] == null)
  178. { return "bar";}
  179. return taskStatus[d.status];
  180. });
  181. if (0) {
  182. chart.selectAll('.foreignObject')
  183. .data(tasks, keyFunction).enter()
  184. .append('foreignObject')
  185. .attr("x", function(d){
  186. return xScale(d.placeName || "unk");
  187. })
  188. .attr("y", function(d){
  189. return yScale(d.startDate);
  190. })
  191. //.attr("y", 0)
  192. //.attr("x", 2)
  193. //.attr("transform", rectTransform)
  194. .attr("width", function(d) {
  195. return xScale.rangeBand();
  196. })
  197. .attr("height", function(d) {
  198. return (yScale(d.endDate) - yScale(d.startDate));
  199. })
  200. .append("xhtml:div")
  201. .html(function(d) {
  202. return '<div style="padding:2px;height:100%"><a href="/event/'+ d.uid +
  203. '">' + d.desc + '</a></div>'
  204. });
  205. }
  206. /* svg.selectAll("text")
  207. .data(tasks, keyFunction).enter()
  208. .append("text")
  209. .text(function(d) { return d.desc; })
  210. .attr("x", 2)
  211. .attr("y", 16)
  212. .attr("transform", rectTransform)
  213. .attr("width", function(d) {
  214. return x.rangeBand();
  215. })
  216. .fill('blue');
  217. */
  218. svg.append("g")
  219. .attr("class", "xAxis axis");
  220. svg.append("g")
  221. .attr("class", "yAxis axis");
  222. //zoomed();
  223. //sched.redraw(tasks);
  224. return sched;
  225. };
  226. sched.redraw = function(who, tasks) {
  227. //initTimeDomain(tasks);
  228. //initAxis();
  229. var svg = d3.select("#"+who);
  230. var schedChartGroup = svg.select(".sched-chart");
  231. var rect = schedChartGroup.selectAll("rect")
  232. .data(tasks, keyFunction);
  233. rect.enter()
  234. .insert("rect",":first-child")
  235. .attr("rx", 5)
  236. .attr("ry", 5)
  237. .attr("class", function(d){
  238. if(taskStatus[d.status] == null)
  239. { return "bar";}
  240. return taskStatus[d.status];
  241. })
  242. //.transition()
  243. .attr("x", function(d){
  244. return xScale(d.placeName || "unk");
  245. })
  246. .attr("y", function(d){
  247. return yScale(d.startDate);
  248. })
  249. //.attr("transform", rectTransform)
  250. .attr("width", function(d) {
  251. return xScale.rangeBand();
  252. })
  253. .attr("height", function(d) {
  254. return (yScale(d.endDate) - yScale(d.startDate));
  255. });
  256. rect.transition()
  257. //.attr("transform", rectTransform)
  258. .attr("x", function(d){
  259. return xScale(d.placeName || "unk");
  260. })
  261. .attr("y", function(d){
  262. return yScale(d.startDate);
  263. })
  264. .attr("width", function(d) {
  265. return xScale.rangeBand();
  266. })
  267. .attr("height", function(d) {
  268. return (yScale(d.endDate) - yScale(d.startDate));
  269. });
  270. rect.exit()
  271. .remove();
  272. var content = schedChartGroup.selectAll("foreignObject")
  273. .data(tasks, keyFunction);
  274. content.enter()
  275. .insert("foreignObject",":first-child")
  276. //.transition()
  277. .attr("x", function(d){
  278. return xScale(d.placeName || "unk");
  279. })
  280. .attr("y", function(d){
  281. return yScale(d.startDate);
  282. })
  283. //.attr("transform", rectTransform)
  284. .attr("width", function(d) {
  285. return xScale.rangeBand();
  286. })
  287. .attr("height", function(d) {
  288. return (yScale(d.endDate) - yScale(d.startDate));
  289. })
  290. .append("xhtml:div")
  291. .html(function(d) {
  292. return '<div style="padding:2px;height:100%"><a href="/event/'+ d.uid +
  293. '">' + d.desc + '</a></div>'
  294. });
  295. content.transition()
  296. //.attr("transform", rectTransform)
  297. .attr("x", function(d){
  298. return xScale(d.placeName || "unk");
  299. })
  300. .attr("y", function(d){
  301. return yScale(d.startDate);
  302. })
  303. .attr("width", function(d) {
  304. return xScale.rangeBand();
  305. })
  306. .attr("height", function(d) {
  307. return (yScale(d.endDate) - yScale(d.startDate));
  308. });
  309. content.exit()
  310. .remove();
  311. return sched;
  312. };
  313. sched.margin = function(value) {
  314. if (!arguments.length)
  315. return margin;
  316. margin = value;
  317. return sched;
  318. };
  319. sched.timeDomain = function(value) {
  320. if (!arguments.length)
  321. return [ timeDomainStart, timeDomainEnd ];
  322. timeDomainStart = +value[0], timeDomainEnd = +value[1];
  323. return sched;
  324. };
  325. /**
  326. * @param {string}
  327. * vale The value can be "fit" - the domain fits the data or
  328. * "fixed" - fixed domain.
  329. */
  330. sched.timeDomainMode = function(value) {
  331. if (!arguments.length)
  332. return timeDomainMode;
  333. timeDomainMode = value;
  334. return sched;
  335. };
  336. sched.taskTypes = function(value) {
  337. if (!arguments.length)
  338. return taskTypes;
  339. taskTypes = value;
  340. return sched;
  341. };
  342. sched.taskStatus = function(value) {
  343. if (!arguments.length)
  344. return taskStatus;
  345. taskStatus = value;
  346. return sched;
  347. };
  348. sched.width = function(value) {
  349. if (!arguments.length)
  350. return width;
  351. width = +value;
  352. return sched;
  353. };
  354. sched.height = function(value) {
  355. if (!arguments.length)
  356. return height;
  357. height = +value;
  358. return sched;
  359. };
  360. sched.tickFormat = function(value) {
  361. if (!arguments.length)
  362. return tickFormat;
  363. tickFormat = value;
  364. return sched;
  365. };
  366. sched.name = function(value) {
  367. if (!arguments.length)
  368. return myname;
  369. myname = value;
  370. return sched;
  371. };
  372. return sched;
  373. };