上一章介绍了扇形图或饼状图绘画过程,下面我们一起来看看代码,如果发现错误或者有更好的方法可以联系我,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我的邮箱,我会即时改正,如果转载请注明出处,谢谢