商城系統(tǒng) 注冊(cè)

微信小程序?qū)崿F(xiàn)雷達(dá)圖的方式,小程序雷達(dá)圖怎么做

2018-05-21|HiShop
導(dǎo)讀:小程序雷達(dá)圖是財(cái)務(wù)分析報(bào)表的一種。即將一個(gè)公司的各項(xiàng)財(cái)務(wù)分析所得的數(shù)字或比率,就其比較重要的項(xiàng)目集中劃在一個(gè)圓形的圖表上,來表現(xiàn)一個(gè)公司各項(xiàng)財(cái)務(wù)比率的情況,使用者能一目了...



雷達(dá)圖(Radar Chart),又可稱為戴布拉圖、蜘蛛網(wǎng)圖(Spider Chart),是財(cái)務(wù)分析報(bào)表的一種。即將一個(gè)公司的各項(xiàng)財(cái)務(wù)分析所得的數(shù)字或比率,就其比較重要的項(xiàng)目集中劃在一個(gè)圓形的圖表上,來表現(xiàn)一個(gè)公司各項(xiàng)財(cái)務(wù)比率的情況,使用者能一目了然的了解公司各項(xiàng)財(cái)務(wù)指標(biāo)的變動(dòng)情形及其好壞趨向。

如果你想找到了解H5中怎么制作,可以看一下HTML5 Canvas制作雷達(dá)圖實(shí)戰(zhàn),我也是參考這篇文章,做了小程序的雷達(dá)圖,并做了一點(diǎn)延伸...


先來看看效果圖

微信小程序?qū)崿F(xiàn)雷達(dá)圖的方式,小程序雷達(dá)圖怎么做


開始上菜:

//.wxml ,接下來的操作將在這個(gè)Canvas上面繪制

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

 

//.wxss
.radarContainer{
   background-color: black;
   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
初始化數(shù)據(jù):(我沒寫在data中)
var numCount = 6;  //元素個(gè)數(shù)
var numSlot = 5;  //一條線上的總節(jié)點(diǎn)數(shù)
var mW = 400;  //Canvas的寬度
var mCenter = mW / 2; //中心點(diǎn)
var mAngle = Math.PI * 2 / numCount; //角度
var mRadius = mCenter - 60; //半徑(減去的值用于給繪制的文本留空間)
//獲取指定的Canvas
var radCtx = wx.createCanvasContext("radarCanvas")

 

//.js  模擬對(duì)戰(zhàn)兩方的數(shù)據(jù)
  data: {
    chanelArray1:[["戰(zhàn)績",88],["生存",30],["團(tuán)戰(zhàn)",66],["發(fā)育",90],["輸出",95],["推進(jìn)",88]],
    chanelArray2: [["戰(zhàn)績", 24], ["生存", 60], ["團(tuán)戰(zhàn)", 88], ["發(fā)育", 49], ["輸出", 46], ["推進(jìn)", 92]]
  },


基礎(chǔ)數(shù)據(jù)準(zhǔn)備完成,開始畫圖

// 第一步:繪制6條邊
 drawEdge: function(){
   radCtx.setStrokeStyle("white")
   radCtx.setLineWidth(2)  //設(shè)置線寬
 for (var i = 0; i < numSlot; i++) {
 //計(jì)算半徑
     radCtx.beginPath()
 var rdius = mRadius / numSlot * (i + 1)
 //畫6條線段
 for (var j = 0; j < numCount; j++) {
 //坐標(biāo)
 var x = mCenter + rdius * Math.cos(mAngle * j);
 var y = mCenter + rdius * Math.sin(mAngle * j);
       radCtx.lineTo(x, y);
     }
     radCtx.closePath()
     radCtx.stroke()
   } 
 },


 

// 第二步:繪制連接點(diǎn)
  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();
  },


 

 

//第三步:繪制文字(文字位置可能需要微調(diào))
    drawTextCans: function (mData){

      radCtx.setFillStyle("white")
      radCtx.font = 'bold 17px cursive' //設(shè)置字體
 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);
 //通過不同的位置,調(diào)整文本的顯示位置
 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);
        }

      }
    },


 

//繪制紅色數(shù)據(jù)區(qū)域(數(shù)據(jù)和填充顏色)
  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();
    },


 

//畫點(diǎn)
    drawCircle: function(mData,color){
 var r = 3; //設(shè)置節(jié)點(diǎn)小圓點(diǎn)的半徑
 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();
        }
    }

 


重復(fù)四五步的方法添加另一方的雷達(dá)圖

 

.js文件完整內(nèi)容如下



var numCount = 6;
var numSlot = 5;
var mW = 400;
var mH = 400;
var mCenter = mW / 2; //中心點(diǎn)
var mAngle = Math.PI * 2 / numCount; //角度
var mRadius = mCenter - 60; //半徑(減去的值用于給繪制的文本留空間)
//獲取Canvas
var radCtx = wx.createCanvasContext("radarCanvas")


Page({

 /**
   * 頁面的初始數(shù)據(jù)
   */
  data: {
 stepText:5,
 chanelArray1:[["戰(zhàn)績",88],["生存",30],["團(tuán)戰(zhàn)",66],["發(fā)育",90],["輸出",95],["推進(jìn)",88]],
 chanelArray2: [["戰(zhàn)績", 24], ["生存", 60], ["團(tuán)戰(zhàn)", 88], ["發(fā)育", 49], ["輸出", 46], ["推進(jìn)", 92]]
  },

 /**
   * 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
   */
  onReady: function () {

 //雷達(dá)圖
 this.drawRadar()

  },
 // 雷達(dá)圖
  drawRadar:function(){
 var sourceData1 = this.data.chanelArray1
 var sourceData2 = this.data.chanelArray2

 //調(diào)用
 this.drawEdge()
 this.drawLinePoint()
 //設(shè)置數(shù)據(jù)
 this.drawRegion(sourceData1,'rgba(255, 0, 0, 0.5)') //第一個(gè)人的
 this.drawRegion(sourceData2, 'rgba(255, 200, 0, 0.5)') //第二個(gè)人
 //設(shè)置文本數(shù)據(jù)
 this.drawTextCans(sourceData1)
 //設(shè)置節(jié)點(diǎn)
 this.drawCircle(sourceData1,'red')
 this.drawCircle(sourceData2,'yellow')
 //開始繪制
    radCtx.draw()
  },
 // 繪制6條邊
  drawEdge: function(){
    radCtx.setStrokeStyle("white")
    radCtx.setLineWidth(2)  //設(shè)置線寬
 for (var i = 0; i < numSlot; i++) {
 //計(jì)算半徑
      radCtx.beginPath()
 var rdius = mRadius / numSlot * (i + 1)
 //畫6條線段
 for (var j = 0; j < numCount; j++) {
 //坐標(biāo)
 var x = mCenter + rdius * Math.cos(mAngle * j);
 var y = mCenter + rdius * Math.sin(mAngle * j);
        radCtx.lineTo(x, y);
      }
      radCtx.closePath()
      radCtx.stroke()
    } 
  },
 // 繪制連接點(diǎn)
  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();
  },
 //繪制數(shù)據(jù)區(qū)域(數(shù)據(jù)和填充顏色)
  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' //設(shè)置字體
 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);
 //通過不同的位置,調(diào)整文本的顯示位置
 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);
        }

      }
    },
 //畫點(diǎn)
    drawCircle: function(mData,color){
 var r = 3; //設(shè)置節(jié)點(diǎn)小圓點(diǎn)的半徑
 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();
        }

      }

})

 

電話咨詢 預(yù)約演示 0元開店