JAVASCRIPT   25

Chart.PolarArea.js

Guest on 5th June 2021 05:38:35 PM

  1. (function(){
  2.       "use strict";
  3.  
  4.       var root = this,
  5.             Chart = root.Chart,
  6.             //Cache a local reference to Chart.helpers
  7.             helpers = Chart.helpers;
  8.  
  9.       var defaultConfig = {
  10.             //Boolean - Show a backdrop to the scale label
  11.             scaleShowLabelBackdrop : true,
  12.  
  13.             //String - The colour of the label backdrop
  14.             scaleBackdropColor : "rgba(255,255,255,0.75)",
  15.  
  16.             // Boolean - Whether the scale should begin at zero
  17.             scaleBeginAtZero : true,
  18.  
  19.             //Number - The backdrop padding above & below the label in pixels
  20.             scaleBackdropPaddingY : 2,
  21.  
  22.             //Number - The backdrop padding to the side of the label in pixels
  23.             scaleBackdropPaddingX : 2,
  24.  
  25.             //Boolean - Show line for each value in the scale
  26.             scaleShowLine : true,
  27.  
  28.             //Boolean - Stroke a line around each segment in the chart
  29.             segmentShowStroke : true,
  30.  
  31.             //String - The colour of the stroke on each segement.
  32.             segmentStrokeColor : "#fff",
  33.  
  34.             //Number - The width of the stroke value in pixels
  35.             segmentStrokeWidth : 2,
  36.  
  37.             //Number - Amount of animation steps
  38.             animationSteps : 100,
  39.  
  40.             //String - Animation easing effect.
  41.             animationEasing : "easeOutBounce",
  42.  
  43.             //Boolean - Whether to animate the rotation of the chart
  44.             animateRotate : true,
  45.  
  46.             //Boolean - Whether to animate scaling the chart from the centre
  47.             animateScale : false,
  48.  
  49.             //String - A legend template
  50.             legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
  51.       };
  52.  
  53.  
  54.       Chart.Type.extend({
  55.             //Passing in a name registers this chart in the Chart namespace
  56.             name: "PolarArea",
  57.             //Providing a defaults will also register the deafults in the chart namespace
  58.             defaults : defaultConfig,
  59.             //Initialize is fired when the chart is initialized - Data is passed in as a parameter
  60.             //Config is automatically merged by the core of Chart.js, and is available at this.options
  61.             initialize:  function(data){
  62.                   this.segments = [];
  63.                   //Declare segment class as a chart instance specific class, so it can share props for this instance
  64.                   this.SegmentArc = Chart.Arc.extend({
  65.                         showStroke : this.options.segmentShowStroke,
  66.                         strokeWidth : this.options.segmentStrokeWidth,
  67.                         strokeColor : this.options.segmentStrokeColor,
  68.                         ctx : this.chart.ctx,
  69.                         innerRadius : 0,
  70.                         x : this.chart.width/2,
  71.                         y : this.chart.height/2
  72.                   });
  73.                   this.scale = new Chart.RadialScale({
  74.                         display: this.options.showScale,
  75.                         fontStyle: this.options.scaleFontStyle,
  76.                         fontSize: this.options.scaleFontSize,
  77.                         fontFamily: this.options.scaleFontFamily,
  78.                         fontColor: this.options.scaleFontColor,
  79.                         showLabels: this.options.scaleShowLabels,
  80.                         showLabelBackdrop: this.options.scaleShowLabelBackdrop,
  81.                         backdropColor: this.options.scaleBackdropColor,
  82.                         backdropPaddingY : this.options.scaleBackdropPaddingY,
  83.                         backdropPaddingX: this.options.scaleBackdropPaddingX,
  84.                         lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
  85.                         lineColor: this.options.scaleLineColor,
  86.                         lineArc: true,
  87.                         width: this.chart.width,
  88.                         height: this.chart.height,
  89.                         xCenter: this.chart.width/2,
  90.                         yCenter: this.chart.height/2,
  91.                         ctx : this.chart.ctx,
  92.                         templateString: this.options.scaleLabel,
  93.                         valuesCount: data.length
  94.                   });
  95.  
  96.                   this.updateScaleRange(data);
  97.  
  98.                   this.scale.update();
  99.  
  100.                   helpers.each(data,function(segment,index){
  101.                         this.addData(segment,index,true);
  102.                   },this);
  103.  
  104.                   //Set up tooltip events on the chart
  105.                   if (this.options.showTooltips){
  106.                         helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
  107.                               var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
  108.                               helpers.each(this.segments,function(segment){
  109.                                     segment.restore(["fillColor"]);
  110.                               });
  111.                               helpers.each(activeSegments,function(activeSegment){
  112.                                     activeSegment.fillColor = activeSegment.highlightColor;
  113.                               });
  114.                               this.showTooltip(activeSegments);
  115.                         });
  116.                   }
  117.  
  118.                   this.render();
  119.             },
  120.             getSegmentsAtEvent : function(e){
  121.                   var segmentsArray = [];
  122.  
  123.                   var location = helpers.getRelativePosition(e);
  124.  
  125.                   helpers.each(this.segments,function(segment){
  126.                         if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
  127.                   },this);
  128.                   return segmentsArray;
  129.             },
  130.             addData : function(segment, atIndex, silent){
  131.                   var index = atIndex || this.segments.length;
  132.  
  133.                   this.segments.splice(index, 0, new this.SegmentArc({
  134.                         fillColor: segment.color,
  135.                         highlightColor: segment.highlight || segment.color,
  136.                         label: segment.label,
  137.                         value: segment.value,
  138.                         outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
  139.                         circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
  140.                         startAngle: Math.PI * 1.5
  141.                   }));
  142.                   if (!silent){
  143.                         this.reflow();
  144.                         this.update();
  145.                   }
  146.             },
  147.             removeData: function(atIndex){
  148.                   var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
  149.                   this.segments.splice(indexToDelete, 1);
  150.                   this.reflow();
  151.                   this.update();
  152.             },
  153.             calculateTotal: function(data){
  154.                   this.total = 0;
  155.                   helpers.each(data,function(segment){
  156.                         this.total += segment.value;
  157.                   },this);
  158.                   this.scale.valuesCount = this.segments.length;
  159.             },
  160.             updateScaleRange: function(datapoints){
  161.                   var valuesArray = [];
  162.                   helpers.each(datapoints,function(segment){
  163.                         valuesArray.push(segment.value);
  164.                   });
  165.  
  166.                   var scaleSizes = (this.options.scaleOverride) ?
  167.                         {
  168.                               steps: this.options.scaleSteps,
  169.                               stepValue: this.options.scaleStepWidth,
  170.                               min: this.options.scaleStartValue,
  171.                               max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
  172.                         } :
  173.                         helpers.calculateScaleRange(
  174.                               valuesArray,
  175.                               helpers.min([this.chart.width, this.chart.height])/2,
  176.                               this.options.scaleFontSize,
  177.                               this.options.scaleBeginAtZero,
  178.                               this.options.scaleIntegersOnly
  179.                         );
  180.  
  181.                   helpers.extend(
  182.                         this.scale,
  183.                         scaleSizes,
  184.                         {
  185.                               size: helpers.min([this.chart.width, this.chart.height]),
  186.                               xCenter: this.chart.width/2,
  187.                               yCenter: this.chart.height/2
  188.                         }
  189.                   );
  190.  
  191.             },
  192.             update : function(){
  193.                   this.calculateTotal(this.segments);
  194.  
  195.                   helpers.each(this.segments,function(segment){
  196.                         segment.save();
  197.                   });
  198.                  
  199.                   this.reflow();
  200.                   this.render();
  201.             },
  202.             reflow : function(){
  203.                   helpers.extend(this.SegmentArc.prototype,{
  204.                         x : this.chart.width/2,
  205.                         y : this.chart.height/2
  206.                   });
  207.                   this.updateScaleRange(this.segments);
  208.                   this.scale.update();
  209.  
  210.                   helpers.extend(this.scale,{
  211.                         xCenter: this.chart.width/2,
  212.                         yCenter: this.chart.height/2
  213.                   });
  214.  
  215.                   helpers.each(this.segments, function(segment){
  216.                         segment.update({
  217.                               outerRadius : this.scale.calculateCenterOffset(segment.value)
  218.                         });
  219.                   }, this);
  220.  
  221.             },
  222.             draw : function(ease){
  223.                   var easingDecimal = ease || 1;
  224.                   //Clear & draw the canvas
  225.                   this.clear();
  226.                   helpers.each(this.segments,function(segment, index){
  227.                         segment.transition({
  228.                               circumference : this.scale.getCircumference(),
  229.                               outerRadius : this.scale.calculateCenterOffset(segment.value)
  230.                         },easingDecimal);
  231.  
  232.                         segment.endAngle = segment.startAngle + segment.circumference;
  233.  
  234.                         // If we've removed the first segment we need to set the first one to
  235.                         // start at the top.
  236.                         if (index === 0){
  237.                               segment.startAngle = Math.PI * 1.5;
  238.                         }
  239.  
  240.                         //Check to see if it's the last segment, if not get the next and update the start angle
  241.                         if (index < this.segments.length - 1){
  242.                               this.segments[index+1].startAngle = segment.endAngle;
  243.                         }
  244.                         segment.draw();
  245.                   }, this);
  246.                   this.scale.draw();
  247.             }
  248.       });
  249.  
  250. }).call(this);

Raw Paste


Login or Register to edit or fork this paste. It's free.