java圆饼图插件_饼图----插件

(function( w ) {

// 角度转换为弧度

function angleToRadian( angle ) {

return Math.PI / 180 * angle;

}

/*

* constructor { PipeChart } 饼图构造函数

* param { ctx: Context } 绘图上下文

* param { data: Array } 绘制饼图所需的数据

* param { x: number } 圆心x坐标

* param { y: number } 圆心y坐标

* param { r: number } 饼图半径

* */

function PipeChart( ctx, data, x, y, r ) {

this.ctx = ctx;

this.data = data;

this.x = x;

this.y = y;

this.r = r;

// 文字衬托线到圆的距离

this.lineSpace = 20;

// 扇形和文字的杨色

this.colors =

'blue,hotpink,green,deeppink,ivory,skyblue,lavender,lavenderblush'

.split(',');

// 把数据转换为对应的角度

this.processData();

}

// 置换原型

PipeChart.prototype = {

constructor: PipeChart,

// 绘制饼图

draw: function() {

this.drawPipe();

this.drawText();

},

// 根据数据转换成对应的角度

processData: function() {

/*

* 实现思路:

* 1、求单位数据所占用的角度 ==> 360 / 数据总和

* 2、使用单位数据所占用角度 * 每一份数据值得到每一份

数据所占用的角度

* 3、把计算好的角度使用一个数据存储起来,供其他方法使

* */

var self = this;

// 求数据总和

var num = 0;

this.data.forEach( function( obj ) {

num += obj.val;

});

// 求单位数据所占用的角度

var unitAngle = 360 / num;

// 用来存储数据所占用饼图的角度

this.processArr = [];

this.data.forEach( function( obj ) {

// 这里的this不是饼图实例,所以使用self

self.processArr.push( unitAngle * obj.val );

});

},

// 绘制饼中的扇

drawPipe: function() {

// 扇形默认起点和结束点

var startAngle = 0;

var endAngle = 0;

/*

* 实现思路:

* 1、遍历所有计算好的角度

* 2、beginPath、moveTo到饼图圆心

* 3、画对应扇形的弧

* 3.1、弧的起点位置 = 上一个弧的结束点

* 3.2、弧的结束点位置 = 上一个弧的结束点 + 自己的角度

* 4、closePath

* 5、修改填充色

* 6、fill

* */

// 遍历所有计算好的角度,绘制成不同颜色的扇形

for( var i = 0, len = this.processArr.length; i < len;

i++ ) {

// 当前扇形弧的起点位置 = 上一个扇形弧的结束点

// 当前扇形弧的结束点位置 = 上一个扇形弧的结束点 +

自己扇形所占用的角度

startAngle = endAngle;

endAngle = endAngle + this.processArr[i];

this.ctx.beginPath();

this.ctx.moveTo( this.x, this.y );

this.ctx.arc( this.x, this.y, this.r,

angleToRadian( startAngle ), angleToRadian( endAngle ) );

this.ctx.closePath();

this.ctx.fillStyle = this.colors[ i ];

this.ctx.fill();

}

},

// 绘制文字

drawText: function() {

// 扇形默认起点和结束点

var startAngle = 0;

var endAngle = 0;

// 扇形平分线的角度

var lineAngle = 0;

var lineX = 0;

var lineY = 0;

// 遍历所有计算好的角度,绘制成不同颜色的扇形

for( var i = 0, len = this.processArr.length; i < len;

i++ ) {

// 当前扇形弧的起点位置 = 上一个扇形弧的结束点

// 当前扇形弧的结束点位置 = 上一个扇形弧的结束点 +

自己扇形所占用的角度

startAngle = endAngle;

lineAngle = startAngle + this.processArr[i] / 2;

endAngle = endAngle + this.processArr[i];

/*

* 求平分线的x&y坐标

* x: 圆心x + r * Math.cos( angleToRadian(45) )

* y: 圆心y + r * Math.sin( angleToRadian(45) )

* */

lineX = this.x + (this.r + this.lineSpace) *

Math.cos( angleToRadian(lineAngle) );

lineY = this.y + (this.r + this.lineSpace) *

Math.sin( angleToRadian(lineAngle) );

// 画扇形平分线

this.ctx.beginPath();

this.ctx.moveTo( this.x, this.y );

this.ctx.lineTo( lineX, lineY );

this.ctx.strokeStyle = this.colors[i];

this.ctx.stroke();

// 添加文字描述

if( lineAngle >= 90 & lineAngle <= 270 ) {

this.ctx.textAlign = 'right';

this.ctx.moveTo( lineX, lineY );

this.ctx.lineTo( lineX - this.ctx.measureText(

this.data[i].msg ).width, lineY );

}else {

this.ctx.textAlign = 'left';

this.ctx.moveTo( lineX, lineY );

this.ctx.lineTo( lineX + this.ctx.measureText(

this.data[i].msg ).width, lineY );

}

this.ctx.textBaseline = 'bottom';

this.ctx.fillStyle = this.colors[i];

this.ctx.fillText( this.data[i].msg, lineX, lineY

- 5 );

this.ctx.stroke();

}

}

};

// 给原型添加一个饼图插件方法

jQuery.fn.extend({

// 在第一个元素中,按照指定的数据绘制饼图

pipeChart: function( data ) {

/*

* 实现思路:

* 1、动态创建canvas元素,并且获取绘图环境

* 2、获取第一个元素的大小,按照这个大小动态设置画布的

大小

* 3、创建饼图对象,调用draw方法绘制

* 4、把绘制好的画布添加到第一个元素中

* */

// 创建canvas,获取ctx

var $cvs = $('');

var ctx = $cvs.get(0).getContext( '2d' );

var $first = this.first();

var width = parseInt( $first.css( 'width' ) );

var height = parseInt( $first.css( 'height' ) );

// 根据元素大小动态设置画布大小

$cvs.attr({

width: width,

height: height

});

// 计算饼图半径,圆心

var r = width > height? height / 2: width / 2;

var x = width / 2;

var y = height / 2;

// 根据数据绘制饼图

var pipeChart = new PipeChart( ctx, data, x, y, r - 50

);

pipeChart.draw();

// 把绘制好的画布添加到第一个元素中

$first.append( $cvs );

}

})

}( window ));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值