Canvas画柱状统计图

这个是刚入门前端想写的,一个插件,功能虽然可以实现但是代码有点复杂,在这里留作纪念,大家可以引用。现在知道用echarts更加简单而且echarts的文档很好,自学在网上可以查到很多分享。同时阿里的G2,G6等也都可以用。

在实现中HTML部分的额代码:

<div class="tongji_1" id="div_1">
     <canvas id="canvas1" class="canvasdata20" width="0px;" height="0px;"></canvas>
</div>

在实现过程中JS部分的代码:

//    闰年判断函数

function isLeapYear() {
	var leapYear = new Date();
	return(0 == leapYear.getYear() % 4 && ((leapYear.getYear() % 100 != 0) || (leapYear.getYear() % 400 == 0)));
}

//对于以日为单位的数据类型处理函数,用来获取当前日期前15天的日期数据
function getdata_days() {
	var mydate = new Date();
	var datemonth = mydate.getMonth() + 1;
	var dateday = mydate.getDate();
	var date_day = new Array();
	switch(datemonth) {
		case 1:
		case 2:
		case 4:
		case 6:
		case 8:
		case 9:
		case 11:
			{
				if(dateday <= 15) {
					for(var i = 0; i < 15; i++) {
						date_day[i] = new Array();
						for(var j = 0; j < 2; j++) {
							date_day[i][j] = "";
						}
						if((dateday - i - 1) > 0) {
							date_day[i][0] = datemonth;
							date_day[i][1] = dateday - 1 - i;
						} else {
							if(dateday == 1) {
								date_day[i][0] = 12;
								date_day[i][1] = 31 + dateday - i - 1;
							} else {
								date_day[i][0] = (datemonth + 12) % 13;
								if(date_day[i][0] == 0) {
									date_day[i][0] = 12;
								}
								date_day[i][1] = 31 + dateday - i - 1;
							}
						}
					}
				} else {
					for(var i = 0; i < 15; i++) {
						date_day[i] = new Array();
						date_day[i][0] = datemonth;
						date_day[i][1] = dateday - 1 - i;
					}
				}
			}
			break;
		case 3:
		case 5:
		case 7:
		case 10:
		case 12:
			{
				if(dateday <= 15) {
					for(var i = 0; i < 15; i++) {
						date_day[i] = new Array();
						for(var j = 0; j < 2; j++) {
							date_day[i][j] = "";
						}
						if((dateday - i - 1) > 0) {
							date_day[i][0] = datemonth;
							date_day[i][1] = dateday - 1 - i;
						} else {
							if(datemonth != 3) {
								date_day[i][0] = (datemonth + 12) % 13;
								date_day[i][1] = 30 + dateday - i - 1;
							} else {
								if(0 == mydate.getYear() % 4 && ((leapYear.getYear() % 100 != 0) || (leapYear.getYear() % 400 == 0))) {
									date_day[i][0] = (datemonth + 12) % 13;
									date_day[i][1] = 29 + dateday - i - 1;
								} else {
									date_day[i][0] = (datemonth + 12) % 13;
									date_day[i][1] = 28 + dateday - i - 1;
								}
							}

						}
					}
				} else {
					for(var i = 0; i < 15; i++) {
						date_day[i] = new Array();
						date_day[i][0] = datemonth;
						date_day[i][1] = dateday - 1 - i;
					}
				}
			}
			break;
		default:
			{
				alert("单天数据获取失败,canvas.js-204");
			}
	}
	return date_day;
}

//    对于以月为单位的数据类型处理函数,用来获取当前日期前12个月的日期数据
function get_month() {
	var mydate = new Date();
	var datemonth = mydate.getMonth() + 1;
	var date_month = new Array();
	for(var i = 0; i < 12; i++) {
		if(datemonth - 1 - i > 0) {
			date_month[i] = datemonth - i - 1;
		} else {
			date_month[i] = datemonth + 12 - i - 1;
		}
	}
	return date_month;
}

//    计算固定日期的是本年的第几个星期
//    如果年的第一天不是周一那么这个星期就不算是本年的星期而是上一年的星期
function weekofyear(sdate) {
	var d = new Date(sdate);
	var myYear = d.getFullYear();
	var firstDate = new Date(myYear + "-01-01");
	var dayofyear = 0;
	var f = new Date("01 01,myYear");
	var temp = f.getDay();
	var temp1 = -1;
	if(f.getDay() == 1) {
		temp1 = 0;
	}
	for(var i = 0; i < d.getMonth(); i++) {
		switch(i) {
			case 0:
			case 2:
			case 4:
			case 6:
			case 7:
			case 9:
				dayofyear += 31;
				break;
			case 1:
				if(isLeapYear(d)) {
					dayofyear += 29;
				} else {
					dayofyear += 28;
				}
				break;
			case 3:
			case 5:
			case 8:
			case 10:
				dayofyear += 30;
				break;
		}
	}
	dayofyear += d.getDate() + 1;
	var week = firstDate.getDay();
	var dayNum = dayofyear - (7 - week);
	var weekNum = 1;
	weekNum = weekNum + (dayNum / 7);
	if(dayNum % 7 != 0) {
		weekNum = weekNum + 1;
	}
	var h = parseInt(weekNum) + temp1;
	return h;
}

//    判断当前日期是本年的第几个星期
//    如果年的第一天不是周一那么这个星期就不算是本年的星期而是上一年的星期
function weekorder() {
	//	周日是与周六相连,与周六属于同一周
	var time, week, checkDate = new Date(new Date());
	checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
	time = checkDate.getTime();
	checkDate.setMonth(0);
	checkDate.setDate(1);
	week = Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
	return week;
}

//      获得周的数据信息
function get_week() {
	var tempdate = new Date();
	var temp = weekorder();
	var getweek = new Array();
	if(temp > 12) {
		for(var j = 0; j < 12; j++) {
			getweek[j] = weekorder() - 1 - j;
		}
	} else {
		for(var j = 0; j < 12; j++) {
			if((weekorder() - 1 - j) > 0) {
				getweek[j] = weekorder() - 1 - j;
			} else {
				getweek[j] = weekofyear("12 31,(tempdate.getFullYear()-1)") + weekorder() - j - 1;
			}
		}
	}
	return getweek;
}

//纵方向左边值处理获得函数
function getmax_linedata(a) {
	var tempmax = a[0];
	var temp;
	var linedata = new Array();
	for(i = 1; i < a.length; i++) {
		if(a[i] > tempmax) {
			tempmax = a[i];
		}
	}
	temp = ((tempmax - tempmax % 6) / 6 - ((tempmax - tempmax % 6) / 6) % 5) + 5;
	for(var i = 0; i < 7; i++) {
		linedata[i] = i * temp;
	}
	return linedata;
}

//折线图中数据处理函数
function getBeveling(x, y) {
	return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}

//虚线函数
function drawDashLine(context, x1, y1, x2, y2, dashLen) {
	dashLen = dashLen === undefined ? 5 : dashLen;
	//得到斜边的总长度  
	var beveling = getBeveling(x2 - x1, y2 - y1);
	//计算有多少个线段  
	var num = Math.floor(beveling / dashLen);

	for(var i = 0; i < num; i++) {
		context[i % 2 == 0 ? 'moveTo' : 'lineTo'](x1 + (x2 - x1) / num * i, y1 + (y2 - y1) / num * i);
	}
}

//画布调用函数
//data:要处理的数据,数组的形式;fatherbox:画布所在div的id;
function huabu(data, fatherbox, datatype, id) {
	$(function() {
		var canvasgetwidth1 = parseInt($("#" + fatherbox + "").css("width").replace(/[^0-9]/ig, ""));
		var canvasgetheight1 = parseInt($("#" + fatherbox + "").css("height").replace(/[^0-9]/ig, ""));
		var canvasset1 = document.getElementById("canvas" + id + "");
		canvasset1.width = canvasgetwidth1;
		canvasset1.height = canvasgetheight1;
		var canvaswidth = canvasgetwidth1;
		var canvasheight = canvasgetheight1;
		//          统计表整体看做矩形,左上角开始顺时针旋转四个顶点的坐标分
		//          别为(x1,y1),(x2,y2),(x3,y3),(x4,y4)
		//           alert(canvasset1.height);

		var x1 = canvaswidth * 0.01 + 40,
			y1 = canvasheight * 0.02 + 30;
		var x2 = canvaswidth - 40 - canvaswidth * 0.01,
			y2 = canvasheight * 0.02 + 30;
		var x3 = canvaswidth - 40 - canvaswidth * 0.01,
			y3 = canvasheight - canvasheight * 0.01 - 35;
		var x4 = canvaswidth * 0.01 + 40,
			y4 = canvasheight - canvasheight * 0.01 - 35;

		var c = document.getElementById("canvas" + id + "");
		var cchild1 = c.getContext("2d");
		//var context = document.getElementById('canvas1').getContext('2d');

		var chuandi = getmax_linedata(data);
		cchild1.beginPath();

		cchild1.fillStyle = "8B8989";
		cchild1.lineWidth = 0.2;
		//画从横坐标轴
		cchild1.moveTo(x1, y1 - 15);
		cchild1.lineTo(x4, y4);
		cchild1.moveTo(x4 - 3, y4);
		cchild1.lineTo(x3 + 25, y3);
		//画两个箭头
		cchild1.moveTo(x1, y1 - 15);
		cchild1.lineTo(x1 - 5, y1 - 10);
		cchild1.moveTo(x1, y1 - 15);
		cchild1.lineTo(x1 + 5, y1 - 10);

		cchild1.moveTo(x3 + 25, y3);
		cchild1.lineTo(x3 + 20, y3 - 5);
		cchild1.moveTo(x3 + 25, y3);
		cchild1.lineTo(x3 + 20, y3 + 5);

		cchild1.fillStyle = "8B8989";
		cchild1.lineWidth = 0.2;
		//数值参考线
		for(var i = 0; i < 6; i++) {
			drawDashLine(cchild1, x1 - 3, y1 + i * ((canvasheight - 65 - canvasheight * 0.03) / 6), x2, y1 + i * ((canvasheight - 65 - canvasheight * 0.03) / 6), 3);
		}
		cchild1.font = "15px Arial";
		//从方向标值
		for(var i = 0; i < 7; i++) {
			var a;
			if(chuandi[i] >= 10) {
				if(chuandi[i] >= 100) {
					a = 12;
				} else {
					a = 18;
				}
			} else {
				a = 22;
			}
			cchild1.fillText(chuandi[i], a + canvaswidth * 0.01, y4 + 7.5 - i * ((canvasheight - 65 - canvasheight * 0.03) / 6));
		}
		cchild1.font = "12px Arial";
		cchild1.fillText("单位:千元", x1 + 5, y1 - 24);
		cchild1.stroke();
		//				1代表的是12周的数据;2代表的是15天的数据;3代表的是12个月既是一年的数据
		switch(datatype) {
			case 1:
				{
					var weekdatas = get_week();
					for(var i = 0; i < 12; i++) {
						if(weekdatas[weekdatas.length - 1 - i] > 9) {
							cchild1.font = "12px Arial";
							cchild1.fillText("" + weekdatas[weekdatas.length - 1 - i] + "周", i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01 - 14, y3 + 18);
						} else {
							cchild1.font = "12px Arial";
							cchild1.fillText("" + weekdatas[weekdatas.length - 1 - i] + "周", i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01 - 9, y3 + 18);
						}
					}
				}
				break;
			case 2:
				{
					var daydatas = getdata_days();
					for(var i = 0; i < 15; i++) {
						if(daydatas[i][0] > 9) {

							cchild1.font = "12px Arial";
							cchild1.fillText("" + daydatas[daydatas.length - 1 - i][0] + "-" + daydatas[daydatas.length - 1 - i][1] + "", i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01 -15, y3 + 18);

						} else {

							cchild1.font = "12px Arial";
							cchild1.fillText("" + daydatas[daydatas.length - 1 - i][0] + "-" + daydatas[daydatas.length - 1 - i][1] + "", i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01 - 10, y3 + 18);

						}
					}
				}
				break;
			case 3:
				{
					var monthdatas = get_month();
					for(var i = 0; i < 12; i++) {
						if(monthdatas[monthdatas.length - 1 - i] > 9) {
							cchild1.font = "12px Arial";
							cchild1.fillText("" + monthdatas[monthdatas.length - 1 - i] + "月", i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01 - 7, y3 + 18);
						} else {
							cchild1.font = "12px Arial";
							cchild1.fillText("" + monthdatas[monthdatas.length - 1 - i] + "月", i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01 - 10, y3 + 18);
						}
					}
				}
				break;
			default:
				alert("数据类型参数传送出错!!!canvas.js-485");
		}

		//制作具体柱状图
		for(i = 0; i < data.length; i++) {
			cchild1.beginPath();
			cchild1.fillStyle = "coral";
			cchild1.strokeStyle = "orange";
			cchild1.lineWidth = ((canvaswidth - canvaswidth * 0.02 - 100) / data.length) * 0.4;
			cchild1.moveTo(i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01, canvasheight - canvasheight * 0.01 - 35 - (data[i] / chuandi[chuandi.length - 1]) * (y3 - y1));
			cchild1.lineTo(i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01, y3);
			cchild1.stroke();
		}
		//		制作横坐标数值标记点
		for(i = 0; i < data.length; i++) {
			cchild1.fillStyle = "black";
			cchild1.lineWidth = 1;
			cchild1.moveTo(i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01, y3);
			cchild1.lineTo(i * (canvaswidth - canvaswidth * 0.02 - 100) / data.length + (canvaswidth - canvaswidth * 0.02 - 100) / data.length * 0.8 + 40 + canvaswidth * 0.01, y3 + 5);
		}
		cchild1.stroke();
	})
}

最后在JS代码中应用画布函数,即可!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值