html5 绘制圆饼图,HTML5 Canvas(实战:绘制饼图)

2023-10-09 23:30

本文主要是介绍html5 绘制圆饼图,HTML5 Canvas(实战:绘制饼图),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有了canvas以后,咱们能够很容易地建立一个简单图标,不须要任何插件,不过,有的小伙伴以为它很难,笔者仔细思考一番以后,只能吐嘈一下他们的绘图技能...

因而在开始绘制以前,咱们首先画一下草图~

1460000014841309git

Make It Reusable

为了建立一个能够重用,而且能够灵活地重用的饼图,笔者决定最终的建立饼图方法接收两个参数,分别是要显示的数据data,绘制参数options面试

Data

Data From Server

在实际应用场景中,咱们从后端拿到的每每是诸如几个年份的产量一类的数据,好比(这里,咱们为了简化代码,将颜色也放到了后台返回的数据中):canvas

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像素的空隙,而且根据参数,绘制具备特定内容和样式的标题。spa

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

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);

}

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();

画出来的饼图长这个样子~

1460000014841310

下一篇笔者会加上Tooltip的绘制哦,那部分比较复杂,默默地给本身加油~

这篇关于html5 绘制圆饼图,HTML5 Canvas(实战:绘制饼图)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/176326

相关文章

Python实现Word转PDF全攻略(从入门到实战)

《Python实现Word转PDF全攻略(从入门到实战)》在数字化办公场景中,Word文档的跨平台兼容性始终是个难题,而PDF格式凭借所见即所得的特性,已成为文档分发和归档的标准格式,下面小编就来和大... 目录一、为什么需要python处理Word转PDF?二、主流转换方案对比三、五套实战方案详解方案1:

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例

《PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例》词嵌入解决NLP维度灾难,捕捉语义关系,PyTorch的nn.Embedding模块提供灵活实现,支持参数配置、预训练及变长... 目录一、词嵌入(Word Embedding)简介为什么需要词嵌入?二、PyTorch中的nn.Em

在IntelliJ IDEA中高效运行与调试Spring Boot项目的实战步骤

《在IntelliJIDEA中高效运行与调试SpringBoot项目的实战步骤》本章详解SpringBoot项目导入IntelliJIDEA的流程,教授运行与调试技巧,包括断点设置与变量查看,奠定... 目录引言:为良驹配上好鞍一、为何选择IntelliJ IDEA?二、实战:导入并运行你的第一个项目步骤1

Spring Boot3.0新特性全面解析与应用实战

《SpringBoot3.0新特性全面解析与应用实战》SpringBoot3.0作为Spring生态系统的一个重要里程碑,带来了众多令人兴奋的新特性和改进,本文将深入解析SpringBoot3.0的... 目录核心变化概览Java版本要求提升迁移至Jakarta EE重要新特性详解1. Native Ima