Canvas绘画饼状图(二)

上一章介绍了扇形图或饼状图绘画过程,下面我们一起来看看代码,如果发现错误或者有更好的方法可以联系我,kingni_time@sina.com我的邮箱,共同进步!!

// 这是定义全局变量,保存扇形图或饼状图绘画信息和扇形绘画信息
var sectorChartArray = new Array();

// 自定义伪类 保存扇形图信息
function SectorChart(id, objectCanvas, sectorArray){
    this.id = id;                       // 扇形图的Id方便查找
    this.objectCanvas = objectCanvas;   // canvas的对象
    this.sectorArray = sectorArray;     // 保存扇形图的信息
};
// 自定义伪类 保存扇形信息
function Sector(id, X, Y, radius, angleStart, angleEnd, color,counterClockWise,zIndex, hoverInFun, hoverOutFun, clickFun){
    this.id = id;                       // 保存唯一Id方便查找
    this.X = X;                         // 扇形的开始x坐标
    this.Y = Y;                         // 扇形的开始y坐标
    this.radius = radius;               // 扇形的半径
    this.angleStart = angleStart;       // 扇形的开始角度
    this.angleEnd = angleEnd;           // 扇形的结束角度
    this.color = color;                 // 扇形的颜色
    this.counterClockWise = counterClockWise;       // 画圆方向
    this.zIndex = zIndex;                           // 下标跟id一样方便查找
    this.hoverInFun = hoverInFun;       // 绑定移动到扇形上的悬停事件
    this.hoverOutFun = hoverOutFun;     // 绑定移出扇形事件
    this.clickFun = clickFun;           // 绑定扇形图点击事件
};
// 动态创建canvas
function createSectorChart(objectDiv, top, left, width, height){
    // 实例化保存扇形图信息的伪类
    var tempSectorChart = new SectorChart();
    // 添加扇形图信息
    // 如果sectorChartArray长度大于0,则进行循环判断canvas的最大值为多少
    var maxSectorChartId = 0;
    if (sectorChartArray.length == 0) {
        tempSectorChart.id = maxSectorChartId;
    };
    if (sectorChartArray.length > 0) {
        for(var i = 0; i < sectorChartArray.length; i++){
            if(sectorChartArray[i].id > maxSectorChartId){
                maxSectorChartId = sectorChartArray[i].id;
            };
            tempSectorChart.id = maxSectorChartId + 1;
        };
        tempSectorChart.id = maxSectorChartId;
    };
    var $canvas = $("<canvas width='"+width+"' height='"+height+"'></canvas>");
    tempSectorChart.objectCanvas = $canvas;
    // 设置相对位置
    $(tempSectorChart.objectCanvas).css({"top":top,"left":left});
    $(objectDiv).append(tempSectorChart.objectCanvas);
    var sectorArray = new Array();
    tempSectorChart.sectorArray = sectorArray;

    // 保存到全局变量里 
    sectorChartArray.push(tempSectorChart);
    // 这是调用绘画扇形函数
    createSector(100,100,100,Math.PI*0,Math.PI*(1/6),false,"#ff0000",0,Object);
    createSector(100,100,100,Math.PI*(1/6),Math.PI*(1/4),false,"#00ffff",0,Object);
    createSector(100,100,100,Math.PI*(1/4),Math.PI*(1/3),false,"#ff00ff",0,Object);
    createSector(100,100,100,Math.PI*(1/3),Math.PI*1,false,"#00aacc",0,Object);
    createSector(100,100,100,Math.PI*1,Math.PI*2,false,"#000000",0,Object);

    hoverInFun(tempSectorChart.id);
    sectorClick(tempSectorChart.id);
    removeCanvasSector(tempSectorChart.id, 3);
};

// 画扇形
function createSector(X,Y,radius,angleStart,angleEnd,counterClockWise,color,id,Object){
    // 初始化sector伪类
    var sector = new Sector();
    // 获取canvas对象
    var canvas = $(sectorChartArray[id].objectCanvas);
    // 如果canvas对象不存在就不执行
    if(!canvas[0].getContext){
        return -1;
    };
    // 获取canvas的API接口2d接口
    var context = canvas[0].getContext("2d");
    // 设置扇形颜色
    context.fillStyle = color;
    // 绘制扇形图
    context.publicCreateSector(X,Y,radius,angleStart,angleEnd,counterClockWise).fill();
    // 扇形参数存储到sectorArray数组里
    // 判断id 和 zIndex 是否存在或者最大值是多少
    var maxSectorId = 0;
    var maxSectorZIndex = 0;
    if (sectorChartArray[id].sectorArray.length == 0) {
        sector.id = maxSectorId;
        sector.zIndex = maxSectorZIndex;
    };
    if (sectorChartArray[id].sectorArray.length > 0) {
        for(var i = 0; i < sectorChartArray[id].sectorArray.length; i++){
            // 如果maxSectorId小于sectorChartArray里sectorArray下id,则把断sectorChartArray里sectorArray下id赋给maxSectorId
            if(maxSectorId < sectorChartArray[id].sectorArray[i].id){
                maxSectorId = sectorChartArray[id].sectorArray[i].id;
            };
            // 如果maxSectorZIndex小于sectorChartArray里sectorArray下id,则把断sectorChartArray里sectorArray下id赋给maxSectorZIndex
            if(maxSectorZIndex < sectorChartArray[id].sectorArray[i].zIndex){
                maxSectorZIndex = sectorChartArray[id].sectorArray[i].zIndex;
            };
        };
        // 扇形id
        sector.id = maxSectorId + 1;
        // 扇形下标
        sector.zIndex = maxSectorZIndex + 1;
    };
    // 扇形的开始x坐标
    sector.X = X
    // 扇形的开始y坐标
    sector.Y = Y;
    // 半径
    sector.radius = radius;
    // 开始角度
    sector.angleStart = angleStart;
    // 结束角度
    sector.angleEnd = angleEnd;
    // 颜色
    sector.color = color;
    // 画圆方向
    sector.counterClockWise = counterClockWise;
    // 扇形图鼠标移入事件
    sector.hoverInFun = function(){

    };
    // 扇形图鼠标移出事件
    sector.hoverOutFun = function(){

    };
    // 扇形图鼠标点击事件
    sector.clickFun = function(){

    };
    // 添加到全局数组中
    sectorChartArray[id].sectorArray.push(sector);  
};

// 添加hoverInFun事件 sectorChartId扇形id
function hoverInFun(sectorChartId){
    // 遍历sectorChartArray
    for (var i = 0; i < sectorChartArray.length; i++) {
        // 检查sectorChartId是否在sectorChartArray存在
        if(sectorChartArray[i].id != sectorChartId){
            return 0;
        }
    }
    // 获取扇形图
    var tempSectorChart = sectorChartArray[sectorChartId].objectCanvas;
    if(tempSectorChart == null){
        return;
    }
    tempSectorChart.bind("mousemove",function(event){
        // 获取鼠标移动事件X和Y
        var mouseX = event.offsetX;
        var mouseY = event.offsetY;
        // 保存zIndex
        var allZIndex = new Array();
        for (var i = 0; i < sectorChartArray[sectorChartId].sectorArray.length; i++) {
            // 扇形半径
            var sectorRadius = sectorChartArray[sectorChartId].sectorArray[i].radius;
            // 获取扇形中心点
            var sectorX = sectorChartArray[sectorChartId].sectorArray[i].X;
            var sectorY = sectorChartArray[sectorChartId].sectorArray[i].Y;
            // 获取扇形的角度
            var sectorAngleEnd = sectorChartArray[sectorChartId].sectorArray[i].angleEnd
            var sectorAngleStart = sectorChartArray[sectorChartId].sectorArray[i].angleStart;
            var mouseCirleX = mouseX-sectorX;
            var mouseCirleY = mouseY-sectorY;
            if(Math.pow((mouseCirleX),2) + Math.pow((mouseCirleY),2) <= Math.pow(sectorRadius,2)){
                var mouseAngle = Math.atan2(mouseCirleY, mouseCirleX);
                // 第一象限
                if(mouseAngle >= 0 && mouseAngle <= Math.PI*(1/2)){
                    if(sectorAngleStart <= mouseAngle && mouseAngle <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            // 找出zIndex相同的扇形
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        if(sectorChartArray[sectorChartId].sectorArray[i].zIndex != maxZIndex){
                            sectorChartArray[sectorChartId].sectorArray[i].hoverOutFun();
                        }
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].hoverInFun();
                        return;
                    }
                }
                // 第二象限
                if(Math.PI*(1/2) < mouseAngle && mouseAngle <= Math.PI*1){
                    if(sectorAngleStart <= mouseAngle && mouseAngle <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        if(sectorChartArray[sectorChartId].sectorArray[i].zIndex != maxZIndex){
                            sectorChartArray[sectorChartId].sectorArray[i].hoverOutFun();
                        }
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].hoverInFun();
                        return;
                    }
                }
                // 第三象限
                if(-Math.PI*1< mouseAngle && mouseAngle <= -Math.PI*(1/2)){
                    var mouseAngleMinus = mouseAngle + Math.PI * 2;
                    if(sectorAngleStart <= mouseAngleMinus && mouseAngleMinus <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        if(sectorChartArray[sectorChartId].sectorArray[i].zIndex != maxZIndex){
                            sectorChartArray[sectorChartId].sectorArray[i].hoverOutFun();
                        }
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].hoverInFun();
                        return;
                    }
                }
                // 第四象限
                if(-Math.PI*(1/2) < mouseAngle && mouseAngle < 0){
                    var mouseAngleMinus = mouseAngle + Math.PI * 2;
                    if(sectorAngleStart <= mouseAngleMinus && mouseAngleMinus <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        if(sectorChartArray[sectorChartId].sectorArray[i].zIndex != maxZIndex){
                            sectorChartArray[sectorChartId].sectorArray[i].hoverOutFun();
                        }
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].hoverInFun();
                        return;
                    }
                }
            }
        }


    });
}

// 添加sectorClick事件
function sectorClick(sectorChartId){
    // 遍历sectorChartArray
    for (var i = 0; i < sectorChartArray.length; i++) {
        // 检查sectorChartId是否在sectorChartArray存在
        if(sectorChartArray[i].id != sectorChartId){
            return 0;
        }
    }
    // 获取扇形图
    var tempSectorChart = sectorChartArray[sectorChartId].objectCanvas;
    if(tempSectorChart == null){
        return;
    }
    tempSectorChart.bind("click",function(event){
        // 获取鼠标移动事件X和Y
        var mouseX = event.offsetX;
        var mouseY = event.offsetY;
        // 保存zIndex
        var allZIndex = new Array();
        for (var i = 0; i < sectorChartArray[sectorChartId].sectorArray.length; i++) {
            // 扇形半径
            var sectorRadius = sectorChartArray[sectorChartId].sectorArray[i].radius;
            // 获取扇形中心点
            var sectorX = sectorChartArray[sectorChartId].sectorArray[i].X;
            var sectorY = sectorChartArray[sectorChartId].sectorArray[i].Y;
            // 获取扇形的角度
            var sectorAngleEnd = sectorChartArray[sectorChartId].sectorArray[i].angleEnd
            var sectorAngleStart = sectorChartArray[sectorChartId].sectorArray[i].angleStart;
            var mouseCirleX = mouseX-sectorX;
            var mouseCirleY = mouseY-sectorY;
            if(Math.pow((mouseCirleX),2) + Math.pow((mouseCirleY),2) <= Math.pow(sectorRadius,2)){
                var mouseAngle = Math.atan2(mouseCirleY, mouseCirleX);
                // 第一象限
                if(mouseAngle >= 0 && mouseAngle <= Math.PI*(1/2)){
                    if(sectorAngleStart <= mouseAngle && mouseAngle <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            // 找出zIndex相同的扇形
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].clickFun();
                        return;
                    }
                }
                // 第二象限
                if(Math.PI*(1/2) < mouseAngle && mouseAngle <= Math.PI*1){
                    if(sectorAngleStart <= mouseAngle && mouseAngle <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].clickFun();
                        return;
                    }
                }
                // 第三象限
                if(-Math.PI*1< mouseAngle && mouseAngle <= -Math.PI*(1/2)){
                    var mouseAngleMinus = mouseAngle + Math.PI * 2;
                    if(sectorAngleStart <= mouseAngleMinus && mouseAngleMinus <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].clickFun();
                        return;
                    }
                }
                // 第四象限
                if(-Math.PI*(1/2) < mouseAngle && mouseAngle < 0){
                    var mouseAngleMinus = mouseAngle + Math.PI * 2;
                    if(sectorAngleStart <= mouseAngleMinus && mouseAngleMinus <= sectorAngleEnd){
                        for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                            if(sectorChartArray[sectorChartId].sectorArray[j].angleStart == sectorAngleStart && sectorChartArray[sectorChartId].sectorArray[j].angleEnd == sectorAngleEnd){
                                allZIndex.push(sectorChartArray[sectorChartId].sectorArray[j].zIndex);
                            }
                        } 
                        var maxZIndex = allZIndex[allZIndex.length - 1];
                        sectorChartArray[sectorChartId].sectorArray[maxZIndex].clickFun();
                        return;
                    }
                }
            }
        }


    });
}

/* 画扇型公用函数 */
CanvasRenderingContext2D.prototype.publicCreateSector = function(X,Y,radius,angleStart,angleEnd,counterClockWise){
    // 保存初始化
    this.save();
    // 设置圆心位置
    this.translate(X,Y);
    // 开始画
    this.beginPath();
    // 画出圆弧
    this.arc(0,0,radius,angleStart,angleEnd,counterClockWise);
    // 再次保存 准备旋转
    this.save();
    // 第一次旋转到起始角度
    this.rotate(angleStart);
    // 准备开始画线起始位置
    this.moveTo(radius,0);
    // 连接到原点
    this.lineTo(0,0);
    // 还原 取消旋转
    this.restore();
    // 再次旋转 角度为结束角度
    this.rotate(angleEnd);
    // 连接点形成三角图形
    this.lineTo(radius,0);
    // 关闭画图
    this.closePath();
    // 取消旋转 回到最初状态
    this.restore();
    // 结束
    return this;
}

// 删除canvas
function removeCanvas(sectorChartId){
    // 判断sectorChartId是否在sectorChartArray数组里面
    for(var i = 0; i < sectorChartArray.length; i++){
        // 如果sectorChartArray下id不存在sectorChartId则结束
        if(sectorChartArray[i].id == sectorChartId){
            $(sectorChartArray[sectorChartId].objectCanvas).remove();
        }
    }
}
// 删除canvas里扇形
function removeCanvasSector(sectorChartId, sectorId){
    // 判断sectorChartId是否在sectorChartArray数组里面
    for(var i = 0; i < sectorChartArray.length; i++){
        // 如果sectorChartArray下id不存在sectorChartId则结束
        if(sectorChartArray[i].id == sectorChartId){
            tempSectorChartIndex = sectorChartId;
            for(var j = 0; j < sectorChartArray[sectorChartId].sectorArray.length; j++){
                if(sectorChartArray[sectorChartId].sectorArray[j].id == sectorId){
                    sectorChartArray[sectorChartId].sectorArray.splice(sectorId,1);
                    j--
                }
            }
        }
    }
    var canvas = $(sectorChartArray[sectorChartId].objectCanvas);
    if(!canvas[0].getContext){
        return;
    };
    var context = canvas[0].getContext("2d");
    context.fillRect(0,0,canvas.width(),canvas.height());
    if(sectorChartArray[sectorChartId].sectorArray.length == 0){
        return;
    }
    if(sectorChartArray[sectorChartId].sectorArray.length > 0){
        var length = sectorChartArray[sectorChartId].sectorArray.length;
        for(var fraction = Math.floor(length / 2); fraction > 0; fraction = Math.floor(fraction / 2)){
            for(var i = fraction; i < length; i++){
                for(var j = i - fraction; j>= 0 && sectorChartArray[sectorChartId].sectorArray[j] > sectorChartArray[sectorChartId].sectorArray[fraction + j]; j -= fraciton){
                    var temp = sectorChartArray[sectorChartId].sectorArray[j];
                    sectorChartArray[sectorChartId].sectorArray[j] = sectorChartArray[sectorChartId].sectorArray[fraction+j];
                    sectorChartArray[sectorChartId].sectorArray[fraction + j] = temp;
                }
            }
        }
    }

    for(var a = 0; a < sectorChartArray[sectorChartId].sectorArray.length; a++){
        context.fillStyle = sectorChartArray[sectorChartId].sectorArray[a].color;
        context.publicCreateSector(sectorChartArray[sectorChartId].sectorArray[a].X,sectorChartArray[sectorChartId].sectorArray[a].Y,sectorChartArray[sectorChartId].sectorArray[a].radius,sectorChartArray[sectorChartId].sectorArray[a].angleStart,sectorChartArray[sectorChartId].sectorArray[a].angleEnd,sectorChartArray[sectorChartId].sectorArray[a].counterClockWise).fill();
    }
}

效果图:
效果图
以上就是所有绘画扇形图的全部代码,如果发现错误或有更好的想法可以告诉我。
kingni_time@sina.com我的邮箱,我会即时改正,如果转载请注明出处,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值