微信小程序-canvas雷達圖

效果圖

在這裏插入圖片描述

//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();
    }
  }
  // ****************************雷達圖結束**********************************
})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章