资讯专栏INFORMATION COLUMN

canvas系列教程06-柱状图项目4

wangym / 1447人阅读

摘要:最终效果图下面代码只有一个难点怎么算横轴纵轴坐标位置其余就容易多了,有一个注意问题,我其实写复杂了各种位置都是动态算的,因为实际项目你用写死的数值浏览器适配就会出问题。

上一篇文章我已经说过数据准备好画图就非常简单了,如果你担心不回话好办,我给你个最简单的小例子,

你先练练。

这个很简单吧,什么面向对象什么的都不用,你就先用最粗暴的方式撸出来。

然后,你在看下面我写的代码就容易了。最终效果图

下面代码只有一个难点:

1.怎么算横轴、纵轴label坐标位置

其余就容易多了,有一个注意问题,我其实写复杂了各种位置都是动态算的,因为实际项目你用 写死的数值浏览器适配就会出问题。不说了上代码,先耐着性子敲一遍,然后在一点点研究。

/**
  此处可以写一些装13的东西
  尽可能用英文,不会可以自己百度,

  例如:
  Author:leo lau
  desc:ni shishibushiwozuitengaideren ,ni weisha bushuo hua
**/
"use strict";
//模仿 http://echarts.baidu.com/demo.html#bar-gradient
window.onload = function(){
    var data = [
      {"label":"一月","value":getRandomInt(0,400)},
      {"label":"二月","value":getRandomInt(1,400)},
      {"label":"三月","value":getRandomInt(1,400)},
      {"label":"四月","value":getRandomInt(0,400)},
      {"label":"五月","value":getRandomInt(1,400)}
    ];

    var targetId = "div1";
    var cw = 600;
    var ch = 450;
    //为啥用面向对象方式,因为显得拽呗
    //
    function Bcharts(targetId,cw,ch,data){
      //基础信息
        var c = this;//为啥这么做?我懒,c = chart = this;
        c.configureChart(targetId,cw,ch,data);
        c.init();

    }
    Bcharts.prototype.configureChart = function(targetId,cw,ch,data){
      var c = this;
      c.setCanvasParameters(targetId,cw,ch,data);
      c.setChartParameters(targetId,cw,ch,data);
    };
    Bcharts.prototype.setCanvasParameters = function(targetId,cw,ch,data){
      var c = this;
      c.id = targetId;
      c.cw = cw;
      c.ch = ch;
      c.data = data;
    };
    Bcharts.prototype.setChartParameters = function(targetId,cw,ch,data){
      var c = this;
      c.axeRadio = 10;//定义一个比例,为啥是10,看图大体是这个随便定的,别忒离谱就好
      c.horGap = (c.cw*c.axeRadio)/100;
      c.verGap = (c.ch*c.axeRadio)/100;
    //标识准备
      c.fontRadio = 3;//原因同上
      c.horFontSize = (c.cw*c.fontRadio)/100;
      c.verFontSize = (c.ch*c.fontRadio)/100;

    };
    //初始化
    Bcharts.prototype.init = function(){
        var c = this;
        c.createCanvas();
        //这里只是把后台给你的数据整理好了,并不是图表直接能画的数据
        //比如最大值是234,其实我们要花240,不可能是不整齐的
        c.handleData();
        //所以需要处理数据
        c.prepareData();

        //开画
        c.draw();


    };
    Bcharts.prototype.createCanvas = function(){
        var c = this;
        var canvas = document.createElement("canvas");
        canvas.id = c.id + "-" + Math.random();
        canvas.width = c.cw;
        canvas.height = c.ch;
        document.getElementById(c.id).innerHTML = "";
        document.getElementById(c.id).appendChild(canvas);
        c.canvas = canvas;
        c.context = c.canvas.getContext("2d");
    };
    Bcharts.prototype.handleData = function(){
        //因为后台肯定给你标准的数组格式一堆,但是你没法直接用,得自己666一把
        var c = this;
        c.label = [];//这个数组放循环内容的名字,比如[一月,二月]
        c.values = [];//放值[200,45……]
        c.data.forEach(function(item){
          c.label.push(item.label);
          c.values.push(item.value);
        });
    };
    Bcharts.prototype.prepareData = function(){
        var c = this;
        c.itemNum = c.data.length;
        c.MaxValue = Math.max.apply(null,c.values);
        c.MinValue = Math.min.apply(null,c.values);
        //算坐标宽高
        c.horAxiWidth = c.cw - 2*c.horGap;
        c.verAxiWidth = c.ch - 2*c.verGap;

        //计算最大上边界,比如最大数是234,坐标得到240,而不是234
        //确定横竖格宽度
        c.verBound = Math.ceil(c.MaxValue/10)*10;
        c.verFeq = c.verBound/c.itemNum;
        c.horFeq = c.horAxiWidth/c.itemNum;
    };
    Bcharts.prototype.draw = function(){
        var c = this;
        c.drawX();//x轴
        c.drawY();//y轴
        c.drawYLabel();//y坐标字儿
        c.drawXLabel();//y坐标字儿
        c.HorGuideLines();
        c.verGuideLines();
        c.drawBars();
    };
    Bcharts.prototype.drawX = function(){
      var c = this;
      var gd = c.context;
        gd.beginPath();
        gd.moveTo(c.horGap,c.ch -c.verGap);
        gd.lineTo(c.cw -c.horGap,c.ch -c.verGap);
        gd.lineWidth = 2;
        gd.stroke();
    };
    Bcharts.prototype.drawY = function(){
      var c = this;
      var gd = c.context;
        gd.beginPath();
        gd.moveTo(c.horGap,c.ch -c.verGap);
        gd.lineTo(c.horGap,c.verGap);
        gd.lineWidth = 2;
        gd.stroke();
    };
    Bcharts.prototype.drawYLabel = function(){
      var c = this;
      var gd = c.context;
      for(var i = 0;i<=c.itemNum;i++){
        var labelYText = c.verBound - i*c.verFeq;
        var labelPosX = c.horGap - c.horGap/c.axeRadio;
        var scaleReq = (c.verAxiWidth/c.verBound)*c.verFeq;
        var labelPosY = c.verGap+i*scaleReq;
        gd.textAlign = "right";
        gd.fillText(labelYText,labelPosX,labelPosY);
      }
      Bcharts.prototype.drawXLabel = function(){
        var c = this;
        var gd = c.context;
        for(var i = 0;i

PS:里面很多基础函数要会,其实画canvas考验的不是canvas技术,而是数学和基础知识,一定要打好基础。

整个代码git地址:

https://github.com/leolau2012...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90344.html

相关文章

  • canvas系列教程03-柱状项目1

    摘要:弄了一堆线方块和函数,感觉挺玄乎,然并卵。我们直接写个项目看看。一个比较拽的应用就是图表和游戏,我们从浅入深,先玩图表,图表我们今天说一个最简单柱状图。第三件事,数据我用的模拟,实际项目一般是后台提供。 弄了一堆线方块和函数,感觉挺玄乎,然并卵。我们直接写个项目看看。 canvas一个比较拽的应用就是图表和游戏,我们从浅入深,先玩图表,图表我们今天说一个最简单柱状图。showImg(h...

    xiaolinbang 评论0 收藏0
  • canvas系列教程04-柱状项目2

    摘要:我们提前做些准备工作,比如画图前先把坐标边距做出来,还有各种字体大小算出来。最终代码如下,模仿一月一月一月基础信息为啥这么做我懒,定义一个比例为啥是,看图大体是这个随便定的,别忒离谱就好标识准备原因同上初始化偷个懒,基础函数不写了 我们提前做些准备工作,比如画图前先把坐标边距做出来,还有各种字体大小算出来。 这里需要一点面向对象的知识, use strict; //模仿 http://...

    Dogee 评论0 收藏0

发表评论

0条评论

wangym

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<