使用原生canvasAPI绘制雷达图。(截图以及数据来自于百度Echarts官方示例库【查看示例链接】)。

二. 重点提示

雷达图绘制的看起来并不复杂,无非就是一些路径点的连线,其中的难点都在于一些细节。

  1. 坐标转换
  2. 为了避免在绘制过程中不断根据夹角来计算某个数据点的坐标,我们可以让坐标系先移动到绘图中心,然后在绘制过程中逐步旋转并使用context.lineTo(x,y)来连线即可,这样做的好处是很明显的。比如在绘制背景六边形的时候,每次旋转后,路径点压根就不需要移动,直接在循环中每次都调用context.lineTo( )方法连线至同一个数据点即可,看起来位移没有变,实际上随着坐标系的旋转,连线绕过的是多边形的轨迹。
  3. 文字的对齐
  4. 为了让文字保持正常的方向,我们需要将坐标系的旋转恢复到初始状态再进行绘制。绘制的过程中可以根据绘制点和中心连线相对于x轴的角度来动态修改其绘制时的相对点(left,right,center),否则就会出现下图的结果,也就是文字区域的中心到图形中心的距离的确是一致的,但这并不是我们想要的效果。
  1. canvas坐标系
  2. 请时刻记得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官方示例库中有这样一个雷达图的示例,展示了在雷达图上表现时间维度的示例,感兴趣的读者可以自行查看。

echarts 雷达图_【带着canvas去流浪】绘制雷达图相关推荐

  1. 带着canvas去流浪系列之二 绘制折线图

    [摘要] 用canvasAPI实现echarts简易图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...

  2. 感悟人生的伤感日志_带着眼泪去流浪

    感悟人生的伤感日志_带着眼泪去流浪 - 感悟人生的伤感日志_带着眼泪去流浪 眼泪里不但包含了许多悲哀和伤痕,还包括了埋怨.嫉妒和轻视.展示伤痕,是痛苦的-- 人生里有许多悲哀.人生里有许多伤痕. 这些 ...

  3. 带着canvas去流浪系列之六 绘制雷达图

    [摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...

  4. 【带着canvas去流浪(6)】绘制雷达图

    目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...

  5. 带着canvas去流浪系列之七 绘制水球图

    [摘要] 用原生canvasAPI实现百度echarts 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...

  6. 【带着canvas去流浪(13)】用Three.js制作简易的MARVEL片头动画(下)#华为云·寻找黑马程序员#

    [摘要] three.js实现的Web 3D字体模型动画 示例代码托管在:http://www.github.com/dashnowords/blogs 有了上一篇基础知识的储备,本节就来制作一下简易 ...

  7. 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)

    我的github主页:https://github.com/dashnowords 我的新书上架啦,3天即登京东计算机编程语言类排行榜Top1!!!精选30+JavaScript库,从使用方式,设计原 ...

  8. 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上) #华为云·寻找黑马程序员#

    [摘要] 用three.js实现简易的漫威片头动画 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 大作业说明 通读完上一篇博文中提及的教程,觉得 ...

  9. python绘制简单城市剪影图_利用Python的folium包绘制城市道路图的实现示例

    写在前面 很长一段时间内,我都在研究在线地图的开发者文档,百度地图和高德地图的开发者中心提供了丰富的在线地图服务,虽然有一定的权限限制,但不得不说,还是给我的科研工作提供了特别方便的工具,在博客前面我 ...

最新文章

  1. 怎么连接屏幕_手机屏幕坏了也可以操作?这办法学会了再不怕碎屏
  2. Python之父重回决策层,未来如何发展?
  3. CVS,GIT,Mercurial和SVN比较
  4. myeclipse 删除历史工作空间记录
  5. mysql怎么存照片信息_mysql怎么存储图片信息?
  6. elasticsearch 索引存储深入详解(Elasticsearch教程03)|MVP讲堂
  7. encoder.cpp(340) [feature_index.open(templfile, trainfile)]feature_index.cpp(174) [max_size == size]
  8. 通过phpmyadmin确认此版本的php支持mssql函数,Php5.6.4+IIS8.5+mysql5.6.22+phpmyadmin4.3.6的配置...
  9. Unix中使用MeteoInfo - Xmanager设置
  10. python日历下拉框_selenium+Python(Js处理日历控件)
  11. C#高性能大容量SOCKET并发(八):通讯协议
  12. 文字识别成语音_广东人专属!微信语音转文字可以识别粤语了!
  13. 《软件工程导论第6版》--张海藩 牟永敏 课后答案及其详解 第7章 实现
  14. python实现典型相关分析_典型相关分析 CCA
  15. 产品经理面试必问问题与答题模板
  16. kettle-spoon安装
  17. 日历2021年日历表|2021年日历表打印版 Excel版
  18. ExpandableListView 实现三级菜单中grou_item与child_item点击无响应
  19. Android新浪微博实训报告,完成一份新浪微博目标用户分析报告
  20. QEMU脏页速率计算原理

热门文章

  1. Vue packages version mismatch: 版本冲突;Error: EPERM: operation not permitted
  2. perf 函数调用性能(函数流程图)
  3. Ubuntu 安装arm-linux-gcc交叉编译工具
  4. Android-导航栏特效-新闻类APP(仿iOS版网易新闻今日头条的文字渐变缩放特效)
  5. 基于Python-Pygame:200行代码实现完整的俄罗斯方块
  6. GStreamer架构设计篇(四)
  7. 集成Android免费语音合成功能(在线、离线、离在线融合),有这一篇文章就够了(离线)
  8. Android5.1权限问题解决
  9. UE4之TextureSample
  10. access统计各职务人数_东莞各阶段学生人数统计|终于知道为什么在东莞总是学位紧缺了...