uniapp 画圆形或多边形雷达图

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

<script>
    var numCount = 3;  //元素个数
    var numSlot = 3;  //一条线上的总节点数
    var mW = 400;  //Canvas的宽度
    var mCenter = mW / 2; //中心点
    var mAngle = Math.PI * 2 / numCount; //角度
    console.log(mAngle)
    var mRadius = mCenter - 90; //半径(减去的值用于给绘制的文本留空间)
    //获取指定的Canvas
    let radCtx = uni.createCanvasContext('radarCanvas',this)
    // var radCtx = wx.createCanvasContext("radarCanvas")
    export default {
        data() {
            return {
                chanelArray1: [["亲和力", 71], ["魅力值", 98], ["年龄感", 82]],
            }
        },
        onLoad() {
            //雷达图
            // this.drawRadar()
        },
        onReady() {
            //雷达图
            radCtx = uni.createCanvasContext('radarCanvas',this)
            this.drawRadar()
        },
        methods: {
            // 雷达图
              drawRadar: function () {
                // radCtx.translate(mCenter+mCenter/2,mCenter/10);
                // radCtx.rotate(30*Math.PI/80);
                var sourceData1 = this.chanelArray1
                //调用
                // this.drawEdge() //画六边形
                this.drawArcEdge() //画圆
                this.drawLinePoint()
                
                // radCtx.rotate(-90);
                //设置数据
                this.drawRegion(sourceData1, '#ff81ae') //第一个人的
                //设置文本数据
                this.drawTextCans(sourceData1)
                //设置节点
                this.drawCircle(sourceData1, 'red')
                
                // this.drawCircle(sourceData2, 'yellow')
                //开始绘制
                setTimeout(function() { //必须延迟执行 不然H5不显示
                    radCtx.draw() //必须加上  uniapp 没这儿玩意儿 显示不出来不比原生  不加可以显示
                }, 200)
                // radCtx.draw()
              },
              // 绘制6条边
              drawEdge: function () {
                //将x轴旋转至竖直向上
                   // 
                   
                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("#f9a7bd")
                
                numSlot = 4
                for (var i = numSlot; i > 0; i--) {
                    if(i == 4){
                        var color = "#FFFFFF";
                    }else if(i == 3){
                        var color = "#ffebf2";
                    }else if(i == 2){
                        var color = "#ffd9e6";
                    }else if(i == 1){
                        var color = "#ffc9dc";
                    }
                  //计算半径
                  radCtx.beginPath()
                  
                  // var rdius = mRadius / numSlot * (i + 1)
                  //画6条线段
                  // for (var j = 0; j < numSlot; j++) {
                    // //计算半径
                    radCtx.beginPath()
                    var rdius = mRadius / numSlot * (i)  //计算每个圆的半径
                    // radCtx.fillStyle="#0000ff";
                    radCtx.arc(mCenter, mCenter, rdius, 0, 2 * Math.PI) //开始画圆
                    radCtx.fillStyle = color;
                    radCtx.fill();
                    radCtx.stroke()
                  // }
                  radCtx.closePath()
                  radCtx.stroke()
                }
              },
             
              // 绘制连接点
              drawLinePoint: function () {
                radCtx.beginPath();
                for (var k = 1; k <= 3; k++) {
                  
                  var x = mCenter + mRadius * Math.cos(mAngle * k + Math.PI /6);
                  var y = mCenter + mRadius * Math.sin(mAngle * k + Math.PI /6);
                  console.log(mCenter)
                  console.log(x,y)
                  // ctx.lineTo(0.5 * w + 0.3 * w * Math.sin(angle), 0.5 * w + 0.35 * w * Math.cos(angle))
                // var    x =mCenter + 0.3 * mCenter * Math.sin(angle);
                // var    y =mCenter + 0.35 * mCenter * Math.cos(angle);
                  radCtx.moveTo(mCenter, mCenter);
                  radCtx.lineTo(x, y);
                }
                radCtx.stroke();
              },
              //绘制数据区域(数据和填充颜色)
              drawRegion: function (mData, color) {
                 
                radCtx.beginPath();
                radCtx.setLineWidth(1)  //设置线宽
                radCtx.setStrokeStyle('rgb(255,58,128)')
                radCtx.setFillStyle('rgba(255,58,128,0.4)')
                radCtx.shadowBlur = parseInt(mCenter * 0.01)
                radCtx.shadowColor = "rgba(255,58,128,0.5)"
                for (var m = 0; m < numCount; m++) {
                  var x = mCenter + mRadius * Math.cos(mAngle * m + Math.PI /6) * mData[m][1] / 100;
                  var y = mCenter + mRadius * Math.sin(mAngle * m + Math.PI /6) * mData[m][1] / 100;
             
                  radCtx.lineTo(x, y);
                }
                radCtx.closePath();
             //    radCtx.setFillStyle(color)
                // radCtx.setStrokeStyle("#ff3a80")
                // radCtx.setLineWidth(1)  //设置线宽
               // radCtx.closePath()
               radCtx.fill()
               radCtx.stroke()
              },
             
              // //绘制文字
              drawTextCans: function (mData) {
                
                radCtx.setFillStyle("#1c1c1c")
                radCtx.font = 'bolder 14px cursive'  //设置字体
                for (var n = 0; n < numCount; n++) {
                  var x = mCenter + (mRadius+5) * Math.cos(mAngle * n + Math.PI /6);
                  var y = mCenter + (mRadius+5) * Math.sin(mAngle * n + Math.PI /6);
                  // radCtx.fillText(mData[n][0], x, y);
                  //通过不同的位置,调整文本的显示位置
                  radCtx.setFillStyle('rgb(51,51,51)')
                  if (mAngle * n >= 0 && mAngle * n <= Math.PI / 2) {
                    radCtx.fillText(mData[n][0], x - 2, y + 28);
                  } else if (mAngle * n > Math.PI / 2 && mAngle * n <= Math.PI) {
                    radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width + 3, y + 23);
                  } else if (mAngle * n > Math.PI && mAngle * n <= Math.PI * 3 / 2) {
                    radCtx.fillText(mData[n][0], x - radCtx.measureText(mData[n][0]).width + 15, y-3);
                  } else {
                    radCtx.fillText(mData[n][0], x + 7, y + 2);
                  }
                  
                  radCtx.setFillStyle('rgb(255,58,128)')
                  var x = mCenter + (mRadius+10) * Math.cos(mAngle * n + Math.PI /6);
                  var y = mCenter + (mRadius+30) * Math.sin(mAngle * n + Math.PI /6);
                  // radCtx.fillText(mData[n][0], x, y);
                  //通过不同的位置,调整文本的显示位置
                  if (mAngle * n >= 0 && mAngle * n <= Math.PI / 2) {
                    radCtx.fillText(mData[n][1], x , y );
                  } else if (mAngle * n > Math.PI / 2 && mAngle * n <= Math.PI) {
                    radCtx.fillText(mData[n][1], x - radCtx.measureText(mData[n][0]).width + 14, y - 5);
                  } else if (mAngle * n > Math.PI && mAngle * n <= Math.PI * 3 / 2) {
                    radCtx.fillText(mData[n][1], x - radCtx.measureText(mData[n][0]).width + 20, y + 6);
                  } else {
                    radCtx.fillText(mData[n][1], 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 + Math.PI /6) * mData[i][1] / 100;
                  var y = mCenter + mRadius * Math.sin(mAngle * i + Math.PI /6) * mData[i][1] / 100;
                 radCtx.setStrokeStyle("rgb(255,255,255)")
                 radCtx.setLineWidth(1)  //设置线宽
                  radCtx.beginPath();
                  radCtx.arc(x, y, r, 0, Math.PI * 2);
                  //  radCtx.setLineWidth(1)
                  // radCtx.setStrokeStyle('rgb(255,255,255)')
                  radCtx.setFillStyle('rgb(255,58,128)')
                  // radCtx.fillStyle = color;
                  radCtx.fill();
                  // radCtx.fill()
                  radCtx.stroke()
                }
             
              },
        }
    }
</script>

<style>
    .radarContainer{
         background: linear-gradient(#86d0d0, #81e1b4);
       width:750upx;
       height:750upx;
       display: flex;
       justify-content:center;
        align-items: center; 
       position: relative;
       
    }
    .radarCanvas{
       width:400px;
       height:400px;
       /* margin: 0 auto;
       position: absolute; */
    }
</style>

注意:为了兼容宽度,可以使用this.width = uni.upx2px(690),690为690upx的宽度

原文地址:https://www.pianshen.com/article/312557038/

 

posted @ 2021-05-10 21:54  张志健  阅读(2955)  评论(0编辑  收藏  举报