diff --git a/web/components/visualization/results-general.js b/web/components/visualization/results-general.js
new file mode 100644
index 0000000000000000000000000000000000000000..60493593b479ce1a63fced5a7731468c597c5e76
--- /dev/null
+++ b/web/components/visualization/results-general.js
@@ -0,0 +1,153 @@
+// Imports
+import * as Auth from "/services/auth/auth.js";
+import * as results from "/services/election/calculate-election-generic.js";
+import * as PartyModel from "/services/model/party-model.js";
+import * as CandidateListModel from "/services/model/candidateList-model.js";
+import * as AreaModel from "/services/model/area-model.js";
+import * as Scroller from "/services/common/scroller.js";
+import * as ResultsZone from "/components/visualization/results-zone.js";
+
+export async function mount(where, parent) {
+  const resultGeneralComponent = new ResultGeneralComponent(parent);
+  await resultGeneralComponent.mount(where);
+  return resultGeneralComponent;
+}
+
+class ResultGeneralComponent {
+  constructor(parent) {
+    this.parent = parent;
+    this.PartyModel = PartyModel.getPartyModel();
+    this.CandidateListModel = CandidateListModel.getCandidateListModel();
+    this.AreaModel = AreaModel.getAreaModel();
+  }
+
+  async mount(where) {
+    this.PartyModel.current_user = await Auth.GetUser();
+    this.CandidateListModel.current_user = await Auth.GetUser();
+    this.AreaModel.current_user = await Auth.GetUser();
+    const mountpoint = where;
+    document.getElementById(mountpoint).innerHTML = /* HTML */ `
+      <div class="column is-half">
+        <div class="card-no-hover">
+          <header class="card-header">
+            <p class="card-header-title">
+              Résultats du tour
+            </p>
+          </header>
+          <div id="round-results" class="content"></div>
+          <div id="round-detaileds-results" class="content"></div>
+        </div>
+      </div>
+      <div class="column is-half">
+        <div class="card-no-hover">
+          <header class="card-header">
+            <p class="card-header-title">
+              Statistiques
+            </p>
+          </header>
+          <div id="stats-results" class="content"></div>
+        </div>
+      </div>
+    `;
+    this.handleDom();
+    this.displayRoundResults();
+  }
+
+  handleDom() {}
+
+  displayRoundResults() {
+    document.getElementById("round-results").innerHTML = "";
+    if (this.parent.results.status == this.parent.filter) {
+      for (let i in this.parent.results.roundResults) {
+        let electeds = this.parent.results.candidateLists
+          .filter((candidateList) => {
+            return (
+              candidateList.PartyID == this.parent.results.roundResults[i].ID
+            );
+          })
+          .reduce((electeds, candidateList) => {
+            return electeds + candidateList.SeatsAttributed;
+          }, 0);
+        document.getElementById(
+          "round-results"
+        ).innerHTML += this.parent.progressBarTemplate(
+          this.parent.results.roundResults[i],
+          this.parent.results.roundResults[i].Color,
+          electeds
+        );
+      }
+    } else {
+      if (this.parent.results.status == "no_results") {
+        document.getElementById(
+          "round-results"
+        ).innerHTML = this.parent.showWarningResults(
+          "Aucun résultats n'ont étaient saisis sur cette zone"
+        );
+      } else if (this.parent.results.status == "incompleted") {
+        document.getElementById(
+          "round-results"
+        ).innerHTML = this.parent.showWarningResults(
+          "Les résultats pour cette zone ne sont pas complets"
+        );
+      } else if (this.parent.results.status == "not validated") {
+        document.getElementById(
+          "round-results"
+        ).innerHTML = this.parent.showWarningResults(
+          "Les résultats pour cette zone n'ont pas étaient validés"
+        );
+      }
+    }
+    this.displayRoundDetailedResults();
+  }
+
+  async displayRoundDetailedResults() {
+    document.getElementById("round-detaileds-results").innerHTML =
+      '<br/><h5 class="title is-5">Statistiques</h5>';
+
+    if (this.parent.filter === "partial")
+      document.getElementById(
+        "round-detaileds-results"
+      ).innerHTML += this.parent.progressBarTemplate(
+        {
+          Name: "Pourcentage de saisie",
+          Percentage: this.parent.results.stats.PercentageConsiderated,
+          VoiceNumber: null,
+        },
+        "grey",
+        null
+      );
+    document.getElementById(
+      "round-detaileds-results"
+    ).innerHTML += this.parent.progressBarTemplate(
+      {
+        Name: "Abstention",
+        Percentage: this.parent.results.stats.Abstention,
+        VoiceNumber: null,
+      },
+      "grey",
+      null
+    );
+    document.getElementById(
+      "round-detaileds-results"
+    ).innerHTML += this.parent.progressBarTemplate(
+      {
+        Name: "Votes blancs",
+        Percentage: this.parent.results.stats.BlankPercentage,
+        VoiceNumber: this.parent.results.stats.BlankVoiceNumber,
+      },
+      "grey",
+      null
+    );
+    document.getElementById(
+      "round-detaileds-results"
+    ).innerHTML += this.parent.progressBarTemplate(
+      {
+        Name: "Votes nuls",
+        Percentage: this.parent.results.stats.NullVotePercentage,
+        VoiceNumber: this.parent.results.stats.NullVoteVoiceNumber,
+      },
+      "grey",
+      null
+    );
+  }
+}
diff --git a/web/components/visualization/results-section.js b/web/components/visualization/results-section.js
index d11babdc97edbcc72c6f04c9bac0e588390c085f..45a5c4a036fda33956410ba567b04968d3454923 100644
--- a/web/components/visualization/results-section.js
+++ b/web/components/visualization/results-section.js
@@ -4,7 +4,8 @@ import * as results from "/services/election/calculate-election-generic.js";
 import * as PartyModel from "/services/model/party-model.js";
 import * as CandidateListModel from "/services/model/candidateList-model.js";
 import * as AreaModel from "/services/model/area-model.js";
-import * as Scroller from "/services/common/scroller.js";
+import * as ResultsZone from "/components/visualization/results-zone.js";
+import * as ResultsGeneral from "/components/visualization/results-general.js";
 
 export async function mount(where, round) {
   const resultComponent = new ResultComponent(round);
@@ -27,7 +28,12 @@ class ResultComponent {
     document.getElementById(mountpoint).innerHTML = /* HTML */ `
       <div class="tabs is-boxed is-toggle is-fullwidth">
         <ul>
-          <li id="areas" class="is-active">
+          <li id="general" class="is-active">
+            <a>
+              <span>Général</span>
+            </a>
+          </li>
+          <li id="areas">
             <a>
               <span>Circonscriptions</span>
             </a>
@@ -53,97 +59,14 @@ class ResultComponent {
           Validé
         </label>
       </div>
-      <div class="columns">
-        <div class="column is-half">
-          <div id="map-section" class="card-no-hover">
-            <header class="card-header">
-              <p class="card-header-title">
-                Carte
-              </p>
-              <button id="zoom-map" class="button is-success">
-                <span class="icon is-small">
-                  <i class="fas fa-search"></i>
-                </span>
-              </button>
-            </header>
-            <div class="card-content">
-              <div id="round-list" class="content">
-                La carte du tour
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="column">
-          <div id="news-flow-section" class="card-no-hover">
-            <header class="card-header">
-              <p class="card-header-title">
-                Actualités
-              </p>
-              <button id="zoom-news-flow" class="button is-success">
-                <span class="icon is-small">
-                  <i class="fas fa-search"></i>
-                </span>
-              </button>
-            </header>
-            <div class="card-content">
-              <div id="news-flow" class="content">
-                Flux d'actualité
-              </div>
-            </div>
-          </div>
-          <div id="results-section" class="card-no-hover" ">
-          <header class="card-header">
-            <p class="card-header-title">
-              Résultats
-            </p>
-            <button id="zoom-results" class="button is-success">
-              <span class="icon is-small">
-                <i class="fas fa-search"></i>
-              </span>
-            </button>
-          </header>
-          <div class="card-content">
-            <div id="detailed-results" class="content">
-              <div class="control select">
-                <select id="select-areas" class="input"></select>
-              </div>
-              <div class="control select">
-                <select id="select-sections" class="input"></select>
-              </div>
-              <div id="zone-results"></div>
-              <div id="zone-detaileds-results" style="display:none"></div>
-            </div>
-          </div>
-        </div>
-      </div>
+      <div id="results-general" class="columns"></div>
+      <div id="results-zone" class="columns" style="display: none;"></div>
     `;
     this.calculator = await results.mountCalculator(this.round);
+    await this.calculateResults();
+    this.resultsZone = await ResultsZone.mount("results-zone", this);
+    this.resultsGeneral = await ResultsGeneral.mount("results-general", this);
     this.handleDom();
-    document.getElementById("areas").click();
-  }
-
-  resultFlowTemplate(zone) {
-    let html = document.createElement("div");
-    html.classList = "card-list card-no-hover";
-    html.innerHTML = /* HTML */ `
-      <div class="card-content">
-        <div id="flow-content-${zone.ID}" class="content">
-          <h5 class="title is-5">${zone.Name}</h5>
-        </div>
-      </div>
-    `;
-    html.addEventListener("click", async () => {
-      if (this.zone == "sections") {
-        let area = await this.AreaModel.getArea(zone.AreaID);
-        this.refreshSections(area);
-        document.getElementById("select-sections").value = zone.ID;
-        document.getElementById("select-areas").value = zone.AreaID;
-      } else {
-        document.getElementById("select-areas").value = zone.ID;
-      }
-      this.displayZoneResults(zone);
-    });
-    return html;
   }
 
   progressBarTemplate(candidateList, color, electedsNumber) {
@@ -178,44 +101,47 @@ class ResultComponent {
 
   handleDom() {
     let resultHandler = this;
+    document
+      .getElementById("general")
+      .addEventListener("click", async function () {
+        document.getElementById("results-zone").style.display = "none";
+        document.getElementById("results-general").style.display = "flex";
+        await resultHandler.calculateResults();
+        document.getElementById("sections").setAttribute("class", "");
+        document.getElementById("areas").setAttribute("class", "");
+        document.getElementById("general").setAttribute("class", "is-active");
+      });
     document
       .getElementById("areas")
       .addEventListener("click", async function () {
+        document.getElementById("results-zone").style.display = "flex";
+        document.getElementById("results-general").style.display = "none";
         resultHandler.zone = "areas";
         await resultHandler.calculateResults();
-        resultHandler.displayResults();
+        resultHandler.resultsZone.displayResults();
         document.getElementById("sections").setAttribute("class", "");
+        document.getElementById("general").setAttribute("class", "");
         document.getElementById("areas").setAttribute("class", "is-active");
       });
     document
       .getElementById("sections")
       .addEventListener("click", async function () {
+        document.getElementById("results-zone").style.display = "flex";
+        document.getElementById("results-general").style.display = "none";
         resultHandler.zone = "sections";
         await resultHandler.calculateResults();
-        resultHandler.displayResults();
+        resultHandler.resultsZone.displayResults();
         document.getElementById("areas").setAttribute("class", "");
+        document.getElementById("general").setAttribute("class", "");
         document.getElementById("sections").setAttribute("class", "is-active");
       });
 
-    document.getElementById("zoom-map").addEventListener("click", function () {
-      resultHandler.zoomMap();
-    });
-    document
-      .getElementById("zoom-news-flow")
-      .addEventListener("click", function () {
-        resultHandler.zoomNewsFlow();
-      });
-    document
-      .getElementById("zoom-results")
-      .addEventListener("click", function () {
-        resultHandler.zoomResults();
-      });
-
     let radioButtons = document.getElementsByName("filter");
     for (var i = 0; i < radioButtons.length; i++) {
       radioButtons[i].addEventListener("click", async (e) => {
         await this.calculateResults();
-        this.displayResults();
+        this.resultsZone.displayResults();
+        this.resultsGeneral.displayRoundResults();
       });
     }
 
@@ -229,10 +155,10 @@ class ResultComponent {
             );
 
             if (resultHandler.zone === "areas")
-              resultHandler.displayZoneResults(area);
+              resultHandler.resultsZone.displayZoneResults(area);
             else if (resultHandler.zone === "sections") {
               resultHandler.refreshSections(area);
-              resultHandler.displayZoneResults(area.Sections[0]);
+              resultHandler.resultsZone.displayZoneResults(area.Sections[0]);
             }
           }
         } else if (event.target.id == "select-sections") {
@@ -242,145 +168,18 @@ class ResultComponent {
           let section = area.Sections.find(
             (section) => section.ID == event.target.value
           );
-          resultHandler.displayZoneResults(section);
+          resultHandler.resultsZone.displayZoneResults(section);
         }
       },
       false
     );
   }
 
-  zoomMap() {
-    let resultHandler = this;
-    document.getElementById("map-section").parentElement.className =
-      "column is-full";
-    document.getElementById("zoom-map").addEventListener("click", function () {
-      resultHandler.unZoom();
-    });
-  }
-
-  zoomNewsFlow() {
-    let resultHandler = this;
-    document.getElementById("news-flow-section").parentElement.className =
-      "column is-full";
-    document.getElementById("news-flow-section").style.height = "70vh";
-    document.getElementById("map-section").parentElement.className = "column";
-    document.getElementById("map-section").parentElement.style.display = "none";
-    document.getElementById("results-section").style.display = "none";
-    document
-      .getElementById("zoom-news-flow")
-      .addEventListener("click", function () {
-        resultHandler.unZoom();
-      });
-  }
-
-  zoomResults() {
-    let resultHandler = this;
-    document.getElementById("results-section").parentElement.className =
-      "column is-full";
-    document.getElementById("results-section").style.height = "70vh";
-    document.getElementById("map-section").parentElement.className = "column";
-    document.getElementById("map-section").parentElement.style.display = "none";
-    document.getElementById("news-flow-section").style.display = "none";
-    document
-      .getElementById("zoom-results")
-      .addEventListener("click", function () {
-        resultHandler.unZoom();
-      });
-    document.getElementById("zone-detaileds-results").style.display = "block";
-  }
-
-  unZoom() {
-    document.getElementById("map-section").parentElement.className =
-      "column is-half";
-    document.getElementById("news-flow-section").style.height = "45vh";
-    document.getElementById("results-section").style.height = "25vh";
-    document.getElementById("news-flow-section").parentElement.className =
-      "column is-half";
-    document.getElementById("map-section").parentElement.style.display =
-      "block";
-    document.getElementById("results-section").style.display = "block";
-    document.getElementById("news-flow-section").style.display = "block";
-    document.getElementById("zone-detaileds-results").style.display = "none";
-
-    this.handleDom();
-  }
-
   async calculateResults() {
     this.filter = document.querySelector('input[name="filter"]:checked').value;
     this.results = await this.calculator.calculateResults(this.filter);
   }
 
-  displayResults() {
-    document.getElementById("news-flow").innerHTML = "";
-    if (this.zone === "areas") {
-      this.displayFlowAreas();
-      this.displayAreasResults();
-    } else if (this.zone === "sections") {
-      this.displayFlowSections();
-      this.displaySectionsResults();
-    }
-    Scroller.scrollInit("news-flow");
-  }
-
-  async displayFlowAreas() {
-    this.results.areasResults.sort(function (a, b) {
-      return b.DateCompletion - a.DateCompletion;
-    });
-    for (let j in this.results.areasResults) {
-      let area = this.results.areasResults[j];
-      if (area.status === this.filter) {
-        document
-          .getElementById("news-flow")
-          .appendChild(this.resultFlowTemplate(area));
-
-        for (let i in area.candidateLists) {
-          let party = await this.PartyModel.getParty(
-            area.candidateLists[i].PartyID
-          );
-
-          document.getElementById(
-            "flow-content-" + area.ID
-          ).innerHTML += await this.progressBarTemplate(
-            area.candidateLists[i],
-            party.Color
-          );
-        }
-      }
-    }
-  }
-
-  async displayFlowSections() {
-    let sections = [];
-    this.results.areasResults.forEach((area) => {
-      sections = sections.concat(area.Sections);
-    });
-    sections.sort(function (a, b) {
-      return b.DateCompletion - a.DateCompletion;
-    });
-
-    for (let j in sections) {
-      let section = sections[j];
-      if (section.status === this.filter) {
-        document
-          .getElementById("news-flow")
-          .appendChild(this.resultFlowTemplate(section));
-
-        for (let i in section.candidateLists) {
-          let party = await this.PartyModel.getParty(
-            section.candidateLists[i].PartyID
-          );
-
-          document.getElementById(
-            "flow-content-" + section.ID
-          ).innerHTML += await this.progressBarTemplate(
-            section.candidateLists[i],
-            party.Color
-          );
-        }
-      }
-    }
-  }
-
   displayRoundResults() {
     document.getElementById(
       "detailed-results"
@@ -395,157 +194,6 @@ class ResultComponent {
     }
   }
 
-  displayAreasResults() {
-    let selectAreas = document.getElementById("select-areas");
-    document.getElementById("select-sections").parentNode.style.display =
-      "none";
-
-    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
-      selectAreas.remove(i);
-    }
-
-    this.results.areasResults.forEach((area) => {
-      let el = document.createElement("option");
-      el.textContent = area.Name;
-      el.value = area.ID;
-      selectAreas.appendChild(el);
-    });
-
-    this.displayZoneResults(this.results.areasResults[0]);
-  }
-
-  displaySectionsResults() {
-    let selectAreas = document.getElementById("select-areas");
-    document.getElementById("select-sections").parentNode.style.display =
-      "block";
-
-    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
-      selectAreas.remove(i);
-    }
-
-    this.results.areasResults.forEach((area) => {
-      let el = document.createElement("option");
-      el.textContent = area.Name;
-      el.value = area.ID;
-      selectAreas.appendChild(el);
-    });
-
-    this.refreshSections(this.results.areasResults[0]);
-
-    this.displayZoneResults(this.results.areasResults[0].Sections[0]);
-  }
-
-  async displayZoneResults(zone) {
-    if (zone.status !== this.filter) {
-      if (zone.status == "no_results") {
-        document.getElementById(
-          "zone-results"
-        ).innerHTML = this.showWarningResults(
-          "Aucun résultats n'ont étaient saisis sur cette zone"
-        );
-      } else if (zone.status == "incompleted") {
-        document.getElementById(
-          "zone-results"
-        ).innerHTML = this.showWarningResults(
-          "Les résultats pour cette zone ne sont pas complets"
-        );
-      } else if (zone.status == "not validated") {
-        document.getElementById(
-          "zone-results"
-        ).innerHTML = this.showWarningResults(
-          "Les résultats pour cette zone n'ont pas étaient validés"
-        );
-      }
-      document.getElementById("zone-detaileds-results").innerHTML = "";
-    } else {
-      document.getElementById("zone-results").innerHTML =
-        '<br/><h5 class="title is-5">Résultats</h5>';
-      for (let i in zone.candidateLists) {
-        let electedsNumber = null;
-        if (
-          this.zone === "areas" &&
-          zone.candidateLists[i].SeatsAttributed > 0 &&
-          zone.stats.PercentageConsiderated == 100
-        ) {
-          electedsNumber = zone.candidateLists[i].SeatsAttributed;
-        }
-        let party = await this.PartyModel.getParty(
-          zone.candidateLists[i].PartyID
-        );
-        document.getElementById(
-          "zone-results"
-        ).innerHTML += this.progressBarTemplate(
-          zone.candidateLists[i],
-          party.Color,
-          electedsNumber
-        );
-      }
-      this.displayZoneDetailedResults(zone);
-    }
-  }
-
-  async displayZoneDetailedResults(zone) {
-    document.getElementById("zone-detaileds-results").innerHTML =
-      '<br/><h5 class="title is-5">Statistiques</h5>';
-
-    if (this.filter === "partial")
-      document.getElementById(
-        "zone-detaileds-results"
-      ).innerHTML += this.progressBarTemplate(
-        {
-          Name: "Pourcentage de saisie",
-          Percentage: zone.stats.PercentageConsiderated,
-          VoiceNumber: null,
-        },
-        "grey",
-        null
-      );
-    document.getElementById(
-      "zone-detaileds-results"
-    ).innerHTML += this.progressBarTemplate(
-      {
-        Name: "Abstention",
-        Percentage: zone.stats.Abstention,
-        VoiceNumber: null,
-      },
-      "grey",
-      null
-    );
-    document.getElementById(
-      "zone-detaileds-results"
-    ).innerHTML += this.progressBarTemplate(
-      {
-        Name: "Votes blancs",
-        Percentage: zone.stats.BlankPercentage,
-        VoiceNumber: zone.stats.BlankVoiceNumber,
-      },
-      "grey",
-      null
-    );
-    document.getElementById(
-      "zone-detaileds-results"
-    ).innerHTML += this.progressBarTemplate(
-      {
-        Name: "Votes nuls",
-        Percentage: zone.stats.NullVotePercentage,
-        VoiceNumber: zone.stats.NullVoteVoiceNumber,
-      },
-      "grey",
-      null
-    );
-    if (this.zone === "areas" && zone.stats.PercentageConsiderated == 100) {
-      document.getElementById("zone-detaileds-results").innerHTML +=
-        '<br/><h5 class="title is-5">Élus</h5>';
-      for (let i in zone.Electeds) {
-        let candidateList = await this.CandidateListModel.getCandidateList(
-          zone.Electeds[i].CandidateListID
-        );
-        document.getElementById("zone-detaileds-results").innerHTML +=
-          zone.Electeds[i].FullName + " (" + candidateList.Name + ")<br/>";
-      }
-    }
-  }
-
   refreshSections(area) {
     let selectSections = document.getElementById("select-sections");
     selectSections.parentNode.style.display = "block";
diff --git a/web/components/visualization/results-zone.js b/web/components/visualization/results-zone.js
new file mode 100644
index 0000000000000000000000000000000000000000..6092a166e7edafe2d353fdb27deff63f562c35c8
--- /dev/null
+++ b/web/components/visualization/results-zone.js
@@ -0,0 +1,462 @@
+// Imports
+import * as Auth from "/services/auth/auth.js";
+import * as results from "/services/election/calculate-election-generic.js";
+import * as PartyModel from "/services/model/party-model.js";
+import * as CandidateListModel from "/services/model/candidateList-model.js";
+import * as AreaModel from "/services/model/area-model.js";
+import * as Scroller from "/services/common/scroller.js";
+
+export async function mount(where, parent) {
+  const resultZoneComponent = new ResultZoneComponent(parent);
+  await resultZoneComponent.mount(where);
+  return resultZoneComponent;
+}
+
+class ResultZoneComponent {
+  constructor(parent) {
+    this.parent = parent;
+    this.PartyModel = PartyModel.getPartyModel();
+    this.CandidateListModel = CandidateListModel.getCandidateListModel();
+    this.AreaModel = AreaModel.getAreaModel();
+  }
+
+  async mount(where) {
+    this.PartyModel.current_user = await Auth.GetUser();
+    this.CandidateListModel.current_user = await Auth.GetUser();
+    this.AreaModel.current_user = await Auth.GetUser();
+    const mountpoint = where;
+    document.getElementById(mountpoint).innerHTML = /* HTML */ `
+      <div class="column is-half">
+        <div id="map-section" class="card-no-hover">
+          <header class="card-header">
+            <p class="card-header-title">
+              Carte
+            </p>
+            <button id="zoom-map" class="button is-success">
+              <span class="icon is-small">
+                <i class="fas fa-search"></i>
+              </span>
+            </button>
+          </header>
+          <div class="card-content">
+            <div id="round-list" class="content">
+              La carte du tour
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="column">
+        <div id="news-flow-section" class="card-no-hover">
+          <header class="card-header">
+            <p class="card-header-title">
+              Actualités
+            </p>
+            <label class="checkbox">
+              <input id="auto-scroll" type="checkbox" checked />
+              Défilement automatique &nbsp
+            </label>
+            <button id="zoom-news-flow" class="button is-success">
+              <span class="icon is-small">
+                <i class="fas fa-search"></i>
+              </span>
+            </button>
+          </header>
+          <div class="card-content">
+            <div id="news-flow" class="content">
+              Flux d'actualité
+            </div>
+          </div>
+        </div>
+        <div id="results-section" class="card-no-hover" ">
+        <header class="card-header">
+          <p class="card-header-title">
+            Résultats
+          </p>
+          <button id="zoom-results" class="button is-success">
+            <span class="icon is-small">
+              <i class="fas fa-search"></i>
+            </span>
+          </button>
+        </header>
+        <div class="card-content">
+          <div id="detailed-results" class="content">
+            <div class="control select">
+              <select id="select-areas" class="input"></select>
+            </div>
+            <div class="control select">
+              <select id="select-sections" class="input"></select>
+            </div>
+            <div id="zone-results"></div>
+            <div id="zone-detaileds-results" style="display:none"></div>
+          </div>
+        </div>
+      </div>
+    `;
+    this.handleDom();
+  }
+
+  resultFlowTemplate(zone) {
+    let html = document.createElement("div");
+    html.classList = "card-list card-no-hover";
+    html.innerHTML = /* HTML */ `
+      <div class="card-content">
+        <div id="flow-content-${zone.ID}" class="content">
+          <h5 class="title is-5">${zone.Name}</h5>
+        </div>
+      </div>
+    `;
+    html.addEventListener("click", async () => {
+      if (this.parent.zone == "sections") {
+        let area = await this.AreaModel.getArea(zone.AreaID);
+        this.parent.refreshSections(area);
+        document.getElementById("select-sections").value = zone.ID;
+        document.getElementById("select-areas").value = zone.AreaID;
+      } else {
+        document.getElementById("select-areas").value = zone.ID;
+      }
+      this.displayZoneResults(zone);
+    });
+    return html;
+  }
+
+  handleDom() {
+    let resultHandler = this;
+    document.getElementById("zoom-map").addEventListener("click", function () {
+      resultHandler.zoomMap();
+    });
+    document
+      .getElementById("zoom-news-flow")
+      .addEventListener("click", function () {
+        resultHandler.zoomNewsFlow();
+      });
+    document
+      .getElementById("zoom-results")
+      .addEventListener("click", function () {
+        resultHandler.zoomResults();
+      });
+
+    let radioButtons = document.getElementsByName("filter");
+    for (var i = 0; i < radioButtons.length; i++) {
+      radioButtons[i].addEventListener("click", async (e) => {
+        await this.parent.calculateResults();
+        this.displayResults();
+      });
+    }
+
+    document.addEventListener(
+      "input",
+      function __listener(event) {
+        if (event.target.id == "select-areas") {
+          if (event.target.value != 0) {
+            let area = resultHandler.results.areasResults.find(
+              (area) => area.ID == event.target.value
+            );
+
+            if (resultHandler.zone === "areas")
+              resultHandler.displayZoneResults(area);
+            else if (resultHandler.zone === "sections") {
+              resultHandler.refreshSections(area);
+              resultHandler.displayZoneResults(area.Sections[0]);
+            }
+          }
+        } else if (event.target.id == "select-sections") {
+          let area = resultHandler.results.areasResults.find(
+            (area) => area.ID == document.getElementById("select-areas").value
+          );
+          let section = area.Sections.find(
+            (section) => section.ID == event.target.value
+          );
+          resultHandler.displayZoneResults(section);
+        }
+      },
+      false
+    );
+  }
+
+  zoomMap() {
+    let resultHandler = this;
+    document.getElementById("map-section").parentElement.className =
+      "column is-full";
+    document.getElementById("zoom-map").addEventListener("click", function () {
+      resultHandler.unZoom();
+    });
+  }
+
+  zoomNewsFlow() {
+    let resultHandler = this;
+    document.getElementById("news-flow-section").parentElement.className =
+      "column is-full";
+    document.getElementById("news-flow-section").style.height = "70vh";
+    document.getElementById("map-section").parentElement.className = "column";
+    document.getElementById("map-section").parentElement.style.display = "none";
+    document.getElementById("results-section").style.display = "none";
+    document
+      .getElementById("zoom-news-flow")
+      .addEventListener("click", function () {
+        resultHandler.unZoom();
+      });
+  }
+
+  zoomResults() {
+    let resultHandler = this;
+    document.getElementById("results-section").parentElement.className =
+      "column is-full";
+    document.getElementById("results-section").style.height = "70vh";
+    document.getElementById("map-section").parentElement.className = "column";
+    document.getElementById("map-section").parentElement.style.display = "none";
+    document.getElementById("news-flow-section").style.display = "none";
+    document
+      .getElementById("zoom-results")
+      .addEventListener("click", function () {
+        resultHandler.unZoom();
+      });
+    document.getElementById("zone-detaileds-results").style.display = "block";
+  }
+
+  unZoom() {
+    document.getElementById("map-section").parentElement.className =
+      "column is-half";
+    document.getElementById("news-flow-section").style.height = "45vh";
+    document.getElementById("results-section").style.height = "25vh";
+    document.getElementById("news-flow-section").parentElement.className =
+      "column is-half";
+    document.getElementById("map-section").parentElement.style.display =
+      "block";
+    document.getElementById("results-section").style.display = "block";
+    document.getElementById("news-flow-section").style.display = "block";
+    document.getElementById("zone-detaileds-results").style.display = "none";
+
+    this.handleDom();
+  }
+
+  displayResults() {
+    document.getElementById("news-flow").innerHTML = "";
+    if (this.parent.zone === "areas") {
+      this.displayFlowAreas();
+      this.displayAreasResults();
+    } else if (this.parent.zone === "sections") {
+      this.displayFlowSections();
+      this.displaySectionsResults();
+    }
+    let scroller = Scroller.scrollInit("news-flow");
+    document.getElementById("auto-scroll").addEventListener("change", () => {
+      scroller.switch();
+    });
+  }
+
+  async displayFlowAreas() {
+    this.parent.results.areasResults.sort(function (a, b) {
+      return b.DateCompletion - a.DateCompletion;
+    });
+    for (let j in this.parent.results.areasResults) {
+      let area = this.parent.results.areasResults[j];
+      if (area.status === this.parent.filter) {
+        document
+          .getElementById("news-flow")
+          .appendChild(this.resultFlowTemplate(area));
+
+        for (let i in area.candidateLists) {
+          let party = await this.PartyModel.getParty(
+            area.candidateLists[i].PartyID
+          );
+
+          document.getElementById(
+            "flow-content-" + area.ID
+          ).innerHTML += await this.parent.progressBarTemplate(
+            area.candidateLists[i],
+            party.Color
+          );
+        }
+      }
+    }
+  }
+
+  async displayFlowSections() {
+    let sections = [];
+    this.parent.results.areasResults.forEach((area) => {
+      sections = sections.concat(area.Sections);
+    });
+    sections.sort(function (a, b) {
+      return b.DateCompletion - a.DateCompletion;
+    });
+
+    for (let j in sections) {
+      let section = sections[j];
+      if (section.status === this.parent.filter) {
+        document
+          .getElementById("news-flow")
+          .appendChild(this.resultFlowTemplate(section));
+
+        for (let i in section.candidateLists) {
+          let party = await this.PartyModel.getParty(
+            section.candidateLists[i].PartyID
+          );
+
+          document.getElementById(
+            "flow-content-" + section.ID
+          ).innerHTML += await this.parent.progressBarTemplate(
+            section.candidateLists[i],
+            party.Color
+          );
+        }
+      }
+    }
+  }
+
+  displayAreasResults() {
+    let selectAreas = document.getElementById("select-areas");
+    document.getElementById("select-sections").parentNode.style.display =
+      "none";
+
+    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
+      selectAreas.remove(i);
+    }
+
+    this.parent.results.areasResults.forEach((area) => {
+      let el = document.createElement("option");
+      el.textContent = area.Name;
+      el.value = area.ID;
+      selectAreas.appendChild(el);
+    });
+
+    this.displayZoneResults(this.parent.results.areasResults[0]);
+  }
+
+  displaySectionsResults() {
+    let selectAreas = document.getElementById("select-areas");
+    document.getElementById("select-sections").parentNode.style.display =
+      "block";
+
+    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
+      selectAreas.remove(i);
+    }
+
+    this.parent.results.areasResults.forEach((area) => {
+      let el = document.createElement("option");
+      el.textContent = area.Name;
+      el.value = area.ID;
+      selectAreas.appendChild(el);
+    });
+
+    this.parent.refreshSections(this.parent.results.areasResults[0]);
+
+    this.displayZoneResults(this.parent.results.areasResults[0].Sections[0]);
+  }
+
+  async displayZoneResults(zone) {
+    if (zone.status !== this.parent.filter) {
+      if (zone.status == "no_results") {
+        document.getElementById(
+          "zone-results"
+        ).innerHTML = this.parent.showWarningResults(
+          "Aucun résultats n'ont étaient saisis sur cette zone"
+        );
+      } else if (zone.status == "incompleted") {
+        document.getElementById(
+          "zone-results"
+        ).innerHTML = this.parent.showWarningResults(
+          "Les résultats pour cette zone ne sont pas complets"
+        );
+      } else if (zone.status == "not validated") {
+        document.getElementById(
+          "zone-results"
+        ).innerHTML = this.parent.showWarningResults(
+          "Les résultats pour cette zone n'ont pas étaient validés"
+        );
+      }
+      document.getElementById("zone-detaileds-results").innerHTML = "";
+    } else {
+      document.getElementById("zone-results").innerHTML =
+        '<br/><h5 class="title is-5">Résultats</h5>';
+      for (let i in zone.candidateLists) {
+        let electedsNumber = null;
+        if (
+          this.parent.zone === "areas" &&
+          zone.candidateLists[i].SeatsAttributed > 0 &&
+          zone.stats.PercentageConsiderated == 100
+        ) {
+          electedsNumber = zone.candidateLists[i].SeatsAttributed;
+        }
+        let party = await this.PartyModel.getParty(
+          zone.candidateLists[i].PartyID
+        );
+        document.getElementById(
+          "zone-results"
+        ).innerHTML += this.parent.progressBarTemplate(
+          zone.candidateLists[i],
+          party.Color,
+          electedsNumber
+        );
+      }
+      this.displayZoneDetailedResults(zone);
+    }
+    document.getElementById(
+      "detailed-results"
+    ).scrollTop = document.getElementById("zone-results").offsetTop;
+  }
+
+  async displayZoneDetailedResults(zone) {
+    document.getElementById("zone-detaileds-results").innerHTML =
+      '<br/><h5 class="title is-5">Statistiques</h5>';
+
+    if (this.parent.filter === "partial")
+      document.getElementById(
+        "zone-detaileds-results"
+      ).innerHTML += this.parent.progressBarTemplate(
+        {
+          Name: "Pourcentage de saisie",
+          Percentage: zone.stats.PercentageConsiderated,
+          VoiceNumber: null,
+        },
+        "grey",
+        null
+      );
+    document.getElementById(
+      "zone-detaileds-results"
+    ).innerHTML += this.parent.progressBarTemplate(
+      {
+        Name: "Abstention",
+        Percentage: zone.stats.Abstention,
+        VoiceNumber: null,
+      },
+      "grey",
+      null
+    );
+    document.getElementById(
+      "zone-detaileds-results"
+    ).innerHTML += this.parent.progressBarTemplate(
+      {
+        Name: "Votes blancs",
+        Percentage: zone.stats.BlankPercentage,
+        VoiceNumber: zone.stats.BlankVoiceNumber,
+      },
+      "grey",
+      null
+    );
+    document.getElementById(
+      "zone-detaileds-results"
+    ).innerHTML += this.parent.progressBarTemplate(
+      {
+        Name: "Votes nuls",
+        Percentage: zone.stats.NullVotePercentage,
+        VoiceNumber: zone.stats.NullVoteVoiceNumber,
+      },
+      "grey",
+      null
+    );
+    if (
+      this.parent.zone === "areas" &&
+      zone.stats.PercentageConsiderated == 100
+    ) {
+      document.getElementById("zone-detaileds-results").innerHTML +=
+        '<br/><h5 class="title is-5">Élus</h5>';
+      for (let i in zone.Electeds) {
+        let candidateList = await this.CandidateListModel.getCandidateList(
+          zone.Electeds[i].CandidateListID
+        );
+        document.getElementById("zone-detaileds-results").innerHTML +=
+          zone.Electeds[i].FullName + " (" + candidateList.Name + ")<br/>";
+      }
+    }
+  }
+}
diff --git a/web/services/common/scroller.js b/web/services/common/scroller.js
index 1db60448ef17116231fccdd282d8942f5c5f3800..7274c566fcf406bead57ea778ed397d5130088e6 100644
--- a/web/services/common/scroller.js
+++ b/web/services/common/scroller.js
@@ -1,5 +1,6 @@
 export function scrollInit(divName) {
   let scroller = new Scroller(divName);
+  return scroller;
 }
 
 class Scroller {
@@ -12,11 +13,12 @@ class Scroller {
 
     this.scrollDiv();
     this.elmnt.addEventListener("mouseover", () => {
-      this.pauseScroll();
+      if (this.autoScroll) this.pauseScroll();
     });
     this.elmnt.addEventListener("mouseout", () => {
-      this.resumeScroll();
+      if (this.autoScroll) this.resumeScroll();
     });
+    this.autoScroll = true;
   }
 
   scrollDiv() {
@@ -45,4 +47,14 @@ class Scroller {
   resumeScroll() {
     this.scrollDiv();
   }
+
+  switch() {
+    if (this.autoScroll) {
+      this.pauseScroll();
+      this.autoScroll = false;
+    } else {
+      this.resumeScroll();
+      this.autoScroll = true;
+    }
+  }
 }
diff --git a/web/services/election/calculate-election-generic.js b/web/services/election/calculate-election-generic.js
index eed1675625e11f967b3d2e4d12defc0d8f5c9357..02bfe178b721c9f1a09a8b0f06ed5a7b097144c5 100644
--- a/web/services/election/calculate-election-generic.js
+++ b/web/services/election/calculate-election-generic.js
@@ -362,7 +362,6 @@ class DirectMetropolitanCalculator {
 
     // order candidates by rank and remove refused or removed candidates
     area.candidateLists.forEach((candidateList) => {
-      candidateList.seatNumber = 0;
       candidateList.Candidates.sort(function (a, b) {
         return a.Rank - b.Rank;
       });
diff --git a/web/style.css b/web/style.css
index eaece0420e7cb78b2920e31723668cc8e88014ec..15fbb41128a3addee01bbbc0b65c15ef897121c1 100644
--- a/web/style.css
+++ b/web/style.css
@@ -199,3 +199,8 @@ select {
 .is-warning .message-body {
   border: solid;
 }
+
+#round-results,
+#round-detaileds-results {
+  padding: 20px;
+}