小程序canvas画雷达图

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

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

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

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

那么开始上菜

wxml

<view class='radarContainer'>
<canvas class='radarCanvas' canvas-id='radarCanvas'></canvas>
</view>

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

 

画圆

  // / 第一步:绘制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()
    }
  },

 接下来的方法不变,所以我上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#

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值