小程序实现雷达图

根据自己需要的画布大小去设置更改,这里的需求雷达图区域较小。
由于雷达图的层级太高,且不受z-index控制,这里在绘制完成后导出成了图片。
1、wxml中

<view class='radarContainer'>
      <canvas wx:if="{{!radarImg}}" class='radarCanvasSelf' canvas-id='radarCanvas'></canvas>
      <image wx:else src="{{radarImg}}" style="width: 330rpx; height: 360rpx;" />
</view>

2、wxss中

.radarContainer{
  width:50%;
  height:400rpx;
  padding: 10rpx;
  box-sizing: border-box;
  display: flex;
  justify-content:center;
   align-items: center; 
  position: relative;
  
}
.radarCanvasSelf{
  width:330rpx;
  height:360rpx;
  margin: 0 auto;
  position: absolute;
}

3、js中

//这些数据并没有写在data中
var radCtx;//定义canvas
var numCount = 5;  //元素个数
var numSlot = 1;  //一条线上的总节点数
var mW = 165;  //Canvas的宽度
var mCenter = mW / 2; //中心点
var mAngle = Math.PI * 2 / numCount; //角度
var mRadius = mCenter - 45; //半径(减去的值用于给绘制的文本留空间)

page({
data:{
chanelArray1: [["沟通能力", 80], ["生存能力", 60], ["经济能力", 66], ["创造能力", 90], ["信息能力", 75]],
radarImg: '',
},
onLoad: function (options) {
//页面加载时获取指定的canvas,加上this,指在当前的自定义组件内获取id为radarCanvas的dom元素
  radCtx = wx.createCanvasContext("radarCanvas", this)
  radCtx.save()
  radCtx.setFillStyle('white')
  radCtx.fillRect(0, 0, 165, 180);//画出矩形白色背景
  radCtx.restore()
  //避免Android系统出现黑色背景
  },
}),
onReady: function () {
  this.drawRadar()
},
drawRadar: function () {
  var sourceData1 = this.data.chanelArray1
   wx.showLoading({
      title: '图形绘制中...',
    })
    // this.drawEdge() //画六边形,根据自己需要,可以是多边形或者圆形
    this.drawArcEdge() //画圆
    this.drawLinePoint() //绘制连接点
    this.drawRegion(sourceData1, '#FF6E13') //设置数据
    this.drawTextCans(sourceData1) //设置文本数据
    this.drawNumText(sourceData1)//设置文本数字数据
    // this.drawCircle(sourceData1, 'red') //设置节点
    //开始绘制
    setTimeout(() => {
      // radCtx.draw() //直接绘制
      radCtx.draw(false, setTimeout(() => { this.handleCanvarToImg() }, 500))
      //绘制完成后,将画布内容导出成指定大小的图片
    }, 1500)
  },

  // 绘制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()
    }
  },
  // 第一步:绘制圆,你可以通过修改numSlot的数的大小,来确定绘制几个圆
  drawArcEdge: function () {
    radCtx.setStrokeStyle("#FFD9C2")  //设置线的颜色
    radCtx.setLineWidth(2)  //设置线宽
    for (var i = 0; i < numSlot; i++) {  //需要几个圆就重复几次
      // //计算半径
      radCtx.beginPath()
      var rdius = mRadius / numSlot * (i + 1)  //计算每个圆的半径
      radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI) //开始画圆
      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.closePath();
    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("#999999")
    radCtx.setFontSize(10) //设置字体
    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 (n == 0) {
        radCtx.fillText(mData[n][0], x + 3, y + 10);
      } else if (n == 1) {
        radCtx.fillText(mData[n][0], x - 5, y + 30);
      } else if (n == 2) {
        radCtx.fillText(mData[n][0], x - 40, y + 25);
      } else if (n == 3) {
        radCtx.fillText(mData[n][0], x - 47, y + 5);
      } else if (n == 4) {
        radCtx.fillText(mData[n][0], x - 10, y - 10);
      }

    }
  },
  // 绘制数字
  drawNumText: function (mData) {
    radCtx.setFillStyle("#41B035")
    radCtx.setFontSize(10) //设置字体
    for (var n = 0; n < numCount; n++) {
      var x = mCenter + mRadius * Math.cos(mAngle * n);
      var y = mCenter + mRadius * Math.sin(mAngle * n);
      if (n == 0) {
        radCtx.fillText(mData[n][1], x + 17, y - 8);
      } else if (n == 1) {
        radCtx.fillText(mData[n][1], x + 10, y + 15);
      } else if (n == 2) {
        radCtx.fillText(mData[n][1], x - 26, y + 5);
      } else if (n == 3) {
        radCtx.fillText(mData[n][1], x - 30, y - 15);
      } else if (n == 4) {
        radCtx.fillText(mData[n][1], x + 5, y - 25);
      }

    }
  },
  //画点
  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();
    }
  },
 // 雷达图层级太高,转换为图片
  handleCanvarToImg() {
    var that = this
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 165,
      height: 180,
      destWidth: 495,
      destHeight: 540,
      fileType: 'jpg',
      quality: 1,
      canvasId: 'radarCanvas',
      success: function (res) {
        wx.hideLoading()
        console.log('res', res)
        that.setData({
          radarImg: res.tempFilePath,
        });
      },
      complete: function (err) {
        wx.hideLoading()
        console.log('err', err)
      }
    }, that);
  },
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值