charts.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. // call the original destroy method since we overwrote it
  109. $.Widget.prototype.destroy.call( this );
  110. },
  111. // _setOptions is called with a hash of all options that are changing
  112. _setOptions: function()
  113. {
  114. // in 1.9 would use _superApply
  115. $.Widget.prototype._setOptions.apply( this, arguments );
  116. },
  117. // _setOption is called for each individual option that is changing
  118. _setOption: function( key, value )
  119. {
  120. // in 1.9 would use _super
  121. $.Widget.prototype._setOption.call( this, key, value );
  122. },
  123. _compute_size: function()
  124. {
  125. var legendWidth = 100;
  126. var titleHeight = 20;
  127. var iW = this.element.width();
  128. var iH = this.element.height();
  129. if (iH == 0)
  130. {
  131. iH = 0.75*iW;
  132. this.element.height(iH);
  133. }
  134. this.r = (6*Math.min(iW-legendWidth, iH-titleHeight)/7) / 2; // 1/6 is for the drop shadow
  135. this.x = (iW-legendWidth) / 2;
  136. this.y = titleHeight+(iH-titleHeight) / 2;
  137. },
  138. _draw_ball: function(x, y, r)
  139. {
  140. return this.oR.set(
  141. 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}),
  142. this.oR.ellipse(x, y, r, r).attr({fill: "0-#000-#ccc-#000", stroke: "none"}),
  143. 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"}),
  144. this.oR.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
  145. );
  146. }
  147. });
  148. });
  149. $(function()
  150. {
  151. // the widget definition, where "itop" is the namespace,
  152. // "heatmap_chart" the widget name
  153. $.widget( "itop.heatmap_chart",
  154. {
  155. // default options
  156. options:
  157. {
  158. chart_id: '',
  159. chart_label: '',
  160. values: [],
  161. labels: [],
  162. hrefs: []
  163. },
  164. // the constructor
  165. _create: function()
  166. {
  167. var me = this;
  168. this.element
  169. .addClass('itop-heatmap_chart');
  170. this.oR = Raphael(this.element.get(0), this.element.width(), this.element.height());
  171. this._compute_size();
  172. this.oR.text(this.x, 10, this.options.chart_label).attr({ font: "20px 'Fontin Sans', Fontin-Sans, sans-serif" });
  173. 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],
  174. 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],
  175. 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],
  176. axisy = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  177. 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"];
  178. this.oR.dotchart(10, this.y, this.width, this.height, xs, ys, data, {symbol: "o", max: 10, heat: true, axis: "0 0 1 1", axisxstep: 23, axisystep: 6, axisxlabels: axisx, axisxtype: " ", axisytype: " ", axisylabels: axisy}).hover(function () {
  179. this.marker = this.marker || me.oR.tag(this.x, this.y, this.value, 0, this.r + 2).insertBefore(this);
  180. this.marker.show();
  181. }, function () {
  182. this.marker && this.marker.hide();
  183. });
  184. },
  185. // called when created, and later when changing options
  186. _refresh: function()
  187. {
  188. },
  189. // events bound via _bind are removed automatically
  190. // revert other modifications here
  191. destroy: function()
  192. {
  193. this.element
  194. .removeClass('itop-heatmap_chart');
  195. // call the original destroy method since we overwrote it
  196. $.Widget.prototype.destroy.call( this );
  197. },
  198. // _setOptions is called with a hash of all options that are changing
  199. _setOptions: function()
  200. {
  201. // in 1.9 would use _superApply
  202. $.Widget.prototype._setOptions.apply( this, arguments );
  203. },
  204. // _setOption is called for each individual option that is changing
  205. _setOption: function( key, value )
  206. {
  207. // in 1.9 would use _super
  208. $.Widget.prototype._setOption.call( this, key, value );
  209. },
  210. _compute_size: function()
  211. {
  212. var titleHeight = 20;
  213. var iW = this.element.width();
  214. var iH = this.element.height();
  215. if (iH == 0)
  216. {
  217. iH = 0.75*iW;
  218. this.element.height(iH);
  219. }
  220. this.x = (iW) / 2;
  221. this.y = titleHeight;
  222. this.width = iW;
  223. this.height = iH - titleHeight;
  224. }
  225. });
  226. });