微信小程式(JAVAScript)實現餅圖

靈神翁發表於2020-09-24

大家好,我是夢辛工作室的靈,近期在製作資料統計類的軟體,所以會用到許多的圖形和圖表,下面我就來說明下餅圖的繪製方法,依舊老規矩,先上效果圖=-=:
在這裡插入圖片描述
看上去還是可以的吧,下面直接來看程式碼,我為了提供程式碼的閱讀性寫了不少變數,不然不好閱讀啊:


function drawCircelChart(that){

  let width = app.globalData.width; //手機寬度
  let height = app.globalData.height;	//手機高度

  let data = [	//繪製資料
      {
        name:"1號",
        pre:10, 
      },
      {
        name:"2號",
        pre:5, 
      },
      {
        name:"3號",
        pre:20, 
      },
      {
        name:"4號",
        pre:30, 
      },
      {
        name:"5號",
        pre:10, 
      },
      {
        name:"6號",
        pre:25, 
      },
    ];

  let rectWidth = width * 0.9;	//定義畫布寬度
  let rectHeight = height * 0.26;	//定義畫布高度

  let circlePath = width * 0.2; //定義圓的半徑
  let ringWidth = 20;	//定義 外環的寬度

  let centerPoint = { //計算中心中標(圓點)
    x:rectWidth / 2,
    y:rectHeight / 2
  }

  let ctx = wx.createCanvasContext('cchart');

  ctx.translate(0,40);	//畫布下移動

  ctx.setFontSize(12);	//字型大小

  let colorArray = ["#FFC655","#FADD15","#FD7170","#B391DD","#00A0F8","#5DC97D","#50D2C2"
,"#FADB15","#AABD15","#FCDD55","#CB5D15"];  //顏色陣列

  let preEndAngel = 0;	//上一個資料的結束時的角度

  for(var x in data){
	//處理資料
	
	//計算當前資料的開始角度和結束角度
    let roateAngel = {
      start:preEndAngel,
      end:preEndAngel + data[x].pre / 100 * 2 * Math.PI,
    } 
 	
 	//繪製圓弧
    ctx.beginPath();
    ctx.moveTo(centerPoint.x,centerPoint.y);
    ctx.arc(centerPoint.x, centerPoint.y, circlePath, roateAngel.start,roateAngel.end);
    ctx.setFillStyle(colorArray[x] || "#000");
    ctx.fill(); 

    preEndAngel = roateAngel.end; 

    ctx.setFillStyle("#000");
	//下面就有點點難度了,其實只要你三角函式學 的號也沒撒,
	//下面程式碼就是繪製每個模組的位置
	//需要分四種型別,即四象限,不知道大家還記得否
	//然後就是已知角度,計算當前圓弧中心點和圓的交點座標

    let halfAngel = (roateAngel.end - roateAngel.start) / 2;

    let centerAngel = roateAngel.start + halfAngel;  

    let offset = {
      x:10,
      y:10
    }

    let textPoint = {
      x:0,
      y:0
    }

    if(centerAngel <= Math.PI / 2){
      textPoint.x = centerPoint.x + circlePath * Math.cos(centerAngel) + offset.x; 
      textPoint.y = centerPoint.y + circlePath * Math.sin(centerAngel) + offset.y; 

      ctx.setTextAlign("left");

      if(centerAngel == Math.PI / 2){
        ctx.setTextAlign("center");
        textPoint.y = centerPoint.y + circlePath * Math.sin(centerAngel) + offset.y * 2; 
      }

      ctx.setTextBaseline("top");
      
      ctx.fillText(data[x].pre + "%", textPoint.x,textPoint.y);

      ctx.setTextBaseline("bottom");

      ctx.fillText(data[x].name,textPoint.x,textPoint.y);

    } else if(centerAngel < Math.PI){
      textPoint.x = centerPoint.x - circlePath * Math.cos(Math.PI - centerAngel) - offset.x  * data[x].name.length / 2; 
      textPoint.y = centerPoint.y + circlePath * Math.sin(Math.PI - centerAngel) + offset.y  * data[x].name.length / 2; 

      ctx.setTextAlign("center"); 

      ctx.setTextBaseline("top");
      
      ctx.fillText(data[x].pre + "%",textPoint.x,textPoint.y);

      ctx.setTextBaseline("bottom");

      ctx.fillText( data[x].name ,textPoint.x,textPoint.y);

    } else if(centerAngel < Math.PI * 3 / 2){
      textPoint.x = centerPoint.x - circlePath * Math.cos(centerAngel - Math.PI) - offset.x * data[x].name.length / 2;
      textPoint.y = centerPoint.y - circlePath * Math.sin(centerAngel - Math.PI) - offset.y * data[x].name.length / 2;

      ctx.setTextAlign("right");

      //ctx.setTextBaseline("middle");

      ctx.setTextBaseline("top");
      
      ctx.fillText( data[x].pre + "%",textPoint.x,textPoint.y);

      ctx.setTextBaseline("bottom");

      ctx.fillText(data[x].name ,textPoint.x,textPoint.y);

    } else {
      textPoint.x = centerPoint.x + circlePath * Math.cos(Math.PI * 2 - centerAngel) + offset.x; 
      textPoint.y = centerPoint.y - circlePath * Math.sin(Math.PI * 2 - centerAngel) - offset.y;  

      ctx.setTextAlign("left");

      ctx.setTextBaseline("top");
      
      ctx.fillText( data[x].pre + "%",textPoint.x,textPoint.y);

      ctx.setTextBaseline("bottom");

      ctx.fillText(data[x].name ,textPoint.x,textPoint.y);
    }
   
   
 
  }
	
//最後再在中心繪製一個白圓,這樣就是上面的效果啦
  ctx.beginPath();
  ctx.setFillStyle("#FFFFFF");
  ctx.moveTo(centerPoint.x,centerPoint.y);
  ctx.arc(centerPoint.x, centerPoint.y, circlePath - ringWidth,0,2 * Math.PI);
  ctx.fill();

  ctx.draw();

}

相關文章