chart-pie.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /**
  2. * Pie charts
  3. */
  4. $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, {
  5. type: 'pie',
  6. init: function (el, values, options, width, height) {
  7. var total = 0, i;
  8. pie._super.init.call(this, el, values, options, width, height);
  9. this.shapes = {}; // map shape ids to value offsets
  10. this.valueShapes = {}; // maps value offsets to shape ids
  11. this.values = values = $.map(values, Number);
  12. if (options.get('width') === 'auto') {
  13. this.width = this.height;
  14. }
  15. if (values.length > 0) {
  16. for (i = values.length; i--;) {
  17. total += values[i];
  18. }
  19. }
  20. this.total = total;
  21. this.initTarget();
  22. this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);
  23. },
  24. getRegion: function (el, x, y) {
  25. var shapeid = this.target.getShapeAt(el, x, y);
  26. return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
  27. },
  28. getCurrentRegionFields: function () {
  29. var currentRegion = this.currentRegion;
  30. return {
  31. isNull: this.values[currentRegion] === undefined,
  32. value: this.values[currentRegion],
  33. percent: this.values[currentRegion] / this.total * 100,
  34. color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],
  35. offset: currentRegion
  36. };
  37. },
  38. changeHighlight: function (highlight) {
  39. var currentRegion = this.currentRegion,
  40. newslice = this.renderSlice(currentRegion, highlight),
  41. shapeid = this.valueShapes[currentRegion];
  42. delete this.shapes[shapeid];
  43. this.target.replaceWithShape(shapeid, newslice);
  44. this.valueShapes[currentRegion] = newslice.id;
  45. this.shapes[newslice.id] = currentRegion;
  46. },
  47. renderSlice: function (valuenum, highlight) {
  48. var target = this.target,
  49. options = this.options,
  50. radius = this.radius,
  51. borderWidth = options.get('borderWidth'),
  52. offset = options.get('offset'),
  53. circle = 2 * Math.PI,
  54. values = this.values,
  55. total = this.total,
  56. next = offset ? (2*Math.PI)*(offset/360) : 0,
  57. start, end, i, vlen, color;
  58. vlen = values.length;
  59. for (i = 0; i < vlen; i++) {
  60. start = next;
  61. end = next;
  62. if (total > 0) { // avoid divide by zero
  63. end = next + (circle * (values[i] / total));
  64. }
  65. if (valuenum === i) {
  66. color = options.get('sliceColors')[i % options.get('sliceColors').length];
  67. if (highlight) {
  68. color = this.calcHighlightColor(color, options);
  69. }
  70. return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);
  71. }
  72. next = end;
  73. }
  74. },
  75. render: function () {
  76. var target = this.target,
  77. values = this.values,
  78. options = this.options,
  79. radius = this.radius,
  80. borderWidth = options.get('borderWidth'),
  81. shape, i;
  82. if (!pie._super.render.call(this)) {
  83. return;
  84. }
  85. if (borderWidth) {
  86. target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),
  87. options.get('borderColor'), undefined, borderWidth).append();
  88. }
  89. for (i = values.length; i--;) {
  90. if (values[i]) { // don't render zero values
  91. shape = this.renderSlice(i).append();
  92. this.valueShapes[i] = shape.id; // store just the shapeid
  93. this.shapes[shape.id] = i;
  94. }
  95. }
  96. target.render();
  97. }
  98. });