站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        canvas繪制餅圖的方法介紹(代碼)

        本篇文章給大家?guī)淼膬?nèi)容是關(guān)于canvas繪制餅圖的方法介紹(代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

        一. 任務(wù)說明

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

        canvas繪制餅圖的方法介紹(代碼)

        二. 重點提示

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

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

        canvas繪制餅圖的方法介紹(代碼)

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

        canvas繪制餅圖的方法介紹(代碼)

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

        三. 示例代碼

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

        //繪制餅圖 drawPieChart(options);      /**  * 繪制餅圖  * @param  {[type]} options [description]  * @return {[type]}         [description]  */ function drawPieChart(options) {    //記錄最大數(shù)值以反求面積總和    options.maxValue = 0;    //求數(shù)據(jù)集總和以在后續(xù)計算每個扇形的角度比例    options.totalNum = options.data.reduce((pre,cur)=>{      if (cur.value > options.maxValue) {          options.maxValue = cur.value;      }      return pre+cur.value;    },0);     /*以最大值對應(yīng)最大半徑來計算面積總和,并覆蓋原值     *使得最大的一塊扇形外圓半徑為options.radius[0]     *內(nèi)圓半徑為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);     //繪制每個扇形,過程中累加旋轉(zhuǎn)角度    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(); }  /**  * 計算每個扇形所需要的繪圖參數(shù)  */ 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;//將角度值返回給外層函數(shù)以供累加 }  //繪制扇形 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高亮的實現(xiàn)思路

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

        【相關(guān)推薦:HTML5視頻教程】

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 中文成人无字幕乱码精品区| 无码日韩精品一区二区免费| 无码8090精品久久一区| 精品国精品国产| 日产欧美国产日韩精品| 久久精品无码av| 国产精品电影在线| 四虎国产精品永久地址51| 91精品国产福利在线导航| 日韩精品无码一区二区三区免费| 欧美国产精品va在线观看| 国产精品亚洲美女久久久| 欧美日韩精品一区二区三区| 国产精品熟女一区二区| 久久丫精品国产亚洲av不卡| 亚洲精品在线视频| 欧美日韩专区麻豆精品在线 | 欧美日激情日韩精品| 92国产精品午夜福利| 精品久久久久久无码专区不卡| 野狼第一精品社区| 中文字幕精品久久| 亚洲欧洲精品成人久久曰影片| 久久996热精品xxxx| 国内精品久久久久久久涩爱| 国产高清在线精品一区小说 | 国产午夜精品理论片久久影视| 国产精品亚洲片在线观看不卡| 久久夜色精品国产网站| 久久99精品久久久久久hb无码| 无码精品国产VA在线观看| 久久这里只有精品18| 国产午夜福利精品久久2021 | 99re热视频这里只精品| 国产精品久久久久…| 99久久婷婷免费国产综合精品| 91精品国产综合久久婷婷| 国产成人精品久久一区二区三区| 国产精品久久久福利| 亚洲国产成人久久精品动漫 | 99久久免费只有精品国产|