Introducing d3.js

Introducing d3.js

Practical d3.js introduction which teaches some of d3's fundamentals such as data-joins, scales, axis, labels, ticks, animations...

We start off with a plain SVG representing a chart, refine it, in each iteration touching a new topic to actually update the chart (animate bars and scale) every x minutes.

After the talk, you should be able to understand how scales, axis and data-binding work together.

Demo code for this talk can be found at: https://github.com/toonketels/d3-presentation-demo

Presented at Fronteers Meetup - Mechelen, Belgium

2aacf6307821d3301fac1f47a214307b?s=128

Toon Ketels

May 23, 2013
Tweet

Transcript

  1. @toonketels

  2. Insert SVG into DOM Data joins Scales Axis & labels

    Axis & ticks Animations Update chart when data changes
  3. None
  4. Scalable Vector Graphics (SVG) is an XML- based vector image

    format for two- dimensional graphics that has support for interactivity and animation. The SVG specification is an open standard developed by the World Wide Web Consortium (W3C) since 1999. Wikipedia
  5. XML based - "tags and attributes" optimized for images -

    better for visualization
  6. < s v g > < / s v g

    > < r e c t > < / r e c t > < p a t h > < / p a t h > < c i r c l e > < / c i r c l e > < t e x t > < / t e x t >
  7. < r e c t x = " 0 "

    w i d t h = " 5 " y = " 0 " h e i g h t = " 5 0 " > < / r e c t > < c i r c l e c x = " 1 0 0 " c y = " 2 5 0 " r = " 4 0 " > < / c i r c l e >
  8. Hardcoded into the HTML source

  9. < s v g w i d t h =

    " 7 0 0 " h e i g h t = " 5 0 0 " > < r e c t x = " 0 " w i d t h = " 5 " y = " 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 1 " y = " 7 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 8 6 " y = " 1 4 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 4 7 4 " y = " 2 1 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 0 8 " y = " 2 8 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 7 0 0 " y = " 3 5 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 6 3 0 " y = " 4 2 0 " h e i g h t = " 5 0 " > < / r e c t > < / s v g >
  10. Hardcode SVG into the DOM

  11. How to use d3 to create SVG element?

  12. v a r c a n v a s _

    d = { w i d t h : 7 0 0 , h e i g h t : 5 0 0 } , c a n v a s = d 3 . s e l e c t ( ' # c a n v a s ' ) . a p p e n d ( ' s v g ' ) . a t t r ( ' w i d t h ' , c a n v a s _ d . w i d t h ) . a t t r ( ' h e i g h t ' , c a n v a s _ d . h e i g h t ) ;
  13. < d i v i d = " c a

    n v a s " > < s v g w i d t h = " 7 0 0 " h e i g h t = " 5 0 0 " > < / s v g > < / d i v >
  14. Search for existing DOM node Use . a p p

    e n d ( ' s v g ' ) Set attributies with . a t t r ( ' n a m e ' , ' v a l u e ' )
  15. How to display content in SVG?

  16. None
  17. < r e c t x = " 0 "

    w i d t h = " 5 " y = " 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 1 " y = " 7 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 8 6 " y = " 1 4 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 4 7 4 " y = " 2 1 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 0 8 " y = " 2 8 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 7 0 0 " y = " 3 5 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 6 3 0 " y = " 4 2 0 " h e i g h t = " 5 0 " > < / r e c t >
  18. w i d t h y

  19. y = 7 0 * i w i d t

    h = c a n v a s _ d . w i d t h * ( d / m a x _ o v e r a l l ) 5 0 / / o u r v a l u e 1 0 0 / / m a x i m u m v a l u e 7 0 0 p x / / w i d t h = > w i d t h = 7 0 0 p x * ( 5 0 / 1 0 0 ) / / 3 5 0
  20. v a r d a t a = [ 2

    6 0 0 9 8 9 6 , 1 7 9 8 0 4 7 5 5 , 4 9 4 4 7 8 7 9 7 , 2 7 1 8 5 0 5 8 8 8 , 1 7 6 5 6 8 6 4 6 5 v a r m a x _ o v e r a l l = d 3 . m a x ( d a t a ) ;
  21. d a t a . m a p ( f

    u n c t i o n ( d , i ) { c a n v a s . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , c a n v a s _ d . w i d t h * ( d / m a x _ o v e r a l l ) ) . a t t r ( ' y ' , 7 0 * i ) . a t t r ( ' h e i g h t ' , 5 0 ) } ) ;
  22. d a t a . m a p ( f

    u n c t i o n ( d , i ) { c a n v a s . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , ( f u n c t i o n ( d , i ) { r e t u r n c a n v a s _ d . w i d t h * ( d / m a x _ o v e r a l l ) } ) ( d , i ) ) . a t t r ( ' y ' , ( f u n c t i o n ( d , i ) { r e t u r n 7 0 * i ; } ) ( d , i ) ) . a t t r ( ' h e i g h t ' , 5 0 ) ; } ) ;
  23. < s v g w i d t h =

    " 7 0 0 " h e i g h t = " 5 0 0 " > < r e c t x = " 0 " w i d t h = " 5 " y = " 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 1 " y = " 7 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 8 6 " y = " 1 4 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 4 7 4 " y = " 2 1 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 0 8 " y = " 2 8 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 7 0 0 " y = " 3 5 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 6 3 0 " y = " 4 2 0 " h e i g h t = " 5 0 " > < / r e c t > < / s v g >
  24. None
  25. c a n v a s . s e l

    e c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n c a n v a s _ d . w i d t h * ( d / m a x _ o v e r a l l ) ; } ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n 7 0 * i ; } ) . a t t r ( ' h e i g h t ' , 5 0 )
  26. c a n v a s . s e l

    e c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n c a n v a s _ d . w i d t h * ( d / m a x _ o v e r a l l ) ; } ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n 7 0 * i ; } ) . a t t r ( ' h e i g h t ' , 5 0 )
  27. c a n v a s . s e l

    e c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n c a n v a s _ d . w i d t h * ( d / m a x _ o v e r a l l ) } ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n 7 0 * i } ) . a t t r ( ' h e i g h t ' , 5 0 ) ;
  28. Select elements with . s e l e c t

    A l l ( ' r e c t ' ) Create data join with . d a t a ( d a t a ) Get the enter subcollection via . e n t e r ( ) Append the elements via . a p p e n d ( ' r e c t ' ) Set attributes with . a t t r ( ' n a m e ' , ' v a l u e ' )
  29. Insert SVG container (canvas) Create new elements via data binding

  30. I hate the math in our code, can't we use

    scales for that?
  31. a t t r ( ' w i d t

    h ' , f u n c t i o n ( d , i ) { r e t u r n c h a r t _ d . w i d t h * ( d / m a x _ o v e r a l l )
  32. a t t r ( ' w i d t

    h ' , f u n c t i o n ( d , i ) { r e t u r n c h a r t _ d . w i d t h * ( d / m a x _ o v e r a l l ) } ) w i d t h : d a t a = > p i x e l s v a r w i d t h = s c a l e F u n c ( 1 7 9 8 0 4 7 5 5 ) / / 3 1
  33. v a r d a t a = [ 2

    6 0 0 9 8 9 6 , 1 7 9 8 0 4 7 5 5 , 4 9 4 4 7 8 7 9 7 , 2 7 1 8 5 0 5 8 8 8 , 1 7 6 5 6 8 6 4 6 5 , 4 0 1 5 6 9 2 3 8 0 , 3 6 1 1 6 1 2 0 9 6 ] ;
  34. < r e c t x = " 0 "

    w i d t h = " 5 " y = " 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 1 " y = " 7 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 8 6 " y = " 1 4 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 4 7 4 " y = " 2 1 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 0 8 " y = " 2 8 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 7 0 0 " y = " 3 5 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 6 3 0 " y = " 4 2 0 " h e i g h t = " 5 0 " > < / r e c t >
  35. 2 6 0 0 9 8 9 6 = >

    5 1 7 9 8 0 4 7 5 5 = > 3 1 4 9 4 4 7 8 7 9 7 = > 8 6 2 7 1 8 5 0 5 8 8 8 = > 4 7 4 1 7 6 5 6 8 6 4 6 5 = > 3 0 8 4 0 1 5 6 9 2 3 8 0 = > 7 0 0 3 6 1 1 6 1 2 0 9 6 = > 6 3 0
  36. 0 = > 0 4 0 1 5 6 9

    2 3 8 0 = > 7 0 0 0 = > 0 o v e r a l l _ m a x = > c h a r t _ d . w i d t h
  37. x = d 3 . s c a l e

    . l i n e a r ( ) . d o m a i n ( [ 0 , m a x _ o v e r a l l ] ) . r a n g e ( [ 0 , c h a r t _ d . w i d t h ] ) ;
  38. c h a r t . s e l e

    c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d ) } ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n 6 0 * i } ) . a t t r ( ' h e i g h t ' , 5 0 ) ;
  39. c h a r t . s e l e

    c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , x ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n 6 0 * i } ) . a t t r ( ' h e i g h t ' , 5 0 ) ;
  40. Create a linear scale with d 3 . s c

    a l e . l i n e a r ( ) Set the input domain as the lowest/highest value . d o m a i n ( [ 0 , m a x _ o v e r a l l ] ) Set the output range as the lowest/highest value . r a n g e ( [ 0 , c h a r t _ d . w i d t h ] )
  41. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width
  42. I hate the math in our code, can't we use

    scales for that?
  43. a t t r ( ' y ' , f

    u n c t i o n ( d , i ) { r e t u r n i * 6 0 } )
  44. y : d a t a - i t e

    m = > p i x e l s v a r y = s o m e O t h e r S c a l e F u n c ( 1 7 9 8 0 4 7 5 5 ) / / 7 0
  45. v a r d a t a = [ 2

    6 0 0 9 8 9 6 , 1 7 9 8 0 4 7 5 5 , 4 9 4 4 7 8 7 9 7 , 2 7 1 8 5 0 5 8 8 8 , 1 7 6 5 6 8 6 4 6 5 , 4 0 1 5 6 9 2 3 8 0 , 3 6 1 1 6 1 2 0 9 6 ] ;
  46. < r e c t x = " 0 "

    w i d t h = " 5 " y = " 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 1 " y = " 7 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 8 6 " y = " 1 4 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 4 7 4 " y = " 2 1 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 3 0 8 " y = " 2 8 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 7 0 0 " y = " 3 5 0 " h e i g h t = " 5 0 " > < / r e c t > < r e c t x = " 0 " w i d t h = " 6 3 0 " y = " 4 2 0 " h e i g h t = " 5 0 " > < / r e c t >
  47. 2 6 0 0 9 8 9 6 = >

    0 1 7 9 8 0 4 7 5 5 = > 7 0 4 9 4 4 7 8 7 9 7 = > 1 4 0 2 7 1 8 5 0 5 8 8 8 = > 2 1 0 1 7 6 5 6 8 6 4 6 5 = > 2 8 0 4 0 1 5 6 9 2 3 8 0 = > 3 5 0 3 6 1 1 6 1 2 0 9 6 = > 4 2 0
  48. 2 6 0 0 9 8 9 6 = >

    0 1 7 9 8 0 4 7 5 5 = > ? 4 9 4 4 7 8 7 9 7 = > ? 2 7 1 8 5 0 5 8 8 8 = > ? 1 7 6 5 6 8 6 4 6 5 = > ? 4 0 1 5 6 9 2 3 8 0 = > ? 3 6 1 1 6 1 2 0 9 6 = > 5 0 0 - 6 0 2 6 0 0 9 8 9 6 = > 0 1 7 9 8 0 4 7 5 5 = > ? 4 9 4 4 7 8 7 9 7 = > ? 2 7 1 8 5 0 5 8 8 8 = > ? 1 7 6 5 6 8 6 4 6 5 = > ? 4 0 1 5 6 9 2 3 8 0 = > ? 3 6 1 1 6 1 2 0 9 6 = > h e i g h t - r a n g e B a n d
  49. y = d 3 . s c a l e

    . o r d i n a l ( ) . d o m a i n ( d a t a ) . r a n g e B a n d s ( [ 0 , c h a r t _ d . h e i g h t ] ) ;
  50. c h a r t . s e l e

    c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , x ) . a t t r ( ' y ' , y ) . a t t r ( ' h e i g h t ' , 5 0 ) ;
  51. c h a r t . s e l e

    c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , x ) . a t t r ( ' y ' , y ) . a t t r ( ' h e i g h t ' , y . r a n g e B a n d ) ;
  52. Create an ordinal scale with d 3 . s c

    a l e . o r d i n a l ( ) for individual items Pas all the values as input domain . d o m a i n ( d a t a ) Use rangeBands as output . r a n g e B a n d s ( [ 0 , c h a r t _ d . h e i g h t ] ) Use y . r a n g e B a n d to get the height of a bar
  53. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value
  54. How do we create labels?

  55. None
  56. axis creator function draw axis

  57. a x i s _ y _ f = d

    3 . s v g . a x i s ( ) . s c a l e ( y ) . o r i e n t ( ' l e f t ' )
  58. a x i s _ y = c h a

    r t . a p p e n d ( ' g ' ) . a t t r ( ' c l a s s ' , ' a x i s y ' ) . c a l l ( a x i s _ y _ f ) ;
  59. a x i s _ y _ f = d

    3 . s v g . a x i s ( ) . s c a l e ( y ) . o r i e n t ( ' l e f t ' ) . t i c k P a d d i n g ( 3 0 ) . t i c k S i z e ( 0 , 0 , 0 ) ;
  60. First we create an axis with d 3 . s

    v g . a x i s ( ) We use to scale so it knows what to draw We can set other attributes to "tune" its display Finally, draw it by appending group c h a r t . a p p e n d ( ' g ' ) And call the creator function . c a l l ( a x i s _ y _ f )
  61. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value Display labels through axis
  62. How do we create those vertical lines?

  63. None
  64. a x i s _ x _ f = d

    3 . s v g . a x i s ( ) . s c a l e ( x ) . o r i e n t ( ' t o p ' ) . t i c k P a d d i n g ( 1 0 ) . t i c k s ( 5 ) . t i c k S i z e ( c h a r t _ d . h e i g h t , 0 , 0 ) a x i s _ x = c h a r t . a p p e n d ( ' g ' ) . a t t r ( ' c l a s s ' , ' a x i s x ' ) . a t t r ( ' t r a n s f o r m ' , ' t r a n s l a t e ( ' + 0 + ' , ' + c h a r t _ d . h e i g h t + ' ) ' ) . c a l l ( a x i s _ x _ f ) ;
  65. a x i s _ x _ f = d

    3 . s v g . a x i s ( ) . s c a l e ( x ) . o r i e n t ( ' t o p ' ) . t i c k P a d d i n g ( 1 0 ) . t i c k s ( 5 ) . t i c k S i z e ( c h a r t _ d . h e i g h t , c h a r t _ d . h e i g h t , 0 ) . t i c k S u b d i v i d e ( 2 )
  66. We create axis just like before (create/draw) Just be sure

    we set a the tick size to charts height t i c k S i z e ( c h a r t _ d . h e i g h t , c h a r t _ d . h e i g h t , 0 )
  67. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value Display labels through axis Display ticks through axis
  68. Should we display what the values represent as label?

  69. v a r d a t a = [ {

    v a l u e : 2 6 0 0 9 8 9 6 , n a m e : " a n g u l a r . j s " } , { v a l u e : 1 7 9 8 0 4 7 5 5 , n a m e : " b a c k b o n e . j s " } , { v a l u e : 4 9 4 4 7 8 7 9 7 , n a m e : " b a t m a n . j s " } , { v a l u e : 2 7 1 8 5 0 5 8 8 8 , n a m e : " e m b e r . j s " } , { v a l u e : 1 7 6 5 6 8 6 4 6 5 , n a m e : " k n o c k o u t . j s " } , { v a l u e : 4 0 1 5 6 9 2 3 8 0 , n a m e : " s a m m y . j s " } , { v a l u e : 3 6 1 1 6 1 2 0 9 6 , n a m e : " s p i n e . j s " } ] ;
  70. None
  71. m a x _ o v e r a l

    l = d 3 . m a x ( d a t a ) , m a x _ o v e r a l l = d 3 . m a x ( d a t a , f u n c t i o n ( d , i ) { r e t u r n d . v a l u e } )
  72. . a t t r ( ' w i d

    t h ' , x ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d . v a l u e ) } )
  73. . d o m a i n ( d a

    t a ) . d o m a i n ( d a t a . m a p ( f u n c t i o n ( d , i ) { r e t u r n d . n a m e } ) )
  74. . a t t r ( ' h e i

    g h t ' , y ) . a t t r ( ' h e i g h t ' , f u n c t i o n ( d , i ) { r e t u r n y ( d . n a m e ) } )
  75. To use real labels they need to be in the

    data source We use data accessor functions to tell d3 what attributes to use
  76. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value Display labels through axis Display ticks through axis
  77. Why is stuff not moving?

  78. c h a r t . s e l e

    c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , 0 ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n y ( d . n a m e ) } ) . a t t r ( ' h e i g h t ' , y . r a n g e B a n d ) . s t y l e ( ' f i l l ' , ' # 3 3 3 ' ) . t r a n s i t i o n ( ) . d u r a t i o n ( 6 0 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d . v a l u e ) } )
  79. c h a r t . s e l e

    c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , 0 ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n y ( d . n a m e ) } ) . a t t r ( ' h e i g h t ' , y . r a n g e B a n d ) . s t y l e ( ' f i l l ' , ' # 3 3 3 ' ) . t r a n s i t i o n ( ) . d u r a t i o n ( 6 0 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d . v a l u e ) } ) . t r a n s i t i o n ( ) . d u r a t i o n ( 4 0 0 ) . s t y l e ( ' f i l l ' , ' b l a c k ' )
  80. a x i s _ y = c h a

    r t . a p p e n d ( ' g ' ) . a t t r ( ' c l a s s ' , ' a x i s y ' ) . t r a n s i t i o n ( ) . d e l a y ( 8 0 0 ) . d u r a t i o n ( 8 0 0 ) . c a l l ( a x i s _ y _ f ) ;
  81. To animate use . t r a n s i

    t i o n ( ) Transitions can have . d e l a y ( 5 0 0 ) and d u r a t i o n ( 5 0 0 ) Change a attribute/style... before and after transition, d3 will do the rest
  82. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value Display labels through axis Display ticks through axis Animate the bars
  83. How could we easily update our numbers?

  84. None
  85. We've changed the data source so that: drawChart gets called

    once, the first time every x seconds, updateChart gets called with new data
  86. b a r s = c h a r t

    . s e l e c t A l l ( ' r e c t ' ) . d a t a ( d a t a ) . e n t e r ( ) . a p p e n d ( ' r e c t ' ) . a t t r ( ' x ' , 0 ) . a t t r ( ' w i d t h ' , 0 ) . a t t r ( ' y ' , f u n c t i o n ( d , i ) { r e t u r n y ( d . n a m e ) } ) . a t t r ( ' h e i g h t ' , y . r a n g e B a n d ) u . s t y l e ( ' f i l l ' , ' # 3 3 3 ' ) ; b a r s . t r a n s i t i o n ( ) . d u r a t i o n ( 6 0 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d . v a l u e ) } ) . t r a n s i t i o n ( ) . d u r a t i o n ( 4 0 0 ) . s t y l e ( ' f i l l ' , ' b l a c k ' )
  87. f u n c t i o n u p

    d a t e C h a r t ( d a t a ) { b a r s . d a t a ( d a t a ) . t r a n s i t i o n ( ) . d u r a t i o n ( 6 0 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d . v a l u e ) } ) ; }
  88. To update the chart, rebind the data via . d

    a t a ( u p d a t e d _ d a t a ) To redraw, actually call a method that will update the display like . a t t r ( ' w i d t h ' , . . . )
  89. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value Display labels through axis Display ticks through axis Animate the bars Update the bars when data changes
  90. What's with all that unused whitespace?

  91. Ask ourself: "What would need to change to update our

    axis?"
  92. axis creator function scale function scale's input domain

  93. . d o m a i n ( [ 0

    , 4 0 0 0 ] ) . d o m a i n ( [ 0 , 2 0 0 0 ] )
  94. To update the axis, just update the scale and call

    something on the axis again.
  95. / / S e t t h e c u

    r r e n t o v e r a l m a x ; m a x _ o v e r a l l = d 3 . m a x ( d a t a , f u n c t i o n ( d , i ) { r e t u r n d . v a l u e } ) ; / / U p d a t e t h e x s c a l e x . d o m a i n ( [ 0 , m a x _ o v e r a l l ] ) / / U p d a t e x a x i s a x i s _ x . t r a n s i t i o n ( ) . d u r a t i o n ( 6 0 0 ) . c a l l ( a x i s _ x _ f ) ; / / U p d a t e t h e b a r s w i t h n e w d a t a b a r s . d a t a ( d a t a ) . t r a n s i t i o n ( ) . d e l a y ( 8 0 0 ) . d u r a t i o n ( 6 0 0 ) . a t t r ( ' w i d t h ' , f u n c t i o n ( d , i ) { r e t u r n x ( d . v a l u e ) } ) ;
  96. We can update anything Always ask: "For it to update,

    what needs to change?" Change that value and redraw
  97. Insert SVG container (canvas) Create new elements via data binding

    Use linear scale to convert width Use ordinal scale to convert Y value Display labels through axis Display ticks through axis Animate the bars Update the bars when data changes Update the entire chart when data changes
  98. None
  99. Grab the from github demo code