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

d3js tips and tricks

tkirby
April 12, 2014

d3js tips and tricks

talks in OSDC 2014, Taiwan.

tkirby

April 12, 2014
Tweet

More Decks by tkirby

Other Decks in Technology

Transcript

  1. d3js - tips and tricks
    tkirby@osdc 2014

    View full-size slide

  2. 0
    Convention
    Difficulty
    Number

    View full-size slide

  3. 1
    Visualization 123

    View full-size slide

  4. 1
    2
    3
    4
    反⿊黑箱 ⽩白⾊色正義
    (⼈人次)

    View full-size slide

  5. 1
    2
    3
    4
    反⿊黑箱 ⽩白⾊色正義
    2
    2
    y
    (⼈人次)

    View full-size slide

  6. 50萬
    反⿊黑箱 ⽩白⾊色正義
    10萬
    錯誤的⻑⾧長條圖使⽤用⽅方式!
    基準點需要從零開始

    View full-size slide

  7. 50萬
    反⿊黑箱 ⽩白⾊色正義
    0
    正確的⻑⾧長條圖使⽤用⽅方式!
    ...好吧這是個失敗的例⼦子

    View full-size slide

  8. 1000
    反⿊黑箱 ⽩白⾊色正義
    0
    換個觀點,陳述的事實也不同

    View full-size slide

  9. 1000
    反⿊黑箱 ⽩白⾊色正義
    0
    萬⼈人響應
    ————
    九⼈人到場
    少數⼈人

    不代表主流⺠民意
    y: 響應 / 到場

    View full-size slide

  10. zbryikt.github.io/visualize/jobless/
    台灣⼈人失業原因統計圖 / ⽉月

    View full-size slide

  11. Data Driven !
    Document Model
    Powerful

    Visualizing Lib
    d3js d3js d3js d3js d3js d3js d3js d3js d3js d3js

    View full-size slide

  12. data data data data data
    selection
    enter exit
    selection

    View full-size slide

  13. data data data data
    selection
    enter exit
    selection
    d3.selectAll(“div”)
    .data(data)
    .enter().append(“div”)
    .exit().remove()
    d3.selectAll(“div”)

    View full-size slide

  14. new

    data
    data
    new
    data.onChange
    enter exit
    selection

    View full-size slide

  15. 3
    Read Examples

    View full-size slide

  16. http://mbostock.github.io/d3/talk/20111018/collision.html
    zbryikt.github.io/visualize/dorling/

    View full-size slide

  17. 4
    Attributes with {}

    View full-size slide

  18. d3.select(“circle”)
    .attr(“cx”, “100px”)

    View full-size slide

  19. d3.select(“circle”)
    .attr(“class”, “ball”)!
    .attr(“cx”, “100px”)!
    .attr(“cy”, “100px”)!
    .attr(“r”, “10px”)!
    .attr(“stroke”, “#f00”)!
    .attr(“stroke-width”, “100px”)!
    .attr(“fill”, “#f00”)!

    View full-size slide

  20. attrs = {
    class: "ball"
    cx: "100px"
    cy: "100px"
    r: "10px"
    stroke: "#f00"
    "stroke-width": "100px"
    fill: “#f00”
    };
    d3.select(“circle”).attr(attrs)
    d3.select(“circle”)
    .attr(“class”, “ball”)
    .attr(“cx”, “100px”)
    .attr(“cy”, “100px”)
    .attr(“r”, “10px”)
    .attr(“stroke”, “#f00”)
    .attr(“stroke-width”, “100px”)
    .attr(“fill”, “#f00”)

    View full-size slide

  21. attrs = {
    class: "ball"
    cx: "100px"
    cy: "100px"
    r: "10px"
    stroke: "#f00"
    "stroke-width": "100px"
    fill: “#f00”
    };
    !
    d3.select(“circle”).attr(attrs)
    attrs = {
    class: "ball"
    cx: "100px"
    cy: "100px"
    r: "10px"
    };
    d3.select(“circle”).attr(attrs)
    .ball {
    stroke: #f00
    stroke-width: 100px
    fill: #f00
    }
    javascript
    css

    View full-size slide

  22. attrs = {
    class: "ball"
    cx: function(it) { return it.cx; }
    cy: function(it) { return it.cy; }
    r: function(it) { return it.r; }
    };
    .…selectAll(“circle”).attr(attrs)
    .ball {
    stroke: #f00
    stroke-width: 100px
    fill: #f00
    }
    javascript
    css
    attrs = {
    class: "ball"
    cx: "100px"
    cy: "100px"
    r: "10px"
    };
    d3.select(“circle”).attr(attrs)
    .ball {
    stroke: #f00
    stroke-width: 100px
    fill: #f00
    }
    javascript
    css

    View full-size slide

  23. attrs = {
    class: "ball"
    cx: function(it) { return it.cx; }
    cy: function(it) { return it.cy; }
    r: function(it) { return it.r; }
    stroke:! function(it) { return it.s; }!
    fill:! ! function(it) { return it.fill; }!
    “stroke-width”: function(it) {!
    return it.strokeWidth;!
    }
    };
    .…selectAll(“circle”).attr(attrs)
    javascript
    .ball {
    stroke: #f00
    stroke-width: 100px
    fill: #f00
    }
    javascript
    css
    attrs = {
    class: "ball"
    cx: function(it) { return it.cx; }
    cy: function(it) { return it.cy; }
    r: function(it) { return it.r; }
    };
    .…selectAll(“circle”).attr(attrs)

    View full-size slide

  24. 6
    with AngularJS

    View full-size slide

  25. [“red”,”green”,”blue”,”purple”, “blue”]

    View full-size slide

  26. a = d3.select(“body”).selectAll(“div.bk”).data(data)
    a.enter().append(“div”)!
    .attr(“class”,”bk”)!
    .style(“background”, function(it){!
    return it;!
    });!
    a.exit().remove();!
    1. choose div.bk
    3. append div
    2. set data
    4. update attribute
    6. remove div

    View full-size slide

  27. a = d3.select(“body”).selectAll(“div.bk”).data(data)
    a.enter().append(“div”)
    .attr(“class”,”bk”)
    .text(function(it){
    return it;
    });
    a.exit().remove();
    javascript:
    function main($scope) { $scope.data = data; }
    !
    html:
    ng-attr-style=“background:{{d}}”>

    View full-size slide

  28. attrs = {
    class: "ball"
    cx: function(it) { return it.cx; }
    cy: function(it) { return it.cy; }
    r: function(it) { return it.r; }
    stroke:! function(it) { return it.s; }!
    fill:!! ! function(it) { return it.fill; }!
    “stroke-width”: function(it) {!
    return it.strokeWidth;!
    }
    };
    .…selectAll(“circle”).attr(attrs)

    View full-size slide

  29. ng-repeat=“c in data”
    cx=“{{cx}}”
    cy=“{{cy}}”
    r=“{{r}}”
    stroke=“{{s}}”
    fill=“{{fill}}”
    stroke-width=“{{strokeWidth}}”
    />
    attrs = {
    class: "ball"
    cx: function(it) { return it.cx; }
    cy: function(it) { return it.cy; }
    r: function(it) { return it.r; }
    stroke:! function(it) { return it.s; }!
    fill:! ! function(it) { return it.fill; }!
    “stroke-width”: function(it) {!
    return it.strokeWidth;!
    }};
    .…selectAll(“circle”).attr(attrs)

    View full-size slide

  30. ng-repeat=“c in data”
    cx=“{{cx}}”
    cy=“{{cy}}”
    r=“{{r}}”
    stroke=“{{s}}”
    fill=“{{fill}}”
    stroke-width=“{{strokeWidth}}”
    />
    javascript:!
    function main($scope) { $scope.data = data; }
    html

    View full-size slide


  31. ng-repeat=“t in text”>
    {{t[0]}}
    {{t[1]}}

    xlink:href=“#somepath”/>



    html

    View full-size slide


  32. ng-repeat=“t in text”>
    {{t[0]}}
    {{t[1]}}

    xlink:href=“#somepath”/>



    html

    View full-size slide


  33. ng-repeat=“t in text”>
    {{t[0]}}
    {{t[1]}}

    xlink:href=“#somepath”>

    View full-size slide


  34. ng-repeat=“t in text”>
    {{t[0]}}
    {{t[1]}}

    xlink:href=“#somepath”>

    View full-size slide

  35. g(id=“group1” class=“text-group”)
    text(class=“text” id=“text1”
    ng-repeat=“t in text”)
    textspan {{t[0]}}
    textspan {{t[1]}}
    animationmotion(dur=“2s”)
    mpath(
    xlink:href=“#somepath”)

    View full-size slide

  36. g(id=“group1” class=“text-group”)
    text(class=“text” id=“text1”
    ng-repeat=“t in text”)
    textspan {{t[0]}}
    textspan {{t[1]}}
    animationmotion(dur=“2s”)
    mpath(
    xlink:href=“#somepath”)

    View full-size slide

  37. g#group1.text-group
    text#text1.text(ng-repeat=“t in text”)
    textspan {{t[0]}}
    textspan {{t[1]}}
    animationmotion(dur=“2s”)
    mpath(xlink:href=“#somepath”)

    View full-size slide


  38. ng-repeat=“t in text”>
    {{t[0]}}
    {{t[1]}}

    xlink:href=“#somepath”/>



    g#group1.text-group
    text#text1.text(ng-repeat=“t in text”)
    textspan {{t[0]}}
    textspan {{t[1]}}
    animationmotion(dur=“2s”)
    mpath(xlink:href=“#somepath”)

    View full-size slide

  39. 8
    use LiveScript

    View full-size slide

  40. a = d3.select(“body”).selectAll(“div.bk”).data(data)
    a.enter().append(“div”)!
    .attr(“class”,”bk”)!
    .style(“background”, function(it){!
    return it;!
    });!
    a.exit().remove();!

    View full-size slide

  41. a = d3.select(“body”).selectAll(“div.bk”).data(data)
    a.enter().append(“div”)
    .attr(“class”,”bk”)
    .text(function(it){
    return it;
    });
    a.exit().remove();
    d3.select(“body”).selectAll(“div.bk”).data(data)
    ..enter().append(“div”)
    .attr(“class”,”bk”)
    .text(function(it){
    return it;
    });
    ..exit().remove();

    View full-size slide

  42. d3.select(“body”).selectAll(“div.bk”).data(data)
    ..enter().append(“div”)
    .attr(“class”,”bk”)
    .text( -> it )
    ..exit().remove();
    d3.select(“body”).selectAll(“div.bk”).data(data)
    ..enter().append(“div”)
    .attr(“class”,”bk”)
    .text(function(it){!
    return it;!
    });
    ..exit().remove();

    View full-size slide

  43. d3.select “body” .selectAll “div.bk” .data data
    ..enter!append “div”
    .attr “class”,”bk”
    .text -> it
    ..exit!remove!;
    d3.select(“body”).selectAll(“div.bk”).data(data)
    ..enter().append(“div”)
    .attr(“class”,”bk”)
    .text( -> it )
    ..exit().remove();

    View full-size slide

  44. 9
    Angular !
    + !
    Jade !
    +!
    LiveScript

    View full-size slide

  45. attrs = {
    class: "ball"
    cx: function(it) { return it.cx; }
    cy: function(it) { return it.cy; }
    r: function(it) { return it.r; }
    stroke: function(it) { return it.s; }
    fill: function(it) { return it.fill; }
    “stroke-width”: function(it) {
    return it.strokeWidth;
    }
    };
    p = d3.select(“body”).selectAll(“circle”)
    .data(data);
    p.enter().attr(attrs);
    p.exit().remove();

    View full-size slide

  46. circle.ball(
    ng-controller=“main”
    ng-repeat=“c in data”,
    cx=“{{cx}}”,
    cy=“{{cy}}”,
    r=“{{r}}”,
    stroke=“{{s}}”,
    fill=“{{fill}}”,
    stroke-width=“{{strokeWidth}}”)
    javascript:!
    main = ($scope) -> $scope.data = data;
    html

    View full-size slide

  47. so.. this session is not about!
    D3JS?

    View full-size slide

  48. 10
    as aux library
    D3JS

    View full-size slide

  49. ng-repeat d3.fisheye
    http://zbryikt.github.io/visualize/ajd3/

    View full-size slide




  50. $scope.geoblock = data.map($scope.path);
    $scope.fish = d3.fisheye.circular();
    $scope.path = d3.geo.path!projection(
    function(v) {
    return fish(d3.geo.mercator(v));
    }
    );

    View full-size slide

  51. svg
    path(ng-repeat=“x in geoblock”,ng-attr-d=“{{x}}”)
    $scope
    ..fish = d3.fisheye.circular!
    ..geoblock = data.map $scope.path
    ..path = d3.geo.path!.projection ->
    $scope.fish! d3.geo.mercator v

    View full-size slide

  52. fish = d3.circular.fisheye();
    function projection(v) {
    return fish(d3.geo.mercator(v));
    }
    path = d3.geo.path().projection(projection);
    g = d3.select(“body”).selectAll(“path.geo”).data(data);
    g.exit().remove();
    g.enter().append(“path”)
    ..attr(“class”,”geo”)
    ..attr(“d”, function(it) {
    return path(it);
    });

    View full-size slide

  53. fish = d3.circular.fisheye();
    function projection(v) {
    return
    fish(d3.geo.mercator(v));
    }
    path =
    d3.geo.path().projection(proje
    ction);
    g =
    d3.select(“body”).selectAll(“p
    ath.geo”).data(data);
    g.exit().remove();
    g.enter().append(“path”)
    ..attr(“class”,”geo”)
    ..attr(“d”, function(it) {
    return path(it);
    });
    svg
    path(ng-repeat=“x in geoblock”,
    ng-attr-d=“{{x}}”)
    $scope
    ..fish = d3.fisheye.circular!
    ..geoblock = data.map $scope.path
    ..path = d3.geo.path!.projection ->
    $scope.fish! d3.geo.mercator v

    View full-size slide

  54. 台北市親⼭山步道列表

    View full-size slide

  55. d3.select “circle”
    .transition!duration 500 .style “top”, “200px”

    View full-size slide

  56. 12
    Multiple Animation

    View full-size slide

  57. d3.select “circle”
    .transition!duration 500 .style “top”, “200px”
    .transition!delay 500 !
    .duration 500 .style “left”, “200px”

    View full-size slide

  58. 13
    Animation in CSS

    View full-size slide

  59. d3.select “circle”
    .transition!duration 500 .style “top”, “200px”
    .transition!delay 500
    .duration 500 .style “left”, “200px”
    @keyframes move {
    50%
    top: 200px!
    100%
    left: 200px!
    !
    circle.move {
    animation: move 1s linear 1 forwards
    }

    View full-size slide

  60. d3.select “circle”
    .transition!duration 500 .style “top”, “200px”
    .transition!delay 500
    .duration 500 .style “left”, “200px”
    d3.select “circle” .attr “class”, “move”

    View full-size slide

  61. 14
    Animation in SVG

    View full-size slide

  62. @keyframes move {
    50%
    top: 200px!
    100%
    left: 200px!
    !
    circle.move {
    animation: move 1s linear 1 forwards
    }
    d3.select “circle” .attr “class”, “move”
    javascript
    css

    View full-size slide

  63. @keyframes move {
    50%
    top: {{top}}
    100%
    left: {{left}}
    !
    circle.move {
    animation: move {{dur}} linear {{count}} forwards
    }
    d3.select “circle” .attr “class”, “move”
    javascript
    css

    View full-size slide

  64. attrs = {
    class: ! "ball"!
    cx: ! ! function(it) { return it.cx; }!
    cy: ! ! function(it) { return it.cy; }!
    r: ! ! function(it) { return it.r; }!
    stroke: function(it) { return it.s; }
    fill: function(it) { return it.fill; }
    “stroke-width”: function(it) {
    return it.strokeWidth;
    }
    };
    .…selectAll(“circle”).attr(attrs)
    javascript
    .ball {
    stroke: #f00
    stroke-width: 100px
    fill: #f00
    }
    javascript
    css
    attrs = {
    class: "ball"!
    cx:function(it) { return it.cx; }!
    cy:function(it) { return it.cy; }!
    r: function(it) { return it.r; }!
    };
    .…selectAll(“circle”).attr(attrs)

    View full-size slide

  65. SMIL

    attributeName=“width”
    from=“2”
    to=“10”
    dur=“1s”/>

    View full-size slide

  66. SMIL
    rect: animate(attribute=“width”,
    ng-attr-from=“{{from}}”,
    ng-attr-to=“{{to}}”,
    ng-attr-dur=“{{dur}}s”)
    angularjs + jade

    View full-size slide

  67. http://zbryikt.github.io/visualize/svg-animate/

    View full-size slide

  68. g0v hackath8n 快到了...

    View full-size slide

  69. circle text
    A
    circle text
    B
    circle text
    C
    ……

    View full-size slide

  70. circle text
    A
    circle text
    B
    circle text
    C
    ……
    Z > B
    Z > A

    View full-size slide

  71. circle text
    text
    circle



    View full-size slide

  72. 16
    with Canvas

    View full-size slide

  73. Like a Library
    data = [[0 0] [20 20]]!
    line = d3.canvas.line!!
    d3.select “canvas” .call line, data
    d3 canvas plugin

    View full-size slide

  74. As a DOM Model
    selectAll “custom:circle” .data data!
    .enter! .append “custom:circle”!
    .exit! .remove!
    http://bl.ocks.org/mbostock/1276463
    d3.timer -> selectAll “custom:*” .each ->!
    if @tagName==“circle” => …!
    else …!

    View full-size slide

  75. SVG 2 Canvas - CANVG
    http://loading.io
    SVG Animation —> Tick by JS
    Tick by JS —> SVG
    SVG —> Canvas by canvg
    Canvas —> GIF by gif.js

    View full-size slide

  76. 17
    prerendering

    View full-size slide

  77. CANVG
    svg to canvas
    canvg(canvas, “…”, {
    renderCallback: cb
    })
    <br/>function cb(canvas) { … }<br/>

    View full-size slide

  78. PHANTOMJS
    page = WebPage.create();
    page.onLoadFinished = ->
    page.render(“screenshot.png”);

    View full-size slide

  79. 18
    D3js, in 3D

    View full-size slide

  80. http://bl.ocks.org/zbryikt/raw/4539556/
    3D, in SVG

    View full-size slide

  81. http://bl.ocks.org/dcposch/4056536
    D3GL — d3 globe plugin
    globe = d3.gl.globe!
    d3.selectAll “span” .data texture … .call globe

    View full-size slide

  82. http://www.x3dom.org
    X3DOM = 3D in DOM
    http://bl.ocks.org/camio/5087116

    View full-size slide

  83. http://jsfiddle.net/XG7s8/
    X3D, in AngularJS

    View full-size slide

  84. http://zbryikt.github.io/visualize/banana/
    X3D + D3JS + AngularJS

    View full-size slide

  85. 19
    Other Topics

    View full-size slide

  86. Other Topics
    • with Google Maps and geographics
    • with Firebase
    • with Text, Link, Images and HTML
    • with Crossfilter
    • Plugins
    • Optimization

    View full-size slide

  87. Summary
    d3js + svg + jade + css3 + livescript + angularjs +
    x3d + webgl + canvg + phantomjs + canvas + smil …

    View full-size slide

  88. 0media
    零傳媒
    http://0media.tw

    View full-size slide

  89. Attributions
    Magic Wand by Lemon Liu,
    http://thenounproject.com/term/magic-wand/1294/
    Flame by iconoci,

    http://thenounproject.com/term/flame/9209/

    View full-size slide

  90. links
    http://zbryikt.github.io/visualize/jobless/
    http://mbostock.github.io/d3/talk/20111018/collision.html
    http://zbryikt.github.io/visualize/dorling/
    http://zbryikt.github.io/visualize/ajd3/
    http://zbryikt.github.io/visualize/hiking/
    http://zbryikt.github.io/visualize/svg-animate/
    http://bl.ocks.org/mbostock/1276463
    http://loading.io
    http://bl.ocks.org/dcposch/4056536
    http://bl.ocks.org/zbryikt/raw/4539556/
    http://bl.ocks.org/camio/5087116
    http://jsfiddle.net/XG7s8/
    http://zbryikt.github.io/visualize/banana/

    View full-size slide