Le repo des sources pour le site web des JM2L
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 

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