Le repo des sources pour le site web des JM2L
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

438 linhas
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. };