第一次接触Html5的Canvas,先搞了个练手的页面
脚本代码如下:/Files/Employee/饼图.jpg
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <script type="text/javascript">
2 var color=["#FF0000","#00FF00","#0000FF","#FF00FF","#00FFFF","#FFFF00"];
3 var data=[10,20,30,15,8,17];
4 var list=new Array(data.length);
5 function GetFanShape(id,x0,y0)
6 {
7 var angle_Start=0;
8 //圆心坐标
9 var rx=100;
10 var ry=100;
11 var x=0;
12 var y=0;
13 //x1,y1为弧的起点
14 for(var i=0;i<data.length;i++)
15 {
16 if(id==i)
17 {
18 rx=x0;
19 ry=y0;
20 }
21 else
22 {
23 rx=100;
24 ry=100;
25 }
26 var x1=0;
27 var y1=0;
28 if(x==0&&y==0)
29 {
30 x1=rx+100*(Math.cos(angle_Start*Math.PI/180));
31 y1=ry+100*(Math.sin(angle_Start*Math.PI/180));
32 }
33 else
34 {
35 x1=x;
36 y1=y;
37 }
38 //x3,y3 为弧上中点位置的坐标
39 var x3=rx+100*(Math.cos(((angle_Start+Math.PI*(data[i]/100))+Math.PI*2*(data[i]/100)*Math.PI/180)));
40 var y3=ry+100*(Math.sin(((angle_Start+Math.PI*(data[i]/100))+Math.PI*2*(data[i]/100)*Math.PI/180)));
41
42 angle_Start+=Math.PI*2*(data[i]/100);
43 //x2,y2为弧的终点
44 var x2=rx+100*(Math.cos((angle_Start+Math.PI*2*(data[i]/100)*Math.PI/180)));
45 var y2=ry+100*(Math.sin((angle_Start+Math.PI*2*(data[i]/100)*Math.PI/180)));
46 x=x2;
47 y=y2;
48 var FanShape={};
49 FanShape.Id=i;
50 FanShape.x1=x1;
51 FanShape.y1=y1;
52 FanShape.x2=x2;
53 FanShape.y2=y2;
54 FanShape.x3=x3;
55 FanShape.y3=y3;
56 FanShape.x=rx;
57 FanShape.y=ry;
58 FanShape.data=data[i];
59 //半径
60 FanShape.r=100;
61 list[i]=FanShape;
62 }
63 }
64 function PieMap(id)
65 {
66 var canvas=document.getElementById("pieMap");
67 var pie=canvas.getContext("2d");
68 pie.save();
69 pie.clearRect(0,0,500,500);
70 pie.translate(100,100);
71
72 //画弧度
73 var angle_Start=0;
74 for(var i=0;i<data.length;i++)
75 {
76 pie.beginPath();
77 if(i==id)
78 {
79 var sh=list[id];
80 var x= (sh.x1+sh.x2)/2;
81 var y=(sh.y1+sh.y2)/2;
82 x=(100+x)/2;
83 y=(100+y)/2;
84
85 x=(100+x)/2;
86 y=(100+y)/2;
87 GetFanShape(id,x,y);
88 pie.moveTo(x,y);
89 pie.arc(x,y,100,angle_Start,angle_Start+Math.PI*2*(data[i]/100),false);
90 }
91 else
92 {
93 pie.moveTo(100,100);
94 pie.arc(100,100,100,angle_Start,angle_Start+Math.PI*2*(data[i]/100),false);
95 }
96 pie.fillStyle=color[i];
97 pie.fill();
98 angle_Start+=Math.PI*2*(data[i]/100);
99 }
100 //writeText(pie);
101 writeLine(pie);
102 pie.restore();
103 }
104
105 //判断鼠标所在的区域
106 function GetFanShapeId(x,y)
107 {
108 var id=-1;
109 for(var i=0;i<list.length;i++)
110 {
111 var s=list[i];
112 var p={};
113 p.x=x-100;
114 p.y=y-100;
115 var a={};
116 a.x=s.x;
117 a.y=s.y;
118 var b={};
119 b.x=s.x1;
120 b.y=s.y1;
121 var c={};
122 c.x=s.x2;
123 c.y=s.y2;
124 var result=GetArea(a,b,c)-GetArea(p,a,b)-GetArea(p,b,c)-GetArea(p,c,a);
125 if(result>=0)
126 {
127 id=s.Id;
128 }
129 }
130 return id;
131 }
132
133 //三角形的面积
134 function GetArea(A,B,C)
135 {
136 var result=Math.abs((A.x-C.x)*(B.y-C.y)-(B.x-C.x)*(A.y-C.y))/2;
137 return result;
138 }
139 //扇形外画线
140 function writeLine(pie)
141 {
142 for(var i=0;i<list.length;i++)
143 {
144 var s=list[i];
145 pie.save();
146 pie.beginPath();
147 pie.fillStyle="black";
148 pie.moveTo(s.x3,s.y3);
149 var p=getXY(s.x,s.y,s.x3,s.y3);
150 pie.lineTo(p.x,p.y);
151 pie.fillText(s.data+"%",p.x,p.y);
152 pie.stroke();
153 pie.restore();
154 }
155 }
156 function MouseCanva(e)
157 {
158 var flg=-1;
159 if(e.layerX||e.layerY==0)
160 {
161 flg=GetFanShapeId(e.layerX,e.layerY);
162 }
163 if(flg!=-1)
164 {
165 document.getElementById("pieMap").style.cursor="pointer";
166 }
167 else
168 {
169 document.getElementById("pieMap").style.cursor="";
170 }
171 }
172
173 //鼠标点击事件
174 function CanvaClick(e)
175 {
176 var id=-1;
177 if(e.layerX||e.layerY==0)
178 {
179 id=GetFanShapeId(e.layerX,e.layerY);
180 }
181 if(id==-1)
182 {//鼠标点击不在 扇形区内 让图形恢复初始状态
183 GetFanShape(-1,100,100);
184 }
185 //鼠标点击的是哪个扇形
186 PieMap(id);
187 }
188 window.onload=function(){
189 GetFanShape(-1,100,100);
190 PieMap(-1);
191
192 var canva=document.getElementById("pieMap");
193 canva.addEventListener("click",CanvaClick,true);
194 canva.addEventListener("mousemove",MouseCanva,true);
195 }
196
197 //亮点之间的距离
198 function getDistance(x1,y1,x2,y2)
199 {
200 return Math.sqrt((Math.pow(x1-x2,2)+Math.pow(y1-y2,2)));
201 }
202
203 var xy={};
204 //获取扇形外直线的终点
205 //参数一 圆心坐标X和Y,扇形中点坐标X和Y
206 function getXY(rx,ry,x3,y3)
207 {
208 xy.x=(3*x3-rx)/2;
209 xy.y=(3*y3-ry)/2
210 return xy;
211 }
212 </script>
2 var color=["#FF0000","#00FF00","#0000FF","#FF00FF","#00FFFF","#FFFF00"];
3 var data=[10,20,30,15,8,17];
4 var list=new Array(data.length);
5 function GetFanShape(id,x0,y0)
6 {
7 var angle_Start=0;
8 //圆心坐标
9 var rx=100;
10 var ry=100;
11 var x=0;
12 var y=0;
13 //x1,y1为弧的起点
14 for(var i=0;i<data.length;i++)
15 {
16 if(id==i)
17 {
18 rx=x0;
19 ry=y0;
20 }
21 else
22 {
23 rx=100;
24 ry=100;
25 }
26 var x1=0;
27 var y1=0;
28 if(x==0&&y==0)
29 {
30 x1=rx+100*(Math.cos(angle_Start*Math.PI/180));
31 y1=ry+100*(Math.sin(angle_Start*Math.PI/180));
32 }
33 else
34 {
35 x1=x;
36 y1=y;
37 }
38 //x3,y3 为弧上中点位置的坐标
39 var x3=rx+100*(Math.cos(((angle_Start+Math.PI*(data[i]/100))+Math.PI*2*(data[i]/100)*Math.PI/180)));
40 var y3=ry+100*(Math.sin(((angle_Start+Math.PI*(data[i]/100))+Math.PI*2*(data[i]/100)*Math.PI/180)));
41
42 angle_Start+=Math.PI*2*(data[i]/100);
43 //x2,y2为弧的终点
44 var x2=rx+100*(Math.cos((angle_Start+Math.PI*2*(data[i]/100)*Math.PI/180)));
45 var y2=ry+100*(Math.sin((angle_Start+Math.PI*2*(data[i]/100)*Math.PI/180)));
46 x=x2;
47 y=y2;
48 var FanShape={};
49 FanShape.Id=i;
50 FanShape.x1=x1;
51 FanShape.y1=y1;
52 FanShape.x2=x2;
53 FanShape.y2=y2;
54 FanShape.x3=x3;
55 FanShape.y3=y3;
56 FanShape.x=rx;
57 FanShape.y=ry;
58 FanShape.data=data[i];
59 //半径
60 FanShape.r=100;
61 list[i]=FanShape;
62 }
63 }
64 function PieMap(id)
65 {
66 var canvas=document.getElementById("pieMap");
67 var pie=canvas.getContext("2d");
68 pie.save();
69 pie.clearRect(0,0,500,500);
70 pie.translate(100,100);
71
72 //画弧度
73 var angle_Start=0;
74 for(var i=0;i<data.length;i++)
75 {
76 pie.beginPath();
77 if(i==id)
78 {
79 var sh=list[id];
80 var x= (sh.x1+sh.x2)/2;
81 var y=(sh.y1+sh.y2)/2;
82 x=(100+x)/2;
83 y=(100+y)/2;
84
85 x=(100+x)/2;
86 y=(100+y)/2;
87 GetFanShape(id,x,y);
88 pie.moveTo(x,y);
89 pie.arc(x,y,100,angle_Start,angle_Start+Math.PI*2*(data[i]/100),false);
90 }
91 else
92 {
93 pie.moveTo(100,100);
94 pie.arc(100,100,100,angle_Start,angle_Start+Math.PI*2*(data[i]/100),false);
95 }
96 pie.fillStyle=color[i];
97 pie.fill();
98 angle_Start+=Math.PI*2*(data[i]/100);
99 }
100 //writeText(pie);
101 writeLine(pie);
102 pie.restore();
103 }
104
105 //判断鼠标所在的区域
106 function GetFanShapeId(x,y)
107 {
108 var id=-1;
109 for(var i=0;i<list.length;i++)
110 {
111 var s=list[i];
112 var p={};
113 p.x=x-100;
114 p.y=y-100;
115 var a={};
116 a.x=s.x;
117 a.y=s.y;
118 var b={};
119 b.x=s.x1;
120 b.y=s.y1;
121 var c={};
122 c.x=s.x2;
123 c.y=s.y2;
124 var result=GetArea(a,b,c)-GetArea(p,a,b)-GetArea(p,b,c)-GetArea(p,c,a);
125 if(result>=0)
126 {
127 id=s.Id;
128 }
129 }
130 return id;
131 }
132
133 //三角形的面积
134 function GetArea(A,B,C)
135 {
136 var result=Math.abs((A.x-C.x)*(B.y-C.y)-(B.x-C.x)*(A.y-C.y))/2;
137 return result;
138 }
139 //扇形外画线
140 function writeLine(pie)
141 {
142 for(var i=0;i<list.length;i++)
143 {
144 var s=list[i];
145 pie.save();
146 pie.beginPath();
147 pie.fillStyle="black";
148 pie.moveTo(s.x3,s.y3);
149 var p=getXY(s.x,s.y,s.x3,s.y3);
150 pie.lineTo(p.x,p.y);
151 pie.fillText(s.data+"%",p.x,p.y);
152 pie.stroke();
153 pie.restore();
154 }
155 }
156 function MouseCanva(e)
157 {
158 var flg=-1;
159 if(e.layerX||e.layerY==0)
160 {
161 flg=GetFanShapeId(e.layerX,e.layerY);
162 }
163 if(flg!=-1)
164 {
165 document.getElementById("pieMap").style.cursor="pointer";
166 }
167 else
168 {
169 document.getElementById("pieMap").style.cursor="";
170 }
171 }
172
173 //鼠标点击事件
174 function CanvaClick(e)
175 {
176 var id=-1;
177 if(e.layerX||e.layerY==0)
178 {
179 id=GetFanShapeId(e.layerX,e.layerY);
180 }
181 if(id==-1)
182 {//鼠标点击不在 扇形区内 让图形恢复初始状态
183 GetFanShape(-1,100,100);
184 }
185 //鼠标点击的是哪个扇形
186 PieMap(id);
187 }
188 window.onload=function(){
189 GetFanShape(-1,100,100);
190 PieMap(-1);
191
192 var canva=document.getElementById("pieMap");
193 canva.addEventListener("click",CanvaClick,true);
194 canva.addEventListener("mousemove",MouseCanva,true);
195 }
196
197 //亮点之间的距离
198 function getDistance(x1,y1,x2,y2)
199 {
200 return Math.sqrt((Math.pow(x1-x2,2)+Math.pow(y1-y2,2)));
201 }
202
203 var xy={};
204 //获取扇形外直线的终点
205 //参数一 圆心坐标X和Y,扇形中点坐标X和Y
206 function getXY(rx,ry,x3,y3)
207 {
208 xy.x=(3*x3-rx)/2;
209 xy.y=(3*y3-ry)/2
210 return xy;
211 }
212 </script>
Html页面代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <body>
2 <canvas id="pieMap" width="500" height="500" style="border:1px black solid;"></canvas>
3 <div id="txtDiv">
4 <h1>请用牛X的浏览器运行</h1>
5 <h2>第一次接触Canvas,请不要使用砖块!</h2>
6 </div>
7 </body>
2 <canvas id="pieMap" width="500" height="500" style="border:1px black solid;"></canvas>
3 <div id="txtDiv">
4 <h1>请用牛X的浏览器运行</h1>
5 <h2>第一次接触Canvas,请不要使用砖块!</h2>
6 </div>
7 </body>
运行结果如下: