charts.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // jQuery UI style "widget" for charts
  2. Raphael.fn.ball = function (x, y, r, hue)
  3. {
  4. hue = hue || 0;
  5. return this.set(
  6. this.ellipse(x, y + r - r / 3, r, r / 2).attr({fill: "rhsb(" + hue + ", 0, .25)-hsb(" + hue + ", 0, .25)", stroke: "none", opacity: 0}),
  7. this.ellipse(x, y, r, r).attr({fill: "0-#000-#ccc-#000", stroke: "none"}),
  8. this.ellipse(x, y, r*0.95, r*0.95 ).attr({fill: "r(.5,.9)hsb(" + hue + ", 0, .75)-hsb(" + hue + ", 0, .25)", stroke: "none"}),
  9. this.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
  10. );
  11. };
  12. $(function()
  13. {
  14. // the widget definition, where "itop" is the namespace,
  15. // "pie_chart" the widget name
  16. $.widget( "itop.pie_chart",
  17. {
  18. // default options
  19. options:
  20. {
  21. chart_id: '',
  22. chart_label: '',
  23. values: [],
  24. labels: [],
  25. hrefs: []
  26. },
  27. // the constructor
  28. _create: function()
  29. {
  30. var me = this;
  31. this.element
  32. .addClass('itop-pie_chart');
  33. this.oR = Raphael(this.element.get(0), this.element.width(), this.element.height());
  34. $(window).bind('resize.pie_chart', function() { me._refresh(); });
  35. this._refresh();
  36. },
  37. _clear_r: function()
  38. {
  39. this.oR.clear();
  40. },
  41. // called when created, and later when changing options
  42. _refresh: function()
  43. {
  44. this._clear_r();
  45. var me = this;
  46. this._compute_size();
  47. this.oR.ball(this.x, this.y, this.r, 0);
  48. var aColors = [];
  49. var hue = 0;
  50. var brightness = 1;
  51. for(index = 0; index < 30; index++)
  52. {
  53. hue = (hue+137) % 360;
  54. brightness = 1-((Math.floor(index / 3) % 4) / 8);
  55. aColors.push('hsba('+(hue/360.0)+',1,'+brightness+',0.6)');
  56. //aColors.push('hsba('+(hue/360.0)+',0.5,0.5,0.4)');
  57. }
  58. var aVals = this.options.values.slice(0); // Clone the array since the pie function will alter it
  59. this.pie = this.oR.piechart(this.x, this.y, this.r, aVals, { legend: this.options.labels, legendpos: "east", href: this.options.hrefs, colors: aColors });
  60. this.oR.text(this.x, 10, this.options.chart_label).attr({ font: "20px 'Fontin Sans', Fontin-Sans, sans-serif" });
  61. this.pie.hover(
  62. function ()
  63. {
  64. var positiveAngle = (360 + this.mangle) % 360;
  65. this.sector.attr({opacity: 0.5});
  66. //this.sector.stop();
  67. //this.sector.scale(1.1, 1.1, this.cx, this.cy);
  68. if (this.label)
  69. {
  70. //this.label[0].stop();
  71. //this.label[0].attr({ r: 7.5 });
  72. this.label[1].attr({ "font-weight": 800 });
  73. }
  74. if (this.label_highlight == undefined)
  75. {
  76. var oBBox = this.label.getBBox();
  77. this.label_highlight = this.label_highlight || me.oR.rect(oBBox.x - 2, oBBox.y - 2, oBBox.width + 4, oBBox.height + 4, 4).attr({'stroke': '#ccc', fill: '#ccc'}).toBack();
  78. }
  79. this.label_highlight.show();
  80. //this.marker = this.marker || r.label(this.mx, this.my, this.value.value, 0, 12);
  81. var alpha = 2*Math.PI * this.mangle / 360;
  82. var iDir = Math.floor(((45 + 360 + this.mangle) % 360) / 90);
  83. var aDirs = ['right', 'up', 'left', 'down'];
  84. var sDir = aDirs[iDir];
  85. this.marker = this.marker || me.oR.popup(this.cx + Math.cos(alpha) *(this.r), this.cy - Math.sin(alpha) *(this.r), me.options.labels[this.value.order]+': '+this.value.valueOf(), sDir);
  86. this.marker.show();
  87. },
  88. function ()
  89. {
  90. this.sector.attr({opacity:1});
  91. //this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500);
  92. if (this.label)
  93. {
  94. //this.label[0].animate({ r: 5 }, 200, "bounce");
  95. this.label[1].attr({ "font-weight": 400 });
  96. }
  97. this.marker && this.marker.hide();
  98. this.label_highlight && this.label_highlight.hide();
  99. });
  100. },
  101. // events bound via _bind are removed automatically
  102. // revert other modifications here
  103. _destroy: function()
  104. {
  105. this.element
  106. .removeClass('itop-pie_chart');
  107. $(window).unbind('resize.pie_chart');
  108. },
  109. // _setOptions is called with a hash of all options that are changing
  110. _setOptions: function()
  111. {
  112. // in 1.9 would use _superApply
  113. this._superApply(arguments);
  114. },
  115. // _setOption is called for each individual option that is changing
  116. _setOption: function( key, value )
  117. {
  118. // in 1.9 would use _super
  119. this._superApply(arguments);
  120. },
  121. _compute_size: function()
  122. {
  123. var legendWidth = 100;
  124. var titleHeight = 20;
  125. var iW = this.element.width();
  126. var iH = this.element.height();
  127. if (iH == 0)
  128. {
  129. iH = 0.75*iW;
  130. this.element.height(iH);
  131. }
  132. this.r = (6*Math.min(iW-legendWidth, iH-titleHeight)/7) / 2; // 1/6 is for the drop shadow
  133. this.x = (iW-legendWidth) / 2;
  134. this.y = titleHeight+(iH-titleHeight) / 2;
  135. },
  136. _draw_ball: function(x, y, r)
  137. {
  138. return this.oR.set(
  139. this.oR.ellipse(x, y + r - r / 3, r, r / 2).attr({fill: "rhsb(1, 0, .25)-hsb(1, 0, .25)", stroke: "none", opacity: 0}),
  140. this.oR.ellipse(x, y, r, r).attr({fill: "0-#000-#ccc-#000", stroke: "none"}),
  141. this.oR.ellipse(x, y, r*0.95, r*0.95 ).attr({fill: "r(.5,.9)hsb(1, 0, .75)-hsb(1, 0, .25)", stroke: "none"}),
  142. this.oR.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
  143. );
  144. }
  145. });
  146. });
  147. $(function()
  148. {
  149. // the widget definition, where "itop" is the namespace,
  150. // "heatmap_chart" the widget name
  151. $.widget( "itop.heatmap_chart",
  152. {
  153. // default options
  154. options:
  155. {
  156. chart_id: '',
  157. chart_label: '',
  158. hrefs: {},
  159. values: {},
  160. axis_x: {},
  161. axis_y: {}
  162. },
  163. // the constructor
  164. _create: function()
  165. {
  166. var me = this;
  167. this.element
  168. .addClass('itop-heatmap_chart');
  169. this.oR = Raphael(this.element.get(0), this.element.width(), this.element.height());
  170. this._compute_size();
  171. this.oR.text(this.x, 10, this.options.chart_label).attr({ font: "20px 'Fontin Sans', Fontin-Sans, sans-serif" });
  172. var iX = 0;
  173. var xs = [];
  174. var axisx = [];
  175. var ys = [];
  176. var axisy = [];
  177. var data = [];
  178. var hrefs = [];
  179. for(var x in this.options.axis_x)
  180. {
  181. var iY = 0;
  182. axisx.push(this.options.axis_x[x]);
  183. for(var y in this.options.axis_y)
  184. {
  185. xs.push(iX);
  186. ys.push(iY);
  187. data.push(this.options.values[x][y]);
  188. // Not working yet
  189. //hrefs.push(this.options.hrefs[x][y]);
  190. iY = iY + 1;
  191. }
  192. iX = iX + 1;
  193. }
  194. for(var y in this.options.axis_y)
  195. {
  196. axisy.push(this.options.axis_y[y]);
  197. }
  198. /*
  199. xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
  200. ys = [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  201. data = [294, 300, 204, 255, 348, 383, 334, 217, 114, 33, 44, 26, 41, 39, 52, 17, 13, 2, 0, 2, 5, 6, 64, 153, 294, 313, 195, 280, 365, 392, 340, 184, 87, 35, 43, 55, 53, 79, 49, 19, 6, 1, 0, 1, 1, 10, 50, 181, 246, 246, 220, 249, 355, 373, 332, 233, 85, 54, 28, 33, 45, 72, 54, 28, 5, 5, 0, 1, 2, 3, 58, 167, 206, 245, 194, 207, 334, 290, 261, 160, 61, 28, 11, 26, 33, 46, 36, 5, 6, 0, 0, 0, 0, 0, 0, 9, 9, 10, 7, 10, 14, 3, 3, 7, 0, 3, 4, 4, 6, 28, 24, 3, 5, 0, 0, 0, 0, 0, 0, 4, 3, 4, 4, 3, 4, 13, 10, 7, 2, 3, 6, 1, 9, 33, 32, 6, 2, 1, 3, 0, 0, 4, 40, 128, 212, 263, 202, 248, 307, 306, 284, 222, 79, 39, 26, 33, 40, 61, 54, 17, 3, 0, 0, 0, 3, 7, 70, 199],
  202. axisy = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  203. axisx = ["12am", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12pm", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"];
  204. */
  205. this.oR.dotchart(10, this.y, this.width, this.height, xs, ys, data, {symbol: "o", max: 30, heat: true, axis: "0 0 1 1", axisxstep: axisx.length - 1, axisystep: axisy.length - 1, axisxlabels: axisx, axisxtype: " ", axisytype: " ", axisylabels: axisy, href: hrefs}).hover(function () {
  206. this.marker = this.marker || me.oR.tag(this.x, this.y, this.value, 0, this.r + 2).insertBefore(this);
  207. this.marker.show();
  208. }, function () {
  209. this.marker && this.marker.hide();
  210. });
  211. },
  212. // called when created, and later when changing options
  213. _refresh: function()
  214. {
  215. },
  216. // events bound via _bind are removed automatically
  217. // revert other modifications here
  218. _destroy: function()
  219. {
  220. this.element
  221. .removeClass('itop-heatmap_chart');
  222. },
  223. // _setOptions is called with a hash of all options that are changing
  224. _setOptions: function()
  225. {
  226. // in 1.9 would use _superApply
  227. this._superApply(arguments);
  228. },
  229. // _setOption is called for each individual option that is changing
  230. _setOption: function( key, value )
  231. {
  232. // in 1.9 would use _super
  233. this._superApply(arguments);
  234. },
  235. _compute_size: function()
  236. {
  237. var titleHeight = 20;
  238. var iW = this.element.width();
  239. var iH = this.element.height();
  240. if (iH == 0)
  241. {
  242. iH = 0.75*iW;
  243. this.element.height(iH);
  244. }
  245. this.x = (iW) / 2;
  246. this.y = titleHeight;
  247. this.width = iW;
  248. this.height = iH - titleHeight;
  249. }
  250. });
  251. });