关于canvas制作数据可视化圆盘

一直以来都没有写这个的习惯,总是感觉太累。但是发现之前做的东西慢慢的会被遗忘,还是记录一下比较好。夜深人静,抽点时间,慢慢的写。废话不多说上代码。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>canvas圆盘刻度表</title>


</head>
<body>
<canvas id="skyPic" width="300" height="300"></canvas>

</body>
<script type="text/javascript">

function drawBg(number) {
var can = document.getElementById('skyPic');
var width = can.width;
var height = can.height;
var ctx = can.getContext("2d");
var rem = width / 400;
var RADIUS = width / 2 - 20;
var bgColor = "#fff";
var whiteColor = "#d1d3d4";
var scaleColor = "black";
var pointcolor = "yellow";
/* var text = can.getContext("2d"); */
/* console.log(number);*/
ctx.clearRect(0, 0, width, height);
ctx.width = ctx.width;
ctx.fillStyle = bgColor;
ctx.fillRect = (0, 0, width, height);
ctx.save();

ctx.beginPath();
ctx.fillStyle = whiteColor;
ctx.arc(RADIUS, RADIUS, RADIUS, Math.PI * 2, false);
ctx.lineTo(RADIUS, RADIUS);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = bgColor;
ctx.arc(RADIUS, RADIUS, RADIUS - 25, 0, Math.PI * 2, false);
ctx.lineTo(RADIUS, RADIUS);
ctx.fill();
ctx.save();


ctx.strokeStyle = scaleColor;
ctx.translate(RADIUS, RADIUS);

ctx.rotate(Math.PI / 180 * 360);

ctx.lineWidth = 2;
for (var i = 0; i < 20; i++) {
ctx.rotate(Math.PI / 180 * 18);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, RADIUS - 12.5);
ctx.stroke();
}
ctx.restore();
ctx.closePath();
ctx.save();

ctx.beginPath();
ctx.fillStyle = bgColor;
ctx.arc(RADIUS, RADIUS, RADIUS - 25, Math.PI * 2, false);
ctx.lineTo(RADIUS, RADIUS);
ctx.fill();


ctx.strokeStyle = scaleColor;
ctx.translate(RADIUS, RADIUS);

ctx.rotate(Math.PI / 180 * 360);
ctx.lineWidth = 2;
for (var i = 0; i < 10; i++) {
ctx.rotate(Math.PI / 180 * 36);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, RADIUS);
ctx.stroke();
}
ctx.restore();
ctx.closePath();
ctx.save();

ctx.beginPath();
ctx.fillStyle = bgColor;
ctx.arc(RADIUS, RADIUS, RADIUS - 25, Math.PI * 2, false);
ctx.fill();

var percent = ['100%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%'];

ctx.font = 20 * rem + "px Arial";
ctx.textAlign = "center";
ctx.baseline = "middle";
ctx.fillStyle = scaleColor;
percent.forEach(function (index, i) {
ctx.save();
ctx.translate(RADIUS, RADIUS);
ctx.beginPath();
var rad = 2 * Math.PI / 10 * i;
var x = ((RADIUS - 12.5) - 40 * rem) * Math.sin(rad);
var y = -((RADIUS - 12.5) - 40 * rem) * Math.cos(rad);
ctx.translate(x, y);
ctx.rotate(2 * Math.PI / 10 * i);
ctx.fillText(index, 0, 0);
ctx.restore();
ctx.closePath();
});
ctx.save();
ctx.translate(RADIUS, RADIUS);
ctx.beginPath();
ctx.lineWidth = 1;
ctx.lineCap = "round";
ctx.fillStyle = "#97d1af";
ctx.rotate(2 * Math.PI / 100 * number);
ctx.moveTo(0, -RADIUS*0.7);
ctx.lineTo(-5*rem, 15* rem);
ctx.lineTo(5 * rem, 15 * rem);
ctx.fill();
ctx.restore();

ctx.save();
ctx.font = 40 * rem + "px Arial";
ctx.textAlign = "center";
ctx.baseline = "middle";
ctx.fillStyle = scaleColor;
ctx.beginPath;
ctx.fillText(number+"%",RADIUS,0.9*RADIUS);
ctx.restore();
}
function interval(){
var a = [50,3,4,24,65,67,87,99,43,16,43,17,34,21,34,21,34,18];
var b = a[Math.floor(Math.random()* a.length)];
drawBg(b);
}


drawBg(0);
setInterval(interval,1000);

稍微有点绕的地方就是画刻度和画刻度下面对应的值。画大小刻度的时候就是画两个大小不一的圆,然后填充成白色。画百分比就用到了初中时候的三角函数了,求出对应的坐标,把刻度放到相应的位置,再旋转相应的角度。大概就是这样。没怎么写过东西,比较菜,望大家不腻赐教。下面是效果图。

也许要做个过度效果比较好

猜你喜欢

转载自www.cnblogs.com/Elvisde1/p/9108644.html