-
Notifications
You must be signed in to change notification settings - Fork 2
/
feed.xml
2015 lines (1302 loc) · 327 KB
/
feed.xml
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
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Traduction des tutoriels de Scott Murray sur D3.js</title>
<description>Traduction des tutoriels de Scott Murray sur D3.js.
</description>
<link>http://kaisersly.github.io/scottmurray-d3-fr/</link>
<atom:link href="http://kaisersly.github.io/scottmurray-d3-fr/feed.xml" rel="self" type="application/rss+xml" />
<pubDate>Sat, 10 Oct 2015 09:16:27 +0200</pubDate>
<lastBuildDate>Sat, 10 Oct 2015 09:16:27 +0200</lastBuildDate>
<generator>Jekyll v2.4.0</generator>
<item>
<title>16 - Axes</title>
<description><hr />
<p><em>Lien vers le tutoriel original : <a href="http://alignedleft.com/tutorials/d3/axes">http://alignedleft.com/tutorials/d3/axes</a></em></p>
<hr />
<h2 id="axes">Axes</h2>
<p><em>Dernière mise à jour le 30 décembre 2012</em></p>
<p>Après avoir maîtrisé l’usage des échelles de D3, on a ce nuage de points :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/1.png" alt="Grand nuage de points mis à l'échelle" /></p>
<p>Ajoutons des axes horizontaux et verticaux, pour que nous puissions enlever ces horribles nombres rouges qui encombrent la visibilité.</p>
<h3 id="introduction-aux-axes">Introduction aux axes</h3>
<p>Tout comme les fonctions d’échelle, <a href="https://github.com/mbostock/d3/wiki/SVG-Axes">les <em>axes</em> de D3</a> sont en fait des <em>fonctions</em> avec des paramètres que vous définissez. Au contraire des échelles, lorsque qu’une fonction d’axe est appelée, elle ne retourne pas une valeur, mais elle génère les éléments visuels de l’axe, comprenant des lignes, des étiquettes et des marques.</p>
<p>Notez que les fonctions d’axe sont spécifiques à SVG, en ce qu’elle génère des éléments SVG. De plus, les axes sont prévus pour être utilisés avec des échelles quantitatives (par opposition aux échelles ordinales).</p>
<h3 id="paramtrer-un-axe">Paramétrer un axe</h3>
<p>Utilisez <strong>d3.svg.axis()</strong> pour créer une fonction d’axe générique :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">xAxis</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">svg</span><span class="p">.</span><span class="nx">axis</span><span class="p">();</span></code></pre></div>
<p>Au minimum, chaque axe a aussi besoin qu’on lui dise sur quelle <em>échelle</em> il opère. Ici nous lui passerons <strong>xScale</strong> du code de notre nuage :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">xAxis</span><span class="p">.</span><span class="nx">scale</span><span class="p">(</span><span class="nx">xScale</span><span class="p">);</span></code></pre></div>
<p>On peut également lui spécifier où les étiquettes doivent apparaître relativement à l’axe lui-même. Par défaut c’est <strong>bottom</strong>, ce qui veut dire que les étiquettes apparaîtront en bas de la ligne d’axe. (Bien que c’est par défaut, ça ne peut pas faire de mal de le dire explicitement.)</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">xAxis</span><span class="p">.</span><span class="nx">orient</span><span class="p">(</span><span class="s2">"bottom"</span><span class="p">);</span></code></pre></div>
<p>Bien sûr, on peut être plus concis et écrire tout ça en une ligne :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">xAxis</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">svg</span><span class="p">.</span><span class="nx">axis</span><span class="p">()</span>
<span class="p">.</span><span class="nx">scale</span><span class="p">(</span><span class="nx">xScale</span><span class="p">)</span>
<span class="p">.</span><span class="nx">orient</span><span class="p">(</span><span class="s2">"bottom"</span><span class="p">);</span></code></pre></div>
<p>Enfin, pour générer l’axe et insérer toutes ces petites lignes et ces étiquettes dans notre SVG, on doit <em>appeler</em> la fonction <strong>xAxis</strong>. Je placerai ce code à la fin de notre script, pour que l’axe soit généré après les autres éléments SVG :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"g"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">xAxis</span><span class="p">);</span></code></pre></div>
<p><a href="https://github.com/mbostock/d3/wiki/Selections#wiki-call">La fonction <strong>call()</strong> de D3</a> prend en entrée une <em>sélection</em> et transmet cette sélection à une <em>fonction</em>. Donc, dans notre cas, on vient juste d’ajouter un nouvel élément groupe <strong>g</strong> pour contenir tous nos éléments d’axe qui-vont-bientôt-être-générés. (Le <strong>g</strong> n’est pas rigoureusement nécessaire, mais permet de garder les éléments organisés et d’appliquer une classe au groupe entier, ce que nous ferons dans un instant.)</p>
<p>Ce <strong>g</strong> devient la sélection pour le prochain maillon de la chaîne. <strong>call()</strong> transmet la sélection à la fonction <strong>xAxis</strong>, donc notre axe est généré dans le nouveau <strong>g</strong>. Ce bout de code au-dessus est un raccourci pour cet équivalent :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"g"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">d3</span><span class="p">.</span><span class="nx">svg</span><span class="p">.</span><span class="nx">axis</span><span class="p">()</span>
<span class="p">.</span><span class="nx">scale</span><span class="p">(</span><span class="nx">xScale</span><span class="p">)</span>
<span class="p">.</span><span class="nx">orient</span><span class="p">(</span><span class="s2">"bottom"</span><span class="p">));</span></code></pre></div>
<p>Vous voyez, vous pourriez écrire votre axe dans la fonction <strong>call()</strong>, mais il est généralement plus facile pour notre cerveau de définir d’abord des fonctions, et de les appeler plus tard.</p>
<p>Quoi qu’il arrive, <a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/1.html">voilà à quoi ça ressemble</a> :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/2.png" alt="Un axe simple, mais laid" /></p>
<h3 id="faire-le-mnage">Faire le ménage</h3>
<p>Techniquement c’est un axe, mais ce n’est ni joli ni utile. Pour le nettoyer, assignons d’abord une classe <strong>axis</strong> au nouvel élément <strong>g</strong>, pour pouvoir le sélectionner avec CSS :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"g"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"class"</span><span class="p">,</span> <span class="s2">"axis"</span><span class="p">)</span> <span class="c1">// Assigne la classe "axis"</span>
<span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">xAxis</span><span class="p">);</span></code></pre></div>
<p>Ensuite, on ajoute nos styles CSS dans le <strong>&lt;head&gt;</strong> de notre page :</p>
<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nc">.axis</span> <span class="nt">path</span><span class="o">,</span>
<span class="nc">.axis</span> <span class="nt">line</span> <span class="p">{</span>
<span class="py">fill</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="py">stroke</span><span class="p">:</span> <span class="no">black</span><span class="p">;</span>
<span class="py">shape-rendering</span><span class="p">:</span> <span class="n">crispEdges</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.axis</span> <span class="nt">text</span> <span class="p">{</span>
<span class="nl">font-family</span><span class="p">:</span> <span class="nb">sans-serif</span><span class="p">;</span>
<span class="nl">font-size</span><span class="p">:</span> <span class="m">11px</span><span class="p">;</span>
<span class="p">}</span></code></pre></div>
<p><a href="https://developer.mozilla.org/en/SVG/Attribute/shape-rendering">La propriété <strong>shape-rendering</strong></a> est un attribut SVG, utilisée ici pour s’assurer que notre axe et ses marques sont définis au pixel près. Pas d’axe flou pour nous !</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/3.png" alt="Axe plus propre" /></p>
<p>C’est mieux, mais le haut de l’axe est coupé, et on veut, quoi qu’il arrive, qu’il soit à la base du graphique. On peut utiliser la fonction <strong>transform</strong> sur le groupe de l’axe, en le poussant vers le bas :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"g"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"class"</span><span class="p">,</span> <span class="s2">"axis"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"transform"</span><span class="p">,</span> <span class="s2">"translate(0,"</span> <span class="o">+</span> <span class="p">(</span><span class="nx">h</span> <span class="o">-</span> <span class="nx">padding</span><span class="p">)</span> <span class="o">+</span> <span class="s2">")"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">xAxis</span><span class="p">);</span></code></pre></div>
<p>Notez l’utilisation de <strong>(h - padding)</strong>, pour que le bord haut du groupe soit défini à <strong>h</strong>, la hauteur de notre image, moins la valeur de marge <strong>padding</strong> que l’on a créée plus tôt.</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/4.png" alt="Axe propre et joli" /></p>
<p>C’est bien mieux ! <a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/2.html">Voilà le code jusqu’ici.</a></p>
<h3 id="soccuper-des-marques-ticks">S’occuper des marques (<em>ticks</em>)</h3>
<p>Les tiques (<em>ticks</em>) peuvent transmettre des maladies, mais les <a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear_ticks">marques (<em>ticks</em>) de D3</a> communiquent de l’information. Et pourtant afficher plus de marques n’est pas forcément plus efficace, et à partir d’un certain moment elles commencent à surcharger votre graphique. Vous noterez que l’on a jamais spécifié combien de marques inclure dans l’axe, ni à quel intervalle elles devraient apparaître. Sans instructions données, D3 a examiné magiquement notre échelle <strong>xScale</strong> et en a déduit combien de marques ajouter, et à quel intervalle (tous les 50 dans notre cas).</p>
<p>Comme vous pouvez l’imaginer, vous pouvez personnaliser tous les aspects de vos axes, en commençant par un nombre approximatif de marques, en utilisant <strong>ticks()</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">xAxis</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">svg</span><span class="p">.</span><span class="nx">axis</span><span class="p">()</span>
<span class="p">.</span><span class="nx">scale</span><span class="p">(</span><span class="nx">xScale</span><span class="p">)</span>
<span class="p">.</span><span class="nx">orient</span><span class="p">(</span><span class="s2">"bottom"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">ticks</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span> <span class="c1">// Définit un nombre approximatif de 5 marques</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/5.png" alt="Moins de marques" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/3.html">Voilà le code.</a></p>
<p>Vous avez probablement noté que, bien que l’on ait défini cinq marques, D3 a décidé d’en afficher sept. C’est parceque D3 assure vos arrières, et qu’il s’est rendu compte qu’afficher seulement <em>cinq</em> marques aurait demandé de découper notre domaine d’entrée en valeurs bien moins jolies — dans notre cas, 0, 150, 300, 450, et 600. D3 interprète la valeur dans <strong>ticks()</strong> comme une suggestion, et remplacera votre suggestion avec ce qu’il détermine comme la valeur la plus propre et la plus facile à lire par un humain — dans notre cas, des intervalles de 100 — même lorsque cela requiert d’ajouter quelques marques de plus que ce que vous avez demandé. C’est en fait une fonctionnalité brillante qui accroit l’évolutivité (<em>scalability</em>) de votre désign ; à mesure que l’ensemble de données évolue, et que le domaine d’entrée s’étend ou se contracte (des nombres plus grands ou plus petits), D3 s’assure que les marques restent claires et faciles à lire.</p>
<h3 id="pourquoi-pas-y-not-">Pourquoi pas (<em>Y Not</em>) ?</h3>
<p>Il est temps d’étiqueter notre axe vertical ! En copiant et en modifiant le code que l’on a déjà écrit pour l’axe <strong>xAxis</strong>, on ajoute ça vers le haut de notre code</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Définit l'axe Y</span>
<span class="kd">var</span> <span class="nx">yAxis</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">svg</span><span class="p">.</span><span class="nx">axis</span><span class="p">()</span>
<span class="p">.</span><span class="nx">scale</span><span class="p">(</span><span class="nx">yScale</span><span class="p">)</span>
<span class="p">.</span><span class="nx">orient</span><span class="p">(</span><span class="s2">"left"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">ticks</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span></code></pre></div>
<p>et ceci, près du bas :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Créé l'axe Y</span>
<span class="nx">svg</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"g"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"class"</span><span class="p">,</span> <span class="s2">"axis"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"transform"</span><span class="p">,</span> <span class="s2">"translate("</span> <span class="o">+</span> <span class="nx">padding</span> <span class="o">+</span> <span class="s2">",0)"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">yAxis</span><span class="p">);</span></code></pre></div>
<p>Notez que les étiquettes seront orientées vers la gauche <strong>left</strong> et que le groupe <strong>g</strong> de l’axe <strong>yAxis</strong> est déplacé par translation vers la droite par un montant de <strong>padding</strong>.</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/6.png" alt="Axe Y initial" /></p>
<p>Ça commence à prendre forme ! Mais les étiquettes de l’axe <strong>yAxis</strong> sont coupées. Pour leur donner plus de place sur la gauche, je vais augmenter la valeur de <strong>padding</strong> de 20 à 30 :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">padding</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span></code></pre></div>
<p>Bien sûr, vous pourriez aussi faire apparaître des variables séparées de <strong>padding</strong> pour chaque axe, disons <strong>xPadding</strong> et <strong>yPadding</strong>, pour avoir plus de contrôle sur la disposition du graphique.</p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/4.html">Voilà le code</a>, et voila à quoi il ressemble :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/7.png" alt="Nuage de points avec un axe Y" /></p>
<h3 id="touches-finales">Touches finales</h3>
<p>Pour vous prouvez que notre nouvel axe est dynamique et évolutif, j’aimerais passer d’un ensemble statique à un ensemble de nombres aléatoires :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Ensemble dynamique de nombres aléatoires</span>
<span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">var</span> <span class="nx">numDataPoints</span> <span class="o">=</span> <span class="mi">50</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">xRange</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">yRange</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">numDataPoints</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">newNumber1</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="nx">xRange</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">newNumber2</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="nx">yRange</span><span class="p">);</span>
<span class="nx">dataset</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="nx">newNumber1</span><span class="p">,</span> <span class="nx">newNumber2</span><span class="p">]);</span>
<span class="p">}</span></code></pre></div>
<p>Ce code crée un nouveau tableau, itère 50 fois, choisit deux nombres aléatoires à chaque fois, et ajoute (pousse) cette paire de valeurs dans le tableau <strong>dataset</strong>.</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/8.png" alt="Nuage de points avec données aléatoires" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/5.html">Essayez le code ici.</a> Chaque fois que vous rechargez la page, vous obtenez différentes valeurs. Notez comment les axes se mettent à l’échelle pour correspondre aux nouveaux domaines, et comment les marques et les étiquettes sont choisies en conséquence.</p>
<p>Ma démonstration étant finie, je pense que l’on peut retirer ces horribles étiquettes rouges, en commentant les lignes de code qui les concernent :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/9.png" alt="Nuage de points avec des données aléatoires et sans étiquettes rouges" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/6.html">Le code final de notre nuage !</a></p>
<h3 id="mettre-en-forme-les-tiquettes">Mettre en forme les étiquettes</h3>
<p>Une dernière chose : Jusqu’ici, on a travaillé avec des entiers qui sont propres et faciles à lire. Mais les données sont souvent plus complexes, et dans ces cas, vous voudrez avoir plus de contrôle sur la manière dont les étiquettes sont mises en forme. Découvrez <a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear_tickFormat"><strong>tickFormat()</strong></a>, qui vous permet de spécifier comment les nombres doivent être formatés. Par exemple, vous pourriez souhaiter avoir trois chiffres après la virgule, ou afficher les valeurs en pourcentage, ou les deux.</p>
<p>Dans ce cas, vous définiriez d’abord une nouvelle fonction de mise en forme. Celle-ci, par exemple, dit de traiter les valeurs comme des pourcentages avec une précision d’une décimale. (Allez voir <a href="https://github.com/mbostock/d3/wiki/Formatting#wiki-d3_format">la référence de d3.format()</a> pour plus d’options.)</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">formatAsPercentage</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span><span class="s2">".1%"</span><span class="p">);</span></code></pre></div>
<p>Ensuite, transmettez-la à la fonction de formattage des marques :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">xAxis</span><span class="p">.</span><span class="nx">tickFormat</span><span class="p">(</span><span class="nx">formatAsPercentage</span><span class="p">);</span></code></pre></div>
<p>Conseil de développeur : Je trouve plus facile de tester ces fonctions de formattage dans la console JavaScript. Par exemple, ouvrez juste une page qui charge D3, comme <a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/6.html">notre nuage final</a>, et écrivez votre règle de formattage dans la console. Ensuite testez-la en lui passant une valeur, comme vous le feriez avec n’importe quelle autre fonction :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/10.png" alt="Test de formattage dans la console" /></p>
<p>Vous pouvez voir ici que la valeur <strong>0.54321</strong> est convertie en <strong>54.3%</strong> pour l’affichage — parfait !</p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/160-axes/7.html">Essayez ce code ici.</a> Un formattage en pourcentage n’a pas de sens avec l’ensemble de données de notre nuage, mais à titre d’exercice, vous pourriez essayer de modifier comment les nombres aléatoires sont générés, pour avoir des nombres non-entiers (<em>et compris entre 0 et 1</em>), ou expérimenter la fonction de formattage elle-même.</p>
<hr />
<h2 id="note-finale-du-traducteur">Note finale du traducteur</h2>
<p>La traduction de cette série de tutoriels est désormais terminée. J’espère qu’elle vous aura été utile. N’hésitez pas à la faire connaître autour de vous et à laisser un petit “Thanks for your tutorials on D3” sur Twitter à <a href="https://twitter.com/alignedleft">Scott Murray</a>. </p>
<p>Après avoir intégré les bases de D3 en français, vous souhaiterez peut-être lire le livre écrit, en anglais, par Scott Murray sur D3. Il est disponible en <a href="http://www.jdoqocy.com/click-6754088-11260198?url=http%3A%2F%2Fshop.oreilly.com%2Fproduct%2F0636920026938.do%3Fcmp%3Daf-strata-books-videos-product_cj_9781449339739_%2525zp&amp;cjsku=0636920026938">édition papier</a>, ou accessible, <em>gratuitement</em>, <a href="http://chimera.labs.oreilly.com/books/1230000000345/index.html">en ligne</a>.</p>
<p>Un tutoriel visuel et intéractif sur les transitions est aussi disponible <a href="http://alignedleft.com/projects/2014/easy-as-pi/">sur son site</a>. Il suffit de cliquer sur le bouton <strong>Next &gt;</strong> | <strong>Run it &gt;</strong> et d’analyser les lignes de code. </p>
<p>Bonnes visualisations !</p>
</description>
<pubDate>Tue, 28 Oct 2014 00:00:00 +0100</pubDate>
<link>http://kaisersly.github.io/scottmurray-d3-fr/16-axes.html</link>
<guid isPermaLink="true">http://kaisersly.github.io/scottmurray-d3-fr/16-axes.html</guid>
</item>
<item>
<title>15 - Échelles</title>
<description><hr />
<p><em>Lien vers le tutoriel original : <a href="http://alignedleft.com/tutorials/d3/scales">http://alignedleft.com/tutorials/d3/scales</a></em></p>
<hr />
<h2 id="chelles">Échelles</h2>
<p><em>Dernière mise à jour le 30 décembre 2012</em></p>
<p>“Les échelles sont des fonctions qui font correspondre un domaine en entrée à une plage de sortie.”</p>
<p>C’est <a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales">la définition de Mike Bostock des échelles de D3</a>.</p>
<p>Les valeurs de n’importe quel ensemble de données ont peu de chances de correspondre exactement aux mesures en pixels utilisées dans votre visualisation. Les échelles proposent un moyen pratique de faire correspondre les valeurs de vos données à de nouvelles valeurs utilisables dans des visualisations.</p>
<p>Les échelles de D3 sont des <em>fonctions</em> que vous parametrez. Une fois créée, vous appelez la fonction d’échelle, vous lui passez une valeur, et elle vous retourne gentiment une valeur mise à l’échelle. Vous pouvez définir et utiliser autant d’échelles que vous voulez.</p>
<p>Il pourrait être tentant de penser à une échelle comme à quelque chose apparaissant visuellement sur l’image finale — comme un ensemble de marques indiquant une progression de valeurs. <em>Ne vous faites pas avoir !</em> Ces marques font partie d’un <em>axe</em>, qui est fondamentalement une représentation visuelle d’une échelle. Une échelle est une relation mathématique, sans représentation visuelle directe. Je vous encourage à penser les échelles et les axes comme deux choses différentes, mais quand même liées.</p>
<p>Cet article s’intéresse seulement aux échelles <a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear"><em>linéaires</em></a>, car elles sont les plus courantes et les plus facilement compréhensible. Une fois que vous aurez compris les échelles linéaires, comprendre les autres sera un jeu d’enfants.</p>
<h3 id="pommes-et-pixels">Pommes et pixels</h3>
<p>Imaginez que l’ensemble de données qui suit représente le nombre de pommes vendues sur un stand de marché chaque mois :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">400</span><span class="p">,</span> <span class="mi">500</span> <span class="p">];</span></code></pre></div>
<p>Bonne nouvelle, le stand vend 100 pommes de plus chaque mois ! Le business est en plein essor. Pour mettre en valeur ce succès, vous voulez faire un graphique à barres illustrant la montée rapide des ventes de pommes, chaque valeur correspondant à la hauteur d’une barre.</p>
<p>Jusqu’à maintenant, on a utilisé les valeurs des données directement dans les valeurs d’affichage, sans s’intéresser aux différences d’unités. Donc si 500 pommes sont vendues, le barre correspondante ferait 500 pixels de haut.</p>
<p>Ça pourrait fonctionner, mais qu’en est-il du prochain mois, lorsque 600 pommes seront vendues ? Et l’année qui suit, lorsque 1 800 pommes seront vendues ? Votre public devra s’acheter des écrans de plus en plus grands, juste pour pouvoir voir la hauteur totale de vos barres de pommes ! (Miam, des barres de pommes !)</p>
<p>C’est là que les échelles entrent en jeu. Comme les pommes ne sont pas des pixels (qui ne sont pas eux-mêmes des oranges), on a besoin d’échelles pour passer de l’un à l’autre.</p>
<h3 id="domaines-et-plages">Domaines et plages</h3>
<p>Le <em>domaine d’entrée</em> d’une échelle est l’ensemble des valeurs possibles en entrée. Pour les données de pommes plus haut, un domaine d’entrée approprié serait soit entre 100 et 500 (les valeurs minimum et maximum de notre ensemble de données) soit entre 0 et 500.
<em>(la traduction est difficile, mais l’ensemble est à comprendre au sens mathématique, les deux valeurs correspondant à ses bornes : {100 … 500} ou {0 … 500})</em></p>
<p>La <em>plage de sortie</em> d’une échelle est l’ensemble des valeurs possibles en sortie, le plus souvent utilisées comme valeurs d’affichage en pixels. La plage de sortie dépend entièrement de vous, en tant que designer d’information. Si vous décidez que la plus petite barre doit faire 10 pixels de haut, et que la plus grande doit faire 350 pixels de haut, alors vous pourriez définir une plage de sortie entre 10 et 350.</p>
<p>Par exemple, créez une échelle avec un domaine d’entrée de <strong>100,500</strong> et une plage de sortie de <strong>10,350</strong>. Si vous donnez à cette échelle la valeur <strong>100</strong>, elle vous retournera <strong>10</strong>. Si vous lui donnez <strong>500</strong>, elle vous sortira <strong>350</strong>. Si vous lui donnez <strong>300</strong>, elle vous présentera <strong>180</strong> sur un plateau d’argent. (<strong>300</strong> est le centre du domaine d’entrée, et <strong>180</strong> le centre de la plage de sortie.)</p>
<p>On pourrait visualiser le domaine d’entrée et la plage de sortie comme deux axes correspondants, côte-à-côte :</p>
<svg width="505" height="115">
<text x="220" y="15" font-style="italic">Domaine d'entrée</text>
<line x1="5" y1="30" x2="500" y2="30" stroke="gray" stroke-width="1"></line>
<circle cx="5" cy="30" r="3" fill="#008"></circle>
<text x="8" y="48">100</text>
<circle cx="255" cy="30" r="3" fill="#008"></circle>
<text x="258" y="48">300</text>
<circle cx="500" cy="30" r="3" fill="#008"></circle>
<text x="473" y="48">500</text>
<line x1="5" y1="90" x2="500" y2="90" stroke="gray" stroke-width="1"></line>
<circle cx="5" cy="90" r="3" fill="#008"></circle>
<text x="8" y="84">10</text>
<circle cx="255" cy="90" r="3" fill="#008"></circle>
<text x="258" y="84">180</text>
<circle cx="500" cy="90" r="3" fill="#008"></circle>
<text x="473" y="84">350</text>
<text x="220" y="110" font-style="italic">Plage de sortie</text>
</svg>
<p>Une dernière chose : Comme il est vraiment facile de mélanger la terminologie <em>domaine d’entrée</em> et <em>plage de sortie</em>, j’aimerais vous proposer un petit exercice. Quand je dis “entrée”, vous dites “domaine”. Puis je dis “sortie” et vous répondez “plage”. Prêt ? Okay :</p>
<ul>
<li>Entrée! Domaine!</li>
<li>Sortie! Plage!</li>
<li>Entrée! Domaine!</li>
<li>Sortie! Plage!</li>
</ul>
<p>Vous l’avez ? Cool.</p>
<h3 id="normalisation">Normalisation</h3>
<p>Si vous êtes familiés avec le concept de <em>normalisation</em>, il pourrait vous être utile de savoir qu’avec les échelles, c’est tout ce qui ce passe.</p>
<p>La normalisation est le processus qui fait correspondre une valeur numérique à une nouvelle valeur comprise entre 0 et 1, en se basant sur les valeurs minimum et maximum possibles. Par exemple, avec 365 jours dans l’année, le jour 310 correspond à à peu près 0.85, soit 85% de la progression dans l’année.</p>
<p>Avec les échelles linéaires, on laisse juste D3 s’occuper des maths pour le processus de normalisation. La valeur d’entrée est normalisée en accord avec le domaine d’entrée, puis la valeur normalisée est mise à l’échelle par rapport à la plage de sortie.</p>
<h3 id="crer-une-chelle">Créer une échelle</h3>
<p>Les générateurs d’échelles de D3 sont accessibles avec <strong>d3.scale</strong> suivi du type d’échelle que vous souhaitez.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">scale</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">scale</span><span class="p">.</span><span class="nx">linear</span><span class="p">();</span></code></pre></div>
<p>Bravo ! Maintenant <strong>scale</strong> est une fonction à laquelle vous pouvez passer des valeurs en entrée. (Ne soyez pas trompé par le <strong>var</strong> au-dessus ; rappelez-vous qu’en JavaScript les variables peuvent stocker des fonctions.)</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">scale</span><span class="p">(</span><span class="mf">2.5</span><span class="p">);</span> <span class="c1">// Retourne 2.5</span></code></pre></div>
<p>Comme on a pas défini de domaine d’entrée et de plage de sortie, cette fonction fait correspondre les valeurs sur une échelle 1:1. Ce qui veut dire que, quelque soit la valeur en entrée, elle est la même en sortie.</p>
<p>On peut définir le domaine d’entrée à <strong>100,500</strong> en passant ces valeurs dans un tableau à la méthode <strong>domain()</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">scale</span><span class="p">.</span><span class="nx">domain</span><span class="p">([</span><span class="mi">100</span><span class="p">,</span> <span class="mi">500</span><span class="p">]);</span></code></pre></div>
<p>On définit la plage de sortie d’une manière similaire, avec <strong>range()</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">scale</span><span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="mi">10</span><span class="p">,</span> <span class="mi">350</span><span class="p">]);</span></code></pre></div>
<p>Ces étapes peuvent être faites séparément, comme ci-dessus, ou enchaînées en une ligne de code :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">scale</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">scale</span><span class="p">.</span><span class="nx">linear</span><span class="p">()</span>
<span class="p">.</span><span class="nx">domain</span><span class="p">([</span><span class="mi">100</span><span class="p">,</span> <span class="mi">500</span><span class="p">])</span>
<span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="mi">10</span><span class="p">,</span> <span class="mi">350</span><span class="p">]);</span></code></pre></div>
<p>Quoiqu’il arrive, notre échelle est prête à l’emploi !</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">scale</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span> <span class="c1">// Retourne 10</span>
<span class="nx">scale</span><span class="p">(</span><span class="mi">300</span><span class="p">);</span> <span class="c1">// Retourne 180</span>
<span class="nx">scale</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="c1">// Retourne 350</span></code></pre></div>
<p>Typiquement, vous appellerez les fonctions d’échelle dans une méthode <strong>attr()</strong> ou similaire, mais jamais toutes seules. Modifions notre nuage de points pour utiliser des échelles dynamiques.</p>
<h3 id="mettre-le-nuage-de-points--lchelle">Mettre le nuage de points à l’échelle</h3>
<p>Retournons à notre ensemble de données :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span> <span class="p">[</span><span class="mi">480</span><span class="p">,</span> <span class="mi">90</span><span class="p">],</span> <span class="p">[</span><span class="mi">250</span><span class="p">,</span> <span class="mi">50</span><span class="p">],</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">33</span><span class="p">],</span> <span class="p">[</span><span class="mi">330</span><span class="p">,</span> <span class="mi">95</span><span class="p">],</span>
<span class="p">[</span><span class="mi">410</span><span class="p">,</span> <span class="mi">12</span><span class="p">],</span> <span class="p">[</span><span class="mi">475</span><span class="p">,</span> <span class="mi">44</span><span class="p">],</span> <span class="p">[</span><span class="mi">25</span><span class="p">,</span> <span class="mi">67</span><span class="p">],</span> <span class="p">[</span><span class="mi">85</span><span class="p">,</span> <span class="mi">21</span><span class="p">],</span> <span class="p">[</span><span class="mi">220</span><span class="p">,</span> <span class="mi">88</span><span class="p">]</span>
<span class="p">];</span></code></pre></div>
<p>Vous vous rappelez que <strong>dataset</strong> est un tableau de tableaux. On fait correspondre la première valeur de chaque tableau sur l’axe x, et la seconde valeur sur l’axe y. Commençons avec l’axe x.</p>
<p>En survolant les valeurs de x, il semble que les valeurs vont de 5 à 480, donc un domaine d’entrée de <strong>0,500</strong> serait convenable, pas vrai ?</p>
<p>…</p>
<p>Pourquoi vous me regardez comme ça ? Ah, parceque vous voulez garder un code souple et évolutif (<em>scalable</em>), pour qu’il continue de fonctionner même si nos données changent plus tard. Très intelligent !</p>
<p>Plutôt que de spécifier des valeurs fixes pour le domaine, on utilise des fonctions pour les tableaux <strong>min()</strong> et <strong>max()</strong> pour analyser nos données à la volée. Par exemple, ce code itère chaque valeur de x dans nos tableaux et retourne la plus grande valeur :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">d3</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">dataset</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Retourne 480</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="c1">// Référence la première valeur de chaque sous-tableau</span>
<span class="p">});</span></code></pre></div>
<p>En mettant tout ensemble, créons la fonction d’échelle pour notre axe x :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">xScale</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">scale</span><span class="p">.</span><span class="nx">linear</span><span class="p">()</span>
<span class="p">.</span><span class="nx">domain</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">dataset</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="p">})])</span>
<span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="nx">w</span><span class="p">]);</span></code></pre></div>
<p>D’abord, notez que je l’ai nommé <strong>xScale</strong>. Bien sûr, vous pouvez nommer vos variables comme vous le souhaitez, mais un nom comme <strong>xScale</strong> m’aide à me rappeler ce que cette fonction fait.</p>
<p>Ensuite, notez que j’ai défini le début du domaine d’entrée à zéro. (Vous auriez pu également utiliser <strong>min()</strong> pour calculer une valeur dynamique.) La fin de notre domaine est définie comme la valeur maximum dans <strong>dataset</strong> (qui est 480).</p>
<p>Enfin, vous pouvez observer que la plage de sortie est définie de <strong>0</strong> à <strong>w</strong>, la largeur de notre SVG.</p>
<p>On utilisera un code similaire pour créer la fonction d’échelle de notre axe y :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">yScale</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">scale</span><span class="p">.</span><span class="nx">linear</span><span class="p">()</span>
<span class="p">.</span><span class="nx">domain</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">dataset</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="p">})])</span>
<span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="nx">h</span><span class="p">]);</span></code></pre></div>
<p>Notez que la fonction <strong>max()</strong> référence <strong>d[1]</strong>, la valeur y de chaque sous-tableau. Également, la fin de la plage de sortie est définie comme <strong>h</strong> (<em>la hauteur du SVG</em>) plutôt que <strong>w</strong>.</p>
<p>Les fonctions d’échelle sont en place ! Maintenant il nous faut les utiliser. Modifiez juste le code où l’on crée un cercle <strong>circle</strong> pour chaque valeur de donnée</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"cx"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">})</span></code></pre></div>
<p>pour retourner une valeur mise à l’échelle (à la place de la valeur originale) :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"cx"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">xScale</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="p">})</span></code></pre></div>
<p>De la même manière, pour l’axe y, ceci</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"cy"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">})</span></code></pre></div>
<p>donne cela :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"cy"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">yScale</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="p">})</span></code></pre></div>
<p>Changeons également le placement des étiquettes ; ces lignes</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">})</span></code></pre></div>
<p>deviennent ce qui suit :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">xScale</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">yScale</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="p">})</span></code></pre></div>
<p>Nous y voilà !</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/1.png" alt="Nuage de points utilisant des échelles en x et y" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/1.html">Voilà le code en fonctionnement.</a> Visuellement, ça ressemble étrangement à notre nuage original ! Et pourtant on a fait plus de progrès que ce qui est apparait.</p>
<h3 id="affiner-le-nuage">Affiner le nuage</h3>
<p>Vous avez peut-être remarqué que les valeurs de y les plus petites sont en haut du nuage, et les plus grandes en bas. Maintenant que l’on utilise des échelles, il est super facile d’inverser cela, de sorte que les plus grandes valeurs soient en haut, comme vous pourriez vous y attendre. Il suffit juste de changer la plage de sortie de</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="nx">h</span><span class="p">]);</span></code></pre></div>
<p>à</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="nx">h</span><span class="p">,</span> <span class="mi">0</span><span class="p">]);</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/2.png" alt="Nuage de points avec une échelle en y inversée" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/2.html">Voilà le code.</a> Oui, maintenant une valeur d’entrée <em>plus petite</em> qui passe par la fonction d’échelle <strong>yScale</strong> produira une valeur de sortie plus grande, poussant ces éléments <strong>circle</strong> et <strong>text</strong> vers le bas, plus près de la ligne de base de l’image. Je sais, c’est presque trop facile !</p>
<p>Et pourtant certains éléments sont coupés. Définissons une variable de marge <strong>padding</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">padding</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span></code></pre></div>
<p>Ajoutons-là aux deux échelles. La plage de sortie de <strong>xScale</strong> était <strong>range([0, w])</strong>, maintenant elle devient</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="nx">padding</span><span class="p">,</span> <span class="nx">w</span> <span class="o">-</span> <span class="nx">padding</span><span class="p">]);</span></code></pre></div>
<p>Pour <strong>yScale</strong> on passe de <strong>range([h, 0])</strong>, à</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="nx">h</span> <span class="o">-</span> <span class="nx">padding</span><span class="p">,</span> <span class="nx">padding</span><span class="p">]);</span></code></pre></div>
<p>Ça devrait nous donner 20 pixels en haut, en bas, à gauche et à droite du SVG. Et ça le fait !</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/3.png" alt="Nuage de points avec des marges" /></p>
<p>Mais les étiquettes sur le bord droit sont toujours coupés, je double donc la marge droite de <strong>xScale</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="nx">padding</span><span class="p">,</span> <span class="nx">w</span> <span class="o">-</span> <span class="nx">padding</span> <span class="o">*</span> <span class="mi">2</span><span class="p">]);</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/4.png" alt="Nuage de points avec des marges plus grandes" /></p>
<p>C’est mieux ! <a href="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/3.html">Voilà le code.</a> Mais il y a encore un changement que j’aimerais apporter. Plutôt que de définir le rayon de chaque <strong>circle</strong> comme la racine carrée de sa valeur y (ce qui était un peu du bricolage, et pas vraiment utile quoi qu’il arrive), pourquoi ne pas définir une nouvelle échelle personnalisée ?</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">rScale</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">scale</span><span class="p">.</span><span class="nx">linear</span><span class="p">()</span>
<span class="p">.</span><span class="nx">domain</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">dataset</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="p">})])</span>
<span class="p">.</span><span class="nx">range</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">]);</span></code></pre></div>
<p>Puis définir le rayon comme ceci :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"r"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">rScale</span><span class="p">(</span><span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="p">});</span></code></pre></div>
<p>C’est excitant, car on garantit que notre rayon tombera <em>toujours</em> dans une plage de sortie <strong>2,5</strong>. (Ou <em>presque</em> toujours : Jetez un oeil à la référence à <strong>clamp()</strong> plus bas.) Donc une valeur de <strong>0</strong> (l’entrée minimum) donnera des cercles de rayon <strong>2</strong> (ou d’un diamètre de 4 pixels). La plus grande valeur donnera un cercle de rayon <strong>5</strong> (d’un diamètre de 10 pixels).</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/5.png" alt="Nuage de points avec des rayons mis à l'échelle" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/4.html">Voilà</a> : Notre première échelle utilisée pour une propriété visuelle autre qu’une valeur d’axe.</p>
<p>Enfin, juste au cas où la puissance des échelles ne vous aurait pas encore sauté aux yeux, je vais ajouter un point dans notre ensemble de données : <strong>[600, 150]</strong></p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/6.png" alt="Nuage de points avec des valeurs plus grandes ajoutées" /></p>
<p>Boom ! <a href="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/5.html">Voilà le code.</a> Notez comment tous les anciens points maintiennent leurs positions relatives, mais ont migré ensemble plus près, plus bas et plus à gauche, pour laisser de la place au nouveau venu.</p>
<p>Et maintenant, une dernière révélation : On peut désormais changer facilement les dimensions de notre SVG, et tout se mettra à l’échelle en conséquence. Ici, j’ai augmenté la valeur de h de <strong>100</strong> à <strong>300</strong> et je n’ai fait <em>aucun autre changement</em> :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/7.png" alt="Grand nuage de points" /></p>
<p>Boom, encore ! <a href="http://alignedleft.com/content/03-tutorials/01-d3/150-scales/6.html">Voilà le code mis à jour.</a> J’espère qu’en regardant cela vous réalisez : Plus de nuit blanche à cause de votre client qui vous dit que le graphique devrait faire 800 pixels de large plutôt que 600. Oui, vous dormirez plus grâce à moi (et aux méthodes intégrées brillantes de D3). Être bien reposé est un avantage (<em>pour être plus efficace au travail</em>). Vous pourrez me remercier plus tard.</p>
<h3 id="autres-mthodes">Autres méthodes</h3>
<p><strong>d3.scale.linear()</strong> a quelques autres méthodes utiles que je vais mentionner rapidement :</p>
<ul>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear_nice"><strong>nice()</strong></a> — Indique à l’échelle de d’arrondir les valeurs en entrée. Je cite le wiki de D3 : “Par exemple, pour un domaine de [0.20147987687960267, 0.996679553296417], le domaine arrondi est [0.2, 1].” C’est utile pour les gens normaux, pour qui lire des nombres comme 0.20147987687960267 est difficile.</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear_rangeRound"><strong>rangeRound()</strong></a> — Utilisez <strong>rangeRound()</strong> à la place de <strong>range()</strong> et toutes les valeurs de sortie seront arrondies au nombre entier le plus proche. C’est utile lorsque vous voulez que vos formes aient des valeurs de pixels exactes, pour éviter d’avoir des bords flous qui pourraient apparaître avec l’anticrénelage (<em>antialiasing</em>).</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear_clamp"><strong>clamp()</strong></a> — Par défaut, une échelle linéaire <em>peut</em> retourner des valeurs en dehors de la plage spécifiée. Par exemple, si vous donnez en entrée une valeur qui dépasse le domaine, l’échelle retournera aussi une valeur qui dépasse la plage de sortie. En appelant <strong>.clamp(true)</strong> sur une échelle, en revanche, on force les valeurs de sorties à être dans la plage spécifiée. Ce qui veut dire que les valeurs qui dépassent seront arrondies aux valeurs haute et basse de la plage de sortie (celle qui est la plus proche).</li>
</ul>
<h3 id="autres-chelles">Autres échelles</h3>
<p>En plus des échelles linéaires <a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear"><strong>linear</strong></a> (dont on a parlé plus haut), D3 possède quelques autres méthodes d’échelle intégrées :</p>
<ul>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-identity"><strong>identity</strong></a> — Une échelle 1:1, utile principalement pour des valeurs de pixels</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-sqrt"><strong>sqrt</strong></a> — Une échelle racine carrée</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-pow"><strong>pow</strong></a> — Une échelle de puissance (<em>exponentielle</em>)</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-log"><strong>log</strong></a> — Une échelle logarithmique</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-quantize"><strong>quantize</strong></a> — Une échelle avec des valeurs discrètes en sortie, lorsque vous voulez rangez des données dans des “bacs”</li>
<li><a href="https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-quantile"><strong>quantile</strong></a> — Similaire à celle du dessus, mais avec des valeurs discrètes en entrée (lorsque vous avez déjà des “bacs”)</li>
<li><a href="https://github.com/mbostock/d3/wiki/Ordinal-Scales"><strong>ordinal</strong></a> — Les échelles ordinales utilisent des valeurs non quantitatives (par exemple des noms de catégories) en sortie ; parfait pour comparer des pommes et des oranges</li>
</ul>
</description>
<pubDate>Tue, 28 Oct 2014 00:00:00 +0100</pubDate>
<link>http://kaisersly.github.io/scottmurray-d3-fr/15-echelles.html</link>
<guid isPermaLink="true">http://kaisersly.github.io/scottmurray-d3-fr/15-echelles.html</guid>
</item>
<item>
<title>14 - Faire un nuage de points</title>
<description><hr />
<p><em>Lien vers le tutoriel original : <a href="http://alignedleft.com/tutorials/d3/making-a-scatterplot">http://alignedleft.com/tutorials/d3/making-a-scatterplot</a></em></p>
<hr />
<h2 id="faire-un-nuage-de-points">Faire un nuage de points</h2>
<p><em>Dernière mise à jour le 30 décembre 2012</em></p>
<p>Jusqu’ici on a seulement dessiné des barres à partir de données simples - juste un ensemble à une dimension de nombres.</p>
<p>Mais lorsque vous avez deux ensembles de valeurs à tracer ensemble, il vous faut une seconde dimension. Le nuage de point est un type courant de visualisation qui représente deux ensembles de valeurs correspondantes sur deux axes différents : horizontal et vertical, x et y.</p>
<h3 id="les-donnes">Les données</h3>
<p>Comme vous l’avez vu dans <em>Types de données</em>, vous pouvez être assez flexible dans la manière de structurer vos données. Pour notre nuage, je vais utiliser un tableau de tableaux. Le premier tableau contiendra un élément pour chaque “point” de donnée. Chacun de ces éléments “point” seront eux-aussi des tableaux, avec seulement deux valeurs : une pour la valeur x, et une pour la valeur y.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span> <span class="p">[</span><span class="mi">480</span><span class="p">,</span> <span class="mi">90</span><span class="p">],</span> <span class="p">[</span><span class="mi">250</span><span class="p">,</span> <span class="mi">50</span><span class="p">],</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">33</span><span class="p">],</span> <span class="p">[</span><span class="mi">330</span><span class="p">,</span> <span class="mi">95</span><span class="p">],</span>
<span class="p">[</span><span class="mi">410</span><span class="p">,</span> <span class="mi">12</span><span class="p">],</span> <span class="p">[</span><span class="mi">475</span><span class="p">,</span> <span class="mi">44</span><span class="p">],</span> <span class="p">[</span><span class="mi">25</span><span class="p">,</span> <span class="mi">67</span><span class="p">],</span> <span class="p">[</span><span class="mi">85</span><span class="p">,</span> <span class="mi">21</span><span class="p">],</span> <span class="p">[</span><span class="mi">220</span><span class="p">,</span> <span class="mi">88</span><span class="p">]</span>
<span class="p">];</span></code></pre></div>
<p>Rappelez-vous, les crochets <strong>[]</strong> signifient un tableau, donc des crochets imbriqués <strong>[[]]</strong> signifient un tableau dans un tableau. Nous séparons les éléments d’un tableau avec des virgules, donc un tableau qui contiendrait trois tableaux ressemblerait à ça : <strong>[[],[],[]]</strong></p>
<p>On pourrait réécrire notre ensemble de données pour qu’il soit plus facile à lire, comme ça :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">20</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">480</span><span class="p">,</span> <span class="mi">90</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">50</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">33</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">330</span><span class="p">,</span> <span class="mi">95</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">410</span><span class="p">,</span> <span class="mi">12</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">475</span><span class="p">,</span> <span class="mi">44</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">67</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">85</span><span class="p">,</span> <span class="mi">21</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">88</span> <span class="p">]</span>
<span class="p">];</span></code></pre></div>
<p>Maintenant vous pouvez voir que chacune de ces dix entrées correspond à un point dans notre visualisation. Avec l’entrée <strong>[5, 20]</strong>, par exemple, on utilisera <strong>5</strong> pour la valeur de x, et <strong>20</strong> pour la valeur de y.</p>
<h3 id="le-nuage-de-points">Le nuage de points</h3>
<p>Réutilisons la plupart de code de nos expériences avec le graphique à barres, notamment la partie qui crée l’élément SVG :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Crée l'élément SVG</span>
<span class="kd">var</span> <span class="nx">svg</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="s2">"body"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"svg"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"width"</span><span class="p">,</span> <span class="nx">w</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="nx">h</span><span class="p">);</span></code></pre></div>
<p>Cependant, plutôt que de créer des rectangles <strong>rect</strong>s, on créera un cercle <strong>circle</strong> pour chaque point de donnée :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">selectAll</span><span class="p">(</span><span class="s2">"circle"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span>
<span class="p">.</span><span class="nx">enter</span><span class="p">()</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"circle"</span><span class="p">)</span></code></pre></div>
<p>Également, plutôt que de spécifier les attributs de <strong>rect</strong> <strong>x</strong>, <strong>y</strong>, <strong>width</strong>, et <strong>height</strong>, nos <strong>circle</strong>s ont besoin de <strong>cx</strong>, <strong>cy</strong>, et <strong>r</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"cx"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"cy"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"r"</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/1.png" alt="Nuage de points simple" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/1.html">Voilà le nuage de points en action.</a></p>
<p>Notez comment on accède aux valeurs des données et comment on les utilise pour les valeurs <strong>cx</strong> et <strong>cy</strong>. Lorqu’on utlise <strong>function(d)</strong>, D3 assigne automatiquement la valeur courante à <strong>d</strong> dans votre fonction. Dans notre cas, la valeur courante est un des petits tableaux dans notre tableau <strong>dataset</strong> qui les englobe.</p>
<p>Lorsque <strong>d</strong> est un tableau de valeurs (et pas juste une valeur comme <strong>3.14159</strong>), vous devez utiliser la notation crochets pour accéder à ses valeurs. D’où <strong>return d[0]</strong> et <strong>return d[1]</strong>, plutôt que <strong>return d</strong>. Ces deux expressions retournent, respectivement, la première et la seconde valeur du tableau.</p>
<p>Par exemple, dans le cas de notre premier point <strong>[5, 20]</strong>, la première valeur (position <strong>0</strong> dans le tableau) est <strong>5</strong>, et la seconde valeur (position <strong>1</strong> dans le tableau) est <strong>20</strong>. Ce qui nous donne :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="nx">retourne</span> <span class="mi">5</span>
<span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="nx">retourne</span> <span class="mi">20</span></code></pre></div>
<p>Au fait, s’il vous arrive un jour d’avoir besoin d’accéder à une valeur précise de notre ensemble de données (disons en dehors de D3), vous pouvez le faire en utilisant la notation crochets. Par exemple :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">dataset</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="nx">retourne</span> <span class="p">[</span><span class="mi">410</span><span class="p">,</span> <span class="mi">12</span><span class="p">]</span></code></pre></div>
<p>Vous pouvez enchaîner les crochets pour accéder à des valeurs dans des tableaux imbriqués :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">dataset</span><span class="p">[</span><span class="mi">5</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="nx">retourne</span> <span class="mi">12</span></code></pre></div>
<p>Vous ne me croyez pas ? <a href="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/1.html">Jetez encore un oeil à notre nuage de points</a>, ouvrez votre console JavaScript, et tapez <strong>dataset[5]</strong> ou <strong>dataset[5][1]</strong> et voyez ce qui se passe.</p>
<h3 id="taille">Taille</h3>
<p>Peut-être voulez-vous que vos cercles soient de différentes tailles, que leur rayon corresponde à leur valeur <strong>y</strong>. Plutôt que de définir toutes les valeurs <strong>r</strong> comme valant <strong>5</strong>, essayez :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"r"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">sqrt</span><span class="p">(</span><span class="nx">h</span> <span class="o">-</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/2.png" alt="Nuage de points avec des cercles de différentes tailles" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/2.html">Ce n’est ni joli ni particulièrement utile</a>, mais ça illustre comment vous pourriez utiliser <strong>d</strong>, avec la notation crochets, pour faire référence aux données et définir <strong>r</strong> en fonction.</p>
<h3 id="tiquettes-labels">Étiquettes (<em>labels</em>)</h3>
<p>Étiquettons nos points avec des éléments <strong>text</strong>. Je vais adapter le code de notre graphique à barres, à commencer par :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">selectAll</span><span class="p">(</span><span class="s2">"text"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span>
<span class="p">.</span><span class="nx">enter</span><span class="p">()</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"text"</span><span class="p">)</span></code></pre></div>
<p>Jusqu’ici, ça regarde tous les éléments <strong>text</strong> dans le SVG (il n’y en a encore aucun), puis ça ajoute un nouvel élément <strong>text</strong> pour chaque point de donnée. Utilisez la méthode <strong>text()</strong> pour spécifier le contenu de chaque élément :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">text</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s2">","</span> <span class="o">+</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">})</span></code></pre></div>
<p>C’est le désordre, mais restez avec moi. Encore une fois, on utilise <strong>function(d)</strong> pour accéder à chaque point de donnée. Ensuite, dans la fonction, on utilise <em>et</em> <strong>d[0]</strong> <em>et</em> <strong>d[1]</strong> pour récupérer les deux valeurs dans ce point de donnée qui est un tableau.</p>
<p>Les symboles <strong>+</strong>, lorsqu’ils sont utilisés avec des chaînes de caractères, comme les virgules entre guillemets <strong>”,”</strong>, agissent comme des opérateurs de concaténation. Donc ce que nous dit réellement cette ligne de code c’est : Prends les valeurs de <strong>d[0]</strong> et <strong>d[1]</strong> et assemble les avec une virgule au milieu. Le résultat final devrait être quelque chose comme <strong>5,20</strong> ou <strong>25,67</strong>.</p>
<p>Ensuite, on spécifie <em>où</em> le texte devrait se placer avec les valeurs <strong>x</strong> et <strong>y</strong>. Pour l’instant, utilisons juste <strong>d[0]</strong> et <strong>d[1]</strong>, les mêmes valeurs que pour la position du <strong>circle</strong>.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">})</span></code></pre></div>
<p>Enfin, ajoutons un peu de style typographique :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"font-family"</span><span class="p">,</span> <span class="s2">"sans-serif"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"font-size"</span><span class="p">,</span> <span class="s2">"11px"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"fill"</span><span class="p">,</span> <span class="s2">"red"</span><span class="p">);</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/3.png" alt="Nuage de points avec des étiquettes" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/140-making-a-scatterplot/3.html">Voilà le code en action.</a></p>
<h3 id="prochains-pas">Prochains pas</h3>
<p>Normallement, certains concepts de base de D3 deviennent clairs : Chargez les données, générer de nouveaux éléments, et utiliser les valeurs des données pour en dériver des valeurs pour les attributs de ces éléments.</p>
<p>Et pourant l’image ci-dessus est à peine passable en tant que visualisation de données. Le nuage de points est difficile à lire, et le code n’est pas flexible. Pour être honnête, on ne s’est pas vraiment amélioré par rapport à l’<em>assistant de graphiques</em> — gag — d’Excel !</p>
<p>Ne vous inquiétez pas : D3 est bien plus cool que l’assistant de graphiques d’Excel (sans mentionner Clippy), mais générer un graphique clinquant et intéractif impliquent d’amener nos compétences en D3 au niveau supérieur. Pour devenir flexible en ce qui concerne nos données, on apprendra à utiliser les <em>échelles</em> de D3. Pour rendre notre nuage plus facile à lire, on apprendra à utiliser les <em>générateurs d’axe</em> et les étiquettes d’axe. Après cela, on pourra rendre les choses intéractives et on apprendra comment mettre à jour les données à la volée.</p>
</description>
<pubDate>Tue, 28 Oct 2014 00:00:00 +0100</pubDate>
<link>http://kaisersly.github.io/scottmurray-d3-fr/14-faire-un-nuage-de-points.html</link>
<guid isPermaLink="true">http://kaisersly.github.io/scottmurray-d3-fr/14-faire-un-nuage-de-points.html</guid>
</item>
<item>
<title>13 - Faire un graphique à barres</title>
<description><hr />
<p><em>Lien vers le tutoriel original : <a href="http://alignedleft.com/tutorials/d3/making-a-bar-chart">http://alignedleft.com/tutorials/d3/making-a-bar-chart</a></em></p>
<hr />
<h2 id="faire-un-graphique--barres">Faire un graphique à barres</h2>
<p><em>Dernière mise à jour le 30 décembre 2012</em></p>
<p>Intégrons maintenant tout ce que l’on a appris jusqu’ici pour générer un graphique à barres simple avec D3.</p>
<p>On commencera par revoir le graphique à barres que l’on a fait plutôt en utilisant des éléments <strong>div</strong>. Puis on adaptera ce code pour dessiner les barres avec SVG, nous donnant plus de flexibilité sur la présentation visuelle. Finalement, on ajoutera des étiquettes (<em>labels</em>), pour voir plus clairement les valeurs.</p>
<h3 id="le-vieux-graphique">Le vieux graphique</h3>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/1.html">Voilà ce que l’on avait la dernière fois, avec des nouvelles données.</a></p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="kd">var</span> <span class="nx">dataset</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">21</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span>
<span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">25</span> <span class="p">];</span>
<span class="nx">d3</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="s2">"body"</span><span class="p">).</span><span class="nx">selectAll</span><span class="p">(</span><span class="s2">"div"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span>
<span class="p">.</span><span class="nx">enter</span><span class="p">()</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"div"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"class"</span><span class="p">,</span> <span class="s2">"bar"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">style</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">barHeight</span> <span class="o">=</span> <span class="nx">d</span> <span class="o">*</span> <span class="mi">5</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">barHeight</span> <span class="o">+</span> <span class="s2">"px"</span><span class="p">;</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/1.png" alt="Graphique à barres avec des divs" /></p>
<p>Ça peut être difficile à imaginer, mais on peut clairement améliorer ce simpe graphique à barres fait avec des <strong>div</strong>s.</p>
<h3 id="le-nouveau-graphique">Le nouveau graphique</h3>
<p>En premier, on doit définir la taille du nouveau SVG :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Largeur et hauteur</span>
<span class="kd">var</span> <span class="nx">w</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">h</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span></code></pre></div>
<p>(Bien sûr, vous pourriez appeler <strong>w</strong> et <strong>h</strong> d’une autre manière, comme <strong>svgWidth</strong> et <strong>svgHeight</strong>. Utilisez ce qui vous semble le plus clair. JavaScript a une culture de l’efficacité, donc vous verrez souvent des variables à un seul caractère, du code écrit sans espaces, et d’autres syntaxes difficiles à lire, et pourtant programmatiquement efficace.)</p>
<p>Ensuite, on dit à D3 de créer un élément SVG vide et on l’ajoute au DOM :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Crée l'élément SVG</span>
<span class="kd">var</span> <span class="nx">svg</span> <span class="o">=</span> <span class="nx">d3</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="s2">"body"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"svg"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"width"</span><span class="p">,</span> <span class="nx">w</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="nx">h</span><span class="p">);</span></code></pre></div>
<p>Ça insert un nouvel élément <strong>&lt;svg&gt;</strong> juste avant la balise fermante <strong>&lt;/body&gt;</strong>, et assigne au SVG les dimensions de 500 par 100 pixels. Cette déclaration met également le résultat dans une nouvelle variable appelée <strong>svg</strong>, pour que nous puissions facilement référencer SVG sans avoir à le resélectionner plus tard en utilisant quelque chose comme <strong>d3.select(“svg”)</strong>.</p>
<p>Ensuite, plutôt que de créer des <strong>div</strong>s, on génère des <strong>rect</strong>s et on les ajoute à <strong>svg</strong>.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">selectAll</span><span class="p">(</span><span class="s2">"rect"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span>
<span class="p">.</span><span class="nx">enter</span><span class="p">()</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"rect"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"width"</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span></code></pre></div>
<p>Ce code sélectionne tous les <strong>rect</strong>s à l’intérieur de <strong>svg</strong>. Bien sûr, il n’y en a encore aucun, donc une sélection vide est retournée. (Bizarre, je vous l’accorde, mais restez avec moi. Avec D3, vous devez toujours sélectionner quoi que ce soit sur lequel vous voulez travailler, même si cette sélection est vide.)</p>
<p>Ensuite, <strong>data(dataset)</strong> voit que l’on a 20 valeurs dans l’ensemble de données, donc il appelle <strong>enter()</strong> 20 fois. <strong>enter()</strong>, à son tour, retourne une sélection placeholder pour chaque élément de données qui n’a pas de <strong>rect</strong> correspondant — ce qui veut dire tous les <strong>rect</strong>s.</p>
<p>Pour chacun des 20 placeholders, <strong>append(“rect”)</strong> insert un <strong>rect</strong> dans le DOM. Comme nous l’avons appris dans l’introduction à SVG, chaque <strong>rect</strong> doit avoir les valeurs <strong>x</strong>, <strong>y</strong>, <strong>width</strong>, et <strong>height</strong> définies. On utilise <strong>attr()</strong> pour ajouter ces attributs sur chacun des <strong>rect</strong> nouvellement créés.</p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/2.html">C’est beau, hein ?</a></p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/2.png" alt="Une barre solitaire" /></p>
<p>Okay, pas sûr. Toutes les barres sont présentes (regardez le DOM sur la page de démo avec votre inspecteur web), mais toutes partagent les mêmes valeurs de <strong>x</strong>, <strong>y</strong>, <strong>width</strong>, et <strong>height</strong>, avec pour résultat qu’elles se superposent toutes. Ce n’est pas encore de la visualisation de données.</p>
<p>Corrigeons d’abord le fait qu’elles se superposent. Plutôt que d’utiliser un <strong>x</strong> de zéro, on lui assignera une valeur dynamique qui correspond à <strong>i</strong>, la position de chaque élément dans l’ensemble de données. Donc la première barre sera à zéro, mais les suivantes seront à <strong>21</strong>, puis <strong>42</strong>, et ainsi de suite.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">i</span> <span class="o">*</span> <span class="mi">21</span><span class="p">;</span> <span class="c1">// Largeur de barre de 20 plus 1 pour la marge</span>
<span class="p">})</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/3.png" alt="Vingt barres" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/3.html">Voilà le code en action.</a></p>
<p>Ça fonctionne, mais c’est pas super flexible. Si nos données étaient plus nombreuses, les barres se suivraient sur la droite, même après la fin du SVG ! Comme chaque barre fait 20 pixels de large, plus 1 pixel de marge, un SVG de 500 pixels de large ne pourrait afficher que 23 éléments de données. Notez comment la 24ème barre se trouve coupée :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/4.png" alt="Vingt-quatre barres" /></p>
<p>Une bonne pratique est d’utiliser des coordonnées flexibles et dynamiques — hauteurs, largeurs, valeurs de x, et valeurs de y — de manière à ce que votre visualisation se redimensionne de manière appropriée en fonction de vos données.</p>
<p>Comme avec n’importe quel problème en programmation, il y a mille façons d’arriver à ce résultat. J’en utiliserai une simple. Premièrement, je vais changer la ligne où l’on définit la position <strong>x</strong> de chaque barre :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">i</span> <span class="o">*</span> <span class="p">(</span><span class="nx">w</span> <span class="o">/</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
<span class="p">})</span></code></pre></div>
<p>Notez comment la valeur de <strong>x</strong> est maintenant liée directement à la largeur de SVG (w) et au nombre de valeurs dans notre ensemble de données (<strong>dataset.length</strong>). C’est excitant, car maintenant nos barres seront espacées uniformément, que l’on ait vingt barres :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/5.png" alt="Vingt barres espacées uniformément" /></p>
<p>ou juste cinq :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/6.png" alt="Cinq barres espacées uniformément" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/4.html">Voilà le code jusqu’ici.</a></p>
<p>Maintenant on devrait rendre les <em>largeurs</em> des barres proportionnelles, elles aussi, pour qu’elles deviennent plus fines à mesure que des données sont ajoutées, ou plus large lorsqu’il y a moins de valeurs. Je vais ajouter une nouvelle variable à côté de là où l’on définit la hauteur et la largeur de SVG</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Largeur et hauteur</span>
<span class="kd">var</span> <span class="nx">w</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">h</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">barPadding</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// &lt;-- Nouveau !</span></code></pre></div>
<p>puis faire référence à cette variable dans la ligne où l’on définit la largeur <strong>width</strong> de chaque barre. Plutôt qu’une valeur statique de <strong>20</strong>, la largeur sera maintenant définit comme une fraction entre la largeur du SVG et le nombre de données, moins la valeur de la marge :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"width"</span><span class="p">,</span> <span class="nx">w</span> <span class="o">/</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">barPadding</span><span class="p">)</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/7.png" alt="Vingt barres espacées avec des largeurs dynamiques" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/5.html">Ça fonctionne !</a> Les largeurs et les positions en x des barres se mettent à l’échelle correctement qu’il y ait vingt points, juste cinq</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/8.png" alt="Cinq barres espacées avec des largeurs dynamiques" /></p>
<p>ou même cent :</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/9.png" alt="Cent barres espacées avec des largeurs dynamiques" /></p>
<p>Pour finir, programmons la hauteur de chaque barre. Vous espériez que ce soit aussi facile que faire référence à la valeur <strong>d</strong> lorsque l’on définit la hauteur <strong>height</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">;</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/10.png" alt="Hauteurs dynamiques" /></p>
<p>Hum, ça à l’air funky. On pourrait peut-être agrandir un peu nos nombres ?</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span> <span class="o">*</span> <span class="mi">4</span><span class="p">;</span> <span class="c1">// &lt;-- Fois quatre !</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/11.png" alt="Hauteurs dynamiques" /></p>
<p>Hélas, c’est pas aussi facile — on veut que nos barres grandissent depuis le bord bas, pas depuis le haut — mais ne blamez pas D3, blamez SVG.</p>
<p>Rappellez-vous de l’introduction à SVG : lorsque l’on dessine des <strong>rect</strong>s, les valeurs <strong>x</strong> et <strong>y</strong> spécifient les coordonnées du <em>coin en haut à gauche</em>. Ce qui veut dire que l’origine ou point de référence de chaque <strong>rect</strong> est son point supérieur gauche. Pour nos besoins, il serait teeeeelllement plus facile que notre point de référence soit le point inférieur gauche, mais c’est juste pas comme ça que SVG fonctionne, et, franchement, SVG est plutôt indifférent à vos sentiments en la matière.</p>
<p>Étant donné que nos barres doivent “grandir depuis le haut”, où est “le haut” de chaque barre par rapport au haut de SVG ? Eh bien, le haut de chaque barre peut être définit comme une relation entre la hauteur de SVG et la valeur correspondante de la donnée, comme ça :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">h</span> <span class="o">-</span> <span class="nx">d</span><span class="p">;</span> <span class="c1">// Hauteur moins la valeur de la donnée</span>
<span class="p">})</span></code></pre></div>
<p>Ensuite, pour mettre le “bas” de chaque barre au bas du SVG, chaque hauteur des <strong>rect</strong>s doit être juste la valeur de la donnée elle-même :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">;</span> <span class="c1">// Juste la valeur de la donnée</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/12.png" alt="Grandir à partir du bas" /></p>
<p>Agrandissons le tout un peu en changeant <strong>d</strong> par <strong>d * 4</strong>. (Note : Plus tard on en apprendra plus sur les <em>échelles</em> de D3, qui offrent de meilleurs moyens d’accomplir cela.)</p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/13.png" alt="Grandir plus à partir du bas" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/6.html">Voilà le code de notre graphique où nos barres grandissent du bas.</a></p>
<h3 id="couleurs">Couleurs</h3>
<p>Ajouter une couleur est facile. Utilisez juste <strong>attr()</strong> pour définir un remplissage <strong>fill</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"fill"</span><span class="p">,</span> <span class="s2">"teal"</span><span class="p">);</span></code></pre></div>
<p><em>Teal correspond à la couleur appelée <a href="http://fr.wikipedia.org/wiki/Sarcelle_(couleur)">sarcelle</a></em></p>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/14.png" alt="Barres de couleur sarcelle" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/7.html">Voila un graphique à barres tout en sarcelle.</a> Mais souvent vous voudrez ajuster la couleur de la forme pour refléter une des qualités de la donnée. Ce qui veut dire que vous voudrez <em>programmer</em> la donnée en couleur. (Pour notre graphique, ça donne une <em>programmation double</em>, dans laquelle la même valeur de donnée est programmée dans deux propriétés visuelles : la hauteur et la couleur.)</p>
<p>Utiliser une donnée pour définir une couleur revient à écrire une fonction qui elle aussi référence <strong>d</strong>. Ici nous remplaçons <strong>“teal”</strong> par une fonction personnalisée :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"fill"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="s2">"rgb(0, 0, "</span> <span class="o">+</span> <span class="p">(</span><span class="nx">d</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span> <span class="o">+</span> <span class="s2">")"</span><span class="p">;</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/15.png" alt="Barres bleues pilotées par des données" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/8.html">Voilà le code.</a> C’est pas particulièrement un codage visuel utile, mais au moins vous avez une idée de comment traduire la donnée en couleur. Ici, <strong>d</strong> est multiplé par 10, puis il est utilisé dans la valeur du bleu dans une définition de couleur <strong>rgb()</strong>. Plus grande sera la valeur de <strong>d</strong> (barres plus grandes), plus bleue la barre sera. Pour des valeurs plus petites de <strong>d</strong> (barres plus petites) les barres seront moins bleues (plus proche du noir).</p>
<h3 id="tiquettes-ou-labels">Étiquettes (<em>ou labels</em>)</h3>
<p>Les visuels sont supers, mais quelques fois vous aurez besoin d’afficher les valeurs des données en texte dans votre visualisation. C’est la que les étiquettes de valeur entrent en jeu, et elles sont vraiment, vraiment faciles à générer avec D3.</p>
<p>Vous vous rappelez de l’introduction à SVG : vous pouvez ajouter des éléments <strong>text</strong> à l’élément SVG. On débutera avec :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">svg</span><span class="p">.</span><span class="nx">selectAll</span><span class="p">(</span><span class="s2">"text"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span><span class="nx">dataset</span><span class="p">)</span>
<span class="p">.</span><span class="nx">enter</span><span class="p">()</span>
<span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="s2">"text"</span><span class="p">)</span></code></pre></div>
<p>Ça semble familier ? Tout comme on a fait pour les <strong>rect</strong>s, on fait de même pour les <strong>text</strong>s. D’abord, sélectionnez ce que vous voulez, amenez les données, ajoutez les nouveaux éléments avec <strong>enter()</strong> (qui sont juste des placeholders à ce moment), et finallement ajoutez les nouveaux éléments <strong>text</strong> elements au DOM.</p>
<p>Complétons ce code pour inclure la valeur de la donnée dans chaque élément de texte en utilisant la méthode <strong>text()</strong></p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">text</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">d</span><span class="p">;</span>
<span class="p">})</span></code></pre></div>
<p>et définissons les valeurs <strong>x</strong> et <strong>y</strong> pour positionner le texte. C’est plus facile si je copie/colle juste le même code que l’on a utilisé plus haut pour les barres :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">i</span> <span class="o">*</span> <span class="p">(</span><span class="nx">w</span> <span class="o">/</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">h</span> <span class="o">-</span> <span class="p">(</span><span class="nx">d</span> <span class="o">*</span> <span class="mi">4</span><span class="p">);</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/16.png" alt="Bébés étiquettes !" /></p>
<p>Aha ! Des étiquettes ! Mais certaines sont coupées en haut. Essayons de les déplacer vers le bas, à l’intérieur des barres, en ajoutant quelques pixels à <strong>x</strong> et <strong>y</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">i</span> <span class="o">*</span> <span class="p">(</span><span class="nx">w</span> <span class="o">/</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">+</span> <span class="mi">5</span><span class="p">;</span> <span class="c1">// +5</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">h</span> <span class="o">-</span> <span class="p">(</span><span class="nx">d</span> <span class="o">*</span> <span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="mi">15</span><span class="p">;</span> <span class="c1">// +15</span>
<span class="p">});</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/17.png" alt="Étiquettes dans les barres" /></p>
<p>Mieux, mais pas lisible. Heureusement, on peut corriger ça :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"font-family"</span><span class="p">,</span> <span class="s2">"sans-serif"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"font-size"</span><span class="p">,</span> <span class="s2">"11px"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"fill"</span><span class="p">,</span> <span class="s2">"white"</span><span class="p">);</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/18.png" alt="Des étiquettes vraiment belles" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/9.html">Fantasti-code !</a> Si vous n’êtes pas un maniaque de typographie, alors ça suffit. Si, au contraire, vous êtes comme moi, vous noterez que les étiquettes ne sont pas parfaitement alignées dans leur barre. C’est assez facile de corriger ça. Utilisons l’attribut SVG <strong>text-anchor</strong> pour centrer le texte horizontalement par rapport à <strong>x</strong> :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"text-anchor"</span><span class="p">,</span> <span class="s2">"middle"</span><span class="p">)</span></code></pre></div>
<p>Ensuite, changeons la manière de calculer la position <strong>x</strong> en la définissant comme le côté gauche de chaque barre <em>plus</em> la moitié de la largeur de la barre :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"x"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">i</span> <span class="o">*</span> <span class="p">(</span><span class="nx">w</span> <span class="o">/</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="nx">w</span> <span class="o">/</span> <span class="nx">dataset</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">barPadding</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">})</span></code></pre></div>
<p>Montons également les étiquettes d’un pixel pour un espacement parfait :</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">h</span> <span class="o">-</span> <span class="p">(</span><span class="nx">d</span> <span class="o">*</span> <span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="mi">14</span><span class="p">;</span> <span class="c1">// 15 vaut est maintenant 14</span>
<span class="p">})</span></code></pre></div>
<p><img src="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/19.png" alt="Étiquettes centrées" /></p>
<p><a href="http://alignedleft.com/content/03-tutorials/01-d3/130-making-a-bar-chart/10.html">Fini !</a> Maintenant, éloignons-nous un peu des graphiques à barres.</p>
</description>
<pubDate>Tue, 28 Oct 2014 00:00:00 +0100</pubDate>
<link>http://kaisersly.github.io/scottmurray-d3-fr/13-faire-un-graphique-a-barres.html</link>
<guid isPermaLink="true">http://kaisersly.github.io/scottmurray-d3-fr/13-faire-un-graphique-a-barres.html</guid>
</item>
<item>
<title>12 - Types de données</title>
<description><hr />
<p><em>Lien vers le tutoriel original : <a href="http://alignedleft.com/tutorials/d3/data-types">http://alignedleft.com/tutorials/d3/data-types</a></em></p>
<hr />
<h2 id="types-de-donnes">Types de données</h2>
<p><em>Dernière mise à jour le 30 décembre 2012</em></p>
<p>D3 est vraiment flexible pour ce qui est des données en entrée. Cet article introduit les structures de D3 communément utilisées avec JavaScript et D3.</p>
<h3 id="variables">Variables</h3>
<p>Une variable est le plus petit élément de données. La variable est le fondement de toutes les autres structures de données, qui sont juste différentes configurations de variables.</p>
<p>Si vous êtes nouveau en JavaScript, sachez que c’est un langage <em>faiblement typé</em>, ce qui veut dire que vous n’avez pas besoin de spécifier quel <em>type</em> d’information sera stocké dans une variable à l’avance. Beaucoup d’autres langages, comme Java (qui est complètement différent de JavaScript !), requièrent que vous déclariez un type de données, comme <strong>int</strong>, <strong>float</strong>, <strong>boolean</strong>, ou <strong>String</strong>.</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Déclarer des variables en Java</span>
<span class="kr">int</span> <span class="nx">number</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="kr">float</span> <span class="nx">value</span> <span class="o">=</span> <span class="mf">12.3467</span><span class="p">;</span>
<span class="kr">boolean</span> <span class="nx">active</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nb">String</span> <span class="nx">text</span> <span class="o">=</span> <span class="s2">"Crystal clear"</span><span class="p">;</span></code></pre></div>
<p>JavaScript, au contraire, <em>assigne automatiquement un type</em> à une variable, en fonction de l’information que vous lui assignez. (Notez que <strong>’‘</strong> ou <strong>”“</strong> indique une chaîne de caractères. Je préfère les guillemets doubles <strong>”“</strong>, mais d’autres préfèrent les guillemets simples <strong>’‘</strong>.)</p>
<div class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// Déclarer des variables en JavaScript</span>
<span class="kd">var</span> <span class="nx">number</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="mf">12.3467</span><span class="p">;</span>