带着canvas去流浪系列之三 绘制饼图
【摘要】 用canvas原生API绘制Echarts图表
示例代码托管在:http://www.github.com/dashnowords/blogs
一. 任务说明
使用原生canvasAPI绘制饼图(南丁格尔玫瑰)。(截图以及数据来自于百度Echarts官方示例库【查看示例链接】)。
二. 重点提示
南丁格尔玫瑰图的画法有很多种,Echarts中提供的以半径或面积两种不同模式,本文中以面积比例画法为例,绘制算法如下:
确定每个扇区的角度。由于所有扇区的角度加在一起为2π ,我们先按照数据比例来计算角度:
每个扇区面积与总面积之间的比例即为数值的比,将给定参数数组
options.radius中的最大和最小数值作为数值最大的一块扇形的绘图数据,代入如下公式即可求得总面积S:
3. 再利用上述公式分别计算出每个扇形对应的外圆半径,在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);
}
浏览器中可查看效果:
四. hover高亮的实现思路
绘图过程中,将每个扇区的绘图数据(半径,相对于圆心的起始转角,扇区角度)均挂载在绘图数据上。
在
canvas标签上监听鼠标移动事件mousemove,并在回调函数中将鼠标移动事件event.clientX和event.clientY转换为相对于canvas坐标的数值(mouseX,mouseY)。从圆心坐标
(paintingCenter.x,paintingCenter.y)到(mouseX,mouseY)连接为向量,根据该向量的角度和模即可判断鼠标是否处于某个扇区之上。如果处于扇区之上,则以过渡动画来绘制关键帧使得hover效果表现出来。先修改
context.fillStyle颜色为对应扇区的高亮色,然后让外圆绘图半径以线性的方式逐帧增加至目标大小(例如10%),每一帧中使用canvas绘图上下文重新对绘图区域进行封闭画线,然后填充即可。hover效果出现时绘制高亮色的绘图区域,hover效果消失时从外圆开始逐帧绘制白色外层扇区即可,最终再将数据扇区绘制为原色。
来源:华为云社区 作者:大史不说话
带着canvas去流浪系列之三 绘制饼图的更多相关文章
- 带着canvas去流浪系列之五 绘制K线图
[摘要] 用canvas原生API实现百度Echarts 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 带着canvas去流浪系列之四 绘制散点图
[摘要] 用原生canvasAPI实现百度Echarts图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI ...
- 带着canvas去流浪系列之七 绘制水球图
[摘要] 用原生canvasAPI实现百度echarts 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 带着canvas去流浪系列之六 绘制雷达图
[摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...
- 带着canvas去流浪系列之二 绘制折线图
[摘要] 用canvasAPI实现echarts简易图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 带着canvas去流浪系列之八 碰撞
[摘要] canvas动画-碰撞仿真 示例代码托管在:http://www.github.com/dashnowords/blogs 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生A ...
- 带着canvas去流浪系列之八 碰撞【华为云技术分享】
[摘要] canvas动画-碰撞仿真 示例代码托管在:http://www.github.com/dashnowords/blogs 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生A ...
- 带着canvas去流浪系列之一:绘制柱状图
[摘要] 学习使用canvasAPI来实现数据可视化. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制柱 ...
- 带着canvas去流浪系列之九 粒子动画【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
随机推荐
- 使用Typescript重构axios(十三)——让响应数据支持泛型
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- Unicode字符串和非Unicode字符串
什么是Unicode? Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每 ...
- [转载]2.5 UiPath循环活动Do While的介绍和使用
一.Do While的介绍 先执行循环体, 再判断条件是否满足, 如果满足, 则再次执行循环体, 直到判断条件不满足, 则跳出循环. 二.Do While在UiPath中的使用 1. 打开设计器,在设 ...
- 二叉搜索树BST(C语言实现可用)
1:概述 搜索树是一种可以进行插入,搜索,删除等操作的数据结构,可以用作字典或优先级队列.二叉搜索树是最简单的搜索树.其左子树的键值<=根节点的键值,右子树的键值>=根节点的键值. 如果共 ...
- 玩转VSCode-完整构建VSCode开发调试环境
随着VSCode的不断完善和强大,是时候将部分开发迁移到VS Code中了. 目前使用VS2019开发.NET Core应用,一直有一个想法,在VS Code中复刻VS的开发环境,同时迁移到VS Co ...
- Zabbix-(一) 安装与部署
Zabbix-(一)安装与部署 一.前言 本文记录在Centos7.6平台 通过yum安装部署Zabbix 4.4 准备 Centos7.6 虚拟机一台(ip: 192.168.152.140) My ...
- 【计算机网络】TCP基础知识详解
1. TCP概念相关 [!NOTE] TCP(Transmission Control Protocol),又叫传输控制协议. TCP协议是面向连接的,可靠的,基于字节流的传输协议.在基于 TCP 进 ...
- 隐藏input输入框的增减按钮
当input 使用了type='number'后,会出现这个增减数值的按钮,如上所示, 解决办法: 1.type='text' ,改为输入字符串,缺点是要做类型转换,而且移动端不会调出纯数字键盘 2. ...
- Flex实现web版图片查看器
项目需求: 在web端实现图片浏览,具有放大.缩小.滚轴放大缩小.移动.旋转以及范围控制. 成果图:
- Liunx 安装配置zsh和oh-my-zsh 替换 bash
一.前言 本文将基于 Liunx 环境安装配置zsh 和 oh-my-zsh 替换 bash oh my zsh Liunx默认shell是单调的bash,而zsh比较高大上,bash有的功能,zsh ...