参考文档: https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html

const numCount = 3; // 元素个数 const numSlot = 4; // 一条线上的总节点数 const mW = 340; // Canvas的宽度 const mCenter = mW / 2; // 中心点 const mAngle = (Math.PI * 2) / numCount; // 角度 const mRadius = mCenter - 80; // 半径(减去的值用于给绘制的文本留空间) // 获取指定的Canvas let radCtx = null;
// 获取canvas 节点
getNodecanvas(valuedata) {
radCtx = wx.createCanvasContext(‘radarCanvas‘, this(子组件中添加));
this.drawRadar(valuedata);
},
// 雷达图
drawRadar(valdata) {
// console.log(valdata)
// 调用
this.drawArcEdge(); // 画圆
this.drawLinePoint();
// 设置数据
this.drawRegion(valdata, ‘rgba(101, 163, 243, 1)‘);
// 设置文本数据
this.drawTextCans(valdata);
// 设置节点
this.drawCircle(valdata, ‘#267EF0‘);
radCtx.draw(true, this.saveCanvasImage);
},
// / 第一步:绘制5个圆,可以通过修改numSlot的数的大小,来确定绘制几个圆
drawArcEdge() {
// radCtx.strokeStyle = "#E0E2E9"
// radCtx.lineWidth = 1 //设置线宽
radCtx.setStrokeStyle(‘#E0E2E9‘);
radCtx.setLineWidth(1); // 设置线宽
for (let i = 0; i < numSlot; i++) {
// 计算半径
radCtx.beginPath();
const rdius = (mRadius / numSlot) * (i + 1); // 计算每个圆的半径
// 画6条线段
for (let j = 0; j < numSlot; j++) {
// 计算半径
radCtx.beginPath();
radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI); // 开始画圆
// radCtx.stroke()
}
radCtx.closePath();
radCtx.stroke();
}
},
// 绘制连接点
drawLinePoint() {
radCtx.setLineDash([5, 10], 2);
radCtx.beginPath();
for (let k = 0; k < numCount; k++) {
const x = mCenter + mRadius * Math.cos(mAngle * k);
const y = mCenter + mRadius * Math.sin(mAngle * k);
radCtx.moveTo(mCenter, mCenter);
radCtx.lineTo(x, y);
}
radCtx.stroke();
},
// 绘制数据区域(数据和填充颜色)
drawRegion(mData, color) {
radCtx.beginPath();
for (let m = 0; m < numCount; m++) {
const x = mCenter + (mRadius * Math.cos(mAngle * m)) * (mData[m][1] / 100);
const y = mCenter + (mRadius * Math.sin(mAngle * m)) * (mData[m][1] / 100);
radCtx.lineTo(x, y);
}
radCtx.closePath();
radCtx.fillStyle = color;
radCtx.fill();
},
// 绘制文字
drawTextCans(mData) {
// radCtx.fillStyle = "#9B9B9B"
radCtx.setFillStyle(‘#9B9B9B‘);
radCtx.font = ‘bold 15px cursive‘; // 设置字体
for (let n = 0; n < numCount; n++) {
const x = mCenter + mRadius * Math.cos(mAngle * n);
const y = mCenter + mRadius * Math.sin(mAngle * n);
// radCtx.fillText(mData[n][0], x, y);
// 通过不同的位置,调整文本的显示位置
if (mAngle * n >= 0 && mAngle * n <= Math.PI / 2) {
radCtx.fillText(mData[n][0], x + 5, y + 5);
} else if (mAngle * n > Math.PI / 2 && mAngle * n <= Math.PI) {
radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width - 7, y + 5);
} else if (mAngle * n > Math.PI && mAngle * n <= (Math.PI * 3) / 2) {
radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width - 5, y);
} else {
radCtx.fillText(mData[n][0], x + 7, y + 2);
}
}
},
// 画点
drawCircle(mData, color) {
const r = 3; // 设置节点小圆点的半径
for (let i = 0; i < numCount; i++) {
const x = mCenter + (mRadius * Math.cos(mAngle * i)) * (mData[i][1] / 100);
const 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();
}
},
注意1 最新版 只能在page 页面中画canvas 生效 在子组件中使用 要加this
注意2 生成图片的方法要加延时器 canvas画布是异步操作 重要 不然生成图有问题
注意3 canvas的画布和图片交替的时候 隐藏问题 利用定位 fixed absoulted 定位到显示区外面 不然不会根据画布生成图片
原文:https://www.cnblogs.com/taxun/p/15012027.html