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

Web-Based Visualizations with D3.js

Web-Based Visualizations with D3.js

Stephen Thomas

November 19, 2012
Tweet

More Decks by Stephen Thomas

Other Decks in Programming

Transcript

  1. [email protected]
    icon-comment
    icon-comment-alt
    icon-comments
    icon-comments-alt
    icon-credit-card
    icon-dashboard
    icon-download
    icon-download-alt
    icon-edit
    icon-envelope
    icon-envelope-alt
    icon-key
    icon-leaf
    icon-legal
    icon-lemon
    icon-lock
    icon-unlock
    icon-magic
    icon-magnet
    icon-map-marker
    icon-minus
    icon-minus-sign
    icon-resize-horiz
    icon-resize-verti
    icon-retweet
    icon-road
    icon-rss
    icon-screenshot
    icon-search
    icon-share
    icon-share-alt
    icon-shopping-c
    http://speakerdeck.com/sathomas
    Web-Based
    Visualizations with D3.js
    Stephen Thomas

    View Slide

  2. Why Are You Viewing
    This Presentation?
    Seriously, unless you’re stuck in a room
    forced to hear my voice, there are better
    alternatives available. You could start here1,
    with a workshop presented by Mike Bostock
    himself.
    1http://bost.ocks.org/mike/d3/workshop/

    View Slide

  3. Visualization: From Data
    I could tell you that in the War of 1812
    Napoleon began his march on Moscow with
    an army of 422,000 men and ended his
    retreat with about 10,000 men.

    View Slide

  4. …to Understanding
    or Charles Joseph Minard could show you:

    View Slide

  5. What the Web Brings:
    Source: http://bost.ocks.org/mike/uberdata/

    View Slide

  6. What the Web Brings:
    1. Interactivity
    Source: http://bost.ocks.org/mike/uberdata/

    View Slide

  7. What the Web Brings:
    2. Real Time
    Source: https://github.com/meloncholy/mt-stats-viewer

    View Slide

  8. What D3.js Brings
    •Javascript library to help you create
    spectacular visualizations
    •With full interactivity using standard
    HTML/CSS/Javascript events
    •That can be automatically updated in
    real time as underlying data changes

    View Slide

  9. D3.js is not Beta
    Many top notch organizations are actively
    using D3.js for their online content, e.g.:
    • New York Times: Four Ways to Slice
    Obama’s 2013 Budget Proposal
    • Le Monde: De Maastricht au traité
    budgétaire
    • New Scientist: The Changing Face of
    America

    View Slide

  10. But Doesn’t It Have a
    Reputation?
    “Once you pass the learning curve…”
    “D3 has a steep learning curve…”
    “…it has a steep learning curve…”
    “There is a huge learning curve…”
    “…the learning curve was quite steep.”
    http://www.datameer.com/blog/uncategorized/whats-behind-our-business-infographics-designer-d3-js-of-course-2.html
    http://www.recursion.org/d3-for-mere-mortals/
    http://www.visweek.org/visweek/2012/tutorial/visweek/introduction-data-visualization-web-d3js
    http://dyninc.github.com/lunch-and-learn/1202-d3js.html
    http://www.tips-for-excel.com/tag/learn-d3-js-book/

    View Slide

  11. Let’s Clean Up that
    Reputation
    •Climbing the D3.js
    Learning Curve in 15
    minutes.

    View Slide

  12. D3.js: Data Driven
    Documents
    •Javascript utilities that manage the
    association of data with DOM elements
    •Convenience functions for common,
    tedious tasks
    •Leaves it to you to design the best way to
    make the data understandable

    View Slide

  13. D3.js as Assembly Line
    Data (JSON, CSV, XML, …) plus elements (HTML, SVG, …)
    Photograph source: http://www.flickr.com/photos/lac-bac/4679195538/
    Office national du film du Canada. Photothèque. Bibliothèque et Archives Canada

    View Slide

  14. Assembly Plant:
    HTML Document









    View Slide

  15. Assembly Line
    Part A: Data
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    });

    View Slide

  16. Assembly Line
    Part A: Data
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    });
    d3.json( ) is part of the
    D3 library. It retrieves
    JSON-formatted data
    from a URL, in this
    case the URL is
    numbers.json.

    View Slide

  17. Assembly Line
    Part A: Data
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    });
    When the data is
    available, D3 calls the
    indicated (callback)
    function; the
    parameter is the data
    returned from the
    URL.

    View Slide

  18. Assembly Line
    Part B: Elements
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers);
    });

    View Slide

  19. Assembly Line
    Part B: Elements
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers);
    });
    We tell D3 we want to
    use elements
    within the tag
    for our data values.
    (The function names
    will make sense in a
    bit.)

    View Slide

  20. Assembly Line
    Part B: Elements
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers);
    });
    Create a one-to-one
    correspondence
    between data values
    and elements.

    View Slide

  21. Optional: “Serial
    Numbers” for the Data
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    });

    View Slide

  22. Optional: “Serial
    Numbers” for the Data
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    });
    The call to D3’s data( )
    takes an optional
    second parameter.
    That parameter
    provides a key, or
    unique identifier, for
    the given data value.

    View Slide

  23. Optional: “Serial
    Numbers” for the Data
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // numbers[i].value is the value itself
    // numbers[i].key is a unique key for each
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    });
    This function is
    important if we need
    D3 to distinguish
    different data values
    from each other. (By
    default, D3 uses their
    index in the data set.)

    View Slide

  24. Assembly Instructions
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // what to do when data becomes available
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });

    View Slide

  25. Assembly Instructions
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // what to do when data becomes available
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });
    If there isn’t a tag
    for a particular data
    value, ...

    View Slide

  26. Assembly Instructions
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // what to do when data becomes available
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });
    … create a new
    tag for the data
    value, ...

    View Slide

  27. Assembly Instructions
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // what to do when data becomes available
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });
    … and set the text
    contents of the newly
    created tag to
    show the value of the
    data.

    View Slide

  28. Assembly Instructions
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // what to do when data becomes available
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });
    Note that D3’s
    append( ) returns the
    newly created
    element, not the
    container to which it
    was appended.

    View Slide

  29. Assembly Instructions
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // what to do when data becomes available
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });
    This return value is
    different from the
    jQuery append( )
    function, so be careful
    when chaining
    methods.

    View Slide

  30. Waste Removal
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // ...
    // what to do if data disappears
    ptags.exit().remove();
    });

    View Slide

  31. Waste Removal
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // ...
    // what to do if data disappears
    ptags.exit().remove();
    });
    If there isn’t a data
    value (any more) for a
    particular tag, ...

    View Slide

  32. Waste Removal
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // ...
    // what to do if data disappears
    ptags.exit().remove();
    });
    then just remove the
    tag from the
    document.

    View Slide

  33. Start the Day Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // ...
    });
    }
    setInterval(update, 5000);

    View Slide

  34. Start the Day Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // ...
    });
    }
    setInterval(update, 5000);
    Put all the previous
    code in a function, ...

    View Slide

  35. Start the Day Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // ...
    });
    }
    setInterval(update, 5000);
    and call that function
    periodically.

    View Slide

  36. And the Night Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // ...
    });
    }

    View Slide

  37. And the Night Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // ...
    });
    }
    On subsequent
    passes, D3 will
    automatically identify
    the tags that are
    already present in the
    HTML document.

    View Slide

  38. And the Night Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    // numbers has the values we want to “visualize”
    // and we want to associate each point with a
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    // ...
    });
    }
    And D3 will
    automatically match
    the (possibly) updated
    data set to the pre-
    existing elements.

    View Slide

  39. And the Night Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    });
    }
    If there isn’t a tag
    for a particular data
    value, create a new
    tag for the data
    value.

    View Slide

  40. And the Night Shift
    function update() {
    d3.json("numbers.json", function(numbers) {
    var ptags = d3.select("body").selectAll("p")
    .data(numbers, function(d) {
    return d.key;
    });
    ptags.enter().append("p")
    .text(function(d) {
    return "Value: " + d.value;
    });
    ptags.exit().remove();
    });
    }
    If there isn’t a data
    value (any more) for a
    particular tag,
    then just remove the
    tag from the
    document.

    View Slide

  41. The Key Concept:
    D3.js as Assembly Line
    •D3 automatically keeps track of data
    values and associated HTML (or SVG)
    elements.
    •As the data set changes, D3 identifies
    elements that need to be created and
    elements that are no longer needed.
    •All you have to do is tell it what to do
    with those elements.

    View Slide

  42. The Power of D3.js
    •You can do anything you want with the
    HTML or SVG elements; after all, they’re
    standard HTML or SVG. (Style with CSS,
    make interactive with javascript, …)
    •You can control what happens when
    elements are added or removed.
    (Animations, anyone?)
    •But that seems like a lot of work...

    View Slide

  43. Need Help with that Work?
    D3.js as Toolkit
    •Transitions, Arrays, Colors, Scales, Time
    •Scalable Vector Graphics (shapes, axes,
    controls)
    •Layouts (chords, clusters, force,
    hierarchy, histogram, pack, partition, pie,
    stack, tree, treemap)
    •Geography (paths, projections)

    View Slide

  44. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  45. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  46. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  47. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  48. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  49. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  50. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  51. Lots of Inspiration
    in the D3.js Gallery

    View Slide

  52. Lots of Inspiration
    in the D3.js Gallery

    View Slide