利用canvas对数据可视化的扇形图实现

canvas是HTML5中十分有意思的应用。利用canvas我们可以运用基本的数学知识就能绘画出很多有意思的图案。

像目前比较流行的数据可视化插件,Echarts,HighCharts等都是利用的canvas来进行描绘的。

前段时间碰到一个需求,我需要做一个有缺口的圆形图表,来表达一种百分比占有量。类似于仪表盘的效果。

每个用户的占用比例是不同的,所以这个数据可视化就必须是能够动态的改变的。

于是,canvas成为了一个不错的选择。

利用canvas对数据可视化的扇形图实现_第1张图片
效果图.png

代码实现如下:

  var Arccanvas = function(Total, SY, eleID) {
  /**
     * total:总数
     * remaind:剩余数
     * captionText:图说明
     * x:剩余数占总数的百分比
     * sin:Math.sin函数
     * cos:Math.cos函数
     * PI:Math.PI
     * R_x,R_y:画圆的坐标,canvas元素的中心点
     *
     */

    var eleDiv = document.getElementById("" + eleID + "");
    eleDiv.innerHTML = "";
    var ele = " "
    eleDiv.innerHTML = ele;

    var canvas = document.getElementById("mycanvas"),
        total = Total ? Total : 100,
        Sy = SY ? (SY >= 0 && SY <= Total ? SY : Total) : 0,
        x = Sy / total * 10,
        captionText = "有效套餐",
        sin = Math.sin,
        cos = Math.cos,
        PI = Math.PI,
        R_x = canvas.width / 2,
        R_y = canvas.height / 2,
        cv = canvas.getContext("2d");
    //   cv.fillStyle = "#ff0";
    //   cv.fillRect(0, 0, canvas.width, canvas.height);


    cv.textBaseline = 'middle';
    cv.textAlign = 'center';


    /*******************************************************
     * 先画外面的大圆,canvas起点和终点都是顺时针来找角度的。
     * 所以选好角度,选择逆时针来画就能画出效果
     ******************************************************/
    cv.lineWidth = 14;
    cv.strokeStyle = "#999999";
    cv.beginPath();
    cv.arc(R_x, R_y, 150, PI / 3, PI * 4 / 6, true);
    cv.stroke();

    /********************************************************
     * 画大圆上面的百分比占有量的小圆。
     * 将0%-100%我设定的数值区间为 0-10;所以,求得百分比后要*10;
     * 根据外面大圆的特性,通过构造函数模型来生成。
     * 这个模型是分段函数。
     * y=πx/6+2π/3  (8=>x>=0);
     * y=π(x-8)/6;  (10=>x>8);
     * 通过计算终点角度来实现百分比覆盖。
     ********************************************************/
    cv.lineWidth = 14;
    cv.beginPath();
    cv.strokeStyle = "#39f";
    if (x >= 0 && x <= 8) {
        cv.arc(R_x, R_y, 150, PI * 2 / 3, PI * x / 6 + 2 * PI / 3, false);
    } else if (x > 8 && x <= 10) {
        cv.arc(R_x, R_y, 150, PI * 2 / 3, PI * (x - 8) / 6, false);
    }
    cv.stroke();
    cv.closePath();
    /************************************************************
     * 绘制圆圈内侧的百分比文字
     * 通过三角函数来实现文字坐标的平移
     * x=-R*sin((π*i)/6+π/6);
     * y=R*cos((π*i)/6+π/6);
     ************************************************************/
    cv.font = '12px 宋体';

    cv.lineWidth = 1;
    for (var i = 0; i <= 10; i++) {
        //cv.strokeStyle = '#f00';
        var text = (i * 10) + '%';
        cv.save();
        cv.translate(-130 * sin(PI * i / 6 + PI / 6), 130 * cos(PI * i / 6 + PI / 6));
        cv.strokeText(text, R_x, R_y);
        cv.restore();

    }
    /************************************************************
     * 绘制内层有色填充圆                                         *
     ************************************************************/
    cv.beginPath();
    cv.arc(R_x, R_y, 100, 0, 360, false);
    cv.fillStyle = "#d8e2ec";
    cv.fill();
    cv.closePath();
    cv.save();
    /************************************************************
     * 绘制套餐剩余数目与总数目的比值表达式                        *
     ************************************************************/
    cv.beginPath();
    cv.font = '16px 宋体';
    cv.moveTo(R_x, R_y);
    cv.translate(0, 0)
    cv.strokeText(Sy + "/" + total, R_x, R_y);
    cv.closePath();
    /***************************************************************
     * 绘制图表反应的主题信息                                        *
     ***************************************************************/
    cv.beginPath();
    cv.font = '16px 宋体';
    cv.moveTo(R_x, R_y);
    cv.translate(0, 20)
    cv.strokeText(captionText, R_x, R_y);
    cv.closePath();
}
   /**调用*/
   Arccanvas();

你可能感兴趣的:(利用canvas对数据可视化的扇形图实现)