国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

HTML5 Canvas(實戰:繪制餅圖)

tinna / 2666人閱讀

摘要:綜上,最后我們的工具函數應該長成下面這個樣子首先獲取繪圖上下文,仍要注意先判斷是否存在方法。把標題繪制在畫布頂部的中間,距離頁面頂部留有像素的空隙,并且根據參數,繪制具有特定內容和樣式的標題。

有了canvas之后,我們可以很容易地創建一個簡單圖標,不需要任何插件,不過,有的小伙伴覺得它很難,筆者仔細思考一番之后,只能吐嘈一下他們的繪圖技能...
于是在開始繪制之前,我們首先畫一下草圖~

講解之前,先貢獻出源碼:https://github.com/Sue1024/Ca...

Make It Reusable

為了創建一個可以重用,并且可以靈活地重用的餅圖,筆者決定最終的創建餅圖方法接收兩個參數,分別是要顯示的數據data,繪制參數options

Data
Data From Server

在實際應用場景中,我們從后端拿到的往往是諸如幾個年份的產量一類的數據,比如(這里,我們為了簡化代碼,將顏色也放到了后臺返回的數據中):

var data = [
              {
                data: 10,
                color: "red",
                label: "2016"
              },
              {
                data: 15,
                color: "grey",
                label: "2017"
              },
              {
                data: 15,
                color: "black",
                label: "2018"
              }
];
To Process Data

而繪制餅圖時, 我們需要根據比例"分餅", 并且在某些地方顯示出實際的數據(比如tooltip),因此我們需要一個如下的數據處理函數:

function calculateData(data) {
  if(data instanceof Array) {
    var sum = data.reduce(function(a, b) {
      return a + b.data;
    }, 0);
    var map = data.map(function(a) {
      return {
        label: a.label,
        data: a.data,
        color: a.color,
        portion: a.data/sum
      }
    });
    return map;
  }      
}
Options

另外,即使我們可以根據不同的數據繪制不同的圖表,恐怕也只能滿足個別需求,畢竟每個人的喜好都不一樣,我們需要創建一個可以顯示不同數據,又可以擁有不同排版、不同布局的圖表,實現上述目標,我們需要如下參數列表:

var options = {
    legend: {
        font: {
          size: 18,
          family: "Arial",
          weight: "bold"
        }
    },
    title: {
        text: "Pie Chart",
        font: {
          size: 18,
          family: "Arial",
          weight: "bold"
        }
    },
    tooltip: {
        template: "
Year: {{label}}
Production: {{data}}
", font: { size: 18, family: "Arial", weight: "bold" } } }
Canvas

我們的工具函數不應該可以提前知道用戶想要用來繪制圖表的canvas,用戶可能想在頁面中的多個canvas上繪制圖表,因此工具函數應該可以接受一個參數,用來確定繪制圖表的canvas,很多開源庫都使用id作為識別canvas的標識,筆者認為接收element更好一些,因為不是所有的用戶都愿意給canvas添加ID屬性, 有的時候,用戶想給擁有某一個class屬性的所有canvas批量繪圖,并根據它們的dataset屬性動態的生成數據。
綜上,最后我們的工具函數應該長成下面這個樣子:

function drawPie(canvas, data, option) {
// To Do
}
Start Coding Get Context

首先獲取繪圖上下文,仍要注意先判斷是否存在getContext()方法。

var canvas = document.getElementById("canvas");
if(canvas.getContext) {
  var ctx = canvas.getContext("2d");
}
Generate Options

然后,我們需要將自定義的參數和默認參數合并在一起,組成一個新的完整的參數列表,原則就是沒有自定義的都采用默認值。

function mergeJSON(source1,source2){
  var mergedJSON = JSON.parse(JSON.stringify(source2));
  for (var attrname in source1) {
    if(mergedJSON.hasOwnProperty(attrname)) {
      if ( source1[attrname]!=null && source1[attrname].constructor==Object ) {
        mergedJSON[attrname] = mergeJSON(source1[attrname], mergedJSON[attrname]);
      }
    } else {
      mergedJSON[attrname] = source1[attrname];
    }
  }
    return mergedJSON;
}

function generateOptions(givenOptions, defaultOptions) {
  return mergeJSON(defaultOptions, givenOptions);
}
Draw Title

把標題繪制在畫布頂部的中間,距離頁面頂部留有20像素的空隙,并且根據參數,繪制具有特定內容和樣式的標題。

var width = canvas.width,
    height = canvas.height,
    op = generateOptions(options, defaultOptions),
    title_text = op.title.text,
    title_position = {};
ctx.font = op.title.font.weight + " " + op.title.font.size+"px " + op.title.font.family;
title_position .x = (width - title_width)/2;
title_position.y = 20 + op.title.font.size;
title_width = ctx.measureText(title_text).width, title_height = op.title.font.size;
ctx.fillText(title_text, title_position.x, title_position.y);
Radius & Center

筆者決定使餅圖距離標題有30像素的空隙,距離左邊框和底部分別留有20像素的空隙,因此它的半徑和圓心分別是:

var radius = (height - title_height - title_position.y - 20) / 2 ;
var center = {
  x: radius + 20,
  y: radius + 30 + title_position.y
};
Legend

圖例的高設置為圖例字體大小的1.2倍,寬設置為圖例字體大小的2.5倍,距離餅圖40像素的間隙,第一個圖例頂部距離頁面頂端80像素,文字距離圖例5像素,垂直居中,于是圖例的大體信息總結如下:

var legend_width = op.legend.font.size * 2.5, 
    legend_height = op.legend.font.size * 1.2,
    legend_posX = center.x * 2 +20, 
    legend_posY = 80,
    legend_textX = legend_posX + legend_width + 5, 
    legend_textY = legend_posY + op.legend.font.size * 0.9;
Draw Pie & Legends
Border

先給圖表加一個邊框

  ctx.strokeStyle = "grey";
  ctx.lineWidth = 3;
  ctx.strokeRect(0, 0, canvas.width, canvas.height);
Pie & Legends

遍歷數據繪圖。

var data_c = calculateData(data);
var startAngle = 0, endAngle = 0;
for(var i=0, len=data.length; i
Let"s try it!

我們的工具函數已經做到一半啦,可以畫出一個帶有圖例的餅圖,并且標題和圖例文字大小 粗細 字體均可配置,下面試一下靈不靈~

var init = function(){
    var data = [
              {
                data: 10,
                color: "red",
                label: "2016"
              },
              {
                data: 15,
                color: "grey",
                label: "2017"
              },
              {
                data: 15,
                color: "black",
                label: "2018"
              }
    ];
    var options = {
        title: {
            text: "Production By Year",
            font: {
                  size: 30
            }
        }
    }
    drawCircle(data, document.getElementById("drawing"), options);
};
init();

畫出來的餅圖長這個樣子~

下一篇筆者會加上Tooltip的繪制哦,那部分比較復雜,默默地給自己加油~

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94957.html

相關文章

  • HTML5 Canvas實戰繪制餅圖2 Tooltip)

    摘要:繼上一篇實戰繪制餅圖之后,筆者研究了一下如何給餅圖加鼠標停留時顯示的提示框。為了方便保存,創建一個構造函數。最終我們的方法成品圖源碼地址 繼上一篇HTML5 Canvas(實戰:繪制餅圖)之后,筆者研究了一下如何給餅圖加鼠標停留時顯示的提示框。 Plot對象 在開始Coding之前,筆者能夠想到的最easy的方式,就是給餅圖的每一個區域添加mousemove事件,鼠標在其上移動時則顯示...

    CoderBear 評論0 收藏0
  • HTML5 Canvas實戰繪制餅圖2 Tooltip)

    摘要:繼上一篇實戰繪制餅圖之后,筆者研究了一下如何給餅圖加鼠標停留時顯示的提示框。為了方便保存,創建一個構造函數。最終我們的方法成品圖源碼地址 繼上一篇HTML5 Canvas(實戰:繪制餅圖)之后,筆者研究了一下如何給餅圖加鼠標停留時顯示的提示框。 Plot對象 在開始Coding之前,筆者能夠想到的最easy的方式,就是給餅圖的每一個區域添加mousemove事件,鼠標在其上移動時則顯示...

    songze 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<