Skip to content

Commit d697b74

Browse files
authored
原生js仿echarts饼状图
1 parent 4dc7797 commit d697b74

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

饼状图-高清.html

+232
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head lang="en">
4+
<meta charset="UTF-8">
5+
<title></title>
6+
<style>
7+
canvas{
8+
border: 1px solid #A4E2F9;
9+
}
10+
</style>
11+
</head>
12+
<body>
13+
<div height="400" width="600" style="margin:50px">
14+
<canvas id="chart"> 你的浏览器不支持HTML5 canvas </canvas>
15+
</div>
16+
17+
<script type="text/javascript">
18+
function goChart(dataArr){
19+
20+
// 声明所需变量
21+
var canvas,ctx;
22+
// 图表属性
23+
var cWidth, cHeight, cMargin, cSpace;
24+
// 饼状图属性
25+
var radius,ox,oy;//半径 圆心
26+
var tWidth, tHeight;//图例宽高
27+
var posX, posY, textX, textY;
28+
var startAngle, endAngle;
29+
var totleNb;
30+
// 运动相关变量
31+
var ctr, numctr, speed;
32+
//鼠标移动
33+
var mousePosition = {};
34+
35+
//线条和文字
36+
var lineStartAngle,line,textPadding,textMoveDis;
37+
38+
// 获得canvas上下文
39+
canvas = document.getElementById("chart");
40+
if(canvas && canvas.getContext){
41+
ctx = canvas.getContext("2d");
42+
}
43+
initChart();
44+
45+
// 图表初始化
46+
function initChart(){
47+
// 图表信息
48+
cMargin = 20;
49+
cSpace = 40;
50+
51+
canvas.width = canvas.parentNode.getAttribute("width")* 2 ;
52+
canvas.height = canvas.parentNode.getAttribute("height")* 2;
53+
canvas.style.height = canvas.height/2 + "px";
54+
canvas.style.width = canvas.width/2 + "px";
55+
cHeight = canvas.height - cMargin*2;
56+
cWidth = canvas.width - cMargin*2;
57+
58+
//饼状图信息
59+
radius = cHeight*2/6; //半径 高度的2/6
60+
ox = canvas.width/2 + cSpace; //圆心
61+
oy = canvas.height/2;
62+
tWidth = 60; //图例宽和高
63+
tHeight = 20;
64+
posX = cMargin;
65+
posY = cMargin; //
66+
textX = posX + tWidth + 15
67+
textY = posY + 18;
68+
startAngle = endAngle = 90*Math.PI/180; //起始弧度 结束弧度
69+
rotateAngle = 0; //整体旋转的弧度
70+
71+
//将传入的数据转化百分比
72+
totleNb = 0;
73+
new_data_arr = [];
74+
for (var i = 0; i < dataArr.length; i++){
75+
totleNb += dataArr[i][0];
76+
}
77+
for (var i = 0; i < dataArr.length; i++){
78+
new_data_arr.push( dataArr[i][0]/totleNb );
79+
}
80+
totalYNomber = 10;
81+
// 运动相关
82+
ctr = 1;//初始步骤
83+
numctr = 50;//步骤
84+
speed = 1.2; //毫秒 timer速度
85+
86+
//指示线 和 文字
87+
lineStartAngle = -startAngle;
88+
line=40; //画线的时候超出半径的一段线长
89+
textPadding=10; //文字与线之间的间距
90+
textMoveDis = 200; //文字运动开始的间距
91+
}
92+
93+
drawMarkers();
94+
//绘制比例图及文字
95+
function drawMarkers(){
96+
ctx.textAlign="left";
97+
for (var i = 0; i < dataArr.length; i++){
98+
//绘制比例图及文字
99+
ctx.fillStyle = dataArr[i][1];
100+
ctx.fillRect(posX, posY + 40 * i, tWidth, tHeight);
101+
ctx.moveTo(posX, posY + 40 * i);
102+
ctx.font = 'normal 24px 微软雅黑'; //斜体 30像素 微软雅黑字体
103+
ctx.fillStyle = dataArr[i][1]; //"#000000";
104+
var percent = dataArr[i][2] + ":" + parseInt(100 * new_data_arr[i]) + "%";
105+
ctx.fillText(percent, textX, textY + 40 * i);
106+
}
107+
};
108+
109+
//绘制动画
110+
pieDraw();
111+
function pieDraw(mouseMove){
112+
113+
for (var n = 0; n < dataArr.length; n++){
114+
ctx.fillStyle = ctx.strokeStyle = dataArr[n][1];
115+
ctx.lineWidth=1;
116+
var step = new_data_arr[n]* Math.PI * 2; //旋转弧度
117+
var lineAngle = lineStartAngle+step/2; //计算线的角度
118+
lineStartAngle += step;//结束弧度
119+
120+
ctx.beginPath();
121+
var x0=ox+radius*Math.cos(lineAngle),//圆弧上线与圆相交点的x坐标
122+
y0=oy+radius*Math.sin(lineAngle),//圆弧上线与圆相交点的y坐标
123+
x1=ox+(radius+line)*Math.cos(lineAngle),//圆弧上线与圆相交点的x坐标
124+
y1=oy+(radius+line)*Math.sin(lineAngle),//圆弧上线与圆相交点的y坐标
125+
x2=x1,//转折点的x坐标
126+
y2=y1,
127+
linePadding=ctx.measureText(dataArr[n][2]).width+10; //获取文本长度来确定折线的长度
128+
129+
ctx.moveTo(x0,y0);
130+
//对x1/y1进行处理,来实现折线的运动
131+
yMove = y0+(y1-y0)*ctr/numctr;
132+
ctx.lineTo(x1,yMove);
133+
if(x1<=x0){
134+
x2 -= line;
135+
ctx.textAlign="right";
136+
ctx.lineTo(x2-linePadding,yMove);
137+
ctx.fillText(dataArr[n][2],x2-textPadding-textMoveDis*(numctr-ctr)/numctr,y2-textPadding);
138+
}else{
139+
x2 += line;
140+
ctx.textAlign="left";
141+
ctx.lineTo(x2+linePadding,yMove);
142+
ctx.fillText(dataArr[n][2],x2+textPadding+textMoveDis*(numctr-ctr)/numctr,y2-textPadding);
143+
}
144+
145+
ctx.stroke();
146+
147+
}
148+
149+
150+
151+
//设置旋转
152+
ctx.save();
153+
ctx.translate(ox, oy);
154+
ctx.rotate((Math.PI*2/numctr)*ctr/2);
155+
156+
//绘制一个圆圈
157+
ctx.strokeStyle = "rgba(0,0,0,"+ 0.5*ctr/numctr +")"
158+
ctx.beginPath();
159+
ctx.arc(0, 0 ,(radius+20)*ctr/numctr, 0, Math.PI*2, false);
160+
ctx.stroke();
161+
162+
for (var j = 0; j < dataArr.length; j++){
163+
164+
//绘制饼图
165+
endAngle = endAngle + new_data_arr[j]* ctr/numctr * Math.PI * 2; //结束弧度
166+
167+
ctx.beginPath();
168+
ctx.moveTo(0,0); //移动到到圆心
169+
ctx.arc(0, 0, radius*ctr/numctr, startAngle, endAngle, false); //绘制圆弧
170+
171+
ctx.fillStyle = dataArr[j][1];
172+
if(mouseMove && ctx.isPointInPath(mousePosition.x*2, mousePosition.y*2)){
173+
ctx.globalAlpha = 0.8;
174+
}
175+
176+
ctx.closePath();
177+
ctx.fill();
178+
ctx.globalAlpha = 1;
179+
180+
startAngle = endAngle; //设置起始弧度
181+
if( j == dataArr.length-1 ){
182+
startAngle = endAngle = 90*Math.PI/180; //起始弧度 结束弧度
183+
}
184+
}
185+
186+
ctx.restore();
187+
188+
if(ctr<numctr){
189+
ctr++;
190+
setTimeout(function(){
191+
//ctx.clearRect(-canvas.width,-canvas.width,canvas.width*2, canvas.height*2);
192+
ctx.clearRect(-canvas.width, -canvas.height,canvas.width*2, canvas.height*2);
193+
drawMarkers();
194+
pieDraw();
195+
}, speed*=1.085);
196+
}
197+
}
198+
199+
200+
201+
//监听鼠标移动
202+
var mouseTimer = null;
203+
canvas.addEventListener("mousemove",function(e){
204+
e = e || window.event;
205+
if( e.offsetX || e.offsetX==0 ){
206+
mousePosition.x = e.offsetX;
207+
mousePosition.y = e.offsetY;
208+
}else if( e.layerX || e.layerX==0 ){
209+
mousePosition.x = e.layerX;
210+
mousePosition.y = e.layerY;
211+
}
212+
213+
clearTimeout(mouseTimer);
214+
mouseTimer = setTimeout(function(){
215+
ctx.clearRect(0,0,canvas.width, canvas.height);
216+
drawMarkers();
217+
pieDraw(true);
218+
},10);
219+
});
220+
221+
222+
223+
}
224+
225+
var chartData = [[50,"#2dc6c8","瓜子"], [100,"#b6a2dd", "花生"], [200,"#5ab1ee","土豆"], [700,"#d7797f","南瓜四号"]];
226+
227+
goChart(chartData);
228+
229+
230+
</script>
231+
</body>
232+
</html>

0 commit comments

Comments
 (0)