uniapp 使用canvas制作柱状图

发布时间:2024年01月16日

效果图:
在这里插入图片描述
实现思路:
1、通过展示数据计算需要画几根柱子;
2、通过组件宽度、高度计算出每根柱子的宽度及高度;
3、for循环依次绘制每根柱子;
4、绘制柱子时,先绘制顶部百分比、value值,再绘制柱子,再绘制底部标题;
5、文字需要居中,可绘制前丈量文字宽度再确定起始坐标。

// columnar.vue

<template>
	<view class="container">
		<canvas style="width:100%;height:250px;margin-top:20px;" canvas-id="columnarCanvas" id="columnarCanvas"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				canvasInfo: { },
				dataList: [{
					title: "玛莎拉蒂",
					value: 2
				}, {
					title: "奥迪",
					value: 8
				}, {
					title: "奔驰",
					value: 9
				}, {
					title: "保时捷",
					value: 4
				}, {
					title: "宝马",
					value: 7
				}, {
					title: "凯迪拉克",
					value: 3
				}]
			}
		},

		onReady() {
			this.getCanvasInfo()
		},

		methods: {
			/** 获取节点信息,动态得到组件的宽度,高度 **/
			getCanvasInfo() {
				var view = uni.createSelectorQuery().in(this).select("#columnarCanvas"); 
				view.fields({ size: true, rect: true }, res => {
				  // console.log("得到节点信息" + JSON.stringify(res))
					var canvasInfo = {}
					canvasInfo.width = res.width
					canvasInfo.height = res.height
					this.canvasInfo = canvasInfo
					this.drawColumnar()
				}).exec();
			},
			
			/** 画图 **/
			drawColumnar() {
				const ctxColumnar = uni.createCanvasContext("columnarCanvas")
				var dataList = this.dataList
				var canvasInfo = this.canvasInfo
				var columnarNum = dataList.length
				var columnarWidth = (canvasInfo.width - 30) / (2 * columnarNum + 1)
				// console.log("宽度", columnarWidth)
				var maxColumnarHeight = canvasInfo.height - 60 - 20
				var maxColumnarValue = 0
				var totalValue = 0
				for (var i = 0; i < dataList.length; i++) {
					if (dataList[i].value > maxColumnarValue) {
						maxColumnarValue = dataList[i].value
					}
					totalValue = totalValue + dataList[i].value
				}
				for (var i = 0; i < dataList.length; i++) {
					ctxColumnar.setFontSize(15)
					var percent = parseInt(dataList[i].value * 100 / totalValue) + "%"
					var dx = columnarWidth * (2 * i + 1)
					var dy = canvasInfo.height - (maxColumnarHeight * (dataList[i].value / maxColumnarValue) + 60) + 10
					ctxColumnar.setFillStyle('#2b2b2b')
					var percentWidth = ctxColumnar.measureText(percent)
					ctxColumnar.fillText(percent, dx + columnarWidth / 2 - percentWidth.width / 2, dy)
					// ctxColumnar.setFillStyle('rgb(99, 112, 210)')
					ctxColumnar.setFillStyle(this.randomColor(i)) //指定每条柱子不同颜色
					var valueWidth = ctxColumnar.measureText(dataList[i].value + "")
					ctxColumnar.fillText(dataList[i].value + "", dx + columnarWidth / 2 - valueWidth.width / 2, dy + 20)
					ctxColumnar.fillRect(dx, dy + 22, columnarWidth, maxColumnarHeight * (dataList[i].value / maxColumnarValue))
					ctxColumnar.setFillStyle('#8a8a8a')
					var titleWidth = ctxColumnar.measureText(dataList[i].title + "")
					ctxColumnar.fillText(dataList[i].title, dx + columnarWidth / 2 - titleWidth.width / 2, canvasInfo.height - 10)
				}
				ctxColumnar.draw()
			},
			
			/**随机指定颜色**/
			randomColor(index) {
				let colorList = ["#63b2ee","#76da91","#f8cb7f","#7cd6cf","#f89588","#9192ab","#efa666","#7898e1","#eddd86","#9987ce","#76da91","#63b2ee"]
				// let index = Math.floor(Math.random() * colorList.length)
				return colorList[index]
			}
			
			
		}
	}
</script>

<style>

</style>
文章来源:https://blog.csdn.net/weixin_38946164/article/details/135628015
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。