Canvas画半圆扇形统计图

1 效果图 每个扇形之间要用白线隔开

  可以动态设置扇形的直径,以及数据的个数,每条数据占据的颜色 占据的百分比还未开发

2 CircleCanvas.vue文件

 1<template>
2    <div id="box" >
3        <canvas  ref='canvas' :width="width" :height="width/2" :index='index'></canvas>
4    </div>
5</template>
6<script>
7    export default{
8        props:{
9            width:[Number,String],
10            index:{Type:String},
11            data:{type:Array},
12            color:{type:Array,default:function(){
13                return ["#8AAFFE","#D2D6E5","#999222","#998322","yellow","pink"]
14            }}
15        },
16        data(){
17            return {
18            col:this.color,
19            persentValue:this.data
20            }
21        },
22        mounted(){
23            //加载cavans
24            this.loadCanvas();
25            console.log(this.data);
26        },
27        watch:{
28            data(val){
29                this.persentValue = val;
30            },
31            color(val){
32                this.col = val;
33            }
34        },
35        methods:{
36            loadCanvas(){
37                let canv = this.$refs.canvas;
38                let ctx=canv.getContext("2d");
39                let num=this.persentValue;
40                let col = this.col;
41                /*
42                    x, 每个扇形的圆心以及半径
43                    y,
44                    r;
45
46                */
47                let x = canv.width/2;
48                let y = canv.height;
49                let r = y;
50                /*
51                    persent_angle=0, 每个数据占据180度的百分比
52                    sAngle=0,每个扇形的开始的角度
53                    eAngle=0;每个扇形的结束的角度
54                    sun :几个数据的总和;
55                */
56                let persent_angle=0,sAngle=0,eAngle=0;
57                let sun=0;
58                for(var i=0;i<num.length;i++){
59                sun=sun+num[i];
60                }
61
62                for(var i=0;i<num.length;i++){
63                    persent_angle=-Math.PI*num[i]/sun;  //每个部分占的百分比
64                    eAngle+=persent_angle; //
65                    ctx.beginPath();
66                    ctx.fillStyle=col[i];
67                    //画扇形
68                    ctx.arc(x,y,r,sAngle,eAngle,true);
69                    ctx.lineTo(x,y);
70                    ctx.closePath();
71                    ctx.fill();
72                    //以下要画扇形与扇形之间的线,用到了sin cos
73                    if(i<num.length-1){
74                        //计算每个和的角度
75                        let angle = Math.abs(eAngle);
76                        ctx.beginPath();
77                        ctx.moveTo(x,y);
78                        //画直线
79                        ctx.lineTo(x+Math.cos(angle)*r,y-Math.sin(angle)*r);
80                        ctx.lineWidth=2;
81                        ctx.strokeStyle="#fff";
82                        ctx.stroke();
83                        ctx.closePath();
84                    }
85                    ctx.font="20px Arial";
86                    //默认颜色;
87                    ctx.fillStyle="#890";
88                    sAngle+=persent_angle;
89                }
90            }
91        }
92    }
93</script>
94<style>
95    #box{
96        margin-bottom: 0.4rem
97    }
98</style>

3使用

 1<template>
2    <div>
3        <circle-canvas :width='setWidth' :data='persentData' :color='persentColor' />
4        <circle-canvas width='200' :data='persentData'  />
5
6    </div>
7</template>
8<script>
9    import CircleCanvas from '@/components/public/CircleCanvas'
10    export default {
11        data(){
12            return {
13                setWidth:180,
14                persentData:[600,300,300,300,300,300],
15                persentColor:["#8AAFFE","#D2D6E5","red","blue","yellow","pink"]
16            }
17        },
18        components:{CircleCanvas}
19    }
20</script>
21

 

posted @ 2018-12-29 17:01  梦蝶庄周  阅读(649)  评论(0编辑  收藏  举报