
使用画布,我们可以轻松创建一个没有任何插件的简单图标. 但是,有些朋友觉得很困难. 考虑之后,我只能谈谈他们的绘画技巧. ...
所以在开始绘制之前,先绘制一个草图〜
在解释之前,请提供源代码:
为了创建可重复使用并可以灵活重复使用的饼图,我决定最终的饼图创建方法接受两个参数,即要显示的数据和图形参数选项
在实际的应用场景中,例如,我们经常从后端获取数据,例如几年的输出(在这里,为了简化代码,我们还在背景返回的数据中添加了颜色): / p>

var data = [
{
data: 10,
color: "red",
label: "2016"
},
{
data: 15,
color: "grey",
label: "2017"
},
{
data: 15,
color: "black",
label: "2018"
}
];
绘制饼图时,我们需要根据比例“散布饼图”canvas 饼图,并在某些地方显示实际数据(例如工具提示),因此我们需要如下数据处理功能:
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;
}
}
此外,即使我们可以根据不同的数据绘制不同的图表,但恐怕我们只能满足个人需求. 毕竟,每个人的偏好都不同. 我们需要创建不同的数据,而且还需要具有不同的排版,不同的布局图以实现上述目标,我们需要以下参数列表:
var options = {
legend: {
font: {
size: 18,
family: 'Arial',
weight: 'bold'
}
},
title: {
text: 'Pie Chart',
font: {
size: 18,
family: 'Arial',
weight: 'bold'
}
},
tooltip: {
template: '<div>Year: {{label}}</div><div>Production: {{data}}</div>',
font: {
size: 18,
family: 'Arial',
weight: 'bold'
}
}
}
我们的工具功能不应该知道用户想要用来提前绘制图表的画布. 用户可能希望在页面上的多个画布上绘制图表,因此工具功能应接受一个参数来确定图表的绘制. 画布,许多开放源代码库都使用id作为标识来标识画布. 我认为最好接收该元素,因为并非所有用户都愿意将ID属性添加到画布. 有时,用户希望将具有特定类属性的所有对象赋予Canvas批量绘制并根据其数据集属性动态生成数据.

总而言之,最后,我们的工具功能应如下所示:
function drawPie(canvas, data, option) {
// To Do
}
首先获取绘图上下文,仍然要注意确定是否存在getContext()方法.
var canvas = document.getElementById("canvas");
if(canvas.getContext) {
var ctx = canvas.getContext("2d");
}
然后,我们需要将自定义参数与默认参数结合起来以形成一个新的完整参数列表. 原则是对未定制的值使用默认值.
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);
}

在画布顶部的中间位置绘制标题,与页面顶部之间留出20像素的间距canvas 饼图,并根据参数绘制具有特定内容和样式的标题.
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);
作者决定使饼图距标题30像素,距左边框和底部20像素,因此其半径和中心为:
var radius = (height - title_height - title_position.y - 20) / 2 ;
var center = {
x: radius + 20,
y: radius + 30 + title_position.y
};
图例的高度设置为图例字体大小的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;

首先在图表上添加边框
ctx.strokeStyle = 'grey';
ctx.lineWidth = 3;
ctx.strokeRect(0, 0, canvas.width, canvas.height);
遍历数据图.
var data_c = calculateData(data);
var startAngle = 0, endAngle = 0;
for(var i=0, len=data.length; i<len; i++) {
endAngle += data_c[i].portion * 2*Math.PI;
ctx.fillStyle = data_c[i].color;
ctx.beginPath();
ctx.moveTo(center.x, center.y);
ctx.arc(center.x, center.y, radius, startAngle, endAngle, false);
ctx.closePath();
ctx.fill();
startAngle = endAngle;
ctx.fillRect(legend_posX, legend_posY + (10 + legend_height) * i, legend_width, legend_height);
ctx.font = 'bold 12px Arial';
var percent = data_c[i].label + ' : ' + (data_c[i].portion*100).toFixed(2) + '%';
ctx.fillText(percent, legend_textX, legend_textY + (10 + legend_height) * i);
}
我们的工具功能完成了一半. 您可以绘制带有图例的饼图,并且可以配置标题和图例的文本大小,粗细和字体. 试试吧.
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();
饼图看起来像这样〜
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-153680-1.html
全世界国家的主政府是美国说了算