JS使用canvas技术模仿echarts柱状图

canvas 画布是html5中新增的标签,可以通过js操作 canvas 绘图 API在网页中绘制图像。

百度开发了一个开源的可视化图表库ECharts,功能非常强大,可以实现折线图、柱状图、散点图、饼图、K线图、地图等多种图表。很多项目都有使用过ECharts开发过图表功能。

本实例教程使用原生js教你开发一个仿ECharts的柱状图。学习本教程之前,读者需要具备html和css技能,同时需要有简单的JavaScript基础。

按照ECharts的开发方法,图表都是生成在一个HTML元素中。所以本实例中也先准备一个id名为canvasWrap的div元素,如下所示:

<div class="canvas_wrap" id="canvasWrap"></div>

然后在canvasWrap元素中创建canvas元素,再在canvas元素上绘制柱状图。开发之前,按照惯例,还是先分析柱状图的具体操作,再根据具体操作把实现功能的方法分成多个步骤,接下来一个步骤一个步骤去完成它。

1. 编写柱状图数据
2. 获取canvasWrap元素及宽高
3. 创建绘图环境
3.1 创建canvas画布
3.2 设置canvas画布的宽度和高度
3.3 将canvas画布放入到canvasWrap元素中
3.4 创建绘图上下文环境
4. 设定坐标区域
5. 绘制x轴
5.1 绘制轴线
5.2 绘制刻度线
5.3 绘制刻度名称
6. 绘制y轴
6.1 绘制轴线
6.2 绘制刻度线
6.3 绘制刻度值
6.4 绘制x轴网格线
7. 绘制柱图
7.1 计算柱图宽度
7.2 计算柱图高度
7.3 计算柱图X起点
7.4 计算柱图Y起点
7.5 绘制柱图

具体代码如下:

//1 编写柱状图数据
option = {
  //x轴数据
  xAxis: {
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  //柱图数据
  series: [{
    //多写几组数据,用于查看不同数据时的图表效果
    // data: [0.01, 0.2, 0.05, 0.07, 0.04, 0.13, 0.9],
    // data: [1, 1, 5, 7, 4, 1, 9],
    // data: [1213, 30, 150, 80, 70, 910, 630],
    data: [120, 199, 150, 180, 70, 110, 130],
    //图形样式:柱图
    type: 'bar'
  }]
};

//创建图表函数,wrap:图表父元素id;data:图表数据
function fnCharts(wrap,data){
  //2.获取canvasWrap元素
  var eWrap = document.getElementById(wrap);
  //2.获取canvasWrap元素宽度和高度,用于设置canvas画布大小
  var nWrapW = eWrap.offsetWidth;
  var nWrapH = eWrap.offsetHeight;

  //3.1 创建canvas画布
  var eCanvas = document.createElement('canvas');
  //3.2 设置canvas画布的宽度和高度
  eCanvas.width = nWrapW;
  eCanvas.height = nWrapH;
  //3.3 将canvas画布放入到canvasWrap元素中
  eWrap.appendChild(eCanvas);
  //3.4 创建绘图上下文环境(才能够在Canvas画布上绘制)
  var oCtx = eCanvas.getContext('2d');

  //4.设定坐标区域左上角和右下角
  //起点设置为50.5,而不是整数,是为了让线条变清晰
  var nZoneStartX = 50.5;
  var nZoneStartY = 50.5;
  var nZoneEndX = nWrapW - nZoneStartX;
  var nZoneEndY = nWrapH - nZoneStartY;

  //5.1 使用线条函数绘制x轴轴线
  fnCreatLine(nZoneStartX,nZoneEndY,nZoneEndX,nZoneEndY);
  //计算x轴长度
  var nLonX = nZoneEndX - nZoneStartX;
  //获取x轴数据数组长度
  var nDataLon = option.xAxis.data.length;
  //根据x轴数据数组长度循环,在循环中绘制刻度线和刻度数值名称
  for(let i=0;i<nDataLon;i++){
    //计算出x轴刻度线起点在x轴上的值
    let nScaleX = nZoneStartX+Math.floor(nLonX*(i/nDataLon));
    //刻度线起点都在x轴上
    let nScaleY = nZoneEndY;
    //5.2 绘制刻度线,长度为10
    fnCreatLine(nScaleX,nScaleY,nScaleX,nScaleY+10);
    //从数据中获取刻度名称字符串
    let sName = option.xAxis.data[i];
    //计算出刻度名称起点
    let nNameX = nZoneStartX+Math.floor(nLonX*(i/nDataLon))+Math.floor(nLonX*(1/nDataLon))/2;
    let nNameY = nZoneEndY+15;
    //5.3 绘制刻度名称
    fnCreatText(sName,nNameX,nNameY,'#aaa','center');
  }

  //6.1 使用线条函数绘制y轴轴线
  fnCreatLine(nZoneStartX,nZoneEndY,nZoneStartX,nZoneStartY);
  //绘制y轴刻度线前,需要有刻度最大值、最小值、刻度线段数和刻度线之间的间隔这些数据。
  //刻度最大值先从数组中取最大值,等下再计算应该显示的最大值
  var nMaxScal =  Math.max.apply(null,option.series[0].data);
  //刻度最小值在本实例中取0
  var nMinScal = 0;
  //刻度线段数在本实例中设置为4
  var nSplit = 4;
  //计算刻度间隔值
  var nStep = (nMaxScal-nMinScal)/nSplit;
  //这时候会发现刻度间隔值好像有点奇怪,因为一般图表的刻度间隔值都是5的倍数,
  //比如:[0,0.5,1.0,1.5,2]或[0,50,100,150,200]。
  //所以还需要进一步计算,看nStep是否是5的倍数,如果不是,则递增nIncrease,使其达到最接近的5的倍数。
  //计算第一步,根据nStep算出倍数值应该是0.5或5或50或...
  //在本实例中通过把nStep数值先转换为字符串再进行处理(也可以使用对数和指数去计算)。
  var sTemp = '' + nStep; //把nStep转换为字符串
  //声明一个需要递增的数,默认为1
  var nIncrease = 1;
  //声明一个变量用于解决小数相乘产生的精度bug
  var nTempMultiple = 1;  

  //nIncrease取10的n次幂,通过以下判断计算
  if(sTemp.indexOf('.')==-1){
    //如果nStep不包含小数点,nIncrease取10的sTemp.length-2次幂。
    //比如nStep为19的话,nIncrease = 10的0次幂,递增数为1
    //nStep为9的话,nIncrease = 10的-1次幂,递增数为0.1
    //nStep为199的话,nIncrease = 10的1次幂,递增数为10
    nIncrease = Math.pow(10,sTemp.length-2);
  }else{
    //如果nStep包含小数点,nIncrease取10的sTemp整数位-2次幂。
    nIncrease = Math.pow(10,sTemp.indexOf('.')-2);
    //这个变量用于解决小数相乘可能产生的精度bug,比如nIncrease是小数的情况
    nTempMultiple = Math.pow(10,sTemp.indexOf('.'));
  }
  //倍数取整,便于递增,如165改成160,16.5改成16,1.65改成1.6,可通过下列公式实现
  nStep = Math.ceil(nStep/nIncrease)*(nIncrease*nTempMultiple)/nTempMultiple;
  //使用循环递增nIncrease修正刻度值
  while(nStep%(nIncrease*5)!=0){
    nStep += nIncrease*1;
  }
  //通过间隔值乘以线段数,修改刻度最大值
  nMaxScal = nStep * nSplit;
  //计算y轴长度,这里多减3是因为y轴顶端要留点距离
  var nLonY = nZoneEndY - nZoneStartY - 3;
  //绘制y轴刻度
  for(let i=0;i<=nSplit;i++){
    //刻度线起点都在y轴上
    let nScaleX = nZoneStartX;
    //计算出y轴刻度线起点在y轴上的值
    let nScaleY = nZoneEndY-Math.floor(nLonY*(i/nSplit));
    //6.2 绘制刻度线
    fnCreatLine(nScaleX,nScaleY,nScaleX-10,nScaleY);
    //6.3 绘制刻度值
    fnCreatText(''+i*nStep,nScaleX-20,nScaleY,'#333');
    if(i!=0){
      //6.4 非0位置,绘制x轴网格线
      fnCreatLine(nScaleX,nScaleY,nScaleX+nLonX,nScaleY,'#ccc');
    }
  }

  //7.1 计算柱图宽度
  let nBarWidth = Math.ceil(Math.floor(nLonX*(1/nDataLon))*.8);
  //遍历x轴数据
  for(let i=0;i<nDataLon;i++){
    //7.2 计算柱图高度
    let nBarHeight = nLonY/nMaxScal*option.series[0].data[i];
    //7.3 计算柱图X起点
    let nBarStartX = nZoneStartX+Math.floor(nLonX*(i/nDataLon))
                     +(Math.floor(nLonX*(1/nDataLon))-nBarWidth)/2;
    //7.4 计算柱图Y起点
    let nBarStartY = nZoneEndY-nBarHeight;
    //7.5 绘制柱图
    fnCreatRect(nBarStartX,nBarStartY,nBarWidth,nBarHeight);
  }

  //绘制线条函数
  function fnCreatLine(sX,sY,eX,eY,color='#000'){
    //开始绘制路径
    oCtx.beginPath();
    //设置路径颜色
    oCtx.strokeStyle = color;
    //设置路径起点和终点,绘制线条
    oCtx.moveTo(sX,sY);
    oCtx.lineTo(eX,eY);
    //给路径添加颜色
    oCtx.stroke();
  }

  //绘制文字
  function fnCreatText(text,x,y,color='#000',align='end',baseLine='middle'){
    //设置文字颜色
    oCtx.fillStyle = color;
    //设置水平对齐方式
    oCtx.textAlign = align;
    //设置垂直对齐方式
    oCtx.textBaseline = baseLine;
    //绘制文字
    oCtx.fillText(text,x,y);
  }

  //绘制矩形
  function fnCreatRect(x,y,width,height,color='#a00'){
    //设置颜色
    oCtx.fillStyle = color;
    oCtx.fillRect(x,y,width,height);
  }
}
//调用图表函数,并传入元素id和option数据
fnCharts('canvasWrap',option);

这篇实例教程可能需要点耐心去读源码,如果碰到不明白的地方,可以在不明白的源码位置输出值,也许能豁然开朗。

以上就是JS使用canvas技术模仿echarts柱状图的详细内容,更多关于JS使用canvas柱状图的资料请关注我们其它相关文章!

(0)

相关推荐

  • JavaScript canvas基于数组生成柱状图代码实例

    HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形.字符以及添加图像的方法. canvas 元素本身是没有绘图能力的.所有的绘制工作必须在 JavaScript 内部完成: canvas柱状图 var arr = [ { id: 1001, price: 100 }, { id: 1002, price: 150 }, { id: 1003, price: 200 }, { id

  • jQuery.Highcharts.js绘制柱状图饼状图曲线图

    在数据统计和分析业务中,有时会遇到客户需要在一个图表中将柱状图.饼状图.曲线图的都体现出来,即可以从柱状图中看出具体数据.又能从曲线图中看出变化趋势,还能从饼状图中看出各部分数据比重.Highcharts可以轻松实现三图合一的效果. 复制代码 代码如下: var chart;             $(document).ready(function() {                 chart = new Highcharts.Chart({                     c

  • JS highcharts动态柱状图原理及实现

    实现一个柱状图,这个柱状图的高度在不停的刷新,效果如下: 官网是没有动态刷新的示例的,由于需要我查看了其源码,并根据之前示例做出了动态柱状图的效果,希望对同学们有用! 看一下代码: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>Highcharts Example&l

  • 利用D3.js实现最简单的柱状图示例代码

    首先把效果图放出来: 具备了一个柱状图的基础元素:柱形,坐标轴,刻度,数值等. 不得不说,d3.js比直接用的echarts更麻烦,但是确实更自由. 来看看如何实现吧. //确定画布的大小 var width = 400; var height = 400; //在 body 里添加一个 SVG 画布 var svg = d3.select("body") .append("svg") .attr("width", width) .attr(&q

  • Javascript实时柱状图实现代码

    实时柱状图 span{ background-color:lime;font-size:1px;} var arr = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,

  • JavaScript实现的DOM绘制柱状图效果示例

    本文实例讲述了JavaScript实现的DOM绘制柱状图效果.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>www.jb51.net JavaScript DOM绘制柱状图</title> <

  • D3.js实现柱状图的方法详解

    D3.js介绍 D3.js 是一个基于数据操作文档JavaScript库.D3帮助你给数据带来活力通过使用HTML.SVG和CSS.D3重视Web标准为你提供现代浏览器的全部功能,而不是给你一个专有的框架.结合强大的可视化组件和数据驱动方式Dom操作.这里也可以看到它是用SVG来呈现图表的,所以使用D3.js是需要一定的SVG基础的. 如何用D3.js实现柱状图? 柱状图里面有坐标轴和柱子.然而我们还需要SVG画布来画这些东西.先把大概的画图框架搭起来,代码如下(请注意此时我在body标签里添加

  • angularjs实现柱状图动态加载的示例

    一 准备工作 1.引用文件 下面链接中有一个jquery.js文件,请在index.html中引用. 2.新建文件 新建一个js文件,编写指令.这也是我第一次写指令,指令可扩展性强,还很方便,当项目中重复使用的一些效果时可以通过指令来减少冗余的代码. 二 代码编写 /** * Created by xiehan on 2017/12/8. * 柱状图动态加载指令 */ angular.module('studyApp.directives') .directive('progressPer',

  • JavaScript根据数据生成百分比图和柱状图的实例代码

    复制代码 代码如下: <HTML> <head> <title>JS百分比图和柱状图</title>   <xml:namespace prefix="v"/>   <style>    v\:* {behavior=url(#default#VML)}   </style>   <style>   a:hover {color:maroon}   h2 {color:#006600;  

  • JS使用canvas技术模仿echarts柱状图

    canvas 画布是html5中新增的标签,可以通过js操作 canvas 绘图 API在网页中绘制图像. 百度开发了一个开源的可视化图表库ECharts,功能非常强大,可以实现折线图.柱状图.散点图.饼图.K线图.地图等多种图表.很多项目都有使用过ECharts开发过图表功能. 本实例教程使用原生js教你开发一个仿ECharts的柱状图.学习本教程之前,读者需要具备html和css技能,同时需要有简单的JavaScript基础. 按照ECharts的开发方法,图表都是生成在一个HTML元素中.

  • js+h5 canvas实现图片验证码

    本文实例为大家分享了js+h5 canvas实现图片验证码的具体代码,供大家参考,具体内容如下 实现效果 一.使用技术 原生js技术+html5 canvas画图 利用Math.random()函数随机生成 颜色 字符串  及障碍物 点击 验证码可变更验证码图案 二.使用步骤 1.html+css 代码如下(示例): <div class="login_code_box"> <div class="login_code"> <input

  • 使用echarts柱状图实现select下拉刷新数据

    目录 echarts柱状图实现select下拉刷新数据 表格的下拉框中包含echarts图表的demo echarts柱状图实现select下拉刷新数据 废话少说,直接上代码 <div>月度 <select id="year_data"> <option value="1" class="active">3月</option> <option value="2">4月

  • JS基于VML技术实现的五角星礼花效果代码

    本文实例讲述了JS基于VML技术实现的五角星礼花效果代码.分享给大家供大家参考,具体如下: 这里演示的五角星礼花,基于HTML+js+VML技术共同编写实现,打开页面即可看到礼花绽放效果,五角星符号可以换成其它的符号,本效果可轻松修改成烟花升空爆炸特效,不过你要事先制作一个烟花的GIF小图,然后替换掉五角星. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-vml-wjx-style-demo/ 具体代码如下: <HTML> <HE

  • Js利用Canvas实现图片压缩功能

    最近做的APP项目涉及到手机拍照上传图片,因为手机拍照的图片通常都比较大,所以上传的时候就会很慢.为此,需要对图片进行压缩处理来优化上传功能.以下是具体实现: /* * 图片压缩 * img 原始图片 * width 压缩后的宽度 * height 压缩后的高度 * ratio 压缩比率 */ function compress(img, width, height, ratio) { var canvas, ctx, img64; canvas = document.createElement

  • JS+html5 canvas实现的简单绘制折线图效果示例

    本文实例讲述了JS+html5 canvas实现的简单绘制折线图效果.分享给大家供大家参考,具体如下: 1.实例代码: <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>画图</title> <style> #divContainer{ margin-top: 20px; text-align: center; } #cv{ width: 300px;

  • JS使用面向对象技术实现的tab选项卡效果示例

    本文实例讲述了JS使用面向对象技术实现的tab选项卡效果.分享给大家供大家参考,具体如下: 运行效果图如下: 代码如下: html: <ul class="scrollUl"> <li id="m01" class="sd01" value="0"><a href="#" rel="external nofollow" rel="external

  • js实现canvas保存图片为png格式并下载到本地的方法

    整理文档,搜刮出一个js实现canvas保存图片为png格式并下载到本地的方法,稍微整理精简一下做下分享. 1.canvas 保存图片 2.下载到本地 function base64Img2Blob(code){ var parts = code.split(';base64,'); var contentType = parts[0].split(':')[1]; var raw = window.atob(parts[1]); var rawLength = raw.length; var

  • js 将canvas生成图片保存,或直接保存一张图片的实现方法

    将canvas数组保存 function downLoadImage(canvas,name) { var a = document.createElement("a"); a.href = canvas.toDataURL(); a.download = name; a.click(); } canvas:传入canvas的dom对象 name:保存的图片的名字 直接将图片保存的方法 function downLoadImage(img,name) { var a = documen

  • JS和Canvas实现图片的预览压缩和上传功能

    先来一张效果图,压压惊 第一步:用户选择需要上传的图片 <input type="file" accept="image/*" type="file"" name="imageFile" onchange="upload()"> 在选定了图片后 upload 函数将被触发,我们需要在这个函数中,获取到图片的资源,将它压缩并利用canvas绘制出来,若需要上传到服务器,也可以利用ajax

随机推荐