canvas绘制饼状图动画
1、HTML
1 2 3 4 5 6饼状图面向对象版本 7 15 16 17 18 192021 22 60 61
2、PieChart.js
1 //英 [paɪ] 美 [paɪ] 2 function PieChart( option ) { 3 this._init( option ); 4 } 5 6 PieChart.prototype = { 7 _init: function( option ) { 8 this.x = option.x || 0; 9 this.y = option.y || 0; 10 this.r = option.r || 0; 11 this.data = option.data || []; 12 13 //饼状图所有的 物件的组 14 this.group = new Konva.Group({ 15 x: this.x, 16 y: this.y 17 }); 18 19 //饼状图:所有的 扇形的组 20 this.wedgeGroup = new Konva.Group({ 21 x: 0, 22 y: 0 23 }); 24 25 //饼状图: 所有的文字的组 26 this.textGroup = new Konva.Group({ 27 x: 0, 28 y: 0 29 }); 30 31 this.group.add( this.wedgeGroup ); 32 this.group.add( this.textGroup ); 33 34 var self = this; 35 var tempAngel = -90;//从-90开始绘制 36 37 this.data.forEach(function(item, index ) { 38 //把每条数据创建成一个扇形 39 var angle = 360 * item.value;//当前扇形的角度 40 //创建一个扇形 41 var wedge = new Konva.Wedge({ 42 x: 0, //扇形圆心坐标 43 y: 0, 44 angle: angle , //扇形的角度 45 radius: self.r, //扇形的半径 46 fill: item.color, //扇形的填充颜色 47 rotation: tempAngel //扇形的旋转角度 48 }); 49 50 self.wedgeGroup.add( wedge ); 51 52 //绘制文本的 角度 53 var textAngle = tempAngel + 1/2 * angle; 54 55 //绘制的 百分比的文本 56 var text = new Konva.Text({ 57 x: (self.r+20) * Math.cos(Math.PI/ 180 * textAngle ), 58 y: (self.r+20) * Math.sin(Math.PI/ 180 * textAngle ), 59 text: item.value*100 +'%', 60 fill: item.color 61 }); 62 63 //根据角度判断设置文字的 位置 64 if( textAngle > 90 && textAngle < 270 ) { 65 //让文本向左边 移动文字宽度的位置。 66 text.x( text.x() - text.getWidth() ); 67 } 68 69 self.textGroup.add( text ); 70 71 tempAngel += angle; 72 }); 73 //绘制所有的楔形 74 75 //绘制文字 76 77 //绘制圆环的线 78 var cir = new Konva.Circle({ 79 x: 0, 80 y: 0, 81 radius: this.r+10, 82 stroke: '#ccc', 83 strokeWidth: 2 84 }); 85 86 this.group.add( cir ); 87 88 this._animateIndex = 0; 89 }, 90 playAnimate: function() { 91 92 var self = this; 93 //根据索引显示动画 94 //把所有扇区 角度设置为0 95 if( this._animateIndex == 0 ) { 96 //拿到所有的 扇形 97 this.wedgeGroup.getChildren().each(function(item, index ){ 98 item.angle(0); 99 });100 }101 102 //展示当前索引对应的动画103 var item = this.wedgeGroup.getChildren()[this._animateIndex];104 item.to({105 angle: this.data[this._animateIndex].value * 360,106 duration: 2 * this.data[this._animateIndex].value,107 onFinish: function() {108 self._animateIndex ++;109 if( self._animateIndex >= self.data.length) {110 111 self._animateIndex = 0;//让他的索引再回到0112 113 //************************重点***********************114 return;// 会把整个递归执行完成。115 }116 //继续执行当前方法,播放下一个动画117 self.playAnimate();118 }119 });120 },121 //把饼状图添加到层里面的方法122 addToGroupOrLayer: function( arg ) {123 arg.add( this.group );124 }125 }
运行效果: