This article introduces the sample code for dynamically drawing a pie chart using html5 canvas and shares it with everyone. The details are as follows:
Let’s look at the renderings first
This does not refer to third-party libraries such as jquery, but is written using DOM operations and canvas features.
Canvas drawing circles are generally divided into solid circles and hollow circles.
According to the demand analysis, we know that the circle is a solid circle.
1. First use canvas to draw a solid circle
//Pseudocode var canvas = document.createElement(canvas);var ctx = canvas.getContext('2d');ctx.beginPath();ctx.arc(circle center x-axis coordinate, circle center y-axis coordinate, radius, starting angle , end angle);ctx.fillStyle = 'green';ctx.closePath();ctx.fill();
2. Draw a pie chart based on different colors
//Pseudocode var canvas = document.createElement(canvas);var ctx = canvas.getContext('2d');ctx.beginPath();ctx.arc(center x-axis coordinate, center y-axis coordinate, radius, green start corner, green end corner);ctx.fillStyle = 'green';ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(center x-axis coordinate, center y-axis coordinate, radius, red starting angle, red ending angle);ctx.fillStyle = 'red';ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(circle center x-axis coordinate, circle center y-axis coordinate, radius, yellow starting angle, yellow ending angle);ctx.fillStyle = 'yellow';ctx.closePath();ctx.fill();ctx.beginPath();ctx.arc(circle center x-axis coordinate, circle center y-axis coordinate, radius, purple starting angle, purple ending angle);ctx.fillStyle = 'purple';ctx.closePath();ctx.fill();
3. Dynamically draw pie charts
Three methods are generally recommended on the dynamic circle drawing website: requestAnimationFrame, setInterval (timing), and dynamic angle calculation.
Here I use the first requestAnimationFrame method.
During the writing process, I discovered a problem, that is, when dynamically drawing a circle, it is not drawn based on the coordinates of the center of the circle. In order to solve this problem, you need to redefine the coordinates of the canvas brush as the coordinates of the original circle center each time you draw a circle.
<!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><div id=circle style=width: 500px;float: left;></div></body></html><script type=text/javascript>(function(window,undefined){ var data = [ {product: product 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:product2,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:product 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:product 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; } //Coordinate axis area//Note that the actual line chart area is slightly smaller than this return { p1:'green', p2:'red', p3:'yellow', p4:'purple', x: 0 , //The left coordinate of the coordinate axis on the canvas y: 0, //The top coordinate of the coordinate axis on the canvas maxX: canvas.width, //The right coordinate of the coordinate axis on the canvas maxY: canvas.height, //The bottom coordinate of the coordinate axis on the canvas r:(canvas.width)/2, //Starting point ry:(canvas.height)/2, //Starting point cr: (canvas.width)/4, //Radius startAngle :-(1/2*Math.PI), //Start angle endAngle:(-(1/2*Math.PI)+2*Math.PI), //End angle xAngle:1*(Math.PI/ 180) //Offset}; } //Draw a circle 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>
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.