-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1044 lines (975 loc) · 61.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html itemscope itemtype="http://schema.org/Article">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Painting with Data</title>
<meta name="description" content="Data-visualisation trades in metaphor and allusion. At its best, it’s imaginative storytelling with data and algorithms. We’ll explore how to create beauty with JavaScript, how dataviz can shape the way we see the world, and how you can get started painting with data." />
<!-- Schema.org markup for Google+ -->
<meta itemprop="name" content="Painting with Data">
<meta itemprop="description" content="Data-visualisation trades in metaphor and allusion. At its best, it’s imaginative storytelling with data and algorithms. We’ll explore how to create beauty with JavaScript, how dataviz can shape the way we see the world, and how you can get started painting with data.">
<meta itemprop="image" content="https://www.richardwestenra.com/painting-with-data-talk/img/cover.png">
<!-- Twitter Card data -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@richardwestenra">
<meta name="twitter:title" content="Painting with Data">
<meta name="twitter:description" content="Data-visualisation trades in metaphor and allusion. At its best, it’s imaginative storytelling with data and algorithms. We’ll explore how to create beauty with JavaScript, how dataviz can shape the way we see the world, and how you can get started painting with data.">
<meta name="twitter:creator" content="@richardwestenra">
<meta name="twitter:image:src" content="https://www.richardwestenra.com/painting-with-data-talk/img/cover.png">
<!-- Open Graph data -->
<meta property="og:title" content="Painting with Data" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://www.richardwestenra.com/painting-with-data-talk/" />
<meta property="og:image" content="https://www.richardwestenra.com/painting-with-data-talk/img/cover.png" />
<meta property="og:description" content="Data-visualisation trades in metaphor and allusion. At its best, it’s imaginative storytelling with data and algorithms. We’ll explore how to create beauty with JavaScript, how dataviz can shape the way we see the world, and how you can get started painting with data." />
<meta property="og:site_name" content="Richard Westenra" />
<meta property="article:published_time" content="2018-10-08T19:00:00+01:00" />
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/custom.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/monokai.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<span class="twitter-handle">@richardwestenra</span>
<canvas id="voronoi" class="fullscreen demo"></canvas>
<canvas id="dvd" class="fullscreen demo"></canvas>
<div id="darksky" class="fullscreen demo"></div>
<div id="unsure" class="fullscreen demo"></div>
<div class="reveal">
<div class="slides">
<section data-id="title">
<h1 class="title"><b>PAINTING</b> WITH DATA</h1>
<aside class="notes">
<p class="meta">SLOW</p>
<p>Hey all, I’m Richard. I’m a front-end engineer, or UI developer, or creative technologist, or senior webmaster, or whatever - I’m not even sure anymore.</p>
<p>I’m originally from New Zealand, but for the last eight years I’ve been living in London. And I’ve been working with interactive dataviz for most of that time.</p>
</aside>
</section>
<section>
<section data-background="img/quantumblack1.jpg">
<img src="img/logo-white.svg" alt="QuantumBlack logo" class="plain" width=700 />
<aside class="notes">
<p>I work at a company called QuantumBlack, which is part of McKinsey.</p>
<p class="meta">SLOW</p>
<p>I know the company name sounds kind of sinister, but we’re actually a completely legitimate organisation.</p>
<p class="meta">DOWN 👇</p>
<p>We have a bunch of different offices around the world. This is our new Japanese office!</p>
</aside>
</section>
<section data-background="img/bond-lair.jpg" data-background-size="contain">
<aside class="notes">
<p>We have a bunch of different offices around the world. This is our new Japanese office!</p>
<p class="meta">DOWN 👇</p>
</aside>
</section>
<section data-background="img/henchmen.jpg" data-background-size="contain">
<aside class="notes">
<p>Here are some of my friendly coworkers. As you can see, we're a diverse team.</p>
<p class="meta">DOWN 👇</p>
</aside>
</section>
<section data-background="img/blofeld.png" data-background-size="contain">
<aside class="notes">
<p>And this is my boss, he's a big animal-lover.</p>
<p>Anyway QB is an advanced analytics company, so we do a lot of fancy things with data.</p>
</aside>
</section>
</section>
<section data-background="img/data.gif" data-background-size="cover">
<aside class="notes">
<p class="meta">SLOW</p>
<p>I work with a lot of smart people with ‘data’ in their job title, like data scientists, and data engineers, and dataviz designers and developers.</p>
</aside>
</section>
<section data-background="img/StudioAI.jpg" data-background-size="120%" data-background-color="black">
<aside class="notes">
<p>And my job is to take this data, and translate that into an interactive chart-based tool or product, that will help them explore it, or explain their insights to clients and stakeholders.</p>
<p>So I’m going to talk to you today about how to make great charts in the browser. But before I get to that, let’s begin with a story. </p>
<p class="meta">SLOW</p>
</aside>
</section>
<section>
<h1 style="margin-top: 1.5em; text-shadow: 1px 3px 3px rgba(0,0,0,0.3)">1854</h1>
<section data-background="img/Leadenhall_Street.jpg" data-background-position="center bottom">
<aside class="notes">
<p>To set the scene, I want you to imagine that it's 1854, and you’re in Victorian London.</p>
<p>At this time, London is the largest city in the world - it's arguably the global political and financial capital. Nobody is talking about Brexit, yet.</p>
<p class="meta">DOWN 👇</p>
<p>Meanwhile, the British Empire is fighting Russia in the Crimea.</p>
<p>and author Charles Dickens is an international celebrity.</p>
</aside>
</section>
<section data-background="img/crimean-war.jpg">
<aside class="notes">
<p>Meanwhile, the British Empire is fighting Russia in the Crimea.</p>
<p class="meta">DOWN 👇</p>
<p>and author Charles Dickens is an international celebrity.</p>
</aside>
</section>
<section data-background="img/charles-dickens.gif">
<aside class="notes">
<p>and author Charles Dickens is an international celebrity.</p>
</aside>
</section>
</section>
<section data-background="img/cholera.jpg" data-background-size="contain" data-background-color="white">
<aside class="notes">
<p>London is suffering one of its worst ever cholera outbreaks. The disease has ripped through Soho, killing over 600 people, and causing many of the local residents to flee the area.</p>
<p>At the time there were two competing theories on the cause of cholera’s spread: Some people argued that it was spread by rank-smelling air or “miasma”, that came out of rotten, decaying matter.</p>
<p>Meanwhile, others said that it was spread through some sort of unidentified microscopic organism, or “germ”. If you’ve heard of germ theory but haven’t heard of miasma theory then at this point you might have an idea which side was right, but please don’t spoil it for your neighbours if they haven't figured it out yet.</p>
<p>Now every good story needs to have a hero, and this one is no exception. He was an English physician, and a skeptic of miasma theory. His name was John Snow.</p>
</aside>
</section>
<section data-background="img/jon-snow.jpeg" data-background-size="cover" data-background-position="center 15%">
<aside class="notes">
<p class="meta">UNCOMFORTABLY LONG PAUSE</p>
<p>Not that one</p>
</aside>
</section>
<section data-background="img/john-snow.jpg" data-background-size="contain" data-background-color="white">
<aside class="notes">
<p>Yep that’s the guy.</p>
<p>John Snow didn't understand exactly how cholera was transmitted, but he knew how to read the evidence, and he didn't like the foul air theory. He reckoned that it was spread through the water supply.</p>
</aside>
</section>
<section data-background="img/cholera-map.png" data-background-size="contain" data-background-color="white">
<aside class="notes">
<p>By chatting to local residents and studying the pattern of how the disease spread, he identified the source of the outbreak as the public water pump on Broad Street - just a few minutes’ walk from my present-day office at Picadilly Circus, down in the bottom right corner of the map.</p>
<p>John Snow tried to warn everyone about this pump, but they told him, “You know nothing John Snow”.</p>
</aside>
</section>
<section data-background="img/jon-snow-annoyed.jpg" data-background-size="contain">
<aside class="notes">
<p class="meta">PAUSE.</p>
</aside>
</section>
<section data-background="img/cholera-map.png" data-background-size="200%" data-background-position="62% 43%" data-background-color="white">
<aside class="notes">
<p>But he was eventually able to convince the local authorities about his theory, with the aid of this dot map, which illustrates the clusters of cholera cases, juxtaposed with the locations of water pumps.</p>
<p>You can see on the map how the infections are concentrated around the Broad Street pump, marked in blue in the middle.</p>
<p>Once he convinced the parish authorities that almost all the deaths occurred at houses which were a shorter walking distance to the Broad Street water pump than to other pumps, they solved the problem by removing the pump handle. This forced people to draw their water from other wells which were uncontaminated, and the number of new cholera cases fell.</p>
<p>So what does this tell us?</p>
</aside>
</section>
<section data-background="img/john-snow-pub.jpg" data-background-position="center top">
<aside class="notes">
<p>Firstly, not to drink water from public taps in Soho. If you’re in any doubt about this, you should know that <i>not one</i> of the employees at the brewery just up the street from the pump contracted cholera. That's because they were paid in beer, so they didn’t drink the water. So if in doubt, don’t drink water, drink beer.</p>
<p>There’s actually a pub on the location of the former pump called the John Snow, so you can drink your beer there instead if you come visit me in London.</p>
</aside>
</section>
<section>
<h2>Good charts<br> save lives 💪</h2>
<aside class="notes">
<p>Secondly, that a well-executed chart can inspire action. John Snow’s use of a map-based dataviz helped convince the city to shut down the infected well. His chart might have saved hundreds of lives.</p>
</aside>
</section>
<section>
<h2>A good chart<br> should have a story</h2>
<aside class="notes">
But thirdly and most importantly, it tells us that a good chart should have a story.
<p>Most data visualization is done for the purpose of communication. We have an insight about a dataset, and we have a potential audience, and we would like to convey our insight to our audience. To communicate our insight successfully, we will have to present the audience with a clear and exciting story.</p>
<p>The need for a story may sound a bit disturbing to engineers, who may equate it with making things up, putting a spin on things, or overselling results. After all, surely the point of a chart is to persuade people with cold hard numbers, not wishy washy emotions. However, we must not overlook the important role that stories play in reasoning and memory. We get excited when we hear a good story, and we get bored when the story is bad or when there is none.</p>
</aside>
</section>
<section>
<h2>What is your<br> chart's purpose?</h2>
<aside class="notes">
<p>So when you want to make a chart, the first and most important thing to think about, is what point your chart is trying to make, or what problem you’re trying to solve.</p>
<p>Are you trying to persuade people, and change their minds? To teach them something new? Or do you just want to make some dank chart based memes?</p>
</aside>
</section>
<section>
<h2>Who are your audience?</h2>
<aside class="notes">
<p>Next, consider who your audience is. Is this a dashboard that they use every day at work, or will they be random reddit users? If it's the former, then they can afford to spend more time learning to use a complex interface.</p>
<p>You'll also want to consider their level of education and technical ability. Like are they data scientists with PhDs, or are they teenagers? How familiar are they with complex web user interfaces, or with common chart metaphors like graph axes?</p>
<p>All of these factors will influence how much hand-holding you’ll need to do for your users. There’s often a balance or trade-off to be made, between intuitiveness on the one hand, and originality on the other.</p>
</aside>
</section>
<section>
<h3>Aesthetics</h3>
<svg class="svg" width="400" height="300">
<line x1="10" x2="10" y1="3" y2="291" stroke="white" stroke-width="3" />
<line x1="9" x2="397" y1="290" y2="290" stroke="white" stroke-width="3" />
<polygon points="10,0 20,20 0,20" fill="white" />
<polygon points="400,290 380,300 380,280" fill="white" />
<text x="20" y="40" fill="white" style="font-size: 16px">x</text>
<text x="360" y="275" fill="white" style="font-size: 16px">y</text>
<text x="40" y="255" fill="white" style="font-size: 25px">Position</text>
<text x="60" y="190" fill="white" style="font-size: 25px">Position</text>
<text x="140" y="120" fill="white" style="font-size: 25px">Position</text>
<text x="250" y="75" fill="white" style="font-size: 25px">Position</text>
</svg>
<svg class="svg" width="400" height="300">
<g transform="translate(30, -25)">
<g transform="translate(35, 40)">
<polygon points="50,0 100,80 0,80" stroke="#aaa" stroke-width="3" />
<text x="15" y="60" fill="white" style="font-size: 25px">Shape</text>
</g>
<g transform="translate(250, 50)">
<circle cx="40" cy="40" r="40" stroke="#aaa" stroke-width="3" />
<text x="5" y="50" fill="white" style="font-size: 25px">Shape</text>
</g>
<g transform="translate(250, 200)">
<rect x="0" y="0" width="80" height="80" stroke="#aaa" stroke-width="3" />
<text x="5" y="50" fill="white" style="font-size: 25px">Shape</text>
</g>
<g transform="translate(50, 200)">
<rect x="0" y="0" width="80" height="80" transform="rotate(45, 40, 40)" stroke="#aaa" stroke-width="3" />
<text x="5" y="50" fill="white" style="font-size: 25px">Shape</text>
</g>
</g>
</svg>
<svg class="svg" width="800" height="240" style="font-weight: 900">
<g transform="translate(1, 10)">
<text x="0" y="50" fill="crimson" style="font-size: 30px">Colour</text>
<text x="0" y="100" fill="green" style="font-size: 30px">Colour</text>
<text x="0" y="150" fill="royalblue" style="font-size: 30px">Colour</text>
<text x="0" y="200" fill="gold" style="font-size: 30px">Colour</text>
</g>
<g transform="translate(220, 10)">
<text x="0" y="50" dy="-5" fill="white" style="font-size: 20px">Size</text>
<text x="0" y="100" dy="-6" fill="white" style="font-size: 30px">Size</text>
<text x="0" y="150" dy="-3" fill="white" style="font-size: 40px">Size</text>
<text x="0" y="200" dy="8" fill="white" style="font-size: 50px">Size</text>
</g>
<g transform="translate(400, 10)">
<text x="0" y="50" fill="black" stroke="white" stroke-width="0.5" style="font-size: 30px">Line width</text>
<text x="0" y="100" fill="black" stroke="white" stroke-width="1" style="font-size: 30px">Line width</text>
<text x="0" y="150" fill="black" stroke="white" stroke-width="2" style="font-size: 30px">Line width</text>
<text x="0" y="200" fill="black" stroke="white" stroke-width="3" style="font-size: 30px">Line width</text>
</g>
<g transform="translate(630, 10)">
<text x="0" y="50" fill="black" stroke="white" stroke-width="1" style="font-size: 30px">Line type</text>
<text x="0" y="100" fill="black" stroke="white" stroke-width="1" stroke-dasharray="1,1" style="font-size: 30px">Line type</text>
<text x="0" y="150" fill="black" stroke="white" stroke-width="1" stroke-dasharray="5,2" style="font-size: 30px">Line type</text>
<text x="0" y="200" fill="black" stroke="white" stroke-width="1" stroke-dasharray="1,4" style="font-size: 30px">Line type</text>
</g>
</svg>
<aside class="notes">
<p>Now, my favourite thing about charts is their ability to tell a compelling story in a beautiful way using just a few kilobytes of data and code. And just as most good storytellers use metaphors, good dataviz uses metaphors too. Like you can represent data in your visual stories with properties like position, shape, size, color, line width, and line type.</p>
<p>All aesthetics fall into one of two groups: Those that can represent continuous data and those that can't.</p>
</aside>
</section>
<section>
<h1 class="continuous">Continuous</h1>
<p>vs</p>
<h1 class="discrete"><span>D</span><span>i</span><span>s</span><span>c</span><span>r</span><span>e</span><span>t</span><span>e</span></h1>
<aside class="notes">
<p>Continuous data values are values for which arbitrarily fine intermediates exist. For example, distance is a continuous value, because you can break that down into as many intermediates as you like, from kilometres down to nanometers. On the other hand, number of persons in a room is a discrete value. A room can hold 5 persons, or 6 persons, but not 5 and a half persons.</p>
<p>You can use position, size, colour or line width to represent continuous data, while shape and line type should usually only be used to represent discrete data.</p>
<p>Each of these can have advantages and disadvantages for different types of data. e.g. size can be misleading because it's tricky for the human eye to accurately tell how much bigger one thing is than another, while certain colour scales don’t work well for colour-blind people. So you’ll want to be careful how you use these scales.</p>
</aside>
</section>
<section>
<h3>Animated aesthetics</h3>
<br>
<svg class="svg" width="820" height="300" style="font-weight: 900">
<g class="frequency" transform="translate(10, 5)">
<text x="0" y="50" fill="white" style="font-size: 40px">Frequency</text>
<text x="0" y="120" fill="white" style="font-size: 40px">Frequency</text>
<text x="0" y="190" fill="white" style="font-size: 40px">Frequency</text>
<text x="0" y="260" fill="white" style="font-size: 40px">Frequency</text>
</g>
<g class="velocity" transform="translate(300, 5)">
<text x="0" y="50" fill="white" style="font-size: 40px">Velocity</text>
<text x="0" y="120" fill="white" style="font-size: 40px">Velocity</text>
<text x="0" y="190" fill="white" style="font-size: 40px">Velocity</text>
<text x="0" y="260" fill="white" style="font-size: 40px">Velocity</text>
</g>
</svg>
<aside class="notes">
<p>By the way, we've discussed static visual aesthetics but you don't have to stop there. Instead of paper and ink, we’re using computer screens, CSS and JavaScript, so you can use Time as a medium. Consider playing around with animation too, like you can use frequency or velocity as a visual metaphor.</p>
</aside>
</section>
<section>
<h2>⚠️</h2>
<h3>Photosensitive<br> seizure warning</h3>
<br>
<p>The following slide contains<br> rapidly flashing images</p>
<aside class="notes">
<p>Speaking of which, I just want to give a quick photosensitivity warning. If you’re strongly affected by flashing images then I’d recommend that you look away for the next slide.</p>
</aside>
</section>
<section data-id="snapchat">
<p class="snapchat-title">
<b>Every second</b><br>
<b>8,796 photos</b><br>
<b>are shared on Snapchat.</b>
</p>
<aside class="notes">
<p>In 2015, I was working with a creative team making interactive web content. And we did a piece about this hot new app called Snapchat. At the time, it was growing very quickly, and it was amazing to think there might be nearly 9 thousand photos being shared per second. We wanted to impress upon people just how many photos this was, so we visualised it by using the Snapchat logo or an emoji to represent each photo.</p>
<p>I thought it was effective, and it did okay on Reddit, but that many photos per second was a lot for most computer’s GPUs to handle.</p>
<p>So, predictably, the frame-rate suffered on all but the most powerful computers. Mobile phones did not handle it well at all. It was a good learning experience about performance limits on different devices.</p>
<p>By the way, the number of Snapchats being shared these days is closer to 34 thousand per second, which would probably be enough to completely ruin the frame rate for everyone, if not completely crash your browser.</p>
<p>So that was a fun project :). But you can also use animation in more subtle ways to communicate about your data!</p>
</aside>
</section>
<section data-id="darksky" data-background="img/dark-sky.gif" data-background-size="contain">
<aside class="notes">
<p>And this is done really well in one of my favourite apps. Dark Sky is a smartphone app that does hyper-local weather forecasting to predict exactly when it’s going to rain in the next hour, by cross-referencing your phone’s GPS against local weather radar. It’s amazing for working out whether you need to bring an umbrella when you step out for lunch. But before you all download it at once, I should warn you that unfortunately it only works in the US, UK and Ireland.</p>
<p>Anyway Dark Sky uses an area chart to show when and how much it’ll be raining over the next hour. And the developers have included this cute little wiggle animation, which is great for communicating the level of uncertainty in the data. I think it’s really clever.</p>
</aside>
</section>
<section>
<h5>Common dataviz variable types</h5>
<table class="variables">
<colgroup>
<col width="30%" />
<col width="25%" />
<col width="15%" />
</colgroup>
<thead>
<tr class="header">
<th>Type of variable</th>
<th>Examples</th>
<th>Appropriate scale</th>
</tr>
</thead>
<tbody>
<tr>
<td>quantitative/numerical continuous</td>
<td>1.3, 5.7, 83, 1.5x10<sup>-2</sup></td>
<td>continuous</td>
</tr>
<tr>
<td>quantitative/numerical discrete</td>
<td>1, 2, 3, 4</td>
<td>discrete</td>
</tr>
<tr>
<td>qualitative/categorical unordered</td>
<td>dog, cat, fish</td>
<td>discrete</td>
</tr>
<tr>
<td>qualitative/categorical ordered</td>
<td>good, fair, poor</td>
<td>discrete</td>
</tr>
<tr>
<td>date or time</td>
<td>Jan. 5 2018, 8:03am</td>
<td>continuous or discrete</td>
</tr>
<tr>
<td>text</td>
<td>The quick brown fox jumps over the lazy dog.</td>
<td>none, or discrete</td>
</tr>
</tbody>
</table>
<cite>Source: <a href="https://serialmentor.com/dataviz/aesthetic-mapping.html">https://serialmentor.com/dataviz/aesthetic-mapping.html</a></cite>
<aside class="notes">
<p>So we have a few different aesthetics that we can use to represent our data. But before you start visualising it, you'll need to consider what types of data you’re going to present.</p>
<p>You might think of data as numbers, but numerical values are only a couple of the many types of data we may encounter. In addition to continuous and discrete quantitative values, data can come in the form of discrete qualitatitive categories, or as dates or times, or as text.</p>
</aside>
</section>
<section>
<h3>Scales map data values<br> onto aesthetics</h3>
<table class="scales">
<tbody>
<tr>
<th></th>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<th>Position</th>
<td>
<svg class="svg" width="48" height="20">
<line x1="6" x2="42" y1="10" y2="10" stroke="white" stroke-width="2" />
<circle cx="6" cy="10" r="6" fill="darkturquoise" />
</svg>
</td>
<td>
<svg class="svg" width="48" height="20">
<line x1="6" x2="42" y1="10" y2="10" stroke="white" stroke-width="2" />
<circle cx="18" cy="10" r="6" fill="darkturquoise" />
</svg>
</td>
<td>
<svg class="svg" width="48" height="20">
<line x1="6" x2="42" y1="10" y2="10" stroke="white" stroke-width="2" />
<circle cx="30" cy="10" r="6" fill="darkturquoise" />
</svg>
</td>
<td>
<svg class="svg" width="48" height="20">
<line x1="6" x2="42" y1="10" y2="10" stroke="white" stroke-width="2" />
<circle cx="42" cy="10" r="6" fill="darkturquoise" />
</svg>
</td>
</tr>
<tr>
<th>Shape</th>
<td>
<svg class="svg" width="30" height="30">
<circle cx="15" cy="15" r="15" fill="darkturquoise" />
</svg>
</td>
<td>
<svg class="svg" width="30" height="30">
<rect x="2" y="2" width="26" height="26" fill="darkturquoise" />
</svg>
</td>
<td>
<svg class="svg" width="40" height="40">
<rect x="6" y="6" width="26" height="26" fill="darkturquoise" transform="rotate(45, 20, 20)" />
</svg>
</td>
<td>
<svg class="svg" width="36" height="30">
<polygon points="18,0 36,30 0,30" fill="darkturquoise" />
</svg>
</td>
</tr>
<tr>
<th>Colour</th>
<td>
<svg class="svg" width="30" height="30">
<rect x="2" y="2" width="26" height="26" fill="#f0f9e8" />
</svg>
</td>
<td>
<svg class="svg" width="30" height="30">
<rect x="2" y="2" width="26" height="26" fill="#bae4bc" />
</svg>
</td>
<td>
<svg class="svg" width="30" height="30">
<rect x="2" y="2" width="26" height="26" fill="#7bccc4" />
</svg>
</td>
<td>
<svg class="svg" width="30" height="30">
<rect x="2" y="2" width="26" height="26" fill="#2b8cbe" />
</svg>
</td>
</tr>
</tbody>
</table>
<aside class="notes">
<p>In order to translate your data into a visual aesthetic, you’re going to want a scale function. Scales are your basic low-level building block of any chart. They make it easy to take data of different formats, and convert it consistently into a corresponding aesthetic value, like a pixel distance or a colour or a shape.</p>
<p>Importantly, a scale’s input and output must always have a deterministic one-to-one relationship. So for each specific data value there should be exactly one aesthetic value, and vice versa. If a scale isn’t one-to-one, then the visualization can be ambiguous.</p>
</aside>
</section>
<section data-id="scale-demo">
<div class="scale-demo">
<h3>Scale functions</h3>
<table>
<tbody>
<tr>
<th>Domain (pixels):</th>
<td id="domain"></td>
</tr>
<tr>
<th>Range (hue):</th>
<td id="range"></td>
</tr>
<tr>
<th>Input value (pixels):</th>
<td id="inputValue"></td>
</tr>
<tr>
<th>Output value (hue):</th>
<td id="outputValue"></td>
</tr>
</tbody>
</table>
</div>
<p id="scale-colour"></p>
<aside class="notes">
<p>To set up a scale function, you’ll start by providing an input domain and an output range. The domain is the complete set of data values that the function can expect to receive, and the range is the set of aesthetic values that you want it to return.</p>
<p class="meta">Move mouse to other screen</p>
<p>So for this slide, for example, I’m using a linear colour scale to set the background colour based on the mouse position on the screen. We have a continuous numerical domain, which is based on the screen height. The input value is set to the current Y position of my mouse, as I move it around. Our output range is using the hue of an HSL colour, which goes from 0 to 360. And you can see the aesthetic output on the screen background here.</p>
</aside>
</section>
</section>
<section>
<h2>Choosing a<br> chart type</h2>
<aside class="notes">
<p>So now it’s time to choose a chart type. There are hundreds of different established formats, and each has various advantages and disadvantages for different situations and types of data.</p>
<p>The most important thing though, is that you choose a chart type because it’s the right type for your data.</p>
<p class="meta">SLOW</p>
</aside>
</section>
<section data-background="img/bubble.png" data-background-color="#F7F8F9" data-background-size="contain">
<aside class="notes">
<p>A couple of years ago, I did some work for a client project, with a team who asked us to make a bubble chart. We asked why they wanted a bubble chart specifically, and they said it’s mainly because the client likes bubble charts. You can show a lot of different dimensions at once with a bubble chart, and it’s what they’ve always used, so the client has grown to expect them. So we built it for them. And I think it ended up being a really good bubble chart, with lots of filters and animated transitions between states and so on, and the client was impressed and the team were happy. But I can’t help thinking that we were going in with one arm tied behind our backs, and that we could have chosen a chart that would have communicated so much better if we’d been allowed more flexibility to choose a chart that would suit the dataset.</p>
</aside>
</section>
<section>
<h3>Don’t choose a chart type just because you think it looks cool</h3>
<aside class="notes">
<p>So above all, if you learning nothing else from this talk, I want you to learn from my mistakes, and don't do what we did on that project. Instead, remember that you should choose your chart style based on your data type, the problem you’re trying to solve, the story you’re trying to tell, and your audience.</p>
</aside>
</section>
<section>
<ul class="chart-chooser-apps stretch">
<li>
<a href="https://datavizproject.com/">Data Viz Project</a>
<img src="img/chooser-apps/dataviz-project.png" alt="" />
</li>
<li>
<a href="https://datavizcatalogue.com/">Data Visualisation Catalogue</a>
<img src="img/chooser-apps/dataviz-catalogue.png" alt="" />
</li>
<li>
<a href="http://labs.juiceanalytics.com/chartchooser/">Chart Chooser</a>
<img src="img/chooser-apps/chart-chooser.png" alt="" />
</li>
<li>
<a href="https://www.d3-graph-gallery.com/">D3.js Graph Gallery</a>
<img src="img/chooser-apps/d3-gallery.png" alt="" />
</li>
<li>
<a href="https://public.tableau.com/en-us/s/gallery/visual-vocabulary">Tableau Visual Vocabulary</a>
<img src="img/chooser-apps/tableau-viz-vocab.png" alt="" />
</li>
<li>
<a href="https://www.ibm.com/design/v1/language/experience/data-visualization/">IBM Design Language</a>
<img src="img/chooser-apps/ibm.png" alt="" />
</li>
<li>
<a href="https://www.labnol.org/software/find-right-chart-type-for-your-data/6523/">Choose the Right Chart Type for your Data</a>
<img src="img/chooser-apps/data-chart-type.png" alt="" />
</li>
</ul>
<aside class="notes">
<p>This is a hard problem, but fortunately there are loads of tools around to help you out. I’ve listed a few here, and I’ll tweet out some links to them later on.</p>
<p>Each one is slightly different, but they all have a common starting point, which is to ask yourself, what are you trying to show? Are you trying to demonstrate a correlation between variables? Or a size comparison? Or maybe how something changes over time? Find the thing you’re trying to present, and work from there until you’ve found the right chart for your data story.</p>
</aside>
</section>
<section>
<h2>Choosing a web technology</h2>
<aside class="notes">
<p>Ok so once you’ve chosen a chart type, now it’s time for the fun part: Building the chart. But we’ve still got so many options to choose from! Like, which web technology will you build it in?</p>
</aside>
</section>
<section>
<h1><svg /></h1>
<aside class="notes">
<p>The most common choice is SVG. I spend a lot of my time working with SVG and often assume that it’s a core part of every front-end developer’s toolkit, but I meet a lot of devs who haven’t really worked with it much and don’t feel confident writing it from scratch. If this is you, that’s okay! Here’s my lightning summary of SVG:</p>
</aside>
</section>
<section>
<pre><code data-trim>
<svg width="600" height="400">
<circle cx="250" cy="200" r="100" fill="steelblue" stroke="lime" stroke-width="6" />
<line x1="50" x2="500" y1="250" y2="50" stroke="deeppink" stroke-width="6" />
<path d="M150 0 L75 200 L225 200 Z" fill="gold" stroke="indigo" stroke-width="6" />
<text x="50" y="340" fill="white" style="font-size: 16px">Why can't I wrap this text without manually inserting line breaks? 😔</text>
<polygon points="400,10 550,300 300,100 400,350" fill="crimson" stroke="skyblue" stroke-width="6" />
</svg>
</code></pre>
<svg class="svg-demo" width="600" height="400">
<circle cx="250" cy="200" r="100" fill="steelblue" stroke="lime" stroke-width="6" />
<line x1="50" x2="500" y1="250" y2="50" stroke="deeppink" stroke-width="6" />
<path d="M150 0 L75 200 L225 200 Z" fill="gold" stroke="indigo" stroke-width="6" />
<text x="50" y="340" fill="white" style="font-size: 16px">Why can't I wrap this text without manually inserting line breaks? 😔</text>
<polygon points="400,10 550,300 300,100 400,350" fill="crimson" stroke="skyblue" stroke-width="6" />
</svg>
<aside class="notes">
<p>SVG is basically an alternate universe version of HTML focused on graphics instead of documents, but where everything is set to position absolute. You get some new element types like circles and polygons and lines, but you have to use a bizarro-world version of CSS which has features like stroke and fill, but you can’t use most of the regular useful features that you’d normally depend on, like background-image and border and box-shadow and so on.</p>
<p>Also, text won’t wrap automatically which even more annoying than it sounds, so you need to use JavaScript to calculate text wrap with weird hacks like rendering to the DOM, then measuring the text width, then deleting it and re-rendering it with extra tags inserted to add line breaks, which is basically a nightmare.</p>
<p>SVG has a DOM just like HTML, so it’s not great for JavaScript animations on large numbers of elements, but you can use CSS animations which are super performant, so I try to use those over JavaScript animations wherever possible.</p>
</aside>
</section>
<section>
<img class="trump plain" src="img/DonaldTrump.svg" alt="" />
<aside class="notes">
<p>Also, SVG is vector so it scales well and you can make it YUGE without sacrificing image quality, even if the result is extremely upsetting and you start to wonder why you did it in the first place.</p>
</aside>
</section>
<section>
<h1><canvas /></h1>
<aside class="notes">
<p>Next up, Canvas! Canvas is often used for visualisations that have a large number of animated nodes, like force-directed network graphs.</p>
<p></p>
</aside>
</section>
<section data-background="img/ripmspaint.jpg" data-background-size="contain">
<aside class="notes">
<p>In practice, writing to Canvas is a lot like using Microsoft Paint, but with JavaScript. Did anybody else here use to mess around creating weird images in MS Paint?</p>
<p>An old flatmate of mine used to use my computer to do these really weird pictures in MS Paint while I was out, and set them as my desktop background. So whenever I turn on my computer I would just be like… what IS this?</p>
<p>But if you’ve used Paint then you’ll remember that in Paint there are no layers or objects. If you draw over something then it’s gone forever. HTML Canvas is the same. Everything is raster and there’s no DOM, there’s just a big area that you need to paint onto.</p>
</aside>
</section>
<section>
<pre><code data-trim>
<canvas></canvas>
</code></pre>
<pre><code data-trim>
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
context.clearRect(0, 0, width, height);
context.drawImage(object.image, x, y, object.width, object.height);
context.fillStyle = object.fillStyle;
context.fillRect(x, y, object.width, object.height);
</code></pre>
<p><canvas id="canvas" style="position: static;" height="300" width="300"></canvas></p>
<script>
const canvas = document.querySelector('#canvas');
const context = canvas.getContext('2d');
context.fillStyle = '#eee';
context.fillRect(0, 0, 300, 300);
context.fillStyle = 'red';
context.fillRect(150, 50, 100, 100);
context.fillStyle = 'red';
const image = new Image();
image.src = 'img/cat-cheese.jpg';
image.onload = () => context.drawImage(image, 50, 100, 150, 150);
</script>
<aside class="notes">
<p>The native JavaScript for writing Canvas tends is a lot more imperative than writing SVG, which can make it a lot more time-consuming to work with. You also can’t inspect any DOM elements, or attach mouse events to objects, because there aren’t any. All of which makes it sound like a massive pain, which it is.</p>
<p>But! It’s really performant for complex animations with lots of different elements. If you loaded 8000 DOM elements and animated them all with JavaScript, your frame rate would drop through the floor, but you can do it with Canvas and it’s fine.</p>
</aside>
</section>
<section data-id="canvas">
<aside class="notes">
<p class="meta">(Press R to reset)</p>
<p>Because there aren’t persistent objects that you can move around like you would in HTML or SVG, you need to repaint every single frame from scratch. To illustrate this, here’s an example I’ve made, which has loaded a JPG file, and is moving it a little bit every frame and drawing it again and again.</p>
<p>If you let it run, then the canvas will fill up with old copies of the image, which would cause all sorts of performance issues if these were HTML images. But it’s Canvas so it doesn’t matter, it’s just pixels persisting until you draw over them again.</p>
</aside>
</section>
<section data-id="canvas-clear">
<aside class="notes">
<p>But you don’t usually want to leave a trail every time you move something on screen. So usually, what you’ll do is to erase the entire canvas and redraw it again from scratch, every time you request a new animation frame.</p>
</aside>
</section>
<section>
<h1>WebGL</h1>
<aside class="notes">
<p>So we’ve looked at using Canvas in a 2D context. But it also has a 3D big brother, WebGL.</p>
</aside>
</section>
<section data-background="img/webgl.jpg" data-background-size="contain">
<aside class="notes">
<p>WebGL is basically “galaxy-brain Canvas”. Like, it is to 2D Canvas what 2D Canvas was to everything else, but even more so. If you think Canvas is performant, well WebGL is even more performant! Do you find Canvas tricky to write sometimes? Well WebGL is an absolute nightmare!</p>
<p>Consider the following example:</p>
</aside>
</section>
<section data-background-iframe="webgl.html">
<aside class="notes">
<p class="meta">(Controls: T = start. R = stop. Y = reset.)</p>
<p>I've shown examples of SVG and Canvas code, so this here is a relatively straightforward example, basically a "Hello World" demo, from the Intro to WebGL tutorials on the Mozilla docs website. Let's quickly read over the code and see if we can figure out what it draws.</p>
<p class="meta">Press T</p>
<p>Okay so we're initialising our canvas and WebGL context, setting up some shaders for vertices, and fragments, handling lighting sources, creating some objects, and buffers, loading textures, drawing the scene... uhhh. oh no.</p>
<p>Right, easy. Did you all get that? Anybody able to work out what it makes? The answer is a spinning cube.</p>
</aside>
</section>
<section data-id="webgl">
<h3 class="fragment">Just because you can<br> doesn't mean you should</h3>
<aside class="notes">
<p>For that reason, I don't think many people actually write native WebGL code. You're better off using a library like Three.js, which is what I used to code this lovely spinning bar chart.</p>
<p class="meta">Down 👇 to show title text</p>
<p>I use this example to raise a very real issue with 3D charts, which is that most of the time, they're completely gratuitous and don't add anything useful. In fact by projecting data into a third dimension then representing it on a 2D screen, you're introducing visual distortion. Our eyes can try to correct for visual ambiguity, but we can only do so much.</p>
<p>Much like all those crappy clip-art-looking 3D pie charts generated with Microsoft Excel for early 2000s Powerpoint presentations, many WebGL charts are gratuitous decoration that do nothing to help the viewer understand the data. So I'd avoid them if at all possible. The best exceptions to this rule, are visualisations of actual 3D objects, like topographical maps with mountainous terrain. But in this case, you'll still want to allow users to rotate the view, to reduce the distortion effect by providing different perspectives.</p>
</aside>
</section>
<section>
<p>Don't forget about</p>
<h1>HTML & CSS!</h1>
<aside class="notes">
<p>And last but not least, let’s not forget about HTML & CSS! You can totally make charts using just HTML elements.</p>
<p class="meta">Slow</p>
</aside>
</section>
<section>
<pre><code data-trim>
<ul>
<li style="width: 30%; background: red;">30%</li>
<li style="width: 40%; background: orange;">40%</li>
<li style="width: 50%; background: yellow;">50%</li>
<li style="width: 60%; background: green;">60%</li>
<li style="width: 70%; background: blue;">70%</li>
<li style="width: 80%; background: indigo;">80%</li>
<li style="width: 90%; background: violet;">90%</li>
</ul>
</code></pre>
<ul class="css-bar">
<li style="width: 30%; background: red;">30%</li>
<li style="width: 40%; background: orange;">40%</li>
<li style="width: 50%; background: yellow;">50%</li>
<li style="width: 60%; background: green;">60%</li>
<li style="width: 70%; background: blue;">70%</li>
<li style="width: 80%; background: indigo;">80%</li>
<li style="width: 90%; background: violet;">90%</li>
</ul>
<aside class="notes">
<p>HTML is great for things like simple bar charts, where you can make use of the normal document flow to arrange them, without needing to calculate each bar’s vertical offset. You already know HTML & CSS, so there’s no learning curve, and you can use CSS for animations. Also, HTML makes it easy to write semantic and accessible markup, compared to Canvas which is basically a black box.</p>
<p>The downside of HTML is that, although there are loads of shapes and layouts that you can make with CSS, it’s ultimately not as flexible as SVG and Canvas. I’d recommend saving it for very simple things like prototypes and spark charts, and using SVG and Canvas when you have a more complex chart in mind.</p>
</aside>
</section>
<section>
<h2>Choosing a<br> charting library</h2>
<aside class="notes">
<p>Right so we've figured out some technologies we can use. But you probably don't want to build it completely from scratch, right? Other people have done this sort of thing before, there's no need to reinvent the wheel.</p>
<p class="meta">SLOW</p>
</aside>
</section>
<!-- <section data-background="img/unsure.gif" data-background-size="cover" data-background-position="center top"> -->
<section data-id="unsure">
<div class="chartlibs">
<img class="chartlib fragment" src="img/libs/highcharts.png" alt="highcharts logo" />
<img class="chartlib fragment" src="img/libs/chartist.gif" alt="chartist logo" />
<img class="chartlib fragment plain" src="img/libs/chartjs.svg" alt="chartjs logo" />
<img class="chartlib fragment" src="img/libs/semiotic.png" alt="Semiotic logo" />
<img class="chartlib fragment" src="img/libs/victory.svg" alt="Victory logo" />
<img class="chartlib fragment" src="img/libs/react-vis.png" alt="React-Vis logo" />
<img class="chartlib fragment" src="img/libs/recharts.png" alt="Recharts logo" />
<img class="chartlib fragment plain" src="img/libs/plotly.png" alt="plotly logo" />
<img class="chartlib fragment" src="img/libs/c3.png" alt="C3 logo" />
<img class="chartlib fragment plain" src="img/libs/r2d3.png" alt="r2d3 logo" />
<img class="chartlib fragment" src="img/libs/nvd3.png" alt="nvd3 logo" />
<img class="chartlib fragment" src="img/libs/rjd2.jpg" alt="rjd2" />
<img class="chartlib fragment plain" src="img/libs/d20.png" alt="d20" />
<img class="chartlib fragment plain" src="img/libs/c4.png" alt="c4" />
<img class="chartlib fragment plain" src="img/libs/r2d2.png" alt="r2d2" />
<!-- <img class="chartlib fragment" src="img/libs/nva.jpg" alt="nva" /> -->
</div>
<aside class="notes">
<p>But this can be a tricky decision too, because there are so many charting libraries to choose from!</p>
<p>There are loads of popular ones out there, like <b>Highcharts</b>, <b>Chartist</b>, and <b>ChartJS</b>. There's a bunch that use D3 with React, like <b>Semiotic</b>, <b>Victory</b>, <b>React-Vis</b>, and <b>ReCharts</b>. And there's also dozens that are just reusable abstractions for D3, like <b>Plotly</b>, <b>C3</b>, <b>R2D3</b>, <b>NVD3</b>, <b>RJD2</b>, <b>D20</b>, <b>C4</b>, and <b>R2D2</b>. It's overwhelming.</p>
<p>These libraries typically provide a few basic chart types, and abstract away most of the complexity. Whether this is a help or a hindrance depends on your use case.</p>
</aside>
</section>
<section data-background="img/d3.jpg" data-background-size="contain" data-background-color="white" data-background-position="center bottom">
<aside class="notes">
<p>But some of you might be wondering what D3 is, and why I didn't include it in the list. D3 is a data visualisation library too, in a way. But unlike the others, it's much more low-level. It's a bit more like jQuery or Underscore than a chart library, in the sense that, rather than giving you ready-built charts or chart components that you can configure, it gives you the tools to build your own custom charts from scratch, and a set of best practices to follow.</p>
<p>And in fact the syntax looks pretty similar to jQuery too. So if you like method chaining, you'll love it!</p>
<p>D3 is designed to enforce separation of concerns between data and presentation, just like the web was designed to do with HTML & CSS. I know that's not a popular idea lately, what with CSS in JS and all, but I reckon it's still a useful model in the right context. Fight me.</p>
</aside>
</section>
<section>
<table class="libraries">
<colgroup>
<col width="40%" />
<col width="30%" />
<col width="30%" />
</colgroup>
<tbody>
<tr>
<th></th>
<th>D3</th>
<th>Charting libraries</th>
</tr>
<tr class="fragment">
<td>Development time</td>
<td>🐌</td>
<td>⚡️</td>
</tr>
<tr class="fragment">
<td>Flexibility</td>
<td>💃</td>
<td>👴🏻</td>
</tr>
<tr class="fragment">
<td>Learning curve</td>
<td>😖</td>
<td>😌</td>
</tr>
<tr class="fragment">
<td>Performance</td>
<td>🏎</td>
<td>🚗</td>
</tr>
<tr class="fragment">
<td>Code readability</td>
<td>🙅</td>
<td>🤷</td>
</tr>
<tr class="fragment">
<td>Popularity</td>
<td>👯</td>
<td>📭</td>
</tr>
</tbody>
</table>
<aside class="notes">
<p>So instead of asking “which library should I use”, the real question is, “should I use D3, or another charting library”? And this one really depends on your situation, because each has a set of pros and cons.</p>
<p class="meta">DOWN</p>
<p>1. For instance, making a chart with a charting library is typically much quicker than writing something from scratch with D3. That’s the whole point: They’re an abstraction that saves you having to repeat the same basic steps every time you make a new chart.</p>
<p class="meta">DOWN</p>
<p>2. But when it comes to power and flexibility, that’s when D3 can really dance around the competition. It gives you full control over how things look, and has so many different tools and algorithms that you can mix and match to create really cool effects. I've been working with D3 for many years and I still regularly come across things where I'm like, whoa, D3 can do that?</p>
<p>It also works seamlessly with existing web technologies, and can be used in conjunction with other tools and frameworks. You can manipulate any part of the DOM, or use it with SVG, Canvas, WebGL, or whatever.</p>
<p>By contrast, most charting libraries are fairly opinionated, so they don't always do everything you want them to. If you have a specific design in mind, then the abstractions they’ve chosen may not fit your use case.</p>
<p>I often find that it's not until I’ve nearly finished building a chart, that I discover the limitations of a given library's API, and realise that it it's not able to implement certain quirks of the design I've been given. So then I have to start all over again in something else.</p>
<p>So what I sometimes do is make a basic prototype in a charting library, then build a more fleshed-out version in D3 once I've got more time to invest.</p>
<p class="meta">DOWN</p>
<p>3. But when it comes to the learning curve, that’s definitely a downside for D3. Most charting libraries are designed to be fairly easy to get started - often you just need to modify an example config, and it’s usually pretty intuitive.</p>
<p>Whereas D3 can take a bit longer to get your head around. I found D3’s data binding and element creation especially tricky to understand when I was making my first chart with it: First, you need to create a new Selection, to select all the DOM elements on the page. But they don’t exist yet, because you haven't created them. Then you bind data to them, even though they still don’t exist. Then you ‘enter’ them, which means specifically selecting the ones that exist in the data, but not in the DOM. Then you append DOM nodes to this selection, and only then do they actually get created on the page. It makes sense once you understand why it works that way, but it did my head in.</p>
<p class="meta">DOWN</p>
<p>4. Now when it comes to performance, whether animation performance or download size, that’s a mixed bag. I’ve found that some charting libraries I've used have been a little janky at executing complex animations, but it really depends how far you’re pushing it beyond what it was designed to do. Whereas D3 is usually great for animation, and makes it surprisingly easy to do some really cool transition effects like staggered delays, and you can use CSS animations with it too.</p>
<p>In terms of download size, it really depends on the library. If you only need one bar chart but you have to include the whole kitchen sink, that’s obviously not ideal. D3 used to be the worst culprit for this: It has dozens of different APIs, and if you import the whole thing it’s about half a megabyte unminified. But as of version 4, it's now completely modular, so you can just import the bits you want. Win.</p>
<p class="meta">DOWN</p>
<p>5. Next up, code readability and maintainability. Of course this depends on the library and on your preferences, after all code beauty is in the eye of the beholder. But I think most of us would agree that D3’s more imperative code style and chained functions are a bit more complex to understand. Which means that you need to put more thought into documenting them, and avoid writing sprawling spaghetti code. Most libraries are gonna beat D3 on this one.</p>
<p class="meta">DOWN</p>
<p>6. Finally, D3 is far more popular than any other JavaScript charting library, at least if you’re going by Github stars. It has a large community, and lots of examples, tutorials, stackoverflow questions, demos and even a few books written about it.</p>
</aside>
</section>
<section>
<p class="summary">In summary</pc>
<h3>For prototypes and basic charts,<br> use a charting library.</h3>
<br>
<h3>For bespoke, complex charts,<br> choose D3.</h3>
<aside class="notes">
<p>I know that was a lot of information for one slide, so here's a quick summary: If you just want to do a standard chart type like a bar or line chart and you're not fussy about the details, coding it in D3 will take longer than using a charting library. I'd recommend to use D3 in situations where you're trying to implement an unusual design as closely as possible.</p>
</aside>
</section>
<section>
<img class="plain" src="img/react.svg" alt="React logo" width=350 />
<h1>D3 + React</h1>
<aside class="notes">
<p>I mentioned that D3 plays well with other tools, and that includes React and other JavaScript frameworks. But when using them together, you need to make a big decision about which to use for updating the DOM.</p>
<p>D3 is still perfectly fine to use for layout calculations even if you use React for all the DOM rendering, and in fact, out of D3's 30 different modules, 22 of them don’t have any API methods that come in direct contact with the DOM!</p>
</aside>
</section>
<section>
<h2>Updating the DOM</h2>
<div class="flex">
<div class="fragment">
<h4>D3</h4>
<ul class="list">
<li>Complex animation</li>
<li>SVG helpers, e.g. axes</li>
</ul>
</div>
<div class="fragment">
<h4>React</h4>
<ul class="list">
<li>Better code structure</li>
<li>More readable</li>
</ul>
</div>
</div>
<aside class="notes">
<p>So it's fine if you just want to use React, but they're both great for DOM rendering in their own separate ways, and each have their own advantages and disadvantages.</p>
<p class="meta">DOWN</p>
<p>1. Like D3 is amazing at handling animations, and has some really useful SVG helpers for tricky things like axes.</p>
<p class="meta">DOWN</p>
<p>2. But D3 code tends to make your chart less structured, by putting the whole chart in one component, which can lead to tight-coupling between the individual parts. It's also a bit less readable than React's declarative syntax.</p>
<p>It's a pretty tough call! I like the structure and readability that comes by using React components, but I also like using the transitions directly on the DOM elements.</p>
</aside>
</section>
<section data-background="img/why-not-both.gif" data-background-size="contain">
<aside class="notes">
<p>So why not choose a hybrid approach? What I like to do is to combine both approaches: Let React render static components, but use D3 for axes, and anything that needs complex animations. You can mix and match the syntax together, and see what works for you.</p>
<p class="meta">Slow</p>
<p>If you want to use D3 for DOM rendering in a React component, you just need to pass a container ref to your D3 code, and run it in componentDidMount and componentDidUpdate. There's a great article by Elijah Meeks with more details, which I've added a link to at the end of this slide deck.</p>
</aside>
</section>
<section data-id="mountains" data-transition="zoom">
<h1 class="mountain-text">Have fun with it!</h1>
<aside class="notes">
<p>Finally, you don't have to use your new D3, SVG and Canvas knowledge for just making charts. D3 is not just a data visualisation library! It's also a data analysis library, a data formatting library, an SVG shape library, an animation library, and a DOM manipulation library.</p>
<p>It has dozens of different modules and algorithms to play with, and you can get really creative with them, and mix and match different layouts and scaling functions to create interesting effects in different contexts. They're great for adding playful flourishes to your websites, or talk slides.</p>
</aside>
</section>
<section data-id="mountains-2">
<div class="box">
<h1>Thanks!</h1>
<p style="margin: 1em 0 0.8em">Don't forget to like and subscribe 👍</p>
<a class="social" style="left:-1.85em" href="http://twitter.com/richardwestenra"> <i class="icon-twitter"></i> twitter.com/<b>richardwestenra</b></a>
<a class="social" style="left:-1.85em" href="http://github.com/richardwestenra"> <i class="icon-github"></i> github.com/<b>richardwestenra</b></a>
<a class="social" style="left:0em" href="mailto:[email protected]"> <i class="icon-email"></i> richard@<b>richardwestenra</b>.com</a>
<a class="social" style="left:2.17em" href="http://richardwestenra.com"> <i class="icon-home"></i> <b>richardwestenra</b>.com</a>
<small>Slides: <a href="https://richardwestenra.com/painting-with-data-talk?showNotes">richardwestenra.com/painting-with-data-talk?showNotes</a></small>
</div>
<aside class="notes">
<p>Thanks!</p>
<p>If you have any questions, please come chat to me afterwards, or get in touch online using any of my imaginative usernames.</p>
<p>Also I've added some links to handy resources on the last slide of this talk, and I'll tweet out a link.</p>
</aside>
</section>
<section>
<h4>Resources</h4>
<ul class="resources">
<li><a href="https://github.com/richardwestenra/painting-with-data-talk">Source for these slides on Github</a></li>
<li><a href="https://serialmentor.com/dataviz/">Claus O. Wilke: Fundamentals of Data Visualization</a></li>
<li><a href="http://alignedleft.com/work/d3-book-2e">Scott Murray: Interactive Data Visualization for the Web</a></li>
<li><a href="https://medium.com/@Elijah_Meeks/interactive-applications-with-react-d3-f76f7b3ebc71">Elijah Meeks: Interactive Applications with React & D3</a></li>
<li><a href="https://medium.com/@Elijah_Meeks/d3-is-not-a-data-visualization-library-67ba549e8520">Elijah Meeks: D3 is not a Data Visualization Library</a></li>
<li><a href="https://bl.ocks.org/mbostock">Mike Bostock: bl.ocks</a></li>
<li>
Chart choosing tools:
<ul>
<li><a href="https://datavizproject.com/">Data Viz Project</a></li>
<li><a href="https://datavizcatalogue.com/">Data Visualisation Catalogue</a></li>
<li><a href="http://labs.juiceanalytics.com/chartchooser/">Chart Chooser</a></li>
<li><a href="https://www.d3-graph-gallery.com/">D3.js Graph Gallery</a></li>
<li><a href="https://public.tableau.com/en-us/s/gallery/visual-vocabulary">Tableau Visual Vocabulary</a></li>
<li><a href="https://www.ibm.com/design/v1/language/experience/data-visualization/">IBM Design Language</a></li>
<li><a href="https://www.labnol.org/software/find-right-chart-type-for-your-data/6523/">Choose the Right Chart Type for your Data</a></li>
</ul>
</li>
</ul>
</section>
<section>
<h4>Image sources</h4>
<ul class="sources">
<li><a href="http://new.rushi.net/Home/Works/detail/id/44886.html">Cave Lair</a></li>
<li><a href="https://jamesbond.fandom.com/wiki/Volcano_lair">Volcano Lair</a></li>
<li><a href="https://www.imdb.com/name/nm0003909/mediaviewer/rm998333440">Bond Henchmen</a></li>
<li><a href="https://www.topsimages.com/images/telly-savalas-blofeld-18.html">Bond Villain</a></li>
<li><a href="https://giphy.com/gifs/reaction-animated-mrw-aiSGpwRj5bgJ2">Data from Star Trek TNG</a></li>
<li><a href="https://upload.wikimedia.org/wikipedia/commons/a/a7/Leadenhall_Street_J_Hopkins.jpg">Leadenhall Street</a></li>
<li><a href="https://upload.wikimedia.org/wikipedia/commons/2/2e/Panorama_dentro.JPG">Crimean War</a></li>
<li><a href="http://mentalfloss.com/article/575357/charles-dickens-tried-to-declare-wife-insane">Charles Dickens</a></li>
<li><a href="https://en.wikipedia.org/wiki/1854_Broad_Street_cholera_outbreak#/media/File:Punch-A_Court_for_King_Cholera.png">Cholera</a></li>
<li><a href="https://en.wikipedia.org/wiki/1854_Broad_Street_cholera_outbreak#/media/File:Snow-cholera-map-1.jpg">Cholera map</a></li>
<li><a href="https://gameofthrones.fandom.com/wiki/Jon_Snow">Jon Snow</a></li>
<li><a href="https://www.vox.com/2016/6/26/12029644/winds-of-winter-recap-jon-snow-parents">Jon Snow 2</a></li>