微学习 Canvas [环形占比图]

View代码

<template>
		<canvas class="canvas" canvas-id="ringView"></canvas>
</template>

CSS代码

.canvas {
	width: 750rpx;
	height: 450rpx;
}

Script代码

<script>
	export default {
		data() {
			return {
				rpx: 0,
				colorList: ['#22A887', '#04C5D4', '#299AAA', '#3466A5', '#634490', '#EE5397', '#FE4E4E', '#AA3A39'],
				addNum: 40,
				lineWidth: 18,
				loading:true,
			}
		},
		props: {
			
			dataList:{
				type:Array,
				default: function(){
					return [{name:"200万",value:15.3},{name:"500万",value:20.3},{name:"700万",value:32.8},{name:"700万",value:32.8},{name:"2000万以上",value:22.8}];
				}
			}
		},
		mounted: function() {
			//手机当前屏幕的1%
			this.rpx = uni.getSystemInfoSync().windowWidth / 750;
			
			let dataList = this.dataList; 
			
			let ctx = uni.createCanvasContext("ringView"); 
		 
			const radius = 60;
			const endAngle = 1.5 * Math.PI;
			//线条宽度
			ctx.lineWidth = 30; 
			
			//辅助弧度变量
			let temp = 0; 
			
			//数据总数
			let all = this.getAll(dataList).value 
			
			//起始角度
			let startAngle = Math.PI * 1.5 ;
			for(var a = 0; a < dataList.length; a++){
				ctx.beginPath();
				//计算数据弧度
				let datas = (dataList[a].value / all).toFixed(2) * 100 
				//结束弧度
				let end = (Math.PI * 2 / 100) * (datas + temp) + (Math.PI*1.5)
				
				//画圈
				ctx.arc(200 * this.rpx, 250 * this.rpx, radius, startAngle, end); 
				//颜色
				ctx.strokeStyle = this.colorList[a % this.colorList.length ];
				ctx.stroke(); 
				//下次环形图开始角度
				startAngle = end;
				//下次环形图结束角度
				temp += datas 
				//开始编写文字
				ctx.beginPath() 
				
				var height = (uni.getSystemInfoSync().windowHeight / 2)
				
				//文字靠左
				ctx.textAlign = 'left';
				
				if(dataList.length <= 5){
					ctx.font =  '16px 微软雅黑'
				}else{
					ctx.font =  '12px 微软雅黑'
				}
				this.canvasSarc(ctx,385 * this.rpx, ((height / 2 ) / dataList.length) * (a + 1) - 4,this.colorList[a % this.colorList.length ],a)
				
				this.canvasText(ctx,dataList[a].name, 400 * this.rpx, ((height / 2 ) / dataList.length) * (a + 1));
				
				ctx.textAlign = 'right';
				
				this.canvasText(ctx,( (dataList[a].value / all)  * 100 ).toFixed(2) +"%", 680 * this.rpx, ((height / 2 ) / dataList.length) * (a + 1));
				
				ctx.restore();
			}
			ctx.draw();
		},
		 
		methods: {
			 
			/**
			 * 获取数组集合跟元素总值
			 * @param {Object} arr
			 */
			getAll(arr){
					//返回集合某个字段的总和
					let count = arr.reduce((data1 ,data2) => parseInt(data1) + parseInt(data2.value),0)
					//返回集合的某个字段集合
					let nameArr = arr.map(e => e.name)
					return {name : nameArr,value : count};
			},
			/**
			 * 填写文字
			 * @param {Object} ctx
			 * @param {Object} text
			 * @param {Object} x
			 * @param {Object} y
			 */
			canvasText(ctx,text,x,y){
				ctx.fillText(text, x, y);
			},
			/**
			 * 画圆圈
			 * @param {Object} ctx
			 * @param {Object} x
			 * @param {Object} y
			 * @param {Object} a 线段颜色
			 * @param {Object} b 高度位置
			 */
			canvasSarc(ctx,x,y,a,b){
				ctx.beginPath();
				ctx.save();
				ctx.fillStyle = a;
				ctx.arc(x, y,5,0,Math.PI*1.5)
				ctx.fill();
				ctx.closePath();
				ctx.restore();
			},
			 
		}
	}
</script>

效果展示

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值