Skip to content

Commit fe32a9b

Browse files
committed
Téléchargements page données ✨
1 parent 22f6139 commit fe32a9b

File tree

7 files changed

+150
-2
lines changed

7 files changed

+150
-2
lines changed

client/components/carte/Map.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ onMounted(() => {
7272
container: mapContainer.value,
7373
style: `https://openmaptiles.data.gouv.fr/styles/osm-bright/style.json`,
7474
bounds: initialState,
75+
preserveDrawingBuffer: true,
7576
});
7677
7778
@@ -288,6 +289,15 @@ const resetZoneSelected = () => {
288289
popup.remove();
289290
};
290291
292+
async function downloadMap() {
293+
const content = map.value?.getCanvas().toDataURL('image/png');
294+
295+
const a = document.createElement('a');
296+
a.href = content.replace('image/png', 'image/octet-stream');
297+
a.download = `carte_${props.date}.png`;
298+
a.click();
299+
}
300+
291301
watch(() => selectedTypeEau.value, () => {
292302
resetZoneSelected();
293303
});
@@ -432,6 +442,12 @@ watch(() => props.area, () => {
432442
class="situation-level-bg-4"
433443
label="crise" />
434444
</div>
445+
446+
<div class="text-align-right">
447+
<DsfrButton @click="downloadMap()">
448+
Télécharger la carte en .png
449+
</DsfrButton>
450+
</div>
435451
</div>
436452
<template v-else>
437453
<DsfrAlert title="Votre navigateur ne supporte pas les cartographies"

client/components/carte/Table.vue

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import api from '../../api';
33
import utils from '../../utils';
44
import { Ref } from 'vue';
5+
import { json2csv } from 'json-2-csv';
56
67
const props = defineProps<{
78
date: string,
@@ -43,12 +44,14 @@ const rows = ref([]);
4344
const rowsFiltered: Ref<any[]> = ref([]);
4445
const componentKey = ref(0);
4546
const loading = ref(false);
47+
const departementsData = ref([]);
4648
4749
async function loadData() {
4850
rows.value = [];
4951
loading.value = true;
5052
const { data, error } = await api.getDepartmentsData(props.date, props.area);
5153
dataResume.map(r => r.number = 0);
54+
departementsData.value = data.value;
5255
data.value?.forEach((d: any) => {
5356
const dr = dataResume.find(r => r.niveauGravite === (d.niveauGraviteMax ? d.niveauGraviteMax : 'pas_de_restrictions'));
5457
rows.value.push([d.code, d.nom, dr ? dr.label : 'Pas de restrictions']);
@@ -75,16 +78,40 @@ function filterDepartments() {
7578
componentKey.value += 1;
7679
}
7780
81+
async function downloadCsv() {
82+
const formatDepartements = departementsData.value
83+
.map((departement: any) => {
84+
return {
85+
code: departement.code,
86+
nom: departement.nom,
87+
region: departement.region,
88+
niveau_gravite_max: departement.niveauGraviteMax,
89+
};
90+
});
91+
const csv = await json2csv(formatDepartements, {
92+
expandArrayObjects: true,
93+
});
94+
95+
// Create a CSV file and allow the user to download it
96+
let blob = new Blob([csv], { type: 'text/csv' });
97+
let url = window.URL.createObjectURL(blob);
98+
let a = document.createElement('a');
99+
a.href = url;
100+
a.download = `situation_departement_${props.date}.csv`;
101+
document.body.appendChild(a);
102+
a.click();
103+
}
104+
78105
const tableTitle = computed(() => {
79106
if (props.light) {
80107
return '';
81108
}
82-
return `Niveau de gravité maximal observé par département ${props.filterText ? '(' + props.filterText + ')' : ''}`
109+
return `Niveau de gravité maximal observé par département ${props.filterText ? '(' + props.filterText + ')' : ''}`;
83110
});
84111
85112
const pageTitle = computed(() => {
86113
return `Situation de la sécheresse en France (niveau de gravité maximum contasté par
87-
département) - ${props.filterText ? props.filterText : ''}`
114+
département) - ${props.filterText ? props.filterText : ''}`;
88115
});
89116
90117
watch(() => props, () => {
@@ -131,6 +158,12 @@ watch(() => props, () => {
131158
:key="componentKey"
132159
class="fr-table--layout-fixed" />
133160
</div>
161+
162+
<div class="text-align-right fr-mt-1w">
163+
<DsfrButton @click="downloadCsv()">
164+
Télécharger les données (CSV)
165+
</DsfrButton>
166+
</div>
134167
</template>
135168
<template v-else-if="loading">
136169
<div class="fr-grid-row fr-grid-row--center fr-my-2w">

client/components/donnees/AreaChart.vue

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,16 @@ const chartLineOptions: ChartOptions = {
159159
},
160160
};
161161
162+
async function downloadGraph() {
163+
const el = document.getElementById('area-chart-line') as HTMLCanvasElement;
164+
const content = el.toDataURL('image/png');
165+
166+
const a = document.createElement('a');
167+
a.href = content.replace('image/png', 'image/octet-stream');
168+
a.download = `graphique_surface.png`;
169+
a.click();
170+
}
171+
162172
watch(() => refDataStore.departements, () => {
163173
areaOptions.value = [{
164174
text: 'France entière',
@@ -249,9 +259,16 @@ watch(() => refDataStore.departements, () => {
249259
</div>
250260
<template v-if="!loading">
251261
<Line v-if="chartLineData"
262+
id="area-chart-line"
252263
:options="chartLineOptions"
253264
:data="chartLineData"
254265
:style="{'min-height': '400px'}" />
266+
267+
<div class="text-align-right fr-mt-1w">
268+
<DsfrButton @click="downloadGraph()">
269+
Télécharger le graphique en .png
270+
</DsfrButton>
271+
</div>
255272
</template>
256273
<template v-else>
257274
<div class="fr-grid-row fr-grid-row--center fr-my-2w">

client/components/donnees/ArretesRestrictionsTable.vue

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import api from '../../api';
33
import utils from '../../utils';
4+
import { json2csv } from 'json-2-csv';
45
56
const props = defineProps<{
67
date: string,
@@ -13,11 +14,13 @@ const headers = ['Numéro', 'Département', 'Niveau de gravité maximum', 'Resso
1314
const rows = ref([]);
1415
const loading = ref(false);
1516
const componentKey = ref(0);
17+
const ars = ref([]);
1618
1719
async function loadData() {
1820
rows.value = [];
1921
loading.value = true;
2022
const { data, error } = await api.getArretesRestrictions(props.date, props.area);
23+
ars.value = data.value;
2124
data.value?.forEach((d: any) => {
2225
rows.value.push([d.numero, d.departement?.nom, utils.getShortSituationLabel(utils.getRestrictionRank(d.niveauGraviteMax)),
2326
d.types.map(t => utils.getTypeLabel(t)).join(', '), d.dateDebut, d.dateFin ? d.dateFin : '', d.fichier ? {
@@ -31,6 +34,43 @@ async function loadData() {
3134
loading.value = false;
3235
}
3336
37+
async function downloadCsv() {
38+
const formatArretes = ars.value
39+
.map((arrete: any) => {
40+
return {
41+
id: arrete.id,
42+
numero: arrete.numero,
43+
date_debut: arrete.dateDebut,
44+
date_signature: arrete.dateSignature,
45+
date_fin: arrete.dateFin,
46+
statut: arrete.statut,
47+
departement: arrete.departement.code,
48+
chemin_fichier: arrete.fichier ? arrete.fichier?.url : '',
49+
arrete_cadre: arrete.arretesCadre?.map((arreteCadre: any) => {
50+
return {
51+
id: arreteCadre.id,
52+
numero: arreteCadre.numero,
53+
date_debut: arrete.dateDebut,
54+
date_signature: arrete.dateSignature,
55+
chemin_fichier: arreteCadre.fichier ? arreteCadre.fichier?.url : '',
56+
};
57+
}),
58+
};
59+
});
60+
const csv = await json2csv(formatArretes, {
61+
expandArrayObjects: true,
62+
});
63+
64+
// Create a CSV file and allow the user to download it
65+
let blob = new Blob([csv], { type: 'text/csv' });
66+
let url = window.URL.createObjectURL(blob);
67+
68+
let a = document.createElement('a');
69+
a.href = url;
70+
a.download = `arretes_restrictions_${props.date}.csv`;
71+
a.click();
72+
}
73+
3474
const tableTitle = computed(() => {
3575
return `Arrêtés de restrictions ${props.filterText ? '(' + props.filterText + ')' : ''}`;
3676
});
@@ -53,6 +93,12 @@ watch(() => props, () => {
5393
:pagination="true"
5494
:key="componentKey"
5595
class="fr-table--layout-fixed" />
96+
97+
<div class="text-align-right fr-mt-1w">
98+
<DsfrButton @click="downloadCsv()">
99+
Télécharger les données (CSV)
100+
</DsfrButton>
101+
</div>
56102
</template>
57103
<template v-else>
58104
<div class="fr-grid-row fr-grid-row--center fr-my-2w">

client/components/donnees/DepartementChart.vue

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,16 @@ const chartLineOptions: ChartOptions = {
141141
},
142142
};
143143
144+
async function downloadGraph() {
145+
const el = document.getElementById('departement-chart-line') as HTMLCanvasElement;
146+
const content = el.toDataURL('image/png');
147+
148+
const a = document.createElement('a');
149+
a.href = content.replace('image/png', 'image/octet-stream');
150+
a.download = `graphique_departements.png`;
151+
a.click();
152+
}
153+
144154
watch(() => refDataStore.departements, () => {
145155
areaOptions.value = [{
146156
text: 'France entière',
@@ -225,9 +235,16 @@ watch(() => refDataStore.departements, () => {
225235
</div>
226236
<template v-if="!loading">
227237
<Line v-if="chartLineData"
238+
id="departement-chart-line"
228239
:options="chartLineOptions"
229240
:data="chartLineData"
230241
:style="{'min-height': '400px'}" />
242+
243+
<div class="text-align-right fr-mt-1w">
244+
<DsfrButton @click="downloadGraph()">
245+
Télécharger le graphique en .png
246+
</DsfrButton>
247+
</div>
231248
</template>
232249
<template v-else>
233250
<div class="fr-grid-row fr-grid-row--center fr-my-2w">

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@vuelidate/validators": "^2.0.3",
2222
"chart.js": "^4.4.0",
2323
"chartjs-adapter-luxon": "^1.3.1",
24+
"json-2-csv": "^5.5.5",
2425
"luxon": "^3.4.3",
2526
"maplibre-gl": "^4.3.2",
2627
"oh-vue-icons": "^1.0.0-rc3",

yarn.lock

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5199,6 +5199,11 @@ decimal.js@^10.4.3:
51995199
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
52005200
integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==
52015201

5202+
5203+
version "3.1.0"
5204+
resolved "https://registry.yarnpkg.com/deeks/-/deeks-3.1.0.tgz#ecc47c600bcc6dbda656c6d86bbc96cbe126fd41"
5205+
integrity sha512-e7oWH1LzIdv/prMQ7pmlDlaVoL64glqzvNgkgQNgyec9ORPHrT2jaOqMtRyqJuwWjtfb6v+2rk9pmaHj+F137A==
5206+
52025207
deep-equal@^2.0.5:
52035208
version "2.2.3"
52045209
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1"
@@ -5348,6 +5353,11 @@ dir-glob@^3.0.1:
53485353
dependencies:
53495354
path-type "^4.0.0"
53505355

5356+
5357+
version "4.1.1"
5358+
resolved "https://registry.yarnpkg.com/doc-path/-/doc-path-4.1.1.tgz#5be8c1671877f6b719af5a6077c41904be8913ac"
5359+
integrity sha512-h1ErTglQAVv2gCnOpD3sFS6uolDbOKHDU1BZq+Kl3npPqroU3dYL42lUgMfd5UimlwtRgp7C9dLGwqQ5D2HYgQ==
5360+
53515361
doctrine@^2.1.0:
53525362
version "2.1.0"
53535363
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@@ -7687,6 +7697,14 @@ jsesc@~0.5.0:
76877697
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
76887698
integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==
76897699

7700+
json-2-csv@^5.5.5:
7701+
version "5.5.5"
7702+
resolved "https://registry.yarnpkg.com/json-2-csv/-/json-2-csv-5.5.5.tgz#4e6000fa173c2027f40740e7f04256ca39658274"
7703+
integrity sha512-xLeiOE+jtDMX4SMn9JlD6BVI9c5SYVFmtlsNBSelGlq9iUHdVmwlxQ/uUI/BEVQuKDVLlxNrsOfwlI3rfYy1zA==
7704+
dependencies:
7705+
deeks "3.1.0"
7706+
doc-path "4.1.1"
7707+
76907708
76917709
version "3.0.1"
76927710
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"

0 commit comments

Comments
 (0)