代码比较简单,需要注意的一点就是:
如果想让饼图的边框显示出来,需要找到excanvas.js中的contextPrototype.stroke方法,将其最后一行代码注释掉
contextPrototype.stroke = function(aFill) {
// this.currentPath_ = [];
};
使用了extjs的组件生命周期,如果不采用extjs也很简单,将所有extjs的方法自行实现即可
代码如下:
Ext.ns('Ext.ux'); Ext.ux.pieChart = Ext.extend(Ext.BoxComponent, { circleX : 0, circleY : 0, data : undefined, labels : [], labelX : 0, labelY : 0, radius : 100, onRender : function(ct, position) { this.base(ct, position); this.ct = Ext.get(ct); this.createCanvas(ct); }, afterRender : function() { this.base(arguments); var context = this.ctx; this.drawCircle(context); }, createCanvas : function(ct) { var canvas = document.createElement("canvas"); this.ct.dom.appendChild(canvas); this.el = Ext.get(canvas); if (Ext.isIE && G_vmlCanvasManager) this.el = Ext.get(G_vmlCanvasManager.initElement(canvas)); this.setCanvasSize(this.width, this.height); this.canvas = Ext.getDom(this.el); this.el.position('absolute', this.zIndex); this.ctx = this.getContext(); }, drawCircle : function(ctx) { this.shadow ? this.makeShadow() : ''; var total = 0; for (var i = 0; i < this.data.length; i++) total += this.data[i][1]; this.startangle = -Math.PI / 2;// canvas 的arc采用PI方式的角度进行计算,2PI表示360° ctx.lineWidth = 2; ctx.strokeStyle = "black"; for (var i = 0; i < this.data.length; i++) {// 画每块扇片及其说明 var d = this.data[i]; this.endangle = this.startangle + d[1] / total * Math.PI * 2; ctx.beginPath(); ctx.moveTo(this.circleX, this.circleY);// 画扇片 ctx.arc(this.circleX, this.circleY, this.radius, this.startangle, this.endangle, false); ctx.closePath(); ctx.fillStyle = d[2]; ctx.fill(); ctx.stroke(); this.startangle = this.endangle; ctx.fillStyle = d[2];// 画说明 ctx.fillRect(this.labelX, this.labelY + 30 * i, 20, 20); ctx.strokeRect(this.labelX, this.labelY + 30 * i, 20, 20); var label = Ext.get(this.ct).createChild();// 扇形的文字说明 label.position('absolute'); label.setLeftTop(this.labelX + 30, this.labelY + 30 * i - 4); label.dom.innerHTML = this.labels[i] || d[0]; } }, makeShadow : function() { var c = { x : this.circleX, y : this.circleY, r : this.radius } //this.ctx.beginPath(); 当this.ctx.currentPath_中不存在任何元素时,就可以不调用beginPath this.ctx.arc(c.x + 5, c.y + 5, c.r, 0, Math.PI * 2, false) this.ctx.closePath(); var radgrad = this.ctx.createRadialGradient(c.x + 5, c.y + 5, 0, c.x + 5, c.y + 5, c.r); radgrad.addColorStop(0, '#555555'); this.ctx.fillStyle ='#555555'; this.ctx.fill(); }, getContext : function() { return this.el.dom.getContext("2d"); }, setCanvasSize : function(w, h) { this.el.set( { width : w, height : h }); } }); Ext.onReady(function() { var pie = new Ext.ux.pieChart( { width : 600, height : 400, shadow : true, data : [['North', 12, 'red'], ['South', 23, 'blue'], ['East', 34, 'yellow'], ['West', 45, 'green']], circleX : 200, circleY : 200, labelX : 400, labelY : 100, radius : 150 }); pie.render(Ext.getBody()); });
contextPrototype.stroke = function(aFill) { this.currentPath_ = []; };的效果
contextPrototype.stroke = function(aFill) { // this.currentPath_ = []; };的效果