/** * o------------------------------------------------------------------------------o * | This file is part of the RGraph package - you can learn more at: | * | | * | http://www.rgraph.net | * | | * | This package is licensed under the RGraph license. For all kinds of business | * | purposes there is a small one-time licensing fee to pay and for non | * | commercial purposes it is free to use. You can read the full license here: | * | | * | http://www.rgraph.net/LICENSE.txt | * o------------------------------------------------------------------------------o */ if (typeof(RGraph) == 'undefined') RGraph = {}; /** * The pie chart constructor * * @param data array The data to be represented on the pie chart */ RGraph.Pie = function (id, data) { this.id = id; this.canvas = document.getElementById(id); this.context = this.canvas.getContext("2d"); this.canvas.__object__ = this; this.total = 0; this.subTotal = 0; this.angles = []; this.data = data; this.properties = []; this.type = 'pie'; this.isRGraph = true; /** * Compatibility with older browsers */ RGraph.OldBrowserCompat(this.context); this.properties = { 'chart.colors': ['rgb(255,0,0)', '#ddd', 'rgb(0,255,0)', 'rgb(0,0,255)', 'pink', 'yellow', '#000'], 'chart.strokestyle': '#999', 'chart.linewidth': 1, 'chart.labels': [], 'chart.labels.sticks': false, 'chart.labels.sticks.color': '#aaa', 'chart.segments': [], 'chart.gutter.left': 25, 'chart.gutter.right': 25, 'chart.gutter.top': 25, 'chart.gutter.bottom': 25, 'chart.title': '', 'chart.title.background': null, 'chart.title.hpos': null, 'chart.title.vpos': 0.5, 'chart.title.bold': true, 'chart.title.font': null, 'chart.shadow': false, 'chart.shadow.color': 'rgba(0,0,0,0.5)', 'chart.shadow.offsetx': 3, 'chart.shadow.offsety': 3, 'chart.shadow.blur': 3, 'chart.text.size': 10, 'chart.text.color': 'black', 'chart.text.font': 'Verdana', 'chart.contextmenu': null, 'chart.tooltips': [], 'chart.tooltips.event': 'onclick', 'chart.tooltips.effect': 'fade', 'chart.tooltips.css.class': 'RGraph_tooltip', 'chart.tooltips.highlight': true, 'chart.highlight.style': '3d', 'chart.highlight.style.2d.fill': 'rgba(255,255,255,0.5)', 'chart.highlight.style.2d.stroke': 'rgba(255,255,255,0)', 'chart.centerx': null, 'chart.centery': null, 'chart.radius': null, 'chart.border': false, 'chart.border.color': 'rgba(255,255,255,0.5)', 'chart.key': null, 'chart.key.background': 'white', 'chart.key.position': 'graph', 'chart.key.halign': 'right', 'chart.key.shadow': false, 'chart.key.shadow.color': '#666', 'chart.key.shadow.blur': 3, 'chart.key.shadow.offsetx': 2, 'chart.key.shadow.offsety': 2, 'chart.key.position.gutter.boxed': true, 'chart.key.position.x': null, 'chart.key.position.y': null, 'chart.key.color.shape': 'square', 'chart.key.rounded': true, 'chart.key.linewidth': 1, 'chart.annotatable': false, 'chart.annotate.color': 'black', 'chart.align': 'center', 'chart.zoom.factor': 1.5, 'chart.zoom.fade.in': true, 'chart.zoom.fade.out': true, 'chart.zoom.hdir': 'right', 'chart.zoom.vdir': 'down', 'chart.zoom.frames': 25, 'chart.zoom.delay': 16.666, 'chart.zoom.shadow': true, 'chart.zoom.mode': 'canvas', 'chart.zoom.thumbnail.width': 75, 'chart.zoom.thumbnail.height': 75, 'chart.zoom.background': true, 'chart.zoom.action': 'zoom', 'chart.resizable': false, 'chart.resize.handle.adjust': [0,0], 'chart.resize.handle.background': null, 'chart.variant': 'pie', 'chart.variant.donut.color': 'white', 'chart.exploded': [], 'chart.effect.roundrobin.multiplier': 1 } /** * Calculate the total */ for (var i=0,len=data.length; i 0) || typeof(this.Get('chart.exploded')) == 'number') { var explosion = typeof(this.Get('chart.exploded')) == 'number' ? this.Get('chart.exploded') : this.Get('chart.exploded')[index]; var x = 0; var y = 0; var h = explosion; var t = (subTotal + (degrees / 2)) / (360/6.2830); var x = (Math.cos(t) * explosion); var y = (Math.sin(t) * explosion); this.context.moveTo(this.centerx + x, this.centery + y); } else { var x = 0; var y = 0; } /** * Calculate the angles */ var startAngle = subTotal / 57.3; var endAngle = (last ? 360 : subTotal + degrees) / 57.3; context.arc(this.centerx + x, this.centery + y, this.radius, startAngle * this.Get('chart.effect.roundrobin.multiplier'), endAngle * this.Get('chart.effect.roundrobin.multiplier'), 0); context.lineTo(this.centerx + x, this.centery + y); // Keep hold of the angles this.angles.push([subTotal, subTotal + degrees, this.centerx + x, this.centery + y]) this.context.closePath(); //this.context.stroke(); this.context.fill(); /** * Calculate the segment angle */ this.Get('chart.segments').push([subTotal, subTotal + degrees]); this.subTotal += degrees; } /** * Draws the graphs labels */ RGraph.Pie.prototype.DrawLabels = function () { var hAlignment = 'left'; var vAlignment = 'center'; var labels = this.Get('chart.labels'); var context = this.context; /** * Turn the shadow off */ RGraph.NoShadow(this); context.fillStyle = 'black'; context.beginPath(); /** * Draw the key (ie. the labels) */ if (labels && labels.length) { var text_size = this.Get('chart.text.size'); for (i=0; i 270 ? 2 : -2) : 0), this.centery + explosion_offsety + (((this.radius + 10) * Math.sin(a / 57.3))), labels[i], vAlignment, hAlignment); } context.fill(); } } /** * This function draws the pie chart sticks (for the labels) */ RGraph.Pie.prototype.DrawSticks = function () { var context = this.context; var segments = this.Get('chart.segments'); var offset = this.Get('chart.linewidth') / 2; var exploded = this.Get('chart.exploded'); var sticks = this.Get('chart.labels.sticks'); for (var i=0; i= 0) { theta += 180; } else if (x < 0 && y < 0) { theta += 180; } else if (x > 0 && y < 0) { theta += 360; } if (theta > 360) { theta -= 360; } if (theta >= angles[i][0] && theta < angles[i][1]) { hyp = Math.abs(hyp); if (!hyp || (obj.radius && hyp > obj.radius) ) { return null; } if (obj.type == 'pie' && obj.Get('chart.variant') == 'donut' && (hyp > obj.radius || hyp < (obj.radius / 2) ) ) { return null; } ret[0] = angles[i][2]; ret[1] = angles[i][3]; ret[2] = (obj.type == 'rose') ? angles[i][2] : obj.radius; ret[3] = angles[i][0]; ret[4] = angles[i][1]; ret[5] = i; if (ret[3] < 0) ret[3] += 360; if (ret[4] > 360) ret[4] -= 360; return ret; } } return null; } RGraph.Pie.prototype.DrawBorders = function () { if (this.Get('chart.linewidth') > 0) { this.context.lineWidth = this.Get('chart.linewidth'); this.context.strokeStyle = this.Get('chart.strokestyle'); for (var i=0,len=this.angles.length; i