-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathojs.qmd
More file actions
878 lines (702 loc) · 26.7 KB
/
Copy pathojs.qmd
File metadata and controls
878 lines (702 loc) · 26.7 KB
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
---
title: "Articulation de différents langages (R, JavaScript et Python) pour la géovisualisation avec Quarto"
subtitle: "Atelier Sageo, Québec, Juin 2023"
author: "Timothée Giraud, Nicolas Lambert, Matthieu Viry, Ronan Ysebaert (UAR RIATE, CNRS, Université Paris Cité)"
format:
html:
theme: sandstone
fontsize: 0.9em
code-tools: true
toc: true
toc-depth: 2
linkcolor: "#8631ad"
execute:
cache: false
---
## Observable JavaScript
### Observable Kezako ?
L'<b>Observable javascript {ojs}</b> est un ensemble d'améliorations apportées à vanilla JavaScript créé par Mike Bostock (également auteur de D3). Observable JS se distingue par son exécution réactive, qui convient particulièrement bien à l'exploration et à l'analyse interactives des données.
{width=20%} {width=20%} {width=20%} <br/>
**Observable** est aussi une startup fondée par Mike Bostock et Melody Meckfessel, qui propose une plateforme 100% en ligne ([https://observablehq.com](https://observablehq.com)) pour concevoir, partager et diffuser des visualisations de données.

**Observable** c'est donc aussi C’est aussi une [plateforme web](https://observablehq.com/) qui héberge des notebooks computationnels sur la visualisation de données.

👉 **Objectif** : faire collaborer une communauté autour de la visualisation de données.
### Observable dans Quarto
Le runtime d'Observable est Open Source et est utilisé dans Quarto.
Dans Quarto, toutes les instructions s'écrivent dans des chunks {ojs}
``` {{ojs}}
```
On peut paramétrer l'affiche et/ou l'execution du code avec **//| echo** et **//| eval**.
``` {{ojs}}
//| echo: false
//| eval: true
```
_NB : Contrairement aux chunks R et Python, le code s'execute *just in time* dans le navigateur web une fois le notebook généré. Seul l'export html est donc pris en compte._
### Principes
Le langage JavaScript n'a pas du été conçu pour l’analyse de données. Mais, gros point fort, on a tous un navigateur web et JavaScript tourne sur toutes les machines. Le but : bâtir une évolution du langage JavaScript pour en faire un langage adapté à l’analyse et la visualisation de données sur le web.
#### 👉 Des bibliothèques préchargées 📊
OJS c'est du JavaScript + plein de bibliothèques pré chargées : <br/>
| Symbol | Name | Version |
|----------|-------------------|--------------------|
| \_ | Lodash | 4.17.21 |
| aq | Arquero | \${aq.version} |
| Arrow | Apache Arrow | 4.0.1 |
| d3 | D3.js | \${d3.version} |
| dot | Graphviz | 0.2.1 |
| htl | Hypertext Literal | \${htl.version} |
| Inputs | Observable Inputs | \${Inputs.version} |
| L | Leaflet | \${L.version} |
| mermaid | Mermaid | 9.1.6 |
| Plot | Observable Plot | \${Plot.version} |
| SQLite | SQL.js | 1.7.0 |
| topojson | TopoJSON Client | 3.1.0 |
| vl | Vega, Vega-Lite | 5.22.1, 5.2.0 |
#### 👉 Chaque début de ligne identifie une cellule ojs 🙋
Chaque ligne définit une variable et une cellule qui doit être unique sur l'ensemble du document.
``` {{ojs}}
a = 10 // une cellule
b = 20 // une cellule
```
``` {{ojs}}
c = a + b // une cellule
```
``` {{ojs}}
d = {
let a = 10
let b = 30
return a + b
} // Une cellule
```
#### 👉 L’ordre des cellules n’a pas d’importance 🤯
On peut donc écrire ça
``` {{ojs}}
result = val1 * val2
```
avant ça
``` {{ojs}}
val1 = 10
val2 = 20
```
Le lien entre les cellules se fait de façon topologique et non de haut en bas.

#### 👉 Tout est réactif 🔥
Dès lors qu'une cellule est modifiée, les cellules qui en dépendent sont modifiées également.
Pour modifier la valeutr d'une céllule, on utilise des **`Inputs`** (des composants proposés par OJS pour explorer les données) avec le mot clé **`viewof`**. Voir : https://observablehq.com/@observablehq/inputs
```{ojs}
viewof x = Inputs.range([0, 255], {step: 1})
```
```{ojs}
viewof y = Inputs.text({value: 30})
```
```{ojs}
viewof z = Inputs.radio([10, 100, 1000], {value: 10})
```
```{ojs}
x * y * z
```
Ce système est pratique pour modifier des visualisations de données.
Ici, un exemple avec un simple cercle dessiné en svg.
```{ojs}
viewof color = Inputs.color({ label: "Couleur", value: "#4ab58c" })
viewof radius = Inputs.range([1, 50], { label: "Rayon", step: 1, value: 100 })
viewof position = Inputs.range([50, 950], { label: "Position", step: 1, value: 50 })
```
```{ojs}
html`<svg viewBox="0 0 1000 100" xmlns="http://www.w3.org/2000/svg">
<circle cx=${position} cy="50" r=${radius} fill="${color}"/>
</svg>`
```
### l'écosystème spatial avec Ojs
L'écosystème spatial de JavaScript est moins étoffé que ce qu'on peut trouver en Python ou en R. Mais on trouve quand même des choses intéressantes qui permettent de faire de la géomatique directement dans le navigateur web. Voici quelques exemples.
**Les fonctionnalités spatiales de `d3.js`**
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`d3-geo`**](https://github.com/d3/d3-geo) est le module spatial de d3. Il permet de gérer les projections cartographiques, les formes sphériques et la trigonométrie sphérique. Voir aussi [**`d3-geo-projection`**](https://github.com/d3/d3-geo-projection). [**`d3-delaunay`**](https://github.com/d3/d3-delaunay) est une bibliothèque rapide pour calculer le diagramme de Voronoï d'un ensemble de points bidimensionnels. Elle est basée sur Delaunator, une bibliothèque rapide pour calculer la triangulation de Delaunay en utilisant des algorithmes de balayage. Le diagramme de Voronoï est construit en reliant les circonférences des triangles adjacents dans la triangulation de Delaunay. [**`d3-geo-voronoi`**](https://github.com/Fil/d3-geo-voronoi) est une adaptation de d3-delaunay sur la sphère.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`TopoJSON`**](https://github.com/topojson/topojson) est une extension de GeoJSON. La librairie permet de réaliser des opérations SIG basées sur la topologie (agrégation, voisins, simplification, etc.)
:::
::::
**Les bibliothèques SIG**
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`turf`**](https://turfjs.org/) est une bibliothèque JavaScript pour l'analyse spatiale (de type SIG). Elle comprend les opérations spatiales traditionnelles, des fonctions d'aide pour la création de données GeoJSON, ainsi que des outils de classification des données et de statistiques. L'avantage de turf est d'être modulaire. On ne charge que ce dont on a besoin.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`spl.js`**](https://turfjs.org/) est une implémentation de SpatiaLite (et de ses amis : sqlite, geos, proj, rttopo) pour le navigateur.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`geotoolbox`**](https://github.com/neocarto/geotoolbox) est un outil javascript pour les géographes basé sur d3geo, topojson et jsts. Il permet de traiter simplement les propriétés geojson et fournit plusieurs opérations SIG utiles pour la cartographie thématique.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`Gdals3.js`**](https://github.com/bugra9/gdal3.js) est un portage des applications Gdal (gdal_translate, ogr2ogr, gdal_rasterize, gdalwarp, gdaltransform) vers Webassembly. Il permet de convertir des données géospatiales matricielles et vectorielles dans divers formats et systèmes de coordonnées.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`proj4js`**](http://proj4js.org/) est une bibliothèque JavaScript permettant de transformer les coordonnées d'un système de coordonnées à un autre, y compris les transformations de datum
:::
::::
**Dataviz / cartographie**
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`plot`**](https://observablehq.com/plot/) est la bibliothèque de visualisation de donnée développée par Observable (Mike Bostock et Philippe Rivière). Au départ pensée pour la visualisation de données statistiques, elle permet aujourd'hui de réaliser des cartes. Plot est disponible par défaut dans les cellules {ojs}.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`vega-lite`**](https://github.com/vega/vega-lite) est un outil de visualisation mettant en œuvre une grammaire graphique, similaire à ggplot2. Cette bibliothèque est disponible par défaut dans les cellules {ojs}.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`bertin`**](https://github.com/neocarto/bertin) est une bibliothèque écrite en JavaScript qui permet de réaliser des cartes thématiques pour le web. Sa conception vise à permettre aux utilisateurs de créer rapidement des cartes thématiques interactives sans forcement connaître le langage JavaScript.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`Gridviz`**](https://github.com/eurostat/gridviz) est une bibliothèque JavaScript basée sur WebGL développée par Julien Gaffuri et Joe Davies. Elle permet de visualiser des données carroyées (ou tout ensemble de données tabulaires avec une position x/y) dans le navigateur dans une grande variété de styles cartographiques.
:::
::::
::: columns
::: {.column width="8%"}

::::
::: {.column width="2%"}
:::
::: {.column width="90%"}
[**`go-cart-wasm`**](https://github.com/riatelab/go-cart-wasm) est une bibliothèque JS/WASM permettant de réaliser des cartogrammes basés sur le flux (comme décrit dans "Gastner, Seguy, and More (2018).
:::
::::
### Importer des données
Pour importer des données en **`{ojs}`**, on utilise l'instruction **`FileAttachment()`**
Pour un fichier JSON
```js
mrc = FileAttachment("geom/mrc.geojson").json()
munic = FileAttachment("geom/munic.geojson").json()
```
Pour un fichier csv
```js
FileAttachment("data.csv").csv({typed: true})
```
On peut aussi récupérer des données depuis R ou Python avec l'instruction **`ojs_define`**
```{ojs}
//| eval: false
//| echo: true
mrc = FileAttachment("geom/mrc.geojson").json()
munic = FileAttachment("geom/munic.geojson").json()
```
```{ojs}
//| eval: true
//| echo: false
tmp = FileAttachment("geom/munic.geojson").json()
munic = geo.rewind(geo.simplify(tmp, {k:0.1}))
tmp2 = FileAttachment("geom/mrc.geojson").json()
mrc = geo.rewind(geo.simplify(tmp2, {k:0.1}))
```
### Visualiser les données stats
Pour regarder la table attributaire, on utilise **`Inputs.table()`**
```{ojs}
Inputs.table(munic.features.map(d => d.properties))
```
Avec **`{ojs}`**, on va aussi pouvoir faire des graphiques avec la bibliothèque **`plot`**. Pour cela, on fait quelques manipulations de données.
Tout d'abord, on récupère les noms des 20 communes les plus peuplées, classées par ordre décroissant de population.
```{ojs}
communes = munic.features
.map((d) => d.properties)
.sort((a, b) => d3.descending(a.POP_2022, b.POP_2022))
.map((d) => d.MUS_NM_MUN)
.slice(0, 20)
```
```{ojs}
//| echo: false
//| eval: true
communes
```
On met en forme les données.
```{ojs}
data = {
let arr = [];
communes.forEach((d) => {
let tmp = munic.features
.map((d) => d.properties)
.find((x) => x.MUS_NM_MUN == d);
for (let i = 2001; i <= 2022; i++) {
arr.push({ year: i, pop: tmp["POP_" + i], com: d });
}
});
return arr;
}
```
```{ojs}
//| echo: false
//| eval: true
Inputs.table(data, {width:250, height:250})
```
Puis on réalise le graphique avec `plot` en proposant de sélectionner une commune.
```{ojs}
viewof commune = Inputs.select(communes, { label: "Commune" })
Plot.plot({
grid: true,
x: {
label: "Années →",
tickFormat: ""
},
y: {
label: `↑ Population (${commune})`
},
color: { legend: true },
marginLeft: 60,
marks: [
Plot.lineY(data.filter(d => d.com == commune), {
x: "year",
y: "pop",
stroke: "red",
strokeWidth: 2
})
]
})
```
### Visualiser les gémétries
Comme leaflet est disponible dans les cellules {ojs}, on peut directement afficher les géométries.
```{ojs}
{
const container = yield htl.html`<div style="height: 500px;">`;
const map = L.map(container);
const layer = L.geoJSON(mrc).addTo(map);
map.fitBounds(layer.getBounds(), { maxZoom: 9 });
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
"© <a href=https://www.openstreetmap.org/copyright>OpenStreetMap</a> contributors"
}).addTo(map);
}
```
On peut également afficher la carte simplement avec la bibliothèque [**`bertin`**](https://github.com/neocarto/bertin).
```{ojs}
bertin = require("bertin")
```
```{ojs}
bertin.quickdraw(mrc)
```
### Un peu de SIG
La bibiothèque **`geotoolbox`** permet de faire facilement differentes operations SIG.
```{ojs}
geo = require("geotoolbox")
```
- **Simplification**
```{ojs}
viewof simpl = Inputs.range([0.0001, 0.2], { label: "Simplification", value: 0.1 })
mrc2 = geo.simplify(mrc, { k: simpl })
```
```{ojs}
//| echo: false
bertin.draw({params:{extent: munic},layers:[{geojson: mrc2, stroke:"black", strokeWidth:1.5, fill:"white", rewind: true}]})
```
- **Centroid**
```{ojs}
ctr = geo.centroid(mrc)
```
```{ojs}
//| echo: false
bertin.draw({params:{extent: mrc}, layers:[{geojson: ctr, fill:"red"},{geojson: mrc, fill:"#CCC"}, ]})
```
- **Buffer**
```{ojs}
quebec = geo.filter(mrc, (d) => d.MUS_CO_MRC == "23")
buff = geo.buffer(quebec, { dist: distance})
ctr2 = geo.clip(ctr, {clip: buff})
```
```{ojs}
//| echo: false
viewof distance = Inputs.range([0, 500], {
label: "Distance",
value: 300,
step: 10
})
bertin.draw({layers:[{geojson: quebec, fill:"red"}, {geojson: ctr2, fill:"red"}, {geojson: buff, stroke:"red", fill: "none", strokeWidth:2},{geojson: mrc, fill:"#CCC"}, ]})
```
**Création de cartes thématiques**
Pour créer des cartes thématiques, on peut utiliser la bibliothèque [**`bertin`**](https://github.com/neocarto/bertin)
La fonction **`draw`** permet de réaliser n'importe quel type de carte.

Par défaut, la couche s'affiche simplement.
```{ojs}
bertin.draw({layers:[{geojson: munic, fill: "#d18de0"}]})
```
On peut ajouter l'attrubut **`tooltip`** pour afficher des infobulles.
```{ojs}
bertin.draw({
layers:[
{
geojson: munic, fill: "#d18de0",
tooltip: "$MUS_NM_MUN"
}
]
})
```
**Cartographie thématique**
A présent, réalisons une carte de la population en 2022. Pour cela, on utilise le type **`bubble`**.
Par défaut, ça donne ceci :
```{ojs}
bertin.draw({
layers: [
{
type: "bubble",
geojson: munic,
values: "POP_2022",
fill:"red"
},
{
geojson: munic,
fill: "#CCC"
},
]
})
```
Et en paramétrant un peu, on obtient ceci.
```{ojs}
bertin.draw({
params: { extent: [[-79, 44.5], [-66, 51]]},
layers: [
{ type: "header", text: "Population en 2022", anchor: "start" }, // Titre
{ type: "minimap", x: 10, y: 10, width: 160 },
{
id : "bub", // identifiant de la couche
type: "bubble", // couche de symboles proportionnels
geojson: munic,
values: "POP_2022", // variable à cartographier
k: 50, // Rayon du plus gros cercle
leg_x: 740,
leg_y: 350,
leg_round: 0,
leg_title: "Nombre d'habitants",
fill: "red",
fillOpacity:0.5,
tooltip: ["$MUS_NM_MUN", d => d.properties["POP_2022"] + " habitants"] // infobulle
},
{geojson: munic, fill:"#CCC"}, // Couche des communes
{type:"scalebar"}
]
})
```
On peut facilement combiner cette couche de cercles avec un une carte choroplèthe.
```{ojs}
bertin.draw({
params: { extent: [[-79, 44.5], [-66, 51]]},
layers: [
{ type: "header", text: "Population en 2022", anchor: "start" }, // Titre
{ type: "minimap", x: 10, y: 10, width: 160 },
{
id : "bub",
type: "bubble",
geojson: munic,
values: "POP_2022",
k: 50,
leg_x: 690,
leg_y: 370,
leg_round: 0,
leg_title: "Nombre d'habitants",
fill: "white",
fillOpacity:0.2,
stroke:"black",
strokeWidth:1.4,
tooltip: ["$MUS_NM_MUN", d => d.properties["POP_2022"] + " habitants"]
},
{
geojson: munic,
fill: {
type: "choro",
values: "VIT_ECO",
colors: "RdYlBu",
leg_x:870,
leg_y:315,
leg_title: "Indice de\nvitalité\néconomique",
leg_round: 2
}
}, // Couche des communes
{type:"scalebar"}
]
})
```
On peut aussi colorier les cercles
```{ojs}
bertin.draw({
params: { extent: [[-79, 44.5], [-66, 51]]},
layers: [
{ type: "header", text: "Population en 2022", anchor: "start" }, // Titre
{ type: "minimap", x: 10, y: 10, width: 160 },
{
id : "bub",
type: "bubble",
geojson: munic,
values: "POP_2022",
k: 50,
leg_x: 690,
leg_y: 370,
leg_round: 0,
leg_title: "Nombre d'habitants",
fill: {
type: "choro",
values: "VIT_ECO",
colors: "RdYlBu",
leg_x:870,
leg_y:315,
leg_title: "Indice de\nvitalité\néconomique",
leg_round: 2
},
tooltip: ["$MUS_NM_MUN", d => d.properties["POP_2022"] + " habitants"]
},
{
geojson: munic,
fill: "#CCC"
}, // Couche des communes
{type:"scalebar"}
]
})
```
On peut utiliser les **`Inputs`** pour tester des visualisations, explorer les données ou proposer des interactions à un utilisatuer.
```{ojs}
// Inputs
viewof symbology = Inputs.radio(["bubble", "square", "spikes", "smooth", "dotdensity"], { label: "symbologie", value: "bubble"})
viewof r = Inputs.range([10, 100], { label: "taille", step: 1, value: 50, disabled : ["bubble", "square", "spikes"].includes(symbology) ? false: true})
viewof toggle = Inputs.toggle({label: "dorling", value: false, disabled : ["bubble", "square", "dotdensity"].includes(symbology) ? false: true})
viewof thresholds = Inputs.range([5, 50], { label: "thresholds", step: 1, value: 23, disabled : symbology == "smooth" ? false : true})
viewof bandwidth = Inputs.range([5, 50], { label: "bandwidth", step: 1, value: 27, disabled : symbology == "smooth" ? false : true })
viewof filterpop = Inputs.range([1000, 100000], { label: "POP >= ", step: 1, value: 1000})
// Carte
bertin.draw({
params: { extent: [[-79, 44.5], [-66, 51]]},
layers: [
{
type: symbology,
geojson: geo.filter(munic, (d) => d.POP_2022 >= filterpop),
values: "POP_2022",
fill: symbology == "smooth" ? "RdYlGn" : "red",
fillOpacity:0.7,
dorling: toggle,
k: r,
thresholds,
bandwidth,
symbol_size:25,
w:15,
symbol_shift : toggle ? 1 : 0,
stroke : symbology == "spikes" ? "red" : "white",
tooltip: ["$MUS_NM_MUN", d => d.properties["POP_2022"] + " habitants"]
},
{
geojson: munic,
fill: "#CCC",
stroke : toggle ? "#CCC" : "white"
},
]
})
```
### Références
<ins>Documentation</ins>
- [github.com/neocarto/bertin](https://github.com/neocarto/bertin)
<ins>Exemples</ins>
- [observablehq.com/@neocartocnrs/bertin-js-tooltips?collection=@neocartocnrs/bertin](https://observablehq.com/@neocartocnrs/bertin-js-tooltips?collection=@neocartocnrs/bertin)
<ins>Bibliographie</ins>
- **Bostock M. (2021) JavaScript for Data Analysis. towardsdatascience. [towardsdatascience.com/javascript-for-data-analysis-2e8e7dbf63a7](https://towardsdatascience.com/javascript-for-data-analysis-2e8e7dbf63a7)**
- Bostock M., Ogievetsky V., Heer J. (2011). D³ Data-Driven Documents, IEEE, Volume: 17 [ieeexplore.ieee.org/abstract/document/6064996](https://ieeexplore.ieee.org/abstract/document/6064996)
- Giraud T., Lambert N., (2023). bertin: Thematic Cartography with 'bertin.js'. [github.com/riatelab/bertin/, https://riatelab.github.io/bertin](https://github.com/riatelab/bertin/, https://riatelab.github.io/bertin)
- **Lambert N, Giraud T, Viry Matthieu and, Ysebaert R. (2023) Cartographier pour le web avec la bibliothèque JavaScript ‘bertin‘. SAGEO**
- Lambert N. (2023) Observable en bref. Webinaire ‘Interroger les données’, Groupe de travail ‘Atelier Données’ du CNRS.
- Lambert N., Zanin C., (2020). Practical handbook of thematic cartography: principles, methods, and applications. CRC Press.
[observablehq.com/@neocartocnrs/webinaire-interroger-les-donnees](https://observablehq.com/@neocartocnrs/webinaire-interroger-les-donnees)
- Lambert N. (2023) Cartographie thématique avec ojs. École d’été internationale, Ouidah. [https://ee-cist.github.io/CAR2_cartodyn/intro/docs/index.html](ee-cist.github.io/CAR2_cartodyn/intro/docs/index.html])
- **Perkel M. J. (2021) Reactive, reproducible, collaborative: computational notebooks evolve, Nature. [nature.com/articles/d41586-021-01174-w](https://www.nature.com/articles/d41586-021-01174-w)**
- Rice J., Farquhar A., Piernot P., Gruber T., (1996). “Using the Web instead of a window system”. In: Proceedings of the SIGCHI conference on Human factors in computing systems common ground - CHI ’96. the SIGCHI conference. Vancouver, British Columbia, Canada: ACM Press, pp. 103–110. isbn: 978-0-89791-777-3. doi: 10.1145/238386.238442.
- Roth R.E., Donohue R.G., Sack C.M., Wallace T.R., Buckingham T.M.A., (2015). “A Process for Keeping Pace with Evolving Web Mapping Technologies”. In: Cartographic Perspectives 78, pp. 25–52. issn: 1048-9053. doi: 10.14714/CP78.1273. url: https://cartographicperspectives.org/index.php/journal/article/view/cp78-roth-et-al
- Shen H. (2014). Interactive notebooks: Sharing the code. Nature, 515(7525), 151-152.
## A vous de jouer
::: {.callout-caution appearance="simple"}
## faire des cartes avec {ojs}
::: {.callout-note icon=false}
## Objectif
Réaliser comme ci-dessous, une carte [choroplèthe](http://geoconfluences.ens-lyon.fr/glossaire/choroplethe-choroisoplethe) sur une région du Québec que l'on peut selectionner dans une liste déroulante.
```{ojs}
//| echo: false
//| eval: true
viewof myregion = Inputs.select(["Estrie","Capitale-Nationale","Bas-Saint-Laurent"], {label: "Choisissez une région"})
myreg = bertin.properties.subset({
geojson: munic,
field: "MUS_NM_REG",
selection: [myregion]
})
bertin.draw({ layers: [{type:"header", text: `Les actifs (${myregion})`},{type:"scalebar"},{ geojson: myreg, rewind: true, fill: {type:"choro", values: "TX_2564", colors: "RdYlGn", leg_x: 2, leg_y:2, leg_title:"Taux d'actifs", leg_round:1}, tooltip:["$MUS_NM_MUN", d => "Taux d'actifs :" + d.properties.TX_2564 + "%"]}] })
```
:::
**A vous de jouer**
- Chargez la bibliothèque [`bertin`](https://github.com/neocarto/bertin)
- Importez la couche `munic.geojson`
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
Pour importer des données au format JSON en Observable JavaScript, on utilise l'instruction `FileAttachment()`
:::
- Afficher le fond de carte avec la fonction [`draw`](https://github.com/neocarto/bertin#drawing-a-map)
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
La fonction draw prend en entrée un objet qui a la structure suivante :
```js
bertin.draw({
layers: [{...}]
})
```
:::
::: {.callout-tip icon=false collapse="true"}
## Astuce
Si la carte ne s'affiche pas correctement, utiliser l'attribut `rewind:true`
:::
- Afficher les données attributaires.
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
On peut afficher les données avec l'instruction. `Inputs.table()`
Mais auparavant, il faut récupérer les propriétés du geoJSON comme ceci :
```js
munic.features.map((d) => d.properties)
```
:::
- Créer une liste déroulante pour choisir parmi 3 régions à étudier
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
Par exemple :
```js
mesregions = ["Estrie","Capitale-Nationale","Bas-Saint-Laurent"]
viewof myregion = Inputs.select(mesregions, {label: "Choisissez une région"})
```
:::
- Créez un nouveau fond de carte contenant les municipalités de la région concernée.
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
Pour créer ce sous jeu de données, on peut utiliser la fonction `subset` de la bibliothèque `bertin`.
```js
myreg = bertin.properties.subset({
geojson: munic,
field: "MUS_NM_REG",
selection: [myregion]
})
```
:::
- Afficher le nouveau fond de carte
- Définisser la couleur de fond, l'épaisseur des traits, la couleur des contours.
- Réaliser une carte [chorplèthe](https://github.com/neocarto/bertin#choropleth) à partir d'une variable disponible. Par exemple, le taux d'actifs (TX_2564).
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
Définissez l'attribut `fill` par un objet commençant par `{type: choro, values: ...}`
:::
- Changez les couleurs et la méthode de discretisation
::: {.callout-tip icon=false collapse="true"}
## Besoin d'aide ?
La documentation est disponible [ici](https://github.com/neocarto/bertin#choropleth)
:::
- Ajouter un [titre](https://github.com/neocarto/bertin#header)
- Ajouter la légende
- Ajouter l'[échelle](https://github.com/neocarto/bertin#scalebar)
- Ajoutez des [infobulles](https://observablehq.com/@neocartocnrs/bertin-js-tooltips)
::: {.callout-caution collapse="true"}
## SOLUTION
```{ojs}
//| echo: true
//| eval: false
bertin = require("bertin")
munic = FileAttachment("munic.geojson").json()
viewof myregion = Inputs.select(
["Estrie", "Capitale-Nationale", "Bas-Saint-Laurent"],
{ label: "Choisissez une région" }
)
myreg = bertin.properties.subset({
geojson: munic,
field: "MUS_NM_REG",
selection: [myregion]
})
bertin.draw({
layers: [
{ type: "header", text: `Les actifs (${myregion})` },
{ type: "scalebar" },
{
geojson: myreg,
rewind: true,
fill: {
type: "choro",
values: "TX_2564",
colors: "RdYlGn",
leg_x: 2,
leg_y: 2,
leg_title: "Taux d'actifs",
leg_round: 1
},
tooltip: [
"$MUS_NM_MUN",
(d) => "Taux d'actifs :" + d.properties.TX_2564 + "%"
]
}
]
})
```
:::
:::