<template> <view class='radarContainer'> <canvas class='radarCanvas' canvas-id='radarCanvas'></canvas> </view> </template> <script> var numCount = 3; //元素个数 var numSlot = 3; //一条线上的总节点数 var mW = 400; //Canvas的宽度 var mCenter = mW / 2; //中心点 var mAngle = Math.PI * 2 / numCount; //角度 console.log(mAngle) var mRadius = mCenter - 90; //半径(减去的值用于给绘制的文本留空间) //获取指定的Canvas let radCtx = uni.createCanvasContext('radarCanvas',this) // var radCtx = wx.createCanvasContext("radarCanvas") export default { data() { return { chanelArray1: [["亲和力", 71], ["魅力值", 98], ["年龄感", 82]], } }, onLoad() { //雷达图 // this.drawRadar() }, onReady() { //雷达图 radCtx = uni.createCanvasContext('radarCanvas',this) this.drawRadar() }, methods: { // 雷达图 drawRadar: function () { // radCtx.translate(mCenter+mCenter/2,mCenter/10); // radCtx.rotate(30*Math.PI/80); var sourceData1 = this.chanelArray1 //调用 // this.drawEdge() //画六边形 this.drawArcEdge() //画圆 this.drawLinePoint() // radCtx.rotate(-90); //设置数据 this.drawRegion(sourceData1, '#ff81ae') //第一个人的 //设置文本数据 this.drawTextCans(sourceData1) //设置节点 this.drawCircle(sourceData1, 'red') // this.drawCircle(sourceData2, 'yellow') //开始绘制 setTimeout(function() { //必须延迟执行 不然H5不显示 radCtx.draw() //必须加上 uniapp 没这儿玩意儿 显示不出来不比原生 不加可以显示 }, 200) // radCtx.draw() }, // 绘制6条边 drawEdge: function () { //将x轴旋转至竖直向上 // radCtx.setStrokeStyle("white") radCtx.setLineWidth(2) //设置线宽 for (var i = 0; i < numSlot; i++) { //计算半径 radCtx.beginPath() var rdius = mRadius / numSlot * (i + 1) //画6条线段 for (var j = 0; j < numCount; j++) { //坐标 var x = mCenter + rdius * Math.cos(mAngle * j); var y = mCenter + rdius * Math.sin(mAngle * j); radCtx.lineTo(x, y); } radCtx.closePath() radCtx.stroke() } }, // / 第一步:绘制6个圆,可以通过修改numSlot的数的大小,来确定绘制几个圆 drawArcEdge: function () { radCtx.setStrokeStyle("#f9a7bd") numSlot = 4 for (var i = numSlot; i > 0; i--) { if(i == 4){ var color = "#FFFFFF"; }else if(i == 3){ var color = "#ffebf2"; }else if(i == 2){ var color = "#ffd9e6"; }else if(i == 1){ var color = "#ffc9dc"; } //计算半径 radCtx.beginPath() // var rdius = mRadius / numSlot * (i + 1) //画6条线段 // for (var j = 0; j < numSlot; j++) { // //计算半径 radCtx.beginPath() var rdius = mRadius / numSlot * (i) //计算每个圆的半径 // radCtx.fillStyle="#0000ff"; radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI) //开始画圆 radCtx.fillStyle = color; radCtx.fill(); radCtx.stroke() // } radCtx.closePath() radCtx.stroke() } }, // 绘制连接点 drawLinePoint: function () { radCtx.beginPath(); for (var k = 1; k <= 3; k++) { var x = mCenter + mRadius * Math.cos(mAngle * k + Math.PI /6); var y = mCenter + mRadius * Math.sin(mAngle * k + Math.PI /6); console.log(mCenter) console.log(x,y) // ctx.lineTo(0.5 * w + 0.3 * w * Math.sin(angle), 0.5 * w + 0.35 * w * Math.cos(angle)) // var x =mCenter + 0.3 * mCenter * Math.sin(angle); // var y =mCenter + 0.35 * mCenter * Math.cos(angle); radCtx.moveTo(mCenter, mCenter); radCtx.lineTo(x, y); } radCtx.stroke(); }, //绘制数据区域(数据和填充颜色) drawRegion: function (mData, color) { radCtx.beginPath(); radCtx.setLineWidth(1) //设置线宽 radCtx.setStrokeStyle('rgb(255,58,128)') radCtx.setFillStyle('rgba(255,58,128,0.4)') radCtx.shadowBlur = parseInt(mCenter * 0.01) radCtx.shadowColor = "rgba(255,58,128,0.5)" for (var m = 0; m < numCount; m++) { var x = mCenter + mRadius * Math.cos(mAngle * m + Math.PI /6) * mData[m][1] / 100; var y = mCenter + mRadius * Math.sin(mAngle * m + Math.PI /6) * mData[m][1] / 100; radCtx.lineTo(x, y); } radCtx.closePath(); // radCtx.setFillStyle(color) // radCtx.setStrokeStyle("#ff3a80") // radCtx.setLineWidth(1) //设置线宽 // radCtx.closePath() radCtx.fill() radCtx.stroke() }, // //绘制文字 drawTextCans: function (mData) { radCtx.setFillStyle("#1c1c1c") radCtx.font = 'bolder 14px cursive' //设置字体 for (var n = 0; n < numCount; n++) { var x = mCenter + (mRadius+5) * Math.cos(mAngle * n + Math.PI /6); var y = mCenter + (mRadius+5) * Math.sin(mAngle * n + Math.PI /6); // radCtx.fillText(mData[n][0], x, y); //通过不同的位置,调整文本的显示位置 radCtx.setFillStyle('rgb(51,51,51)') if (mAngle * n >= 0 && mAngle * n <= Math.PI / 2) { radCtx.fillText(mData[n][0], x - 2, y + 28); } else if (mAngle * n > Math.PI / 2 && mAngle * n <= Math.PI) { radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width + 3, y + 23); } else if (mAngle * n > Math.PI && mAngle * n <= Math.PI * 3 / 2) { radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width + 15, y-3); } else { radCtx.fillText(mData[n][0], x + 7, y + 2); } radCtx.setFillStyle('rgb(255,58,128)') var x = mCenter + (mRadius+10) * Math.cos(mAngle * n + Math.PI /6); var y = mCenter + (mRadius+30) * Math.sin(mAngle * n + Math.PI /6); // radCtx.fillText(mData[n][0], x, y); //通过不同的位置,调整文本的显示位置 if (mAngle * n >= 0 && mAngle * n <= Math.PI / 2) { radCtx.fillText(mData[n][1], x , y ); } else if (mAngle * n > Math.PI / 2 && mAngle * n <= Math.PI) { radCtx.fillText(mData[n][1], x - radCtx.measureText(mData[n][0]).width + 14, y - 5); } else if (mAngle * n > Math.PI && mAngle * n <= Math.PI * 3 / 2) { radCtx.fillText(mData[n][1], x - radCtx.measureText(mData[n][0]).width + 20, y + 6); } else { radCtx.fillText(mData[n][1], x + 7, y + 2); } } }, //画点 drawCircle: function (mData, color) { var r = 3; //设置节点小圆点的半径 for (var i = 0; i < numCount; i++) { var x = mCenter + mRadius * Math.cos(mAngle * i + Math.PI /6) * mData[i][1] / 100; var y = mCenter + mRadius * Math.sin(mAngle * i + Math.PI /6) * mData[i][1] / 100; radCtx.setStrokeStyle("rgb(255,255,255)") radCtx.setLineWidth(1) //设置线宽 radCtx.beginPath(); radCtx.arc(x, y, r, 0, Math.PI * 2); // radCtx.setLineWidth(1) // radCtx.setStrokeStyle('rgb(255,255,255)') radCtx.setFillStyle('rgb(255,58,128)') // radCtx.fillStyle = color; radCtx.fill(); // radCtx.fill() radCtx.stroke() } }, } } </script> <style> .radarContainer{ background: linear-gradient(#86d0d0, #81e1b4); 750upx; height:750upx; display: flex; justify-content:center; align-items: center; position: relative; } .radarCanvas{ 400px; height:400px; /* margin: 0 auto; position: absolute; */ } </style>
注意:为了兼容宽度,可以使用this.width = uni.upx2px(690),690为690upx的宽度
原文地址:https://www.pianshen.com/article/312557038/