Upgrade to Pro — share decks privately, control downloads, hide ads and more …

D3.js 資料視覺化入門

Kuro Hsu
December 23, 2015

D3.js 資料視覺化入門

2015/12/23 @ 朝陽科技大學

Kuro Hsu

December 23, 2015
Tweet

More Decks by Kuro Hsu

Other Decks in Technology

Transcript

  1. ᛔ౯Օ奧 Kuro Hsu • 獮ᒒૡ纷䒍 @ ࿞睃瞆叨褸㿁 • COSCUP 拻ᘏ

    • JSDC 拻ᘏ • kurotanshi [at] gmail.com • http://kuro.tw
  2. • D3 = Data-Driven Documents. • ֵአ翕殷秂伛ದ蔩 (HTML / CSS

    / JavaScript / SVG) • 䔶य़ጱ Data-Driven 疥虻碘䌘䛑ک DOM Ӥ牧۱ೡزᔰ ጱी㳫现痀௔虋玕 • ൉׀ SVG ፘ橕媑瑽ૡٍ䓚牧蒈圸 SVG ኴጱ jQuery • 䕃௔᩻य़֕䋿֢斃ٌ犢憙憽玕ૡٍ耆卓 D3.js ฎՋ讕
  3. ොဩ袽 (method chaining) 
 var box = d3.selectAll('.box'); box.style('color', '#f00');

    box.text('Hello World!'); var box = d3.selectAll('.box') .style('color', '#f00') .text('Hello World!');
  4. 痀௔ (attr) 
 // 犥̿ᇔկ̀ጱොୗ瞲ਧ痀௔ d3.selectAll("circle") .attr({ "cx": 50, "cy":

    50, "r": 25 }) .style("fill", "red");
 // 玲஑ circle cx 痀௔ጱ独 d3.select("circle").attr("cx");
  5. 痀௔ (property) 
 d3.selectAll('.name')
 .property('value', 'Kuro'); 
 አဩ膏 attr() ፘݶ牧֕

    property() ֵአࣁ篷ਁᶎ瞲ਧጱ痀௔牐 ই: disabled, checked 犥现 value 缛牐 
 d3.selectAll('.name')
 .property('disabled'); 

  6. Data - ಅ磪ጱ虻碘᮷ฎ檋ڜ jsbin.com/kifihirugu 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}, …… ];
  7. key function var data = [ { 'name': 'kuro', 'age':

    30 }, { 'name': 'John', 'age': 20 }, { 'name': 'Mary', 'age': 18 } ]; var p = d3.select('body') .selectAll('p') .data(data) .enter() .append('p') .text(function(d, i) { return d.name + ': ' + d.age + '䵇'; });

  8. Enter, Update, Exit Pattern 
 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
  9. Enter, Update, Exit Pattern 
 data = [1, 3, 5,

    7, 9];
 d3.select('body') .selectAll('div') .data( data ) .text(function(d, i){ return d });
 1 3 5 7 9
  10. Enter, Update, Exit Pattern data = [10, 20, 30];
 d3.select('body')


    .selectAll('div') .data( data ) .exit() .remove(); 1 3 5 7 9
  11. Enter, Update, Exit Pattern data = [10, 20, 30];
 d3.select('body')


    .selectAll('div') .data( data ) .exit() .remove(); 1 3 5 7 9 ?
  12. Enter, Update, Exit Pattern data = [10, 20, 30];
 d3.select('body')


    .selectAll('div') .data( data ) .text( function(d, i){ return d; }) .exit() .remove(); 10 20 30 7 9
  13. Ajax with D3 d3.json([URL], function(error, data){ if (error) return console.warn(error);

    // do something }); d3.csv([URL]).get(function(error, data){ // do something
 });
  14. 
 var d3Scale = d3.scale.linear() // linear .domain([0, 1000]) //

    㯽獈塅瑻 .range([0, 100]); // 蜍ڊ塅瑻 console.log( d3Scale(500) ); // 50 console.log( d3Scale(123) ); // 12.3 穉ֺ疳
  15. var colorScale = d3.scale.linear() .domain([0, 20]) .range(["#f00", "#0f0"]); for (var

    i = 0; i < 21; i++) { body.append('div') .style('background-color', colorScale(i));
 }

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

    i = 0; i < 13; i++) { body.append('div').text( widthScale(i) ); }
  17. var red = d3.rgb(255,0,0); var green = d3.rgb(0,255,0); var compute

    = d3.interpolate(red, green); console.log( compute(0) ); // #ff0000 console.log( compute(0.3) ); // #b34d00 console.log( compute(0.5) ); // #808000 console.log( compute(0.7) ); // #4db300 console.log( compute(1) ); // #00ff00
  18. var a = "50px"; var b = "1000px"; var compute

    = d3.interpolate(a, b); console.log( compute(0) ); // 50px console.log( compute(0.3) ); // 335px console.log( compute(0.5) ); // 525px console.log( compute(0.7) ); // 715px console.log( compute(1) ); // 1000px
  19. 數娄 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 አ㬵蔭纈ṛଶ
  20. 數娄 // x 數 var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom");

    // ڰଶ֖ᗝ // y 數 var yAxis = d3.svg.axis() .scale(yScale) .orient("left"); // ڰଶ֖ᗝ
  21. Ticks - ڰଶ jsbin.com/cuvubiwipo // 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");
  22. 螂䁰㵕向 SELECTION.transition() .duration(1000) // 㵕向䁆ᤈ碻樌 .delay(1000) // 皤螛 .ease( ...

    ) // Easing 獢碍 .attr({ 'transform': function(d){ ....... } }); *D3.js Easing Checker - http://bl.ocks.org/hunzy/9929724
  23. text - tspan 
 <text x="0" y="20" style="font-size: 17px;"> <tspan>Hello,

    </tspan> <tspan fill="red">World </tspan> </text>

  24. text - tspan 
 <text x="0" y="20" style="font-size: 17px;"> <tspan

    x="10" dy="10">Hello, </tspan> <tspan x="10" dy="20">World </tspan> </text>

  25. path • ᑏ㵕: M (MoveTo) • ፗ娄: L (LineTo) /

    H (Horizontal) / V (Vertical) • ใ娄: C (CurveTo) / S (Shorthand/Smooth CurveTo) 
 Q (Quadratic Bezier CurveTo)
 T (smooth quadratic Bezier CurveTo) • 皭娄: A (elliptical Arc) • 樂ݳ: Z (close-path)
  26. 娄ྦྷ叨ኞ瑊 - d3.svg.line var linePath = d3.svg.line(); var data =

    [[10,50], [390, 130]]; svg.append('path') .attr('d', linePath(data));
 <path d="M10,50L390,130">
  27. 娄ྦྷ叨ኞ瑊 - d3.svg.line 
 var svg = d3.select('.svg'); var linePath

    = d3.svg.line() .x(function(d, i){ return d; }) .y(function(d, i){ return (i%2 === 0) ? 40 : 120;}) var data = [40, 80, 120, 160, 200, 240, 280, 320, 360]; svg.append('path') .attr({ 'd': linePath(data) });
  28. ୡ娄ྦྷ叨ኞ瑊 - d3.svg.arc var myArc1 = { "startAngle": 0, "endAngle":

    Math.PI }; var myArc2 = { "startAngle": Math.PI, "endAngle": Math.PI * 1.5 }; var myArc3 = { "startAngle": Math.PI * 1.5, "endAngle": Math.PI * 2 };
  29. Responsive with D3 // 疥疳ੑ硬౮ܨ碻玲஑ጱ疝ṛ
 width = 
 parseInt(d3.select(".content").style("width")) -

    margin*2; height = 
 parseInt(d3.select(".content").style("height")) - margin*2;
 // 䌃稴ጱ疝ṛ
 var margin = 40, width = 960 - margin*2, height = 500 - margin*2;

  30. 
 var svg = d3.select('.svg'); // 疥媑蕣㵕֢۱蕕ᛗ function 獉 function

    rendering() { // 疥媑蕣ጱ纷ୗ嘨蝢蝢砆ک愊ᶎ // ኼ } // 疥 window 翉ਧ resize Ԫկ牧㪔᯿碝媑蕣瑽ࣳ d3.select(window).on('resize', rendering); // Ḓ稞媑蕣 rendering();

  31. // resize 碻, 㵕眲ๅ碝 x, y 數ڰଶ, ๅ螕ݳ褂捝 var yAxis

    = d3.svg.axis() .scale(yScale2) .orient("left") .ticks( Math.max(height/50, 2) ); Responsive with D3
  32. Responsive with D3 • य़ग़碍ᤈ㵕蕕ᗝ䌘 SVG ඪൔ臑অ • ݻᰁ瑽୵牧婘硯犋०፥ •

    㵕向 / زᔰ螂ग़碻ฃ磪硳胼㺔氂 • 犋ฎ犨֜瑽୵᮷螕ݳࣁಋ秚Ӥ氥纈物
 狶 RWD ౲ฎݚ狶Ӟ㮆ಋ秚粚๜牫
  33. D3.js Layouts • d3.js ൉׀ԧ 11 圵粚ࣳ (layouts) • ݝ襑൉׀扗粚ࣳ瞲ਧጱ虻碘໒ୗ疰ݢ犥ፗ矑ॺአ

    • layouts ๜蛪犋൉׀媑瑽ۑ胼牧ᘒฎ疥ܻতጱ虻碘 旉矦౮螕ݳᤩ d3 媑瑽ጱ虻碘໒ୗ • 睱஑懯ᓒ top, left, d 缛缛痀௔ጱ碻狡粬獨অአ
  34. Chord Layout ݣ傀 ݘ૬ 艰葦 ے೭ य़ ူग़
 讝ݱ 嬝य़ڥ

    ݣ傀 - 4 4 8 4 7 ݘ૬ 1 - 6 1 8 2 艰葦 7 5 - 1 11 16 ے೭य़ 9 5 3 - 2 4 ူग़
 讝ݱ 7 7 7 0 - 7 嬝य़ڥ 1 1 1 0 1 -
  35. Partition Layout // 疥ኞ౮অጱ nodes 蝚螂 data() 癲獈 var gRects

    = svg.selectAll("g").data(nodes).enter().append("g"); // ے獈 rect gRects.append("rect").attr({ ... }).style({ ... }); // ے獈෈ਁ gRects.append("text").attr({ ... }).style({ ... }); // 縷୵褩䍅瑽: d3.layout.partition() // size 瞲ਧ瑽礯य़ੜ, ڥአ .nodes 癲獈虻碘 var nodes = d3.layout.partition() .size([600, 400]) // [width, height] .nodes(data);
  36. Partition Layout // 㾼୵褩䍅瑽: d3.layout.partition() // size 瞲ਧ瑽礯य़ੜ, ڥአ .nodes

    癲獈虻碘 var nodes = d3.layout.partition() .size([2 * Math.PI, radius * radius]) .nodes(data); // d3.svg.arc 蕣֢皭୵ var arc = d3.svg.arc() .startAngle(function (d) { return d.x; }) .endAngle(function (d) { return d.x + d.dx; }) .innerRadius(function (d) { return Math.sqrt(d.y); }) .outerRadius(function (d) { return Math.sqrt(d.y + d.dy); });