小程序canvas画雷达图

首先, 我们先看一下效果图

雷达图(Radar Chart),又可称为戴布拉图、蜘蛛网图(Spider Chart),是财务分析报表的一种。即将一个公司的各项财务分析所得的数字或比率,就其比较重要的项目集中划在一个圆形的图表上,来表现一个公司各项财务比率的情况,使用者能一目了然的了解公司各项财务指标的变动情形及其好坏趋向。

这边文章参考了https://www.jianshu.com/p/598b55aae7b7的博客,我拿到以后稍加修改了一些地方,变成了我想要的雷达图

小程序canvas画雷达图_第1张图片小程序canvas画雷达图_第2张图片

类似这样的雷达图,用html5写和小程序写也是有一些不一样的

那么开始上菜

wxml



wxss

.radarContainer{
     background: linear-gradient(#86d0d0, #81e1b4);
   width:100%;
   height:420px;
   display: flex;
   justify-content:center;
    align-items: center; 
   position: relative;
   
}
.radarCanvas{
   width:400px;
   height:400px;
   margin: 0 auto;
   position: absolute;
}

js 准备基础数据,写在全局

var numCount = 6;  //元素个数(6条边)
var numSlot = 5;  //一条线上的总节点数
var mW = 400;  //Canvas的宽度
var mCenter = mW / 2; //中心点
var mAngle = Math.PI * 2 / numCount; //角度
var mRadius = mCenter - 60; //半径(减去的值用于给绘制的文本留空间)
//获取指定的Canvas
var radCtx = wx.createCanvasContext("radarCanvas")
data: {
    chanelArray1: [["战绩", 50], ["生存", 10], ["团战", 56], ["发育", 90], ["输出", 95], ["推进", 50]],
    chanelArray2: [["战绩", 24], ["生存", 60], ["团战", 88], ["发育", 49], ["输出", 46], ["推进", 92]],
    chanelArray3: [["战绩", 88], ["生存", 40], ["团战", 82], ["发育", 41], ["输出", 46], ["推进", 92]]
  },

基础数据准备完毕

开始画图,先画一个六边形

 // 绘制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()
    }
  },

小程序canvas画雷达图_第3张图片

 

画圆

  // / 第一步:绘制6个圆,可以通过修改numSlot的数的大小,来确定绘制几个圆
  drawArcEdge: 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 < numSlot; j++) {
        // //计算半径
        radCtx.beginPath()
        var rdius = mRadius / numSlot * (i + 1)  //计算每个圆的半径
        radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI) //开始画圆
        // radCtx.stroke()
      }
      radCtx.closePath()
      radCtx.stroke()
    }
  },

小程序canvas画雷达图_第4张图片

 接下来的方法不变,所以我上js全部完整代码

var numCount = 6;  //元素个数
var numSlot = 5;  //一条线上的总节点数
var mW = 400;  //Canvas的宽度
var mCenter = mW / 2; //中心点
var mAngle = Math.PI * 2 / numCount; //角度
var mRadius = mCenter - 60; //半径(减去的值用于给绘制的文本留空间)
//获取指定的Canvas
var radCtx = wx.createCanvasContext("radarCanvas")
Page({

  /**
   * 页面的初始数据
   */
  data: {
    chanelArray1: [["战绩", 50], ["生存", 10], ["团战", 56], ["发育", 90], ["输出", 95], ["推进", 50]],
    chanelArray2: [["战绩", 24], ["生存", 60], ["团战", 88], ["发育", 49], ["输出", 46], ["推进", 92]],
    chanelArray3: [["战绩", 88], ["生存", 40], ["团战", 82], ["发育", 41], ["输出", 46], ["推进", 92]]
  },
  

  // 雷达图
  drawRadar: function () {
    var sourceData1 = this.data.chanelArray1
    var sourceData2 = this.data.chanelArray2
    var sourceData3 = this.data.chanelArray3
    //调用
    this.drawEdge() //画六边形
    // this.drawArcEdge() //画圆
    this.drawLinePoint()
    //设置数据
    this.drawRegion(sourceData1, 'rgba(255, 0, 0, 0.5)') //第一个人的
    this.drawRegion(sourceData2, 'rgba(255, 200, 0, 0.5)') //第二个人
    this.drawRegion(sourceData3, 'rgba(122, 202, 254, 0.5)') //第三个人
    //设置文本数据
    this.drawTextCans(sourceData1)
    //设置节点
    this.drawCircle(sourceData1, 'red')
    // this.drawCircle(sourceData2, 'yellow')
    //开始绘制
    radCtx.draw()
  },
  // 绘制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()
    }
  },
    // / 第一步:绘制6个圆,可以通过修改numSlot的数的大小,来确定绘制几个圆
  drawArcEdge: 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 < numSlot; j++) {
        // //计算半径
        radCtx.beginPath()
        var rdius = mRadius / numSlot * (i + 1)  //计算每个圆的半径
        radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI) //开始画圆
        // radCtx.stroke()
      }
      radCtx.closePath()
      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.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("white")
    radCtx.font = 'bold 17px cursive'  //设置字体
    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 (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: 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();
    }

  },


 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //雷达图
    this.drawRadar()
  },
  

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    //雷达图
  
    // this.drawEdge();
    // this.drawLinePoint();
    // this.drawTextCans();
    // this.drawCircle();
  },

 

#ending#

你可能感兴趣的:(小程序)