<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<canvas id="pie" width="800px" height="600px" style="border: 1px solid #999999;margin: 0px;padding: 0;">
(Your browser doesn't support canvas)
</canvas>
<script type="text/javascript">
DomUtils = {
addEventListener:function(obj,type,fn,context){
function handler(e){
return fn.call(context||obj,e);
}
if(obj.addEventListener){
obj.addEventListener(type,handler,false);
}
else if(obj.attachEvent){
obj.attachEvent("on"+type,handler);
}
},
removeEventListener:function(){
if(obj.addEventListener){
obj.removeEventListener(type,fn,false);
}
else if(obj.attachEvent){
obj.detachEvent("on"+type,handler);
}
}
}
var PieChart = function(){
// func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])
this.init.apply(this,arguments);
};
PieChart.prototype = {
init:function(id,options){
this.renderId = id;
this.canvas = document.getElementById(this.renderId);
this.data = options.data;
this.colors = options.colors;
this.labels = options.labels;
this.linecolor = options.linecolor||"rgba(229, 205, 205, 0.58)";
this.isCircle = options.isCircle;
this.radius = options.radius||[];
this.angles = [];
this.prompt = null;
this.center = {x:0,y:0,radius:50};
this.offset = options.offset||100;
this.legend = {
width:20,
height:10
};
this._calcAngle();
},
_calcAngle(){
var startAngle = 0;
var endAngle = 0;
for(var i=0;i<this.data.length;i++){
endAngle = startAngle+Number(this.data[i])*Math.PI*2;
this.angles.push({
index:i,
label:this.labels[i],
color:this.colors[i],
start:startAngle,
end:endAngle
});
startAngle = endAngle;
}
},
_draw:function(){
// 开始绘画
var width = this.canvas.width;
var height = this.canvas.height;
var radius = Math.min(width,height)/2-this.offset;
var x = radius+this.offset;
var y = height/2+this.canvas.offsetTop-8;
this.center.x = x;
this.center.y = y;
this.center.radius = radius;
var ctx = this.canvas.getContext("2d");
this._antialiasing(ctx,width,height);
ctx.strokeStyle = this.linecolor;
for(var i=0;i<this.angles.length;i++){
ctx.beginPath();
ctx.moveTo(x,y);
ctx.fillStyle=this.angles[i].color;
ctx.arc(x,y,radius,this.angles[i].start,this.angles[i].end);
ctx.closePath();
ctx.lineWidth=1;
//ctx.strokeStyle="#ffffff";
ctx.fill();
ctx.stroke();
}
this._drawCircle(ctx);
},
_antialiasing:function(ctx,width,height){
if (window.devicePixelRatio) {
this.canvas.style.width = width + "px";
this.canvas.style.height = height + "px";
this.canvas.height = height * window.devicePixelRatio;
this.canvas.width = width * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
},
_drawCircle:function(ctx){
if(this.isCircle){
ctx.beginPath();
ctx.moveTo(this.center.x,this.center.y);
ctx.fillStyle="#ffffff";
ctx.arc(this.center.x,this.center.y,this.center.radius/3,0,Math.PI*2);
ctx.closePath();
ctx.fill();
}
},
_drawLegend:function(){
var ctx = this.canvas.getContext("2d");
var x = this.canvas.offsetWidth-150;
var y = this.offset;
for(var i=0;i<this.angles.length;i++){
ctx.beginPath();
ctx.moveTo(x,y);
ctx.fillStyle=this.angles[i].color;
ctx.fillRect(x,y,this.legend.width,this.legend.height);
// 绘制文字
ctx.moveTo(x+this.legend.width+5, y+this.offset/2);
ctx.font = 'bold 12px 微软雅黑';
ctx.fillStyle = color_arr[i];
ctx.fillText(this.angles[i].label,x+this.legend.width+5,y+this.offset/2)
//ctx.closePath();
//ctx.strokeStyle="#ffffff";
ctx.fill();
y = y + 20;
}
},
_drawPrompt(x,y,index){
var pie = this.angles[index];
var d = this.data[index];
if(!this.prompt){
this.prompt = document.createElement("div");
document.body.appendChild(this.prompt);
}
this.prompt.style.display = "block";
this.prompt.style.background = "rgba(50, 50, 50, 0.701961)";
this.prompt.style.position = "absolute";
this.prompt.style.padding = "5px";
this.prompt.style.zindex = "99999";
this.prompt.style.color = "#fff";
this.prompt.style.borderRadius = "4px";
this.prompt.style.top = y+20+"px";
this.prompt.style.left = x+20+"px";
this.prompt.innerHTML = pie.label+"<br/>"+d;
},
_getPieIndex:function(x,y){
var angle = Math.atan2(y,x);
if (angle < 0) angle = -angle;
else {
angle = Math.PI * 2 - angle;
}
for(var i=0;i<this.angles.length;i++){
if(angle<=this.angles[i].end){
return i;
}
}
},
_onMouseOver:function(){
this._draw();
var e = arguments.callee.caller.arguments[0]||event;
var x = e.x|| e.clientX;
var y = e.y|| e.clientY;
var dx = x-this.center.x;
var dy = this.center.y-y;
var d = Math.sqrt(dx*dx+dy*dy);
if(this.center.radius>=d){
console.info(x+","+y);
var index = this._getPieIndex(dx,dy);
var ctx = this.canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(this.center.x,this.center.y);
ctx.fillStyle=this.angles[index].color;
ctx.lineWidth=1;
ctx.arc(this.center.x,this.center.y,this.center.radius+20,this.angles[index].start,this.angles[index].end);
ctx.closePath();
ctx.fill();
this._drawCircle(ctx);
this._drawPrompt(x,y,index);
}else{
if(this.prompt)this.prompt.style.display="none";
}
},
_dispatchEvent:function(){
DomUtils.addEventListener(this.canvas,'mouseover',this._onMouseOver,this);
//DomUtils.addEventListener(this.canvas,'mouseout',canvasOnMouseOut,this);
DomUtils.addEventListener(this.canvas,'mousemove',this._onMouseOver,this);
},
render:function(){
this._draw();
this._dispatchEvent();
this._drawLegend();
}
};
var data_arr = [0.05, 0.25, 0.6, 0.1];
var color_arr = ["#00FF21", "#FFAA00", "#00AABB", "#0044ff"];
var text_arr = ["河北", "山东", "河南", "山西"];
var piechart = new PieChart("pie",{
isCircle:true,
data:data_arr,
colors:color_arr,
labels:text_arr
});
piechart.render();
</script>
</body>
</html>
h5 canvas手工写一个初级的饼状图,只为研究原理,自娱自乐
最新推荐文章于 2024-07-07 15:37:01 发布