推開Canvas&&SVG的大門,一起走向ECharts&&D3的世界

最近遇到線條處理的問題,所以將之前使用過的Canvas,SVG(從實(shí)現(xiàn)畫線的角度進(jìn)行出發(fā)),進(jìn)行總結(jié);順便將ECharts和D3兩大庫引入進(jìn)來,進(jìn)行闡述,這兒我從單一層面闡述ECharts和D3簡單使用,至于它們更強(qiáng)大的光芒,期待自己后面內(nèi)容不斷更新~

關(guān)鍵點(diǎn)

  • 1.Canvas,SVG實(shí)現(xiàn)線條繪制
  • 2.Canvas,SVG對(duì)比
  • 3.Canvas,SVG實(shí)現(xiàn)常見效果畫餅圖
  • 4.ECharts和D3庫的簡單使用

一.Canvas

1.canvas介紹

canvas標(biāo)簽定義圖形渐溶,比如圖表和其他圖像。標(biāo)記由 Apple 在 Safari 1.3 Web 瀏覽器中引入蕉汪。對(duì) HTML 的這一根本擴(kuò)展的原因在于钧舌,HTML 在 Safari 中的繪圖能力也為 Mac OS X 桌面的 Dashboard 組件所使用巡蘸,并且 Apple 希望有一種方式在 Dashboard 中支持腳本化的圖形叨咖。歷史這兒就簡單了解即可,知道Canvas是如何誕生的;

2.canvas使用

使用Canvas(重要點(diǎn)),大多數(shù) Canvas 繪圖 API 都沒有定義在canvas元素本身上,而是定義在通過畫布的 getContext() 方法獲得的一個(gè)“繪圖環(huán)境”對(duì)象上惋戏。直白的說,通過豐富的Canvas API,在畫布上畫出我們想要的美眉(哈哈,你懂的~)
??直接上DEMO,使用我們的強(qiáng)大的Canvas畫起屬于我們的線條;

//1>.畫線
HTML:
    /*注意:此處width,height寫成屬性賦值,不使用css,立flag,不是我們的重點(diǎn)*/
    <canvas id="c1" width="800" height="600"></canvas>;  
JS:
    var oC=document.getElementById('c1');
    var gd=oC.getContext('2d');
        
    gd.beginPath();         //beginPath() 方法開始一條路徑邀杏,或重置當(dāng)前的路徑贫奠。(注意:當(dāng)通過定時(shí)器不斷重新繪制,讓元素動(dòng)起來,beginPath()能夠清除之前的路徑)
    gd.moveTo(100,100);     //起始點(diǎn)
    gd.lineTo(300,300);     //從起始點(diǎn)到某點(diǎn)畫線
    gd.closePath();         //封閉空間
    
    gd.strokeStyle = 'red'; //設(shè)置邊框樣式
    gd.lineWidth=20;        //設(shè)置線條寬度
    gd.stroke();            //繪制路徑
    
    gd.fillStyle = 'green'; //設(shè)置填充樣式
    gd.fill();              //進(jìn)行填充
    
//2>.畫矩形
   var gd = document.getElementById('c1').getContext('2d');
   gd.fillStyle='red';    //設(shè)置填充顏色(注意順序:先設(shè)置樣式,然后根據(jù)樣式進(jìn)行填充;順序錯(cuò)了沒有效果)
   gd.fillRect(100, 100, 400, 300);  //繪制矩形

//3>.繪制圓
  //為了方便(弧度與角度的轉(zhuǎn)換)計(jì)算和使用,可以將其封裝成JavaScript函數(shù)(后面有推薦內(nèi)容可看)
  function getRads (degrees) { return (Math.PI * degrees) / 180; }  //角度轉(zhuǎn)弧度
  function getDegrees (rads) { return (rads * 180) / Math.PI; }  //弧度轉(zhuǎn)角度
  
  var gd = document.getElementById('c1').getContext('2d');
  //語法:arc(圓心x, 圓心y, 半徑, 起點(diǎn)角度(弧度), 終點(diǎn)角度(角度), 是否逆時(shí)針)
  gd.arc(300,300,100,getRads(0),getRads(360),false);  //繪圓
  gd.stroke();     //描邊

二.SVG

1.SVG介紹

可縮放矢量圖形(Scalable Vector Graphics望蜡,SVG)是基于可擴(kuò)展標(biāo)記語言(XML)唤崭,用于描述二維矢量圖形的一種圖形格式。SVG由W3C制定脖律,是一個(gè)開放標(biāo)準(zhǔn)谢肾。

2.SVG畫線

//1>.畫直線(注意點(diǎn):1.svg能夠直接響應(yīng)事件 2.x1,y1起點(diǎn) , x2,y2終點(diǎn))
    <svg id="svg1" width="800" height="600">
      <line x1="100" y1="100" x2="300" y2="300" style="stroke:red; stroke-width:20;" onmouseover="this.style.stroke='green'" onmouseout="this.style.stroke='red'" />
    </svg>
   
//2>.畫矩形[style="stroke:red(外部線條) ; fill:green(填充)"]
    <svg id="svg1" width="800" height="600">
      <rect x="100" y="100" width="300" height="200" style="stroke:red;fill:green" />
    </svg>
  
//3>.畫圓(cx,cy:圓心 , r:半徑)
    <svg id="svg1" width="800" height="600">
      <circle cx="300" cy="300" r="200" />
    </svg>
  
 //4>.畫橢圓(cx,cy:圓心 ; rx:水平半徑,ry:垂直半徑)
    <svg id="svg1" width="800" height="600">
      <ellipse cx="300" cy="200" rx="200" ry="100" />
    </svg>
 
 //5>.使用path能夠?qū)崿F(xiàn)上面的所有效果(line,rect,circle,ellipse)
        *1.實(shí)現(xiàn)line效果(M 起點(diǎn)坐標(biāo) ; L 畫線路徑,可以多點(diǎn)路徑) //注意點(diǎn):數(shù)值之間也可以使用,連接.
        <svg id="svg1" width="800" height="600">
           <path d="M 100 100 L 300 300" style="stroke:black;fill:none;" />
        </svg>
      
      *2.實(shí)現(xiàn)rect效果(Z封閉空間)
        <svg id="svg1" width="800" height="600">
              <path d="M 100,100 L 400,100 400,300 100,300 Z" style="stroke:black;fill:none;" />
           </svg>
      
        *3.實(shí)現(xiàn)circle,ellipse效果
            /*
       path中d屬性的解析:
              M(x,y)  起始點(diǎn)
              L(x,y)  線條位置,可以有很多線條
              Z       封閉空間
              A       rx ry(半徑)  x-axis-rotation(旋轉(zhuǎn)角度)  large-arc-flag(大小弧標(biāo)志0,1) sweep-flag(鏡像標(biāo)志:弧顯示的位置 0左 1右)  x y(終點(diǎn))
       */
    
          <svg id="svg1" width="800" height="600">
              <path d="
                  M 100,100
                  L 200,100
                  A 150,50,0,1,0,300,100
                  L 400,100
              " style="stroke:black;fill:none;" />
         </svg>

三.Canvas和SVG比美

沒有完美的人,自然也沒有完美的代碼,有時(shí)候缺點(diǎn)可能是優(yōu)點(diǎn)的觸發(fā)點(diǎn)(又毒雞湯了,不過確實(shí)如此)

Canvas | SVG|
----|------|----
位圖(像素,放大失真) |矢量圖(沒單位,放大不失真)
依賴js | 脫離js
圖形不能修改 | 圖形可以修改
沒有事件| 有事件
性能很高| 性能一般
適合:大型圖表,游戲|適合:地圖,交互頻繁的圖表

四.常用案例通過Canvas和SVG分別實(shí)現(xiàn)餅圖

1.Canvas畫餅

pie.png
function getRads (degrees) { return (Math.PI * degrees) / 180; }  //角度轉(zhuǎn)弧度
function getDegrees (rads) { return (rads * 180) / Math.PI; }  //弧度轉(zhuǎn)角度

window.onload = function (){
      var oC = document.getElementById('c1');
      var oBtn = document.getElementById('btn1');

      var gd = oC.getContext('2d');

      function pie(startAng, endAng, color) {
        //#1.根據(jù)角度,畫出線條
        var x = Math.cos(getRads(startAng))*150+300;
        var y = Math.sin(getRads(startAng))*150+300;

        gd.beginPath();
        gd.moveTo(300,300);
        gd.lineTo(x,y);
        gd.strokeStyle = 'cyan';
        gd.stroke();

        //#2.畫弧
        gd.arc(300,300,150,getRads(startAng),getRads(endAng),false);

        //#3.閉合
        gd.closePath();

        gd.fillStyle = color;
        gd.fill();
      }

      //原始數(shù)據(jù)
      var arr = [1,1,1,1,1,1];   //每部分的值隨便給
      var aColor = ['red', 'blue', 'green', 'yellow', 'pink', 'purple']; //顏色隨便給

      //1.求和:(目的算出每個(gè)部分所占的等分,求得對(duì)應(yīng)角度)
      var sum = 0;
      for(var i = 0;i<arr.length;i++){
        sum += arr[i];
      }

      //2.比例、角度(算出每份所占角度)
      var arrAng = [];
      for(var i = 0;i<arr.length;i++){
        arrAng[i] = 360*arr[i]/sum;
      }

      //3.畫角
      //第n個(gè)pie      前一次~前一次+arrAng[n]
      var now = 0;
      for(var i = 0;i<arrAng.length;i++){
        pie(now, now+arrAng[i], aColor[i]);
        now += arrAng[i];
      }
    };

2.SVG畫餅

    <svg id="svg1" width="800" height="600">
      <path d=
          "
          M 300,300
          L 441,158
          A 200,200,0,0,1,400,473
          Z
          " 
      style="stroke:black;fill:red;" />
    </svg>

五.ECharts

1.ECharts介紹

ECharts小泉,縮寫來自Enterprise Charts芦疏,商業(yè)級(jí)數(shù)據(jù)圖表,一個(gè)純Javascript的圖表庫微姊,可以流暢的運(yùn)行在PC和移動(dòng)設(shè)備上酸茴,兼容當(dāng)前絕大部分瀏覽器(IE6/7/8/9 /10/11,chrome兢交,firefox薪捍,Safari等),底層依賴輕量級(jí)的Canvas類庫ZRender,提供直觀酪穿,生動(dòng)与倡,可交互,可高度個(gè)性化定制的數(shù)據(jù)可視化圖表昆稿。創(chuàng)新的拖拽重計(jì)算、數(shù)據(jù)視圖息拜、值域漫游等特性大大增強(qiáng)了用戶體驗(yàn)溉潭,賦予了用戶對(duì)數(shù)據(jù)進(jìn)行挖掘、整合的能力少欺。
支持折線圖(區(qū)域圖)喳瓣、柱狀圖(條狀圖)、散點(diǎn)圖(氣泡圖)赞别、K線圖畏陕、餅圖(環(huán)形圖)、雷達(dá)圖(填充雷達(dá) 圖)仿滔、和弦圖惠毁、力導(dǎo)向布局圖、地圖崎页、儀表盤鞠绰、漏斗圖、事件河流圖等12類圖表飒焦,同時(shí)提供標(biāo)題蜈膨,詳情氣泡、圖例牺荠、值域翁巍、數(shù)據(jù)區(qū)域、時(shí)間軸休雌、工具箱等7個(gè)可交 互組件灶壶,支持多圖表、組件的聯(lián)動(dòng)和混搭展現(xiàn)杈曲。

architecture.png

2.ECharts使用

1>.餅圖
        <html>
          <head>
            <meta charset="utf-8">
            <title></title>
            <style media="screen">
            #div1 {width:500px;height:400px;border:1px solid black;}
            </style>
            <script src="echarts.js" charset="utf-8"></script>
            <script>
            window.onload=function (){
              //1.初始化
              var charts=echarts.init(document.getElementById('div1'));
        
              //2.數(shù)據(jù)
              var data={
                title: {   //標(biāo)題
                  text: '性別比例'
                },
                legend: {  //圖例(按鈕可點(diǎn)擊,進(jìn)行禁用)
                  data: ['男', '女', '其他']
                },
                series: [   //系列,可以實(shí)現(xiàn)嵌套餅圖
                  {
                    name: '性別',
                    type: 'pie',   //圖標(biāo)類型
                    radius: ['60%', '70%'],   //內(nèi)圓,外圓的半徑大小
                    data: [    //name顯示部分名字 ; value每部分對(duì)應(yīng)值
                      {name: '男', value: 57.3},
                      {name: '女', value: 41.6},
                      {name: '其他', value: 1.1}
                    ]
                  }
                ]
              };
        
              //3.放進(jìn)去
              charts.setOption(data);
            };
            </script>
          </head>
          <body>
            <div id="div1"></div>
          </body>
        </html>
ECharts_pie.png
1>.柱狀圖
      var oDiv=document.getElementById('div1');

      //1.初始化echarts對(duì)象
      var charts=echarts.init(oDiv);

      //2.數(shù)據(jù)寫好
      var data={
        //1>.標(biāo)題
        title: {
          text: '2016年產(chǎn)量'
        },
        //2>.x軸
        xAxis: {
          data: ['第1季度', '第2季度', '第3季度', '第4季度']
        },
        //3>.y軸
        yAxis: {},
        //4>.圖例
        legend: {},
        //5>.數(shù)據(jù)
        series: [
          {
            name: '產(chǎn)量',
            type: 'bar',
            data: [454334, 554433, 133221, 55666]
          }
        ]
      };

      //3.數(shù)據(jù)扔進(jìn)去
      charts.setOption(data);
    };
ECharts_ histogram.png

六.D3

雖然D3是強(qiáng)大的繪圖庫,用來做圖表,貌似不能突出他的強(qiáng)悍,但是這兒講解依然使用D3進(jìn)行圖表繪制,就忽略逼格的問題了~

1.D3介紹

D3可以將任意數(shù)據(jù)綁定到一個(gè)文檔對(duì)象模型(DOM),然后應(yīng)用數(shù)據(jù)驅(qū)動(dòng)轉(zhuǎn)換的文檔例朱。例如,您可以使用D3來生成一個(gè)HTML表從一個(gè)數(shù)字?jǐn)?shù)組∮悴酰或者,使用相同的數(shù)據(jù)創(chuàng)建一個(gè)交互式SVG條形圖平滑過渡和交互洒嗤。D3不是一個(gè)整體框架,旨在提供所有可能的功能。相反,D3解決了問題的癥結(jié)所在:文檔基于數(shù)據(jù)的有效處理魁亦。這避免了專有的表示和提供非凡的靈活性,暴露web標(biāo)準(zhǔn)的全部功能,如HTML渔隶、SVG和CSS。以最小的開銷,D3非常快,支持大型數(shù)據(jù)集和動(dòng)態(tài)行為交互和動(dòng)畫间唉。D3的功能性風(fēng)格允許代碼重用通過收集不同的組件和插件绞灼。(牛逼吹得可以)

2.D3畫餅

//D3使用過程中抓住:生成器 -> 數(shù)據(jù) -> 結(jié)果,形成整體脈絡(luò)即可,一步一步完成;

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="d3.js" charset="utf-8"></script>
    <style media="screen">
    #svg1 {border:1px solid black;}
    </style>
    <script>
    window.onload=function (){
      /*
      注意點(diǎn):提出g標(biāo)簽概念:在svg中提供了如g元素這樣的將多個(gè)元素組織在一起的元素。由g元素編組在一起的可以設(shè)置相同的顏色呈野,可以進(jìn)行坐標(biāo)變換;
      完成之后結(jié)構(gòu)<svg><g><path></path></g></svg>,如果直接使用path位置默認(rèn)為左上角,使用g標(biāo)簽更好控制圖形位置
      */
      //1.準(zhǔn)備工作
      var svg = d3.select('#svg1');
      var g = svg.append('g') 
      .attr('transform', 'translate(400,300)');  //添加g節(jié)點(diǎn),移動(dòng)位置

      var colors = ['#A0C', '#0AC', '#AC0', '#00C'];

      //2.餅圖生成器
      var pieGen = d3.pie();

      //3.生成一堆a(bǔ)rc數(shù)據(jù)
      var arrArc = pieGen([3000, 48000, 69000, 12000]);

      //4.arc生成器
      var arcGen = d3.arc();

      //5.arc生成器+arc數(shù)據(jù)  =>  一堆字符串(生成的字符串即path標(biāo)簽d屬性需要的屬性值)
      for(var i=0;i<arrArc.length;i++){
        var strArc=arcGen({
          innerRadius: 0,
          outerRadius: 150,
          startAngle: arrArc[i].startAngle,
          endAngle: arrArc[i].endAngle
        });

        //6.生成path元素
        g.append('path')
        .attr('d', strArc)
        .attr('fill', colors[i]);
      }
    };
    </script>
  </head>
  <body>
    <svg id="svg1" width="800" height="600"></svg>
  </body>
</html>

推薦閱讀:
Canvas學(xué)習(xí):繪制圓和圓弧
ECharts官網(wǎng)
D3中文手冊

全部代碼在這兒哦,點(diǎn)我點(diǎn)我;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末低矮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子被冒,更是在濱河造成了極大的恐慌军掂,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昨悼,死亡現(xiàn)場離奇詭異蝗锥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)率触,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門终议,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人葱蝗,你說我怎么就攤上這事穴张。” “怎么了两曼?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵陆馁,是天一觀的道長。 經(jīng)常有香客問我合愈,道長叮贩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任佛析,我火速辦了婚禮益老,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寸莫。我一直安慰自己捺萌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布膘茎。 她就那樣靜靜地躺著桃纯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪披坏。 梳的紋絲不亂的頭發(fā)上态坦,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音棒拂,去河邊找鬼伞梯。 笑死玫氢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谜诫。 我是一名探鬼主播漾峡,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喻旷!你這毒婦竟也來了生逸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤且预,失蹤者是張志新(化名)和其女友劉穎槽袄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辣之,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年皱炉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怀估。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡合搅,死狀恐怖多搀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灾部,我是刑警寧澤康铭,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站赌髓,受9級(jí)特大地震影響从藤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锁蠕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一夷野、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荣倾,春花似錦悯搔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至铸豁,卻和暖如春灌曙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背节芥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工平匈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓增炭,卻偏偏與公主長得像忍燥,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子隙姿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容