Path: blob/master/web-gui/buildyourownbotnet/assets/js/easy-pie-chart/dist/angular.easypiechart.js
1293 views
/**!1* easy-pie-chart2* Lightweight plugin to render simple, animated and retina optimized pie charts3*4* @license5* @author Robert Fleischmann <[email protected]> (http://robert-fleischmann.de)6* @version 2.1.77**/89(function (root, factory) {10if (typeof define === 'function' && define.amd) {11// AMD. Register as an anonymous module unless amdModuleId is set12define(["angular"], function (a0) {13return (factory(a0));14});15} else if (typeof exports === 'object') {16// Node. Does not work with strict CommonJS, but17// only CommonJS-like environments that support module.exports,18// like Node.19module.exports = factory(require("angular"));20} else {21factory(angular);22}23}(this, function (angular) {2425(function (angular) {2627'use strict';2829return angular.module('easypiechart', [])3031.directive('easypiechart', [function() {32return {33restrict: 'AE',34require: '?ngModel',35scope: {36percent: '=',37options: '='38},39link: function (scope, element, attrs) {4041scope.percent = scope.percent || 0;4243/**44* default easy pie chart options45* @type {Object}46*/47var options = {48barColor: '#ef1e25',49trackColor: '#f9f9f9',50scaleColor: '#dfe0e0',51scaleLength: 5,52lineCap: 'round',53lineWidth: 3,54size: 110,55rotate: 0,56animate: {57duration: 1000,58enabled: true59}60};61scope.options = angular.extend(options, scope.options);6263var pieChart = new EasyPieChart(element[0], options);6465scope.$watch('percent', function(newVal, oldVal) {66pieChart.update(newVal);67});68}69};70}]);7172})(angular);7374/**75* Renderer to render the chart on a canvas object76* @param {DOMElement} el DOM element to host the canvas (root of the plugin)77* @param {object} options options object of the plugin78*/79var CanvasRenderer = function(el, options) {80var cachedBackground;81var canvas = document.createElement('canvas');8283el.appendChild(canvas);8485if (typeof(G_vmlCanvasManager) === 'object') {86G_vmlCanvasManager.initElement(canvas);87}8889var ctx = canvas.getContext('2d');9091canvas.width = canvas.height = options.size;9293// canvas on retina devices94var scaleBy = 1;95if (window.devicePixelRatio > 1) {96scaleBy = window.devicePixelRatio;97canvas.style.width = canvas.style.height = [options.size, 'px'].join('');98canvas.width = canvas.height = options.size * scaleBy;99ctx.scale(scaleBy, scaleBy);100}101102// move 0,0 coordinates to the center103ctx.translate(options.size / 2, options.size / 2);104105// rotate canvas -90deg106ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);107108var radius = (options.size - options.lineWidth) / 2;109if (options.scaleColor && options.scaleLength) {110radius -= options.scaleLength + 2; // 2 is the distance between scale and bar111}112113// IE polyfill for Date114Date.now = Date.now || function() {115return +(new Date());116};117118/**119* Draw a circle around the center of the canvas120* @param {strong} color Valid CSS color string121* @param {number} lineWidth Width of the line in px122* @param {number} percent Percentage to draw (float between -1 and 1)123*/124var drawCircle = function(color, lineWidth, percent) {125percent = Math.min(Math.max(-1, percent || 0), 1);126var isNegative = percent <= 0 ? true : false;127128ctx.beginPath();129ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);130131ctx.strokeStyle = color;132ctx.lineWidth = lineWidth;133134ctx.stroke();135};136137/**138* Draw the scale of the chart139*/140var drawScale = function() {141var offset;142var length;143144ctx.lineWidth = 1;145ctx.fillStyle = options.scaleColor;146147ctx.save();148for (var i = 24; i > 0; --i) {149if (i % 6 === 0) {150length = options.scaleLength;151offset = 0;152} else {153length = options.scaleLength * 0.6;154offset = options.scaleLength - length;155}156ctx.fillRect(-options.size/2 + offset, 0, length, 1);157ctx.rotate(Math.PI / 12);158}159ctx.restore();160};161162/**163* Request animation frame wrapper with polyfill164* @return {function} Request animation frame method or timeout fallback165*/166var reqAnimationFrame = (function() {167return window.requestAnimationFrame ||168window.webkitRequestAnimationFrame ||169window.mozRequestAnimationFrame ||170function(callback) {171window.setTimeout(callback, 1000 / 60);172};173}());174175/**176* Draw the background of the plugin including the scale and the track177*/178var drawBackground = function() {179if(options.scaleColor) drawScale();180if(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);181};182183/**184* Canvas accessor185*/186this.getCanvas = function() {187return canvas;188};189190/**191* Canvas 2D context 'ctx' accessor192*/193this.getCtx = function() {194return ctx;195};196197/**198* Clear the complete canvas199*/200this.clear = function() {201ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);202};203204/**205* Draw the complete chart206* @param {number} percent Percent shown by the chart between -100 and 100207*/208this.draw = function(percent) {209// do we need to render a background210if (!!options.scaleColor || !!options.trackColor) {211// getImageData and putImageData are supported212if (ctx.getImageData && ctx.putImageData) {213if (!cachedBackground) {214drawBackground();215cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);216} else {217ctx.putImageData(cachedBackground, 0, 0);218}219} else {220this.clear();221drawBackground();222}223} else {224this.clear();225}226227ctx.lineCap = options.lineCap;228229// if barcolor is a function execute it and pass the percent as a value230var color;231if (typeof(options.barColor) === 'function') {232color = options.barColor(percent);233} else {234color = options.barColor;235}236237// draw bar238drawCircle(color, options.lineWidth, percent / 100);239}.bind(this);240241/**242* Animate from some percent to some other percentage243* @param {number} from Starting percentage244* @param {number} to Final percentage245*/246this.animate = function(from, to) {247var startTime = Date.now();248options.onStart(from, to);249var animation = function() {250var process = Math.min(Date.now() - startTime, options.animate.duration);251var currentValue = options.easing(this, process, from, to - from, options.animate.duration);252this.draw(currentValue);253options.onStep(from, to, currentValue);254if (process >= options.animate.duration) {255options.onStop(from, to);256} else {257reqAnimationFrame(animation);258}259}.bind(this);260261reqAnimationFrame(animation);262}.bind(this);263};264265var EasyPieChart = function(el, opts) {266var defaultOptions = {267barColor: '#ef1e25',268trackColor: '#f9f9f9',269scaleColor: '#dfe0e0',270scaleLength: 5,271lineCap: 'round',272lineWidth: 3,273trackWidth: undefined,274size: 110,275rotate: 0,276animate: {277duration: 1000,278enabled: true279},280easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/281t = t / (d/2);282if (t < 1) {283return c / 2 * t * t + b;284}285return -c/2 * ((--t)*(t-2) - 1) + b;286},287onStart: function(from, to) {288return;289},290onStep: function(from, to, currentValue) {291return;292},293onStop: function(from, to) {294return;295}296};297298// detect present renderer299if (typeof(CanvasRenderer) !== 'undefined') {300defaultOptions.renderer = CanvasRenderer;301} else if (typeof(SVGRenderer) !== 'undefined') {302defaultOptions.renderer = SVGRenderer;303} else {304throw new Error('Please load either the SVG- or the CanvasRenderer');305}306307var options = {};308var currentValue = 0;309310/**311* Initialize the plugin by creating the options object and initialize rendering312*/313var init = function() {314this.el = el;315this.options = options;316317// merge user options into default options318for (var i in defaultOptions) {319if (defaultOptions.hasOwnProperty(i)) {320options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];321if (typeof(options[i]) === 'function') {322options[i] = options[i].bind(this);323}324}325}326327// check for jQuery easing328if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {329options.easing = jQuery.easing[options.easing];330} else {331options.easing = defaultOptions.easing;332}333334// process earlier animate option to avoid bc breaks335if (typeof(options.animate) === 'number') {336options.animate = {337duration: options.animate,338enabled: true339};340}341342if (typeof(options.animate) === 'boolean' && !options.animate) {343options.animate = {344duration: 1000,345enabled: options.animate346};347}348349// create renderer350this.renderer = new options.renderer(el, options);351352// initial draw353this.renderer.draw(currentValue);354355// initial update356if (el.dataset && el.dataset.percent) {357this.update(parseFloat(el.dataset.percent));358} else if (el.getAttribute && el.getAttribute('data-percent')) {359this.update(parseFloat(el.getAttribute('data-percent')));360}361}.bind(this);362363/**364* Update the value of the chart365* @param {number} newValue Number between 0 and 100366* @return {object} Instance of the plugin for method chaining367*/368this.update = function(newValue) {369newValue = parseFloat(newValue);370if (options.animate.enabled) {371this.renderer.animate(currentValue, newValue);372} else {373this.renderer.draw(newValue);374}375currentValue = newValue;376return this;377}.bind(this);378379/**380* Disable animation381* @return {object} Instance of the plugin for method chaining382*/383this.disableAnimation = function() {384options.animate.enabled = false;385return this;386};387388/**389* Enable animation390* @return {object} Instance of the plugin for method chaining391*/392this.enableAnimation = function() {393options.animate.enabled = true;394return this;395};396397init();398};399400401}));402403404