【带着canvas去流浪(6)】绘制雷达图
示例代码托管在:http://www.github.com/dashnowords/blogs
博客园地址:《大史住在大前端》原创博文目录
华为云社区地址:【你要的前端打怪升级指南】
一. 任务说明
使用原生canvasAPI
绘制雷达图。(截图以及数据来自于百度Echarts官方示例库【查看示例链接】)。
二. 重点提示
雷达图
绘制的看起来并不复杂,无非就是一些路径点的连线,其中的难点都在于一些细节。
坐标转换
为了避免在绘制过程中不断根据夹角来计算某个数据点的坐标,我们可以让坐标系先移动到绘图中心,然后在绘制过程中逐步旋转并使用
context.lineTo(x,y)
来连线即可,这样做的好处是很明显的。比如在绘制背景六边形的时候,每次旋转后,路径点压根就不需要移动,直接在循环中每次都调用context.lineTo( )
方法连线至同一个数据点即可,看起来位移没有变,实际上随着坐标系的旋转,连线绕过的是多边形的轨迹。文字的对齐
为了让文字保持正常的方向,我们需要将坐标系的旋转恢复到初始状态再进行绘制。绘制的过程中可以根据绘制点和中心连线相对于x轴的角度来动态修改其绘制时的相对点(
left
,right
,center
),否则就会出现下图的结果,也就是文字区域的中心到图形中心的距离的确是一致的,但这并不是我们想要的效果。
canvas坐标系
请时刻记得canvas坐标系的初始方向是x轴向右,y轴向下,和普通笛卡尔坐标系是不一样的,尤其是在旋转角度和坐标计算的时候,很容易出现和预期角度不相符的结果。
三. 示例代码
//options数据来自于百度Echarts官方示例库
start(options);
/**
* 绘制图表
*/
function start(options) {
drawBg(options);
drawData(options);//绘制雷达图
drawText(options);//绘制文字
}
function drawBg(options) {
let length = options.radar.indicator.length;
let angleStep = -2 * Math.PI / length;
context.strokeStyle="#b2b2b2";
context.lineWidth = 1;
//调整坐标系
//移动中心点
context.translate(500,300);
//将x轴旋转至竖直向上
context.rotate(-90 * 2 * Math.PI / 360);
//每次以不同旋转半径绘制多个由大到小的图形
for(let r = 200; r > 0 ; r -=40){
//移动至第一个绘图点
context.save();
context.beginPath();
context.moveTo(r,0);
//转动坐标系绘制所有点
for(let i = 0; i < length; i++){
context.rotate(angleStep);
context.lineTo(r,0);
}
context.closePath();
context.stroke();
//明暗色替换填充,此处从大到小切换颜色覆盖式绘制即可
context.fillStyle = Math.round(r / 40) % 2 ? 'white':'#eaeaea';
context.fill();
context.restore();
}
}
/**
* 绘制数据
*/
function drawData(options) {
//解构赋值拿到数据关键点
let {radar:{indicator:indicators},series:[{data:data}]} = options;
let colors = ['#c43e3a','#364c5a'];
let length = indicators.length;
let angleStep = -2 * Math.PI / length;
for(let i = 0; i < data.length; i++){
context.save();
context.beginPath();
context.moveTo(200 * data[i].value[0] / indicators[0].max,0);
//遍历每组数据
for(let j = 1; j < data[i].value.length; j++){
context.rotate(angleStep);
context.lineTo(200 * data[i].value[j] / indicators[j].max,0);
}
context.restore();
context.lineTo(200 * data[i].value[0] / indicators[0].max,0);
context.strokeStyle = colors[i];
context.lineWidth = 2;
context.stroke();
}
context.restore();
}
//绘制文字
function drawText(options) {
let {radar:{indicator:indicators}} = options;
let length = indicators.length;
let angleStep = 2 * Math.PI / length;
let r = 220;
context.fillStyle = 'black';
context.font = "14px bold 黑体";
context.textAlign = 'center';
context.rotate(90 * Math.PI * 2 / 360);
for(let i = 0; i < indicators.length; i++){
let curAngle = -90*2*Math.PI/360 - angleStep*i;
//根据方向调整文字的对齐点
let cos = Math.cos(curAngle);
if (Math.abs(cos) < 10e-4) {
context.textAlign = 'center';
}else if(cos > 0){
context.textAlign = 'left';
}else{
context.textAlign = 'right';
}
console.log(indicators[i].name, Math.cos(curAngle))
context.fillText(indicators[i].name, r * Math.cos(curAngle), r * Math.sin(curAngle));
}
}
浏览器中可查看效果:
百度Echarts官方示例库中有这样一个雷达图的示例,展示了在雷达图上表现时间维度的示例,感兴趣的读者可以自行查看。
【带着canvas去流浪(6)】绘制雷达图的更多相关文章
- 【带着canvas去流浪】(2)绘制折线图
目录 一. 任务说明 二. 重点提示 三. 示例代码 3.1 一般折线图 3.2 用贝塞尔曲线绘制平滑折线图 四. 大数据量场景 示例代码托管在:https://github.com/dashnowo ...
- 带着canvas去流浪系列之二 绘制折线图
[摘要] 用canvasAPI实现echarts简易图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 带着canvas去流浪系列之六 绘制雷达图
[摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...
- 【带着canvas去流浪(7)】绘制水球图
目录 一. 任务说明 二. 重点提示 三. 示例代码 四. 文字淹水效果的实现 五. 关于canvas抗锯齿 六. 小结 示例代码托管在:http://www.github.com/dashnowor ...
- 带着canvas去流浪系列之七 绘制水球图
[摘要] 用原生canvasAPI实现百度echarts 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 【带着canvas去流浪(5)】绘制K线图
目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...
- 带着canvas去流浪系列之五 绘制K线图
[摘要] 用canvas原生API实现百度Echarts 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...
- 【带着canvas去流浪(4)】绘制散点图
目录 一. 任务说明 二. 重点提示 三. 示例代码 四.散点hover交互效果的实现 4.1 基本算法 4.2 参考代码 4.3 Demo中的小问题 示例代码托管在:http://www.githu ...
- 【带着canvas去流浪】 (3)绘制饼图
目录 一. 任务说明 二. 重点提示 三. 示例代码 四. hover高亮的实现思路 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:< ...
随机推荐
- Django 项目搭建(ubuntu系统)
1 环境搭建 sudo apt-get install python3-pip 安装pip3 sudo pip3 install virtualenv 安装虚拟环境,这里展示virtualenv vi ...
- 前端学习笔记之CSS选择器
阅读目录 一 基本选择器 二 后代选择器.子元素选择器 三 兄弟选择器 四 交集选择器与并集选择器 五 序列选择器 六 属性选择器 七 伪类选择器 八 伪元素选择器 九 CSS三大特性 一 基本选择器 ...
- zookeeper配置管理+集群管理实战
引言 之前就了解过kafka,看的似懂非懂,最近项目组中引入了kafka,刚好接着这个机会再次学习下. Kafka在很多公司被用作分布式高性能消息队列,kafka之前我只用过redis的list来做简 ...
- Helm学习笔记
Helm学习笔记 Helm 是 Kubernetes 生态系统中的一个软件包管理工具.本文将介绍 Helm 中的相关概念和基本工作原理,并通过一个具体的示例学习如何使用 Helm 打包.分发.安装.升 ...
- 再遇angular(angular4项目实战指南)
这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...
- 微软XAML Studio - WPF, Sliverlight, Xamarin, UWP等技术开发者的福音
目录 编辑器功能 数据源功能 调试数据绑定 伟大的开始 我们来一起实践吧 最近又在继续倒腾WPF的项目,继续使用Caliburn.Micro和Xceed来堆代码.每次调试xaml上的binding,都 ...
- 【转】视频H5 video最佳实践
原文地址:https://github.com/gnipbao/iblog/issues/11 随着 4G 的普遍以及 WiFi 的广泛使用,手机上的网速已经足够稳定和高速,以视频为主的 HTML5 ...
- DSAPI 调用串口选择界面
在DSAPI中,可以通过简单的代码调用串口选择界面,当用户选择了其中一个串口时,将返回选择的串口名称(或序号). Dim 串口名称 As String = DSAPI.串口通讯.显示串口选择界面.选择 ...
- 看懂 ,学会 .NET 事件的正确姿势-简单版
发现之前写了一篇关于事件的阐述写的过于抽象.现在想想先理解本质由简入难比较合适 之前的一篇博客地址:https://www.cnblogs.com/LiMin/p/7212217.html 参照网上 ...
- 【swoole】使用swoole简单实现TCP服务
上一篇写到了如何在windows系统上面利用docker快速搭建swoole开发环境,接下来体验下swoole的使用 使用swoole实现tcp服务 <?php $serv = new Swoo ...