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

目录

  • 一. 任务说明
  • 二. 重点提示
  • 三. 示例代码

示例代码托管在:http://www.github.com/dashnowords/blogs

博客园地址:《大史住在大前端》原创博文目录

华为云社区地址:【你要的前端打怪升级指南】

一. 任务说明

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

二. 重点提示

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

  1. 坐标转换

    为了避免在绘制过程中不断根据夹角来计算某个数据点的坐标,我们可以让坐标系先移动到绘图中心,然后在绘制过程中逐步旋转并使用context.lineTo(x,y)来连线即可,这样做的好处是很明显的。比如在绘制背景六边形的时候,每次旋转后,路径点压根就不需要移动,直接在循环中每次都调用context.lineTo( )方法连线至同一个数据点即可,看起来位移没有变,实际上随着坐标系的旋转,连线绕过的是多边形的轨迹。

  2. 文字的对齐

    为了让文字保持正常的方向,我们需要将坐标系的旋转恢复到初始状态再进行绘制。绘制的过程中可以根据绘制点和中心连线相对于x轴的角度来动态修改其绘制时的相对点(left,right,center),否则就会出现下图的结果,也就是文字区域的中心到图形中心的距离的确是一致的,但这并不是我们想要的效果。

  1. 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官方示例库中有这样一个雷达图的示例,展示了在雷达图上表现时间维度的示例,感兴趣的读者可以自行查看。

原文地址:https://www.cnblogs.com/dashnowords/p/10656750.html

时间: 2024-10-07 06:19:43

【带着canvas去流浪(6)】绘制雷达图的相关文章

【带着canvas去流浪】 (3)绘制饼图

目录 一. 任务说明 二. 重点提示 三. 示例代码 四. hover高亮的实现思路 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 一. 任务说明 使用原生canvasAPI绘制饼图(南丁格尔玫瑰).(截图以及数据来自于百度Echarts官方示例库[查看示例链接]). 二. 重点提示 南丁格尔玫瑰图的画法有很多种,Echarts中提供的以半径或面积两种不同模

带着canvas去流浪系列之八 碰撞【华为云技术分享】

[摘要] canvas动画-碰撞仿真 示例代码托管在:http://www.github.com/dashnowords/blogs 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生API了,那么从这一节开始,我们就开始接触点好玩的东西——动画. 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生API了,那么从这一节开始,我们就开始接触点好玩的东西——动画. 一. canvas的能力 如果你以为canvas只能绘制图表那真的就图样图森破了,且不谈webgl的绘图上

利用d3.js绘制雷达图

利用d3,js将数据可视化,可以做到数据与代码的分离,方便以后修改数据. 这次利用d3.js绘制了一个五维的雷达图,即将多个对象的五种属性在一张图上对比. 数据写入data.csv.数据类型写入type.csv文件. 效果如下图所示 源码连接:http://download.csdn.net/detail/svap1/7358123 使用是只需调用 radar()函数即可,如下是测试页面代码. <!DOCTYPE html> <html> <head> <meta

Emgu-WPF 激光雷达研究-绘制雷达图

原文:Emgu-WPF 激光雷达研究-绘制雷达图 硬件:Hokuyo URG04LX 环境:VS2017- win10- 64??Emgu_3.2.0.2682 语言:C#? WPF?? 数据解析参考: https://sourceforge.net/p/urgnetwork/wiki/Home/ https://github.com/bqhdev/urg04lx_data_decoder http://sourceforge.net/projects/urgnetwork/files/urg_

利用matlibplot绘制雷达图

之前在一些数据分析案例中看到用 Go 语言绘制的雷达图,非常的漂亮,就想着用matlibplot.pyplot也照着画一个,遗憾的是matlibplot.pyplot模块中没有直接绘制雷达图的函数,不过可以基于‘polar’图形特征来改进,下面就记录一下如何绘制雷达图. import numpy as np import matplotlib.pyplot as plt # 用于正常显示中文 plt.rcParams['font.sans-serif'] = 'SimHei' #用于正常显示符号

Mesh绘制雷达图(UGUI)

/******************************************************************************** 参考资料:http://www.cnblogs.com/jeason1997/p/5130413.html ** 类名称: RadarEditor ** 描述:雷达图 ** 作者: 田树东 *************************************************************************

HTML5 WebAudioAPI(三)--绘制频谱图

HTML <style> #canvas { background: black; } </style> <div class="container"> <button class="btn btn-primary" id="playBtn"> <i class="glyphicon glyphicon-pause"></i> </button>

浅谈canvas绘画王者荣耀--雷达图

背景: 一日晚上下班的我静静的靠在角落上听着歌,这时"滴!滴!"手机上传来一阵qq消息.原来我人在问王者荣耀的雷达图在页面上如何做出来的,有人回答用canvas绘画.那么问题来了,已经好久没有使用canvas绘画了东西. SO,就想自己画一个canvas雷达图,顺便重新回顾一下canvas的知识点. 王者荣耀雷达图的基本构成. 聊天记录当中的雷达图不是特别清楚,所以我这边截图了自己的一个战绩雷达图. 是不是有被我的战绩吓到了,害不害怕! 好了扯远了,让我们回到正题上来. 通过截图上面的

玩转Android Camera开发(五):基于Google自带算法实时检测人脸并绘制人脸框(网络首发,附完整demo)

本文主要介绍使用Google自带的FaceDetectionListener进行人脸检测,并将检测到的人脸用矩形框绘制出来.本文代码基于PlayCameraV1.0.0,在Camera的open和preview流程上进行了改动.原先是放在单独线程里,这次我又把它放到Surfaceview的生命周期里进行打开和开预览. 首先要反省下,去年就推出了静态图片的人脸检测demo,当时许诺一周内推出Camera预览实时检测并绘制的demo,结果拖到现在才整.哎,屌丝一天又一天,蹉跎啊.在demo制作过程中