[study4.tw] 前端視覺化實戰 - d3.js

65
前端視覺化實戰 - D3.JS Kuro Hsu @ Study4.TW 2015.07.18

Upload: kuro-hsu

Post on 15-Aug-2015

869 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: [Study4.TW] 前端視覺化實戰 - D3.js

前端視覺化實戰 - D3.JS

Kuro Hsu @ Study4.TW

2015.07.18

Page 2: [Study4.TW] 前端視覺化實戰 - D3.js
Page 3: [Study4.TW] 前端視覺化實戰 - D3.js
Page 4: [Study4.TW] 前端視覺化實戰 - D3.js

D3 是什麼• D3 = Data-Driven Documents.

• 使⽤用網⾴頁標準技術

• 將資料直接對應到 DOM tree 上,包括元素的增刪及屬性變化

• 也提供了 SVG 相關繪圖 libraries

• 號稱 SVG 界的 jQuery

Page 5: [Study4.TW] 前端視覺化實戰 - D3.js

SELECTIONS 選擇器

Page 6: [Study4.TW] 前端視覺化實戰 - D3.js

JavaScript

jQuery

D3.js

 document.querySelectorAll(".block")

 $(".block")

 d3.selectAll(".block")

Page 7: [Study4.TW] 前端視覺化實戰 - D3.js

   var  box  =  d3.selectAll('.box');  

   box.style('color',  '#f00');  

   box.text('Hello  World!');

Page 8: [Study4.TW] 前端視覺化實戰 - D3.js

 //  也可以串在⼀一起  

 var  box  =  d3.selectAll('.box')  

                           .style('color',  '#f00')  

                           .text('Hello  World!');

Page 9: [Study4.TW] 前端視覺化實戰 - D3.js

 $('.foo').addClass('foobar');    $('.foo').removeClass('foobar');

 d3.selectAll('.foo').classed('foobar',  true);        d3.selectAll('.foo').classed('foobar',  false);      

Class

Page 10: [Study4.TW] 前端視覺化實戰 - D3.js

var  foo  =  $('.foo');foo.text('Hello  World!');  foo.html('<div  class="bar">Hello</div>');

var  foo  =  d3.selectAll('.foo');  foo.text('Hello  World!');      foo.html('<div  class="bar">Hello</div>');    

Text / HTML

Page 11: [Study4.TW] 前端視覺化實戰 - D3.js

 //  屬性  attr()  d3.selectAll("circle")          .attr("cx",  50)          .attr("cy",  50)          .attr("r",  25)          .style("fill",  "red");

Attribute

Page 12: [Study4.TW] 前端視覺化實戰 - D3.js

 //  以「物件」的⽅方式指定屬性  d3.selectAll("circle")      .attr({          "cx":  50,  "cy":  50,  "r":  25      })      .style("fill",  "red");

Page 13: [Study4.TW] 前端視覺化實戰 - D3.js

HELLO WORLD

   d3.select('body')  

       .append('div')  

           .text('Hello  World!');

http://jsbin.com/wofibazire

Page 14: [Study4.TW] 前端視覺化實戰 - D3.js

HELLO EVERYONE

   d3.selectAll('section')  

       .append('div')  

           .text('Hello  World!');

http://jsbin.com/gexewehari

Page 15: [Study4.TW] 前端視覺化實戰 - D3.js

DATA所有的資料都是陣列

Page 16: [Study4.TW] 前端視覺化實戰 - D3.js

 var  data  =  [1,  3,  5,  2,  4,  6,  10];

http://jsbin.com/ticamuneni

Page 17: [Study4.TW] 前端視覺化實戰 - D3.js

   var  data  =  [  

       {x:  10.0,  y:  9.14},  {x:    8.0,  y:  8.14},  

       {x:  13.0,  y:  8.74},  {x:    9.0,  y:  8.77},  

       {x:  11.0,  y:  9.26},  ……  

   ];

http://jsbin.com/kifihirugu

Page 18: [Study4.TW] 前端視覺化實戰 - D3.js

從資料到圖像元素ENTER, UPDATE, EXIT

PATTERN

Page 19: [Study4.TW] 前端視覺化實戰 - D3.js
Page 20: [Study4.TW] 前端視覺化實戰 - D3.js

Enter - Update - Exit

 var  data  =  [1,  2,  3,  4,  5];  

 d3.select('body').selectAll('div')  

     .data(  data  )  

     .enter()  

     .append('div')  

       .text(function(d,  i){    return  d;  });

1 2 3 4 5

Page 21: [Study4.TW] 前端視覺化實戰 - D3.js

Enter - Update - Exit

 data  =  [1,  3,  5,  7,  9];  

 d3.select('body').selectAll('div')  

     .data(  data  )  

     .text(function(d,  i){  

return  d;  

});

1 3 5 7 9

Page 22: [Study4.TW] 前端視覺化實戰 - D3.js

Enter - Update - Exit

 data  =  [10,  20,  30];  

 d3.select('body').selectAll('div')  

     .data(  data  )  

     .exit()  

     .remove();

1 3 5 7 9

Page 23: [Study4.TW] 前端視覺化實戰 - D3.js

Enter - Update - Exit

 data  =  [10,  20,  30];  

 d3.select('body').selectAll('div')  

     .data(  data  )  

     .exit()  

     .remove();

1 3 5? 7 9

Page 24: [Study4.TW] 前端視覺化實戰 - D3.js

Enter - Update - Exit

 data  =  [10,  20,  30];  

 d3.select('body').selectAll('div')  

     .data(  data  )  

     .text(function(d,  i){  return  d;  })    //  update  text  

     .exit()  

     .remove();

10 20 30 7 9

Page 25: [Study4.TW] 前端視覺化實戰 - D3.js

SELECTION

Data Data Data

Enter & Update Exit

DataData

SELECTION

Page 26: [Study4.TW] 前端視覺化實戰 - D3.js

Enter - Update - Exit Pattern

Enter: Data > Elements.

Update: Data = Elements.

Exit: Data < Elements.

Page 27: [Study4.TW] 前端視覺化實戰 - D3.js

AJAX

• d3.text

• d3.json

• d3.csv

https://github.com/mbostock/d3/wiki/Requests

• d3.xml

• d3.html

Page 28: [Study4.TW] 前端視覺化實戰 - D3.js

   d3.json("path/to/file.json",        function(error,  data){    

           if  (error)  return  console.warn(error);            //  do  something…  

   });  

   d3.csv("/path/to/file.csv")          .header("header-­‐name",  "header-­‐value")          .get(function(error,  data)  {              //  do  something…  

       });  

Page 29: [Study4.TW] 前端視覺化實戰 - D3.js

⽐比例尺 - SCALE

Page 30: [Study4.TW] 前端視覺化實戰 - D3.js

 d3.scale.linear().domain().range()  

補間⽅方法 輸入範圍 輸出範圍

Page 31: [Study4.TW] 前端視覺化實戰 - D3.js

Domain

Range

Page 32: [Study4.TW] 前端視覺化實戰 - D3.js

 var  d3Scale  =  d3.scale.linear()    //  linear  

   .domain([0,  1000])                    //  傳⼊入範圍  

   .range([0,  100]);                      //  輸出範圍  

   console.log(  d3Scale(500)  );        //  50      console.log(  d3Scale(123)  );        //  12.3  

0

1000

0

100

500 50Domain

Range

Page 33: [Study4.TW] 前端視覺化實戰 - D3.js

d3.scale.linear(): 線性尺度

pow(): 次⽅方尺度,會與 .exponent(x) 共⽤用

如: d3.scale.pow().exponent(2) 會回傳 n^2

d3.scale.log(): 指數尺度

Demo: http://jsfiddle.net/5hqqes61/

Page 34: [Study4.TW] 前端視覺化實戰 - D3.js

DATA APIS

• d3.min():回傳陣列最⼩小值

• d3.max(): 回傳陣列最⼤大值

• d3.extent(): 同時回傳最⼩小及最⼤大值

• d3.sum(): 回傳總和

• d3.medium(): 回傳中間值https://github.com/mbostock/d3/wiki/Arrays

Page 35: [Study4.TW] 前端視覺化實戰 - D3.js

 var  data  =  [0,  150,  200,  300,  500,  1000];    var  d3Scale  =  d3.scale.linear()        

   .domain([d3.min(data),  d3.max(data)])        .range([0,  100]);    

   console.log(  d3Scale(500)  );        //  50      console.log(  d3Scale(123)  );        //  12.3  

Page 36: [Study4.TW] 前端視覺化實戰 - D3.js

 var  data  =  [0,  150,  200,  300,  500,  1000];    var  d3Scale  =  d3.scale.linear()        

   .domain(d3.extent(data))        //  [0,  1000]      .range([0,  100]);    

   console.log(  d3Scale(500)  );        //  50      console.log(  d3Scale(123)  );        //  12.3  

Page 37: [Study4.TW] 前端視覺化實戰 - D3.js

   var  colorScale  =  d3.scale.linear()              .domain([0,  20])              .range(["#f00",  "#0f0"]);  

   var  body  =  d3.select('body');  

   for  (var  i  =  0;  i  <=  20;  i++)  {              body.append('div')                      .style('background-­‐color',  colorScale(i));      }  

http://jsbin.com/bemojotale

Page 38: [Study4.TW] 前端視覺化實戰 - D3.js

   var  widthScale  =  d3.scale.linear()              .domain([0,  12])              .range(["0px",  "720px"]);  

   var  body  =  d3.select('body');  

   for  (var  i  =  0;  i  <  12;  i++)  {              body.append('div').text(widthScale(i));      }  

http://jsbin.com/wovevawisi

Page 39: [Study4.TW] 前端視覺化實戰 - D3.js

   var  domain_data  =  ["a",  "b",  "c",  "d",  "e",  "f",  "g",  "h",  "i",  "j"];  

   var  domain_range  =  ["甲",  "⼄乙",  "丙",  "丁",  "戊",  

"⼰己",  "庚",  "⾟辛",  "壬",  "癸"];  

   var  ordinalScale  =  d3.scale.ordinal()                  .domain(domain_data)                  .range(domain_range);  

   var  body  =  d3.select('body');          for(  var  i  in  domain_data  ){          body.append('div').text(ordinalScale(i));      }

http://jsbin.com/geqaninuye

Page 40: [Study4.TW] 前端視覺化實戰 - D3.js

透過 d3.scale.ordinal() ,輸出的 range 不限於數值,也可以是⽂文字 / 顏⾊色。

d3.scale.category10()  => d3 會產⽣生⼀一組 10 種顏⾊色的集合

https://github.com/mbostock/d3/wiki/Ordinal-­‐Scales

http://jsfiddle.net/hppft7zg

Page 41: [Study4.TW] 前端視覺化實戰 - D3.js

d3.scale.category10()  

d3.scale.category20()  

d3.scale.category20b()  

d3.scale.category20c()

Page 42: [Study4.TW] 前端視覺化實戰 - D3.js

軸線與刻度 - AXIS, TICKS

Page 43: [Study4.TW] 前端視覺化實戰 - D3.js

   var  data    =  [0,  150,  200,  300,  500,  1000];  

   //  x  軸  scale      var  xScale  =  d3.scale.linear()                .domain(d3.extent(data))    //  [0,  1000]  

       .range([0,  500]);                  //  x-­‐range  ⽤用來表⽰示寬度  

   //  y  軸  scale      var  yScale  =  d3.scale.linear()                .domain(d3.extent(data))    //  [0,  1000]  

       .range([0,  300]);                  //  y-­‐range  ⽤用來表⽰示⾼高度  

Page 44: [Study4.TW] 前端視覺化實戰 - D3.js

   //  x  軸      var  xAxis  =  d3.svg.axis()              .scale(xScale)  

           .orient("bottom");              //  刻度位置  

   //  y  軸      var  yAxis  =  d3.svg.axis()              .scale(yScale)  

           .orient("left");                  //  刻度位置  

http://jsbin.com/heducepihe

Page 45: [Study4.TW] 前端視覺化實戰 - D3.js

   //  x  軸      var  xAxis  =  d3.svg.axis()              .scale(xScale)              .orient("bottom")  

.ticks(15)                          //  指定刻度數量,  單位  

.tickFormat(function(d){  return  d  +  "px";  });  

   //  y  軸      var  yAxis  =  d3.svg.axis()              .scale(yScale)              .orient("left");  

http://jsbin.com/cuvubiwipo

Page 46: [Study4.TW] 前端視覺化實戰 - D3.js

https://goo.gl/4TIAv9http://jsbin.com/loyifanama

Page 47: [Study4.TW] 前端視覺化實戰 - D3.js

事件綁定

   SELECTION.on('click',  function(){  

       alert('Hello  D3!');  

   });  

Page 48: [Study4.TW] 前端視覺化實戰 - D3.js

事件綁定• mouse events:

• mousedown, mouseup, mouseover, mouseout, mouseenter, mouseleave, click, dblclick

• 當元素重疊導致事件失效• 由上層元素指定事件• CSS:  pointer-­‐events:  none;

http://kuro.tw/posts/2015/05/04/snippet-d3js-donuts-chart-the-transition-effect

Page 49: [Study4.TW] 前端視覺化實戰 - D3.js

過場動畫• Transitions have a four-phase life cycle:

• The transition is scheduled.

• The transition starts.

• The transition runs.

• The transition ends.

http://bost.ocks.org/mike/transition/

Page 50: [Study4.TW] 前端視覺化實戰 - D3.js

過場動畫

• D3.js Easing Checker - http://bl.ocks.org/hunzy/9929724

   SELECTION.transition()  

           .duration(1000)          //  動畫執⾏行時間  

           .delay(1000)                //  延遲  

           .ease(  ...  )                //  Easing  函數  

           .attr({  

                 'transform':  function(d){  .......  }  

           });  

Page 51: [Study4.TW] 前端視覺化實戰 - D3.js

   SELECTION.transition()  

           .duration(1000)    

           .each('start',  function(){    

//  動畫開始前執⾏行  

           })  

           .attr({  

//  ……  (略)  

           })  

           .each('end',  function(){    

//  動畫結束後執⾏行  

           });  

Page 52: [Study4.TW] 前端視覺化實戰 - D3.js

http://jsbin.com/zaquvihufu

Page 53: [Study4.TW] 前端視覺化實戰 - D3.js

SVG BASIC

Page 54: [Study4.TW] 前端視覺化實戰 - D3.js

(0, 0)

translate(left ,top)

Page 55: [Study4.TW] 前端視覺化實戰 - D3.js

SVG

 <svg  width="300"  height="100"></svg>

Page 56: [Study4.TW] 前端視覺化實戰 - D3.js

RECT

         <rect  x="20"  y="20"      width="150"  height="100"  rx="10"></rect>

Page 57: [Study4.TW] 前端視覺化實戰 - D3.js

CIRCLE

 <circle  cx="55"  cy="55"  r="50"></circle>

LINE        <line  x1="10"  y1="30"  x2="230"  y2="60"></line>    

Page 58: [Study4.TW] 前端視覺化實戰 - D3.js

TEXT    <text                x="0"  y="0"  dx="0"  dy="0"            font-­‐size="50"  text-­‐anchor="start">          Hello      </text>

       <text  text-­‐anchor="start/middle/end"></text>    

Page 59: [Study4.TW] 前端視覺化實戰 - D3.js

G

       <g  transform="rotate(45  50  50)">          <line></line>  

<rect></rect>  <text></text>  

   </g>  

Page 60: [Study4.TW] 前端視覺化實戰 - D3.js

PATH

Page 61: [Study4.TW] 前端視覺化實戰 - D3.js

D3 LAYOUTShttps://github.com/mbostock/d3/wiki/Layouts

Page 62: [Study4.TW] 前端視覺化實戰 - D3.js

d3.layout.pie()

http://output.jsbin.com/rafehuzara

Page 63: [Study4.TW] 前端視覺化實戰 - D3.js

d3.layout.pack()

http://jsbin.com/nadakobeno

Page 64: [Study4.TW] 前端視覺化實戰 - D3.js

d3.layout.partition()

http://jsbin.com/gusozugoku

Page 65: [Study4.TW] 前端視覺化實戰 - D3.js

THANKS!

• Kuro Hsu

• kurotanshi [at] gmail.com

• http://kuro.tw

• http://facebook.com/kurotanshi