代码比较简单,需要注意的一点就是:
如果想让饼图的边框显示出来,需要找到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_ = [];
};的效果