html5+canvas動態(tài)完成餅狀圖步驟詳細說明
發(fā)表時間:2023-09-11 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]這次給大家?guī)韍tml5+canvas動態(tài)實現(xiàn)餅狀圖步驟詳解,html5+canvas動態(tài)實現(xiàn)餅狀圖的注意事項有哪些,下面就是實戰(zhàn)案例,一起來看一下。先來看效果圖這里并沒引用jquery等第三方庫,只是用dom操作和canvas的特性編寫的。canvas畫圓大體分為實心圓和空心圓。根據(jù)需求分析知道...
這次給大家?guī)韍tml5+canvas動態(tài)實現(xiàn)餅狀圖步驟詳解,html5+canvas動態(tài)實現(xiàn)餅狀圖的
注意事項有哪些,下面就是實戰(zhàn)案例,一起來看一下。
先來看效果圖
這里并沒引用jquery等第三方庫,只是用dom操作和canvas的特性編寫的。
canvas畫圓大體分為實心圓和空心圓。
根據(jù)需求分析知道該圓為實心圓。
1.先用canvas畫實心圓
//偽代碼
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,開始角,結(jié)束角);
ctx.fillStyle = 'green';
ctx.closePath();
ctx.fill();
2.根據(jù)不同顏色繪制餅狀圖
//偽代碼
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,綠色開始角,綠色結(jié)束角);
ctx.fillStyle = 'green';
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,紅色開始角,紅色結(jié)束角);
ctx.fillStyle = 'red';
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,黃色開始角,黃色結(jié)束角);
ctx.fillStyle = 'yellow';
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.arc(圓心x軸坐標(biāo),圓心y軸坐標(biāo),半徑,紫色開始角,紫色結(jié)束角);
ctx.fillStyle = 'purple';
ctx.closePath();
ctx.fill();
3.動態(tài)繪制餅狀圖
動態(tài)繪制圓網(wǎng)上普遍推薦三種方法:requestAnimationFrame、setInterval(定時)、還有動態(tài)算角度的。
這里我用的是第一種requestAnimationFrame方式。
在編寫的過程中發(fā)現(xiàn)一個問題,就是動態(tài)畫圓時并不是以圓心的坐標(biāo)畫的。為了解決這一問題,需要在每次畫圓時重新將canvas的畫筆的坐標(biāo)定義為最初圓心的坐標(biāo)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#graph {
/* border: 1px solid black;
height: 100%;
width: 100%;
box-sizing: border-box;*/
}
</style>
</head>
<body>
<p id="circle" style="width: 500px;float: left;"></p>
</body>
</html>
<script type="text/javascript">
(function(window,undefined){
var data = [
{"product":"產(chǎn)品1","sales":[192.44 ,210.54 ,220.84 ,230.11 ,220.85 ,210.59 ,205.49 ,200.55 ,195.71 ,187.46 ,180.66 ,170.90]},
{"product":"產(chǎn)品2","sales":[122.41 ,133.16 ,145.65 ,158.00 ,164.84 ,178.62 ,185.70 ,190.13 ,195.53 ,198.88 ,204.32 ,210.91]},
{"product":"產(chǎn)品3","sales":[170.30 ,175.00 ,170.79 ,165.10 ,165.62 ,160.92 ,155.92 ,145.77 ,145.17 ,140.27 ,135.99 ,130.33]},
{"product":"產(chǎn)品4","sales":[165.64 ,170.15 ,175.10 ,185.32 ,190.90 ,190.01 ,187.05 ,183.74 ,177.24 ,181.90 ,179.54 ,175.98]}
]
var dom_circle = document.getElementById('circle');
if(dom_circle != undefined && dom_circle != null)
{
var canvas = document.createElement("canvas");
dom_circle.appendChild(canvas);
var ctx = canvas.getContext('2d');
var defaultStyle = function(Dom,canvas){
if(Dom.clientWidth <= 300)
{
canvas.width = 300;
Dom.style.overflowX = "auto";
}
else{
canvas.width = Dom.clientWidth;
}
if(Dom.clientHeight <= 300)
{
canvas.height = 300;
Dom.style.overflowY = "auto";
}
else
{
canvas.height = Dom.clientHeight;
}
//坐標(biāo)軸區(qū)域
//注意,實際畫折線圖區(qū)域還要比這個略小一點
return {
p1:'green',
p2:'red',
p3:'yellow',
p4:'purple',
x: 0 , //坐標(biāo)軸在canvas上的left坐標(biāo)
y: 0 , //坐標(biāo)軸在canvas上的top坐標(biāo)
maxX: canvas.width , //坐標(biāo)軸在canvas上的right坐標(biāo)
maxY: canvas.height , //坐標(biāo)軸在canvas上的bottom坐標(biāo)
r:(canvas.width)/2, //起點
ry:(canvas.height)/2, //起點
cr: (canvas.width)/4, //半徑
startAngle:-(1/2*Math.PI), //開始角度
endAngle:(-(1/2*Math.PI)+2*Math.PI), //結(jié)束角度
xAngle:1*(Math.PI/180) //偏移量
};
}
//畫圓
var tmpAngle = -(1/2*Math.PI);
var ds = null;
var sum = data[0]['sales'][0]+data[0]['sales'][1]+data[0]['sales'][2]+data[0]['sales'][3]
var percent1 = data[0]['sales'][0]/sum * Math.PI * 2 ;
var percent2 = data[0]['sales'][1]/sum * Math.PI * 2 + percent1;
var percent3 = data[0]['sales'][2]/sum * Math.PI * 2 + percent2;
var percent4 = data[0]['sales'][3]/sum * Math.PI * 2 + percent3;
console.log(percent1);
console.log(percent2);
console.log(percent3);
console.log(percent4);
var tmpSum = 0;
var drawCircle = function(){
if(tmpAngle >= ds.endAngle)
{
return false;
}
else if(tmpAngle+ ds.xAngle > ds.endAngle)
{
tmpAngle = ds.endAngle;
}
else{
tmpAngle += ds.xAngle;
tmpSum += ds.xAngle
}
// console.log(ds.startAngle+'***'+tmpAngle);
// console.log(tmpSum);
// ctx.clearRect(ds.x,ds.y,canvas.width,canvas.height);
if(tmpSum > percent1 && tmpSum <percent2)
{
ctx.beginPath();
ctx.moveTo(ds.r,ds.ry);
ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle+percent1,tmpAngle);
ctx.fillStyle = ds.p2;
}
else if(tmpSum > percent2 && tmpSum <percent3)
{
ctx.beginPath();
ctx.moveTo(ds.r,ds.ry);
ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle+percent2,tmpAngle);
ctx.fillStyle = ds.p3;
}
else if(tmpSum > percent3 )
{
ctx.beginPath();
ctx.moveTo(ds.r,ds.ry);
ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle+percent3,tmpAngle);
ctx.fillStyle = ds.p4;
}
else{
ctx.beginPath();
ctx.moveTo(ds.r,ds.ry);
ctx.arc(ds.r,ds.ry,ds.cr,ds.startAngle,tmpAngle);
ctx.fillStyle = ds.p1;
}
ctx.closePath();
ctx.fill();
requestAnimationFrame(drawCircle);
}
this.toDraw = function(){
ds= defaultStyle(dom_circle,canvas);
// console.log(tmpAngle);
// console.log(ds.xAngle)
ctx.clearRect(ds.x,ds.y,canvas.width,canvas.height);
drawCircle();
}
this.toDraw();
var self = this;
window.onresize = function(){
self.toDraw()
}
}
})(window);
</script>
相信看了本文案例你已經(jīng)掌握了方法,更多精彩請關(guān)注php中文網(wǎng)其它相關(guān)文章!
推薦閱讀:
H5+WebWorkers多線程開發(fā)使用詳解
H5離線應(yīng)用與客戶端存儲使用詳解
以上就是html5+canvas動態(tài)實現(xiàn)餅狀圖步驟詳解的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
網(wǎng)站建設(shè)是一個廣義的術(shù)語,涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護的網(wǎng)站。