Skip to content
Snippets Groups Projects
results-map.js 4.94 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Imports
    import * as PartyModel from "/services/model/party-model.js";
    import * as AreaModel from "/services/model/area-model.js";
    
    import * as ElectionModel from "/services/model/election-model.js";
    
    
    export async function mount(parent) {
      const mapComponent = new MapComponent(parent);
      return mapComponent;
    }
    
    class MapComponent {
      constructor(parent) {
        this.parent = parent;
        this.PartyModel = PartyModel.getPartyModel();
        this.AreaModel = AreaModel.getAreaModel();
    
        this.ElectionModel = ElectionModel.getElectionModel();
    
      }
    
      async displayMapAreas() {
    
        let election = await this.ElectionModel.getElection(
          this.parent.parent.round.ElectionID
        );
        await this.initMap(
          election.MapAreaFile.replace("web/", ""),
          this.colorAreas
        );
    
      }
    
      async displayMapSections() {
    
        let election = await this.ElectionModel.getElection(
          this.parent.parent.round.ElectionID
        );
        await this.initMap(election.MapSectionFile.replace("web/", ""), this.colorSections);
    
      }
    
      async initMap(mapFile, colorationFunction) {
        // Create datasource
        const request = new XMLHttpRequest();
        request.open("GET", mapFile, false);
        request.send(null);
    
    Alexis POYEN's avatar
    Alexis POYEN committed
        this.dataSource = JSON.parse(request.responseText);
    
    Alexis POYEN's avatar
    Alexis POYEN committed
        // Add parties and colors to datasource
        this.dataSource = await colorationFunction(this, this.dataSource);
    
    
        document.getElementById("map-component").innerHTML = "";
        // Create a popup, but don't add it to the map yet.
        let popup = new mapboxgl.Popup({
          closeButton: false,
        });
    
    
    Alexis POYEN's avatar
    Alexis POYEN committed
        this.map = new mapboxgl.Map({
    
          container: "map-component", // container id
          style: "/assets/mapbox/vector.json", // stylesheet location
          center: [4.9, 45.75], // starting position [lng, lat]
    
          zoom: 9.5, // starting zoom
    
    Alexis POYEN's avatar
    Alexis POYEN committed
        this.map.on("load", () => {
          this.map.addSource("data-source", {
            type: "geojson",
            data: this.dataSource,
          });
    
          this.map.addLayer(
            {
              id: "winners-fills",
              type: "fill",
              source: "data-source",
              layout: {},
              paint: {
                "fill-color": { type: "identity", property: "color" },
                "fill-opacity": 0.5,
                "fill-outline-color": "black",
              },
            },
            "place_label_city"
          );
    
          this.map.addLayer({
            id: "winners-names",
            type: "symbol",
            source: "data-source",
            filter: ["all"],
            layout: {
              "text-field": "{partyName}",
              "text-font": ["titiliumweb-regular"],
            },
          });
        });
    
        this.map.on("mousemove", "winners-fills", (e) => {
          // Change the cursor style as a UI indicator.
          this.map.getCanvas().style.cursor = "pointer";
    
          // Single out the first found feature.
          const feature = e.features[0];
    
          if (e.features.length > 0) {
            // Display a popup with the name of the county
            popup
              .setLngLat(e.lngLat)
              .setText(
                `${feature.properties.Name} : ${
                  feature.properties.partyName == undefined
                    ? "aucun"
                    : feature.properties.partyName
                }`
              )
              .addTo(this.map);
          }
        });
    
        this.map.on("mouseleave", "winners-fills", () => {
          this.map.getCanvas().style.cursor = "";
          popup.remove();
        });
    
    Alexis POYEN's avatar
    Alexis POYEN committed
      async colorAreas(mapHandler, dataSource) {
        for (let area of mapHandler.parent.parent.results.areasResults) {
          if (area.status == mapHandler.parent.parent.filter) {
            let party = await mapHandler.PartyModel.getParty(
              area.candidateLists[0].PartyID
            );
            dataSource = mapHandler.colorTiles(
              dataSource,
              parseInt(area.MapID),
              party.Name,
              party.Color
            );
          } else {
            dataSource = mapHandler.colorTiles(dataSource, area.MapID, "", "");
          }
        }
        return dataSource;
      }
    
    Alexis POYEN's avatar
    Alexis POYEN committed
      async colorSections(mapHandler, dataSource) {
        mapHandler.parent.parent.results.areasResults.forEach(async (area) => {
          for (let section of area.Sections) {
            if (section.status == mapHandler.parent.parent.filter) {
              let party = await mapHandler.PartyModel.getParty(
                section.candidateLists[0].PartyID
              );
              dataSource = mapHandler.colorTiles(
                dataSource,
                parseInt(section.MapID),
                party.Name,
                party.Color
              );
            } else {
              dataSource = mapHandler.colorTiles(dataSource, section.MapID, "", "");
            }
          }
        });
        return dataSource;
      }
    
      colorTiles(dataSource, gid, partyName, color) {
        for (let f of dataSource.features) {
          if (f.properties.nomcircons) f.properties.Name = f.properties.nomcircons;
          if (f.properties["Nom réduit"])
            f.properties.Name = f.properties["Nom réduit"];
          if (f.properties.gid === gid) {
            f.properties.partyName = partyName;
            f.properties.color = color;
    
            break;
          }
        }
        return dataSource;
      }