diff --git a/components/Bulles.jsx b/components/Bulles.jsx
new file mode 100644
index 0000000..5e5d23d
--- /dev/null
+++ b/components/Bulles.jsx
@@ -0,0 +1,166 @@
+import React from 'react';
+import plotly from 'plotly.js/dist/plotly';
+import createPlotComponent from 'react-plotly.js/factory';
+import LoadingScreen from "./LoadingScreen";
+
+function Bulles (props) {
+
+// récupération des résultats de l'élection et stockage en tableau
+const votesBrut = (Object.values(props))[0];
+
+// déclaration et initialisation des mentions et couleurs
+const mentionsBrut = ['Passable', 'Assez bien', 'Bien', 'Très bien', 'Excellent'];
+const couleursBrut = ['#BB9C42', '#AABA44', '#DCDF44', '#B3D849', '#61AD45'];
+
+//----------- Traitement des données -----------//
+
+// fonction d'inversement des éléments de tableau
+function inverse(obj){
+ var retobj = {};
+ for(var key in obj){
+ retobj[obj[key]] = key;
+ }
+ return retobj;
+ }
+
+// fonction de réduction d'amplitude permettant de conserver une représentation ordinale du nombre de votes sans décalage visuel trop important
+/*
+Pattern de calcul :
+
+Soient Ai, Bi, Ci, Di, Ei les nombres de votes initiaux fournis dans le tableau classé par ordre mélioratif de mention (de Passable à Excellent). Il vient :
+A = 1
+B = <{[1 + (Bi/Ai)] / 40} * A>
+C = <{[1 + (Ci/Bi)] / 40} * B>
+D = <{[1 + (Di/Ci)] / 40} * C>
+E = <{[1 + (Ei/Di)] / 40} * D>
+*/
+function redAmpli(tab) {
+ var nvTab = [];
+ nvTab[0] = 100;
+
+ for(i = 1; i < tab.length; i++) {
+ nvTab[i] = ( (1 + ((tab[i]/tab[(i-1)]) / 40 ) ) * nvTab[(i-1)]);
+ }
+ return nvTab;
+}
+
+
+// déclaration de l'objet votes-mention et votes-couleur
+var votesMentionNonOrdonnes = {};
+var votesCouleurNonOrdonnes = {};
+
+// initialisation votes-mention ordonnés croissants
+for (var i = 0; i < mentionsBrut.length; i++) {
+ votesMentionNonOrdonnes[votesBrut[i]] = mentionsBrut[i];
+ votesCouleurNonOrdonnes[votesBrut[i]] = couleursBrut[i];
+}
+
+// déclaration des mentions-votes par ordre croissant
+var votesMentionOrdonnes = inverse(votesMentionNonOrdonnes);
+var votesCouleurOrdonnes = inverse(votesCouleurNonOrdonnes);
+
+// vérification du nombre de votes classés par ordre croissant et passés initialement en propriétés au composant
+console.log("Les données transmises au composant concernant le nombre de votes par mention sont : ");
+console.log(votesBrut);
+
+// vérification des mentions destinées à être associées aux votes et ordonnées initialement par ordre mélioratif
+console.log("Les mentions des votes sont classées initialement par ordre mélioratif de la façon suivante :");
+console.log(mentionsBrut);
+
+// vérification du nombre de votes classés par ordre croissant
+console.log("Les mentions-votes classées par ordre croissant de votes sont : ");
+console.log(votesMentionOrdonnes);
+
+// séparation des mentions et des votes
+const mentions = Object.keys(votesMentionOrdonnes);
+const votes = Object.values(votesMentionOrdonnes);
+const couleurs = Object.keys(votesCouleurOrdonnes);
+
+// vérification des mentions et des votes prêts à être traités pour la représentation graphique
+console.log('La liste des mentions issue du classement par ordre croissant de votes est :');
+console.log(mentions);
+console.log('La liste du nombre de votes correspondant, classée par ordre croissant, est :');
+console.log(votes);
+
+// déclaration et initialisation des rayons de bulle pour la représentation graphique
+var rayons = [];
+rayons = redAmpli(votes)
+
+// vérification des rayons
+console.log('La liste des rayons à représenter graphiquement est la suivante :');
+console.log(rayons);
+
+// déclaration et initialisation des textes des bulles
+const texteBulle1 = (mentions[0] + "
" + votes[0] + " votes").toString();
+const texteBulle2 = (mentions[1] + "
" + votes[1] + " votes").toString();
+const texteBulle3 = (mentions[2] + "
" + votes[2] + " votes").toString();
+const texteBulle4 = (mentions[3] + "
" + votes[3] + " votes").toString();
+const texteBulle5 = (mentions[4] + "
" + votes[4] + " votes").toString();
+
+// déclaration et initialisation d'une instance de graphique en bulles
+// const Plot = createPlotComponent(plotly);
+const Plot = require('react-plotly.js').default;
+
+//---------------------------------------------//
+
+
+
+//----------- Affichage des données -----------//
+const [loading, setLoading] = React.useState(true);
+ React.useEffect(() =>{
+ setTimeout(() => setLoading(false), 3000);
+ })
+return (
+
+ //
Le total des votes est de {totalVotes}.
+ +Importer une photo.
format : jpg, png, pdf
Ajoutez une photo, le nom et une description au candidat.
+Importer une photo.
format : jpg, png, pdf
- {t("The form contains no address.")}
-
-
- {t(
- "The election will be opened to anyone with the link"
- )}
-
-
-
- {t(
- "The results page will not be accessible until the end date is reached."
- )}{" "}
- ({finish.toLocaleDateString()} {t("at")}{" "}
- {finish.toLocaleTimeString()})
+
+
+ {t("The form contains no address.")}
+
+
+ {t(
+ "The results page will not be accessible until the end date is reached."
+ )}{" "}
+ ({finish.toLocaleDateString()} {t("at")}{" "}
+ {finish.toLocaleTimeString()})
+
+
+
- {t("Results available at any time")}
-
+
+
+
+ {t(
+ "The election will be opened to anyone with the link"
+ )}
+
+
+ {restrictResult ? (
+
+
+
+ {t("Results available at any time")}
+
+