您的位置:首页 > 其它

Canvas根据数据绘制饼形统计图

2016-11-17 02:07 344 查看
我们只要不是要去用 canvas 做游戏,那只要能做到 让 数据 可视图形化 即可,下面是 canvas 绘制饼形统计图的练习

<canvas width="600" height="400" id="cas" style='border: 1px solid black;'></canvas>
<script>
/* 公共方法 */
// 弧度与角度的互相切换
function toAngle( radian ) { return radian * 180 / Math.PI }
function toRadian( angle ) { return angle * Math.PI / 180 }

var cas = document.getElementById( 'cas' );
var ctx = cas.getContext( '2d' );   // 获取绘图对象

// 根据数据绘制饼形图,准备一组数据
var data = [ 123, 234, 78, 356, 449 ];
// 准备一组颜色数据
var colors = "red,hotpink,indianred,indigo,blue,lavender,lavenderblush,lawngreen,lemonchiffon".split( ',' );
// 求和以计算占比
var sum = 0;
data.forEach( function( v ) { sum += v; } );
// 根据总和,计算每一个百分比和角度 { value: 123, angle: 角度, text:文字描述 }
var data2 = data.map( function( v ) {
return {value : v, angle : v * 360 / sum, text : v + ",占比:" + (v / sum * 100).toFixed( 2 ) + '%'}
} );
console.log( data2 );

/* 准备绘制 */
var angle = -90, // 绘制起始角度
x = cas.width / 2, // 圆心 x 坐标
y = cas.height / 2, // 圆心 y 坐标
r = 100; // 半径
var x1, y1; // 记录描述文字的坐标
var distance = 30; // 指示线超出圆饼的距离
var txtLine; // 文本下划线
var paddingX = 20 / 3, paddingY = 20 / 3; // 设置文本的移动

/* 遍历数据进行绘制 */
data2.forEach( function( v, i ) {
// 绘制扇形
ctx.beginPath(); // 开启路径  因为每次都要换颜色
ctx.fillStyle = colors[ i ];    // 设置 fill 颜色
ctx.moveTo( x, y ); // 画笔移动到 ( x, y )
ctx.arc( x, y , r, toRadian( angle ), toRadian( angle + v.angle ) ); // 绘制圆弧
ctx.fill(); // fill 路径补全,填充成扇形

/*--- 绘制文本 ----*/
// 绘制直线
ctx.beginPath(); // 开启路径,因为要切换绘制方式
ctx.strokeStyle = colors[ i ]; // 设置 stroke 颜色
ctx.moveTo( x, y ); // 画笔移动到 ( x, y )
x1 = x + (r + distance) * Math.cos( toRadian(angle + v.angle / 2) ); //文字 x 坐标
y1 = y + (r + distance) * Math.sin( toRadian(angle + v.angle / 2) ); //文字 y 坐标
ctx.lineTo( x1, y1 ); // 连线
// 绘制横线
txtLine = ctx.measureText( v.text ).width + 2 * Math.abs( paddingX );
// 根据 是往左还是往右,设置 texLine 的 正负
if ( angle + v.angle / 2 < 270 && angle + v.angle / 2 > 90 ) {
txtLine = -ctx.measureText( v.text ).width - 2 * Math.abs(paddingX);
}
ctx.lineTo( x1 + txtLine, y1 );
ctx.stroke(); // 绘制

// 写文字
if ( angle + v.angle / 2 < 270 && angle + v.angle / 2 > 90 ) {
ctx.textAlign = 'right';
paddingX = - 20 / 3;
}
ctx.fillText( v.text , x1 + paddingX, y1 - paddingY );

angle += v.angle;   // 角度加上去
});

</script>


最终绘制出来的效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  canvas 图形 数据