效果圖
//wxml
<view class='radar-container'>
<canvas class='radarCanvas' canvas-id='radarCanvas' style='width:360px'></canvas>
</view>
//wcss
.radar-container {
width: 100%;
height: 260px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.radarCanvas {
height: 240px;
margin: 0 auto;
position: absolute;
}
js數據初始化 (沒寫在data中)
let radCtx = wx.createCanvasContext("radarCanvas");//雷達圖
let radar = {
mW: 360,//canvas寬
mH: 240,//canvas高
mCenter: 180, //中心點
hCenter: 120, //中心點
mAngle: Math.PI * 2 / 6,//角度
mRadius: 90, //半徑(減去的值用於給繪製的文本留空間)
radarData: [["社會型(S)", 58], ["藝術型(A)", 30], ["研究型(I)", 66], ["現實型(R)", 70], ["常規型(C)", 65], ["企業型(E)", 88]],//數據
};
(1)繪製6條邊
// 繪製6條邊
drawEdge() {
radCtx.setStrokeStyle("#eee");
for (let i = 0; i < 3; i++) {
//計算半徑
radCtx.beginPath();
let rdius = radar.mRadius / 3 * (i + 1) - 0;
//畫6條線段
for (let j = 0; j < 6; j++) {
//座標
let x = radar.mCenter + rdius * Math.sin(radar.mAngle * j);
let y = radar.hCenter + rdius * Math.cos(radar.mAngle * j);
radCtx.lineTo(x, y);
}
radCtx.closePath()
radCtx.stroke()
}
},
(2)繪製連接點
// 繪製連接點
drawLinePoint() {
for (let k = 0; k < 6; k++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * k);
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * k);
radCtx.moveTo(radar.mCenter, radar.hCenter);
radCtx.lineTo(x, y);
}
radCtx.stroke();
},
(3)繪製數據區域(數據和填充顏色)
drawRegion(mData, color) {
radCtx.beginPath();
for (let m = 0; m < 6; m++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * m) * mData[m][1] / 100;
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * m) * mData[m][1] / 100;
radCtx.lineTo(x, y);
}
radCtx.closePath();
radCtx.setFillStyle(color)
radCtx.fill();
},
(4)繪製文字
//繪製文字
drawTextCans(mData) {
radCtx.setFillStyle("#555")
radCtx.setFontSize(12) //設置字體
for (let n = 0; n < 6; n++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * n);
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * n);
//通過不同的位置,調整文本的顯示位置
if (n == 0) {
radCtx.fillText(mData[0][0], x - 23, y + 20);
} else if (n == 1) {
radCtx.fillText(mData[1][0], x + 10, y + 5);
} else if (n == 2) {
radCtx.fillText(mData[2][0], x + 10, y + 5);
} else if (n == 3) {
radCtx.fillText(mData[3][0], x - 23, y - 10);
} else if (n == 4) {
radCtx.fillText(mData[4][0], x - 55, y + 5);
} else if (n == 5) {
radCtx.fillText(mData[5][0], x - 55, y + 5);
}
}
},
(5)畫點
//畫點
drawCircle(mData, color) {
const r = 5; //設置節點小圓點的半徑
for (let i = 0; i < 6; i++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * i) * mData[i][1] / 100;
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * i) * mData[i][1] / 100;
radCtx.beginPath();
radCtx.arc(x, y, r, 0, Math.PI * 2);
radCtx.fillStyle = color;
radCtx.fill();
}
}
完整代碼
let radCtx = wx.createCanvasContext("radarCanvas");//雷達圖
let radar = {
mW: 360,//
mH: 240,
mCenter: 180, //中心點
hCenter: 120, //中心點
mAngle: Math.PI * 2 / 6,
mRadius: 90, //半徑(減去的值用於給繪製的文本留空間)
radarData: [["社會型(S)", 58], ["藝術型(A)", 30], ["研究型(I)", 66], ["現實型(R)", 70], ["常規型(C)", 65], ["企業型(E)", 88]],
};
Page({
onReady() {
this.drawRadar();//雷達圖
},
// ***************************雷達圖開始**********************************
// 雷達圖
drawRadar() {
const radarData = radar.radarData;
this.drawEdge() //畫六邊形
this.drawLinePoint()
this.drawRegion(radarData, 'rgba(51, 136, 255, 0.4)') //設置數據
this.drawTextCans(radarData)//設置文本數據
this.drawCircle(radarData, '#3388FF')//設置節點
radCtx.draw()//開始繪製
},
// 繪製6條邊
drawEdge() {
radCtx.setStrokeStyle("#eee");
for (let i = 0; i < 3; i++) {
//計算半徑
radCtx.beginPath();
let rdius = radar.mRadius / 3 * (i + 1) - 0;
//畫6條線段
for (let j = 0; j < 6; j++) {
//座標
let x = radar.mCenter + rdius * Math.sin(radar.mAngle * j);
let y = radar.hCenter + rdius * Math.cos(radar.mAngle * j);
radCtx.lineTo(x, y);
}
radCtx.closePath()
radCtx.stroke()
}
},
// 繪製連接點
drawLinePoint() {
for (let k = 0; k < 6; k++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * k);
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * k);
radCtx.moveTo(radar.mCenter, radar.hCenter);
radCtx.lineTo(x, y);
}
radCtx.stroke();
},
//繪製數據區域(數據和填充顏色)
drawRegion(mData, color) {
radCtx.beginPath();
for (let m = 0; m < 6; m++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * m) * mData[m][1] / 100;
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * m) * mData[m][1] / 100;
radCtx.lineTo(x, y);
}
radCtx.closePath();
radCtx.setFillStyle(color)
radCtx.fill();
},
//繪製文字
drawTextCans(mData) {
radCtx.setFillStyle("#555")
radCtx.setFontSize(12) //設置字體
for (let n = 0; n < 6; n++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * n);
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * n);
//通過不同的位置,調整文本的顯示位置
if (n == 0) {
radCtx.fillText(mData[0][0], x - 23, y + 20);
} else if (n == 1) {
radCtx.fillText(mData[1][0], x + 10, y + 5);
} else if (n == 2) {
radCtx.fillText(mData[2][0], x + 10, y + 5);
} else if (n == 3) {
radCtx.fillText(mData[3][0], x - 23, y - 10);
} else if (n == 4) {
radCtx.fillText(mData[4][0], x - 55, y + 5);
} else if (n == 5) {
radCtx.fillText(mData[5][0], x - 55, y + 5);
}
}
},
//畫點
drawCircle(mData, color) {
const r = 5; //設置節點小圓點的半徑
for (let i = 0; i < 6; i++) {
let x = radar.mCenter + radar.mRadius * Math.sin(radar.mAngle * i) * mData[i][1] / 100;
let y = radar.hCenter + radar.mRadius * Math.cos(radar.mAngle * i) * mData[i][1] / 100;
radCtx.beginPath();
radCtx.arc(x, y, r, 0, Math.PI * 2);
radCtx.fillStyle = color;
radCtx.fill();
}
}
// ****************************雷達圖結束**********************************
})