根据自己需要的画布大小去设置更改,这里的需求雷达图区域较小。
由于雷达图的层级太高,且不受z-index控制,这里在绘制完成后导出成了图片。
1、wxml中
<view class='radarContainer'>
<canvas wx:if="{{!radarImg}}" class='radarCanvasSelf' canvas-id='radarCanvas'></canvas>
<image wx:else src="{{radarImg}}" style="width: 330rpx; height: 360rpx;" />
</view>
2、wxss中
.radarContainer{
width:50%;
height:400rpx;
padding: 10rpx;
box-sizing: border-box;
display: flex;
justify-content:center;
align-items: center;
position: relative;
}
.radarCanvasSelf{
width:330rpx;
height:360rpx;
margin: 0 auto;
position: absolute;
}
3、js中
//这些数据并没有写在data中
var radCtx;//定义canvas
var numCount = 5; //元素个数
var numSlot = 1; //一条线上的总节点数
var mW = 165; //Canvas的宽度
var mCenter = mW / 2; //中心点
var mAngle = Math.PI * 2 / numCount; //角度
var mRadius = mCenter - 45; //半径(减去的值用于给绘制的文本留空间)
page({
data:{
chanelArray1: [["沟通能力", 80], ["生存能力", 60], ["经济能力", 66], ["创造能力", 90], ["信息能力", 75]],
radarImg: '',
},
onLoad: function (options) {
//页面加载时获取指定的canvas,加上this,指在当前的自定义组件内获取id为radarCanvas的dom元素
radCtx = wx.createCanvasContext("radarCanvas", this)
radCtx.save()
radCtx.setFillStyle('white')
radCtx.fillRect(0, 0, 165, 180);//画出矩形白色背景
radCtx.restore()
//避免Android系统出现黑色背景
},
}),
onReady: function () {
this.drawRadar()
},
drawRadar: function () {
var sourceData1 = this.data.chanelArray1
wx.showLoading({
title: '图形绘制中...',
})
// this.drawEdge() //画六边形,根据自己需要,可以是多边形或者圆形
this.drawArcEdge() //画圆
this.drawLinePoint() //绘制连接点
this.drawRegion(sourceData1, '#FF6E13') //设置数据
this.drawTextCans(sourceData1) //设置文本数据
this.drawNumText(sourceData1)//设置文本数字数据
// this.drawCircle(sourceData1, 'red') //设置节点
//开始绘制
setTimeout(() => {
// radCtx.draw() //直接绘制
radCtx.draw(false, setTimeout(() => { this.handleCanvarToImg() }, 500))
//绘制完成后,将画布内容导出成指定大小的图片
}, 1500)
},
// 绘制6条边
drawEdge: function () {
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()
}
},
// 第一步:绘制圆,你可以通过修改numSlot的数的大小,来确定绘制几个圆
drawArcEdge: function () {
radCtx.setStrokeStyle("#FFD9C2") //设置线的颜色
radCtx.setLineWidth(2) //设置线宽
for (var i = 0; i < numSlot; i++) { //需要几个圆就重复几次
// //计算半径
radCtx.beginPath()
var rdius = mRadius / numSlot * (i + 1) //计算每个圆的半径
radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI) //开始画圆
radCtx.stroke()
}
},
// 绘制连接点
drawLinePoint: function () {
radCtx.beginPath();
for (var k = 0; k < numCount; k++) {
var x = mCenter + mRadius * Math.cos(mAngle * k);
var y = mCenter + mRadius * Math.sin(mAngle * k);
radCtx.moveTo(mCenter, mCenter);
radCtx.lineTo(x, y);
}
radCtx.closePath();
radCtx.stroke();
},
//绘制数据区域(数据和填充颜色)
drawRegion: function (mData, color) {
radCtx.beginPath();
for (var m = 0; m < numCount; m++) {
var x = mCenter + mRadius * Math.cos(mAngle * m) * mData[m][1] / 100;
var y = mCenter + mRadius * Math.sin(mAngle * m) * mData[m][1] / 100;
radCtx.lineTo(x, y);
}
radCtx.closePath();
radCtx.setFillStyle(color)
radCtx.fill();
},
//绘制文字
drawTextCans: function (mData) {
radCtx.setFillStyle("#999999")
radCtx.setFontSize(10) //设置字体
for (var n = 0; n < numCount; n++) {
var x = mCenter + mRadius * Math.cos(mAngle * n);
var y = mCenter + mRadius * Math.sin(mAngle * n);
// radCtx.fillText(mData[n][0], x, y);
//通过不同的位置,调整文本的显示位置
if (n == 0) {
radCtx.fillText(mData[n][0], x + 3, y + 10);
} else if (n == 1) {
radCtx.fillText(mData[n][0], x - 5, y + 30);
} else if (n == 2) {
radCtx.fillText(mData[n][0], x - 40, y + 25);
} else if (n == 3) {
radCtx.fillText(mData[n][0], x - 47, y + 5);
} else if (n == 4) {
radCtx.fillText(mData[n][0], x - 10, y - 10);
}
}
},
// 绘制数字
drawNumText: function (mData) {
radCtx.setFillStyle("#41B035")
radCtx.setFontSize(10) //设置字体
for (var n = 0; n < numCount; n++) {
var x = mCenter + mRadius * Math.cos(mAngle * n);
var y = mCenter + mRadius * Math.sin(mAngle * n);
if (n == 0) {
radCtx.fillText(mData[n][1], x + 17, y - 8);
} else if (n == 1) {
radCtx.fillText(mData[n][1], x + 10, y + 15);
} else if (n == 2) {
radCtx.fillText(mData[n][1], x - 26, y + 5);
} else if (n == 3) {
radCtx.fillText(mData[n][1], x - 30, y - 15);
} else if (n == 4) {
radCtx.fillText(mData[n][1], x + 5, y - 25);
}
}
},
//画点
drawCircle: function (mData, color) {
var r = 3; //设置节点小圆点的半径
for (var i = 0; i < numCount; i++) {
var x = mCenter + mRadius * Math.cos(mAngle * i) * mData[i][1] / 100;
var y = mCenter + mRadius * Math.sin(mAngle * i) * mData[i][1] / 100;
radCtx.beginPath();
radCtx.arc(x, y, r, 0, Math.PI * 2);
radCtx.fillStyle = color;
radCtx.fill();
}
},
// 雷达图层级太高,转换为图片
handleCanvarToImg() {
var that = this
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 165,
height: 180,
destWidth: 495,
destHeight: 540,
fileType: 'jpg',
quality: 1,
canvasId: 'radarCanvas',
success: function (res) {
wx.hideLoading()
console.log('res', res)
that.setData({
radarImg: res.tempFilePath,
});
},
complete: function (err) {
wx.hideLoading()
console.log('err', err)
}
}, that);
},