中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

canvas如何繪制餅圖

發布時間:2020-12-02 10:59:28 來源:億速云 閱讀:202 作者:小新 欄目:web開發

小編給大家分享一下canvas如何繪制餅圖,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

一. 任務說明

使用原生canvasAPI繪制餅圖(南丁格爾玫瑰)。(截圖以及數據來自于百度Echarts官方示例庫【查看示例鏈接】)。

canvas如何繪制餅圖

二. 重點提示

南丁格爾玫瑰圖的畫法有很多種,Echarts中提供的以半徑或面積兩種不同模式,本文中以面積比例畫法為例,繪制算法如下:

  1. 確定每個扇區的角度。由于所有扇區的角度加在一起為2π ,我們先按照數據比例來計算角度:

canvas如何繪制餅圖

  1. 每個扇區面積與總面積之間的比例即為數值的比,將給定參數數組options.radius中的最大和最小數值作為數值最大的一塊扇形的繪圖數據,代入如下公式即可求得總面積S

canvas如何繪制餅圖

  1. 再利用上述公式分別計算出每個扇形對應的外圓半徑,在canvas中繪制路徑并填充即可。

三. 示例代碼

南丁格爾玫瑰圖繪制示例代碼:

//繪制餅圖
drawPieChart(options);
    
/**
 * 繪制餅圖
 * @param  {[type]} options [description]
 * @return {[type]}         [description]
 */
function drawPieChart(options) {
   //記錄最大數值以反求面積總和
   options.maxValue = 0;
   //求數據集總和以在后續計算每個扇形的角度比例
   options.totalNum = options.data.reduce((pre,cur)=>{
     if (cur.value > options.maxValue) {
         options.maxValue = cur.value;
     }
     return pre+cur.value;
   },0);
    /*以最大值對應最大半徑來計算面積總和,并覆蓋原值
    *使得最大的一塊扇形外圓半徑為options.radius[0]
    *內圓半徑為options.radius[1]
    */
    let Rmin = options.radius[0];
    let Rmax = options.radius[1];
    let r = Math.sqrt((Rmax*Rmax - Rmin*Rmin)*options.totalNum / options.maxValue + Rmin*Rmin);
    options.radius[1] = r;
    //移動坐標系原點至繪圖中心
   let paintingCenter={
     x:parseInt(options.center[0],10)/100 * (options.chartZone[2] - options.chartZone[0]) + options.chartZone[0],
     y:parseInt(options.center[1],10)/100 * (options.chartZone[3] - options.chartZone[1]) + options.chartZone[1]
   }
   context.translate(paintingCenter.x, paintingCenter.y);
    //繪制每個扇形,過程中累加旋轉角度
   let allAngle = options.data.reduce((prev,cur,index)=>{
       context.fillStyle = options.colorPool[index]
       let angle = calcPaintingData(cur,options);
       return prev + angle;
   },0);
   //繪制中空白色圓
   context.beginPath();
   context.fillStyle = 'white';
   context.arc(0,0,options.radius[0],0,2*Math.PI,false);
   context.fill();
}

/**
 * 計算每個扇形所需要的繪圖參數
 */
function calcPaintingData(data,options) {
    let scale = data.value / options.totalNum; 
    let angle = scale * 2 * Math.PI;
    let Rmin = options.radius[0];
    let Rmax = options.radius[1];
    let r = Math.sqrt(scale * (Rmax*Rmax - Rmin*Rmin) + Rmin*Rmin);
    data.r = r;
    //繪制扇形
    paintFan({
        r:r,
        angle:angle,
        data:data,
        options:options
    });
    return angle;//將角度值返回給外層函數以供累加
}

//繪制扇形
function paintFan(opt) {
    context.beginPath();
    context.lineTo(opt.r,0);
    context.arc(0,0,opt.r,0,opt.angle,false);
    context.lineTo(0,0);
    context.closePath();
    context.fill();
    context.rotate(opt.angle);
}

瀏覽器中可查看效果:

canvas如何繪制餅圖

四. hover高亮的實現思路

  1. 繪圖過程中,將每個扇區的繪圖數據(半徑,相對于圓心的起始轉角,扇區角度)均掛載在繪圖數據上。
  2. canvas標簽上監聽鼠標移動事件mousemove,并在回調函數中將鼠標移動事件event.clientXevent.clientY轉換為相對于canvas坐標的數值(mouseX,mouseY)
  3. 從圓心坐標(paintingCenter.x,paintingCenter.y)(mouseX,mouseY)連接為向量,根據該向量的角度和模即可判斷鼠標是否處于某個扇區之上。
  4. 如果處于扇區之上,則以過渡動畫來繪制關鍵幀使得hover效果表現出來。先修改context.fillStyle顏色為對應扇區的高亮色,然后讓外圓繪圖半徑以線性的方式逐幀增加至目標大小(例如10%),每一幀中使用canvas繪圖上下文重新對繪圖區域進行封閉畫線,然后填充即可。
  5. hover效果出現時繪制高亮色的繪圖區域,hover效果消失時從外圓開始逐幀繪制白色外層扇區即可,最終再將數據扇區繪制為原色。

以上是“canvas如何繪制餅圖”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

云安县| 佛坪县| 西宁市| 奉化市| 德保县| 阳谷县| 肃宁县| 布尔津县| 稷山县| 临西县| 扎囊县| 庆元县| 德令哈市| 顺昌县| 潮安县| 龙陵县| 青海省| 乾安县| 上杭县| 平塘县| 新和县| 马关县| 华亭县| 金堂县| 永宁县| 丰原市| 耿马| 盐边县| 保康县| 宁海县| 娄烦县| 柏乡县| 大厂| 衡南县| 东辽县| 黑河市| 两当县| 项城市| 阜平县| 麻江县| 晋中市|