canvas系列教程06-柱狀圖項目4

上一篇文章我已經說過數據準備好畫圖就很是簡單了,若是你擔憂不回話好辦,我給你個最簡單的小例子,html

你先練練。
畫圖.pnggit

這個很簡單吧,什麼面向對象什麼的都不用,你就先用最粗暴的方式擼出來。github

而後,你在看下面我寫的代碼就容易了。最終效果圖canvas

screenshot.png

下面代碼只有一個難點:segmentfault

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<c.itemNum;i++){
          var labelXText = c.label[i];
          var labelPosX = c.horGap + i*c.horFeq +c.horFeq/2;
          var labelPosY = c.ch - c.verGap+c.verGap/c.axeRadio;
          gd.textAlign = 'center';
          gd.textBaseline = 'top';
          gd.fillText(labelXText,labelPosX,labelPosY);
        }
      };


    };
    Bcharts.prototype.drawY = function(){
      var c = this;
      var gd = c.context;
        gd.moveTo(c.horGap,c.ch -c.verGap);
        gd.lineTo(c.horGap,c.verGap);
        gd.lineWidth = 2;
        gd.stroke();
    };
    Bcharts.prototype.HorGuideLines = function(){
      var c = this;
      var gd = c.context;

      gd.strokeStyle = '#eeeeee';
      gd.lineWidth = 1;
      for(var i = 0;i<c.itemNum;i++){
        gd.beginPath();
        var scaleReq = (c.verAxiWidth/c.verBound)*c.verFeq;
        var horStartX = c.horGap;
        var horStartY = c.verGap+i*scaleReq;
        var horEndX = c.cw -c.horGap;
        var horEndY = c.verGap+i*scaleReq;
        gd.moveTo(horStartX,horStartY);
        gd.lineTo(horEndX,horEndY);
        gd.stroke();

      }
    };
    Bcharts.prototype.verGuideLines = function(){
      var c = this;
      var gd = c.context;

      gd.strokeStyle = '#eeeeee';
      gd.lineWidth = 1;
      for(var i = 0;i<=c.itemNum;i++){
        gd.beginPath();
        var verStartX = c.horGap+i*c.horFeq;
        var verStartY = c.ch - c.verGap;
        var verEndX = c.horGap+i*c.horFeq;
        var verEndY = c.verGap;
        gd.moveTo(verStartX,verStartY);
        gd.lineTo(verEndX,verEndY);
        gd.stroke();

      }
    };
    Bcharts.prototype.drawBars = function () {
      // alert(1);
      var c = this;

      for(var i = 0; i < c.itemNum; i++){
        // alert(1);
        var color = c.rndColor();
        var fillOpacity = '0.3';
        var fillColor = 'rgba('+ color.r + ', ' + color.g  + ', ' + color.b + ', ' + fillOpacity +')';
        var borderColor = 'rgba('+ color.r + ', ' + color.g  + ', ' + color.b + ')';

        c.context.beginPath();

        var barX = c.horGap + i * c.horFeq+c.horFeq/c.axeRadio;
        var barY = c.ch - c.verGap;
        var barWidth = c.horFeq - 2*c.horFeq/c.axeRadio;
        var barHeight = -c.verAxiWidth * c.values[i] / c.MaxValue;
        console.log(c.MaxValue);

        c.context.fillStyle = fillColor;
        c.context.strokeStyle = borderColor;
        c.context.rect(barX, barY, barWidth, barHeight);
        // console.log(barX,barY,barWidth,barHeight);
        c.context.stroke();
        c.context.fill();
      }
    };

    Bcharts.prototype.rndColor = function () {
      var r = getRandomInt(0, 257);
      var g = getRandomInt(0, 257);
      var b = getRandomInt(0, 257);
      return {r: r, g: g, b: b};
    };
    var charts = new Bcharts(targetId,cw,ch,data);
};
//https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/random
// 偷個懶,基礎函數不寫了
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}

PS:裏面不少基礎函數要會,其實畫canvas考驗的不是canvas技術,而是數學和基礎知識,必定要打好基礎。app

整個代碼git地址:echarts

https://github.com/leolau2012...
相關文章
相關標籤/搜索