PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/visualize/public/js/backbone-d3/visualisations/pie.js

http://github.com/jspears/bobamo
JavaScript | 132 lines | 111 code | 2 blank | 19 comment | 6 complexity | f8eb42b969ff951ea4440633c2cbf235 MD5 | raw file
Possible License(s): Apache-2.0
  1. define(['Backbone.d3', 'd3'], function (Backbone, d3) {
  2. return Backbone.d3.Canned['Pie'] = {
  3. View:Backbone.d3.PlotView.extend({
  4. pieData:[], // Store current pie segment data
  5. modelIds:[], // Store model IDs - needed to make sure the correct pie
  6. // segment is deleted
  7. layout:d3.layout.pie(),
  8. initialize:function (collection, settings) {
  9. Backbone.d3.PlotView.prototype.initialize.apply(this, [collection, settings]);
  10. this.collection.unbind('add');
  11. this.collection.bind('add', this.add);
  12. this.collection.unbind('remove');
  13. this.collection.bind('remove', this.remove);
  14. this.m = 10;
  15. this.radius = settings.radius || 100;
  16. this.colorScale = d3.scale.category20c();
  17. this.arc = d3.svg.arc()
  18. .startAngle(function (d) {
  19. return d.startAngle;
  20. })
  21. .endAngle(function (d) {
  22. return d.endAngle;
  23. })
  24. .innerRadius(this.radius / 8)
  25. .outerRadius(this.radius);
  26. },
  27. addDeletedSegments:function (data) {
  28. /** We never really delete data from the chart as it would make existing
  29. * segments change colour. We just set the size to zero and track it in
  30. * this.deleted so we can distinguish between deleted segments and
  31. * segments that just happen to be zero.
  32. *
  33. * This function puts deleted segments into the data array at the right
  34. * place.
  35. */
  36. _.each(this.deleted, function (d) {
  37. data.splice(d, 0, 0);
  38. });
  39. return data;
  40. },
  41. add:function (model) {
  42. // Add new segment to this.pieData with correct value, but set start/end
  43. // angle to 2pi so it is invisible until transition completes
  44. this.pieData.push({
  45. data:model.get('value'),
  46. value:model.get('value'),
  47. startAngle:2 * Math.PI,
  48. endAngle:2 * Math.PI
  49. });
  50. this.modelIds.push(model.id);
  51. var data = this.addDeletedSegments(this.plotdata());
  52. this.div.selectAll("svg").remove();
  53. this.pieData = this.drawPie({pieData:this.pieData, data:data});
  54. this.redraw();
  55. },
  56. remove:function (model) {
  57. var segment = this.modelIds.indexOf(model.id);
  58. var data = _.map(this.pieData, function (d) {
  59. return d.value;
  60. });
  61. data[segment] = 0;
  62. this.pieData = this.updatePie({data:data});
  63. if (this.deleted) {
  64. this.deleted.push(segment);
  65. } else {
  66. this.deleted = [segment];
  67. }
  68. },
  69. drawPie:function (options) {
  70. /**
  71. * Draw a new pie chart
  72. */
  73. var that = this;
  74. // Allow passing in of custom pieData - this can be used to add new
  75. // segments by creating pieData where the new segment is zero size
  76. var pieData = options.pieData || this.layout(options.data);
  77. var svg = this.div.selectAll("svg")
  78. .data([options.data])
  79. .enter().append("svg:svg")
  80. .attr("width", (this.radius + this.m) * 2)
  81. .attr("height", (this.radius + this.m) * 2)
  82. .append("svg:g")
  83. .attr("transform", "translate(" + (this.radius + this.m) + "," +
  84. (this.radius + this.m) + ")");
  85. svg.selectAll("path")
  86. .data(pieData)
  87. .enter().append("svg:path")
  88. .attr("d", this.arc)
  89. .style("fill",
  90. function (d, i) {
  91. return that.colorScale(i);
  92. });
  93. return pieData;
  94. },
  95. updatePie:function (options) {
  96. /**
  97. * Transition an existing pie chart
  98. */
  99. var svg = this.div.selectAll("svg");
  100. var newPieData = this.layout(options.data);
  101. var that = this;
  102. _.each(newPieData, function (d, i, l) {
  103. d.oldStartAngle = that.pieData[i].startAngle;
  104. d.oldEndAngle = that.pieData[i].endAngle;
  105. });
  106. var pie = svg.selectAll("path");
  107. pie.data(newPieData);
  108. pie.transition()
  109. .duration(this.duration)
  110. .attrTween("d", function (a) {
  111. var i = d3.interpolate(
  112. {startAngle:a.oldStartAngle, endAngle:a.oldEndAngle}, a);
  113. return function (t) {
  114. return that.arc(i(t));
  115. };
  116. });
  117. return newPieData;
  118. },
  119. plot:function (options) {
  120. var data = this.addDeletedSegments(this.plotdata());
  121. if (options.newPlot) {
  122. this.pieData = this.drawPie({data:data});
  123. this.modelIds = this.collection.pluck('id');
  124. } else {
  125. this.pieData = this.updatePie({data:data});
  126. }
  127. }
  128. })
  129. }
  130. });