canvas作图系列——柱图

柱图

canvas画图最主要的就是把一张图分成各个部分,然后一块一块的去进行绘制,比如柱图,在绘制的过程中就可以分成x轴,x轴的label,y轴,y轴的label,平行于x轴的分割线,以及每个柱体等等和一些细节。
柱图的x轴就是等分嘛,有几个数据就等分成几块,y轴就是先得出数据的最大值,然后看你想把这最大值均分成几份嘛,比如把1200分成4份,那y轴就是被均分成四份,每个刻度就是300

在这里插入图片描述
还是要强调一点,以为上面这个图片中的柱图用的是svg,所以一定要先加载图片,等图片加载完了之后再调用绘制函数

js

function DrawRect(dataArr1, dataArr2, nameArr, index) {
		var canvas = document.querySelector('#cav5')
		var cav = canvas.getContext('2d');
		cav.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
		var width = canvas.clientWidth
		var height = canvas.clientHeight
		var zeroPoint = [width * 0.1, height * 0.9]	 //柱图图表零点坐标

		var Yheight = height * 0.5   //图表高度
		var Xwidth = width * 0.8	//图表宽度
		var Ypoint = [zeroPoint[0], zeroPoint[1] - Yheight]		//Y轴顶点坐标
		var Xpoint = [zeroPoint[0] + Xwidth, zeroPoint[1]]	//X轴右端坐标

		var Xpatition = Xwidth * 0.95 / nameArr.length	//第一个柱图的横坐标
		var namePoint = [Xpatition / 2 + zeroPoint[0], zeroPoint[1] + 15]		//X轴第一个label的坐标

		//数据处理获取两个数组中的最大值
		var max = dataArr1[0]
		for (let i = 0; i < dataArr1.length; i++) {
			if (max <= dataArr1[i]) {
				max = dataArr1[i]
			}
		}
		for (let i = 0; i < dataArr2.length; i++) {
			if (max <= dataArr2[i]) {
				max = dataArr2[i]
			}
		}
		var Ypatition = Yheight * 0.95 / 5		//Y轴分隔距离
		var dataPoint = [zeroPoint[0] - 15, zeroPoint[1] - Ypatition / 2]	//Y轴label的坐标
		var YdataLabel = []		//Y轴label数组
		var dataLabel = max / 5		//Y轴分割的倍数
		for (let i = 0; i < 5; i++) {
			YdataLabel.push(dataLabel)
			dataLabel += max / 5
		}
		var barWidth = 10		//柱体宽度
		var linePoint = []		//柱图连线的端点坐标数组
		var tipsPoint = []		//提示框的坐标数组
		//Y轴
		cav.beginPath()
		cav.moveTo(zeroPoint[0], zeroPoint[1])
		cav.lineTo(Ypoint[0], Ypoint[1])
		cav.strokeStyle = 'red'
		cav.closePath()
		cav.stroke()
		
		//X轴
		cav.beginPath()
		cav.moveTo(zeroPoint[0], zeroPoint[1])
		cav.lineTo(Xpoint[0], Xpoint[1])
		cav.strokeStyle = 'red'
		cav.closePath()
		cav.stroke()
		
		//Y轴端点箭头
		cav.beginPath()
		cav.moveTo(Ypoint[0], Ypoint[1])
		cav.lineTo(Ypoint[0] - 3, Ypoint[1] + 3)
		cav.strokeStyle = 'red'
		cav.stroke()
		cav.save()
		cav.restore()
		cav.lineTo(Ypoint[0] + 3, Ypoint[1] + 3)
		cav.strokeStyle = 'red'
		cav.stroke()
		cav.closePath()
		cav.fillStyle = 'red'
		cav.fill()
		
		//X轴端点箭头
		cav.beginPath()
		cav.moveTo(Xpoint[0], Xpoint[1])
		cav.lineTo(Xpoint[0] - 3, Xpoint[1] - 3)
		cav.strokeStyle = 'red'
		cav.stroke()
		cav.save()
		cav.restore()
		cav.lineTo(Xpoint[0] - 3, Xpoint[1] + 3)
		cav.strokeStyle = 'red'
		cav.stroke()
		cav.closePath()
		cav.fillStyle = 'red'
		cav.fill()

		//Y轴文字及分割线
		for (let i = 0; i < YdataLabel.length; i++) {
			cav.textAlign = 'end'
			cav.textBaseline = 'middle'
			cav.font = '14px'
			cav.fillStyle = 'red'
			cav.fillText(parseInt(YdataLabel[i]) + '', dataPoint[0], dataPoint[1])
			cav.beginPath()
			cav.moveTo(zeroPoint[0], dataPoint[1])
			cav.lineTo(Xpoint[0], dataPoint[1])
			cav.strokeStyle = 'red'
			cav.closePath()
			cav.stroke()

			dataPoint[1] -= Ypatition
		}

		//高亮框
		var lightHeightColor = cav.createLinearGradient(Xpatition * index + zeroPoint[0] + 15, zeroPoint[1] - Yheight,
			Xpatition * (index + 1) + zeroPoint[0] - 15, zeroPoint[1]);
		lightHeightColor.addColorStop(0, "rgba(53,103,235,1)");
		lightHeightColor.addColorStop(1, 'rgba(53,103,235,0.3)');
		cav.beginPath()
		cav.rect(Xpatition * (index) + zeroPoint[0], zeroPoint[1] - Yheight, Xpatition, Yheight)
		cav.fillStyle = lightHeightColor
		cav.fill()

		for (let i = 0; i < nameArr.length; i++) {
			//文字
			cav.textAlign = 'center'
			cav.textBaseline = 'top'
			cav.font = '14px'
			cav.fillStyle = 'red'
			cav.fillText(nameArr[i], namePoint[0], namePoint[1])

			//柱图
			var barHeight1 = dataArr1[i] / max * 0.95 * Yheight - Ypatition / 2
			var barHeight2 = dataArr2[i] / max * 0.95 * Yheight - Ypatition / 2
			cav.drawImage(img, namePoint[0] - barWidth, zeroPoint[1] - barHeight1, barWidth, barHeight1)
			cav.drawImage(img3, namePoint[0] - barWidth, zeroPoint[1] - barHeight1 - img3.height / 2, barWidth, img3
				.height)
			cav.drawImage(img2, namePoint[0], zeroPoint[1] - barHeight2, barWidth, barHeight2)
			cav.drawImage(img4, namePoint[0], zeroPoint[1] - barHeight2 - img4.height / 2, barWidth, img4.height)
			linePoint.push({
				startX: namePoint[0] - barWidth / 2,
				startY: zeroPoint[1] - barHeight1,
				endX: namePoint[0] + barWidth / 2,
				endY: zeroPoint[1] - barHeight2
			})
			namePoint[0] += Xpatition
		}

		//连线
		cav.beginPath()
		cav.setLineDash([2]);
		cav.strokeStyle = "#fff"
		cav.moveTo(linePoint[index].startX, linePoint[index].startY)
		cav.lineTo(linePoint[index].endX, linePoint[index].endY)
		cav.closePath()
		cav.stroke()

		//连线端点圆点
		cav.beginPath()
		cav.arc(linePoint[index].startX, linePoint[index].startY, 2, 0, Math.PI * 2, false)
		cav.fillStyle = '#fff'
		cav.closePath()
		cav.fill()
		cav.beginPath()
		cav.arc(linePoint[index].endX, linePoint[index].endY, 2, 0, Math.PI * 2, false)
		cav.fillStyle = '#fff'
		cav.closePath()
		cav.fill()

		//文字框
		if (dataArr1[index] > dataArr2[index]) {
			if(index==dataArr2.length-1) {
				tipsPoint[0] = linePoint[index].startX-tipsImg.width
			}else {
				tipsPoint[0] = linePoint[index].startX
			}
			tipsPoint[1] = linePoint[index].startY - tipsImg.height
		} else {
			if(index==dataArr2.length-1) {
				tipsPoint[0] = linePoint[index].endX-tipsImg.width
			}else {
				tipsPoint[0] = linePoint[index].endX
			}
			tipsPoint[1] = linePoint[index].endY - tipsImg.height
		}
		cav.drawImage(tipsImg, tipsPoint[0], tipsPoint[1])
		cav.textAlign = 'start'
		cav.textBaseline = 'middle'
		cav.font = '14px'
		cav.fillStyle = 'red'
		cav.fillText('独立用户', tipsPoint[0] + 10, tipsPoint[1] + tipsImg.height / 3)
		cav.textAlign = 'right'
		cav.textBaseline = 'middle'
		cav.font = '14px'
		cav.fillStyle = '#fff'
		cav.fillText(dataArr1[index], tipsPoint[0] + tipsImg.width - 12, tipsPoint[1] + tipsImg.height / 3)
		cav.textAlign = 'start'
		cav.textBaseline = 'middle'
		cav.font = '14px'
		cav.fillStyle = 'red'
		cav.fillText('浏览量', tipsPoint[0] + 10, tipsPoint[1] + tipsImg.height - 15)
		cav.textAlign = 'right'
		cav.textBaseline = 'middle'
		cav.font = '14px'
		cav.fillStyle = '#fff'
		cav.fillText(dataArr2[index], tipsPoint[0] + tipsImg.width - 12, tipsPoint[1] + tipsImg.height - 15)
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IsQtion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值