使用JS绘制一个圆环统计图

无意间翻到了之前某次考核做的一个环形统计图,今天又捣鼓了一下把它封装成了一个类,可以根据不同的数据切换内容,下面分享一下我的实现思路。

0.效果预览

使用JS绘制一个圆环统计图_第1张图片

基本功能

  • 环形统计图,按每一项数据自动分配比例。
  • 只需简单地更换数据便可以生成新的环形统计图(统计图大小也可以更改)。
  • 点击每一项可以关闭该项,隐藏右侧数据,然后再重新生成。
使用JS绘制一个圆环统计图_第2张图片

1.该示例的完整JS代码pieChart.js

window.onload = function(){
    var data1 = [
        {"id":"item0","text":"这是第一行","num":10,"color":"#1e90ff","isdraw":1},
        {"id":"item1","text":"这是第二行","num":20,"color":"#36cbcb","isdraw":1},
        {"id":"item2","text":"这是第三行","num":30,"color":"#2fc25b","isdraw":1},
        {"id":"item3","text":"这是第四行","num":40,"color":"#ffd700","isdraw":1},
        {"id":"item4","text":"这是第五行","num":50,"color":"#ff3030","isdraw":1},
        {"id":"item5","text":"这是第六行","num":60,"color":"#8a2be2","isdraw":1},
    ];
    var apie = new pieChart('这里是标题',data1,150,40);
    apie.add_data();
    apie.draw();
}

function pieChart(title, data, radius, width){
    this.title = title;
    this.data = data;
    this.width = width;
    this.radius = radius;

    this.add_data = function(){
        var width = 2*radius;
        var chart = document.createElement('div');
        chart.style.width = width+'px';
        var top = document.createElement('div');
        top.setAttribute('style','text-align:center;font-weight:bold;width:'+width+'px');
        top.innerText = title;
        var circle = document.createElement('canvas');
        circle.setAttribute('id','circle');
        circle.setAttribute('width',width+"px");
        circle.setAttribute('height',width+"px");
        var list = document.createElement('div');
        list.setAttribute('id','list');
        var ul = document.createElement('ul');
        ul.setAttribute('style','font-family:Simsun;margin:0;padding:0;list-style:none;');
        for(var i=0; i"+data[i].num+"";
            li.onclick = this.draw;
            ul.appendChild(li);
        }
        list.appendChild(ul);
        chart.appendChild(top);
        chart.appendChild(circle);
        chart.appendChild(list);
        document.body.appendChild(chart);
    }
    this.draw = function(){
        var len = data.length;
        var id = this.id;
        for(var i=0; i

在一个空白html文件中导入该js文件即可使用(基本的html,body标签要有),不需导入其他的css文件。新建一个pieChart对象,调用add_data()draw()方法即可。
下面是实现思路的分享。

2.实现思路

使用JS绘制图形,那自然离不开canvas标签,这里我们最终绘制的是一个圆环,我的大体思路是:

  1. 根据数据计算所占比例,再根据所占比例使用较大半径绘制每部分的扇形。
  2. 所有部分绘制完毕,再使用一个较小的半径绘制一个白底的完整的圆。
  3. 填充文本。

也就是说,实际上我先是绘制的一个扇形统计图,然后用一个白底的较小的圆将其覆盖,这样看上去就是一个环形统计图了。
下面结合代码详细讲解;
window.onload外我封装了一个pieChart类,他有四个变量和两个方法:

四个变量

title:统计图的标题。

data:统计图的数据,每一条数据含下面五个内容:
①id:该项数据在html中的id值。
②text:该项数据在统计图下方显示的文本。
③num:该项数据的值(数量)。
④color:该项数据在统计图中对应的颜色。
⑤isdraw:是否绘制该项数据,只能填为1或0,默认填1,表示要绘制(在点击重绘时会用到该值)。

radius:外层圆的半径,单位为px。

width:圆环宽度,单位为px,可理解为外层圆与内层圆半径的差值。

两个方法

add_data()方法:负责添加统计图下方的每行内容。

draw()方法:绘制圆环的方法,同时也会绑定到每一行数据中。

3.方法详解

add_data()

    this.add_data = function(){
        var width = 2*radius;//区域宽度即为直径的长度,画布区域(canvas)的宽高等于直径,下方每一个li的宽度也等于直径。
        /***div 'chart',为整个页面的父div。***/
        var chart = document.createElement('div');
        chart.style.width = width+'px';
        /***div 'top',统计图标题区域***/
        var top = document.createElement('div');
        top.setAttribute('style','text-align:center;font-weight:bold;width:'+width+'px');
        top.innerText = title;
        /***canvas 'circle',圆环区域***/
        var circle = document.createElement('canvas');
        circle.setAttribute('id','circle');
        circle.setAttribute('width',width+"px");
        circle.setAttribute('height',width+"px");
        /***div 'list',数据行区域***/
        var list = document.createElement('div');
        list.setAttribute('id','list');
        var ul = document.createElement('ul');
        ul.setAttribute('style','font-family:Simsun;margin:0;padding:0;list-style:none;');
        /*每次循环添加data中的一条数据*/
        for(var i=0; i"+data[i].num+"";
            li.onclick = this.draw;//为每一行添加onclick事件
            ul.appendChild(li);
        }
        list.appendChild(ul);
        chart.appendChild(top);
        chart.appendChild(circle);
        chart.appendChild(list);
        document.body.appendChild(chart);
    }

实际上最终的页面结构为一个父div,包含三个部分:标题区域div 'top',图形区域canvas 'circle',数据区域div 'list';数据区域div 'list'包含一个无序列表ul,根据创建对象的数据条数创建一个个li,向其写入数据并绑定onclick事件draw();每个li又含三个span标签,分别代表:数据前缀(指定该行和统计图中哪个颜色对应),数据文本,文本对应的数量。
页面结构如下:

draw()

代码片段一:

        var id = this.id;
        for(var i=0; i

实际上draw()是为数据区域中的每一个li量身定做的,每一次对li标签的点击都会重绘图形,这时this指向的是被点击的li标签,如果它正在统计图中显示将会去除它,前缀变为灰色,数据值隐藏,isdraw标记为0,接下来的重绘将跳过对此项的绘制。
虽说draw()方法是为li服务的,但第一次生成统计图时也不用担心报错,这时的this标签并不会指向任何一个li标签,id赋值为undefined,虽然也会进入for循环,但始终不会进入if语句,对绘制不会产生任何影响。

代码片段二:

canvas.height = canvas.height;

每次重绘都会先清空画布,这里有个小技巧,重新设置画布的宽度或高度都会使画布清空。

代码片段三:

        /*绘制部分*/
        if (canvas.getContext) {
            var ctx = canvas.getContext('2d');
            var PI = Math.PI;
            var start = PI*1.5;//绘制开始位置
            var gap = 0.01;//两项数据间取的间隙,每个间隙占比1%
            var pros;//除去空隙后内容所占比例
            var sum = 0;//总和
            var zero = 0;//isdraw值为0数据个数(重绘过程不显示的数据个数)
            
            /*计算总和(sum)*/
            for(var i=0; i

务必理解到pros这个变量的意义,在之前的预览图里大家可以看到,每两个数据间是有空隙的,每次扇形比例的计算都是在去掉这些空白区域的前提下进行的,pros为【全部内容】在圆环上的比例,即除去空隙部分后剩余部分所占比例。
当数据显示项大于1时,间隙数等于数据数,只剩一项数据显示时,间隙数为0,该项内容占比100%。
若你对canvas的用法不够熟悉,建议先作一定了解,过程中多百度也是很好的选择。

对代码有疑问,欢迎评论;若你有其他的实现一个圆环的方式,欢迎评论;若你发现我文章中的错误,欢迎评论!感激不尽~

你可能感兴趣的:(使用JS绘制一个圆环统计图)