Skip to content

βœ… Final Template Code

index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello World with MapLibreGl</title>
        <!-- hint: remember to change your page title! -->
        <meta charset="utf-8" />
        <link rel="shortcut icon" href="#">
        <link rel="stylesheet" href="styles/style.css">

        <!-- MapLibreGL's css-->
        <link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" />

        <!-- MapLibreGL's JavaScript-->
        <script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
    </head>

    <body>
        <header>
            COVID Vaccination Stories
            <a href="https://docs.google.com/forms/d/e/1FAIpQLSfcElv5dlXInR7XHQz27_OcYJlWcIUr-GBbc-ocefWlGd1uXg/viewform?embedded=true" target="_blank">
                <button id="surveyButton">Take the Survey</button>
            </a>
        </header>

        <main>
            <div class="portfolio">
                <div id="contents">
                    <div id="legend"></div>
                </div>

            </div>
            <div id="map"></div>
        </main>
        <div id="footer">
            Copyright(2024)
        </div>
        <script src="js/init.js"></script>
    </body>
</html>
js/init.js
let mapOptions = {'centerLngLat': [-118.444,34.0709],'startingZoomLevel':5}

const map = new maplibregl.Map({
    container: 'map',
    style: 'https://api.maptiler.com/maps/streets-v2-light/style.json?key=wsyYBQjqRwKnNsZrtci1',
    center: mapOptions.centerLngLat,
    zoom: mapOptions.startingZoomLevel
});

function addMarker(data){
    let longitude = data['lng']
    let latitude = data['lat'];
    let vaccinationLocation = data['Where did you get vaccinated?'];
    let homeZipcode = data['What zip code do you live in?'];
    let vaccinationStatus = data['Have you been vaccinated?']
    let category = vaccinationStatus == "Yes" ? "vaccinated" : "notVaccinated";
    let popup_message;
    if (vaccinationStatus == "Yes"){
        popup_message = `<h2>Vaccinated</h2> <h3>Location: ${vaccinationLocation}</h3> <p>Zip Code: ${homeZipcode}</p>`
    }
    else{
        popup_message = `<h2>Not Vaccinated</h2><p>Zip Code: ${homeZipcode}</p>`
    }

    const newMarkerElement = document.createElement('div');


    newMarkerElement.className = `marker marker-${category}`;


    new maplibregl.Marker({element:newMarkerElement})
        .setLngLat([longitude, latitude])
        .setPopup(new maplibregl.Popup()
            .setHTML(popup_message))
        .addTo(map)
    createButtons(latitude,longitude,vaccinationLocation);
}

function createButtons(lat,lng,title){
    if (!title){
        return;
    }
    const newButton = document.createElement("button");
    newButton.id = "button"+title; 
    newButton.innerHTML = title;
    newButton.setAttribute("lat",lat);
    newButton.setAttribute("lng",lng);
    newButton.addEventListener('click', function(){
        map.flyTo({
            center: [lng,lat],
        })
    })
    document.getElementById("contents").appendChild(newButton);
}

const dataUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vSNq8_prhrSwK3CnY2pPptqMyGvc23Ckc5MCuGMMKljW-dDy6yq6j7XAT4m6GG69CISbD6kfBF0-ypS/pub?output=csv"

map.on('load', function() {
    createFilterUI();
    Papa.parse(dataUrl, {
        download: true,
        header: true,
        complete: function(results) {
            processData(results.data);
        }
    });
});

function processData(results){
    console.log(results) //for debugging: this can help us see if the results are what we want
    results.forEach(feature => {
        addMarker(feature);
    });
};

function createCheckboxForCategory(category, filterGroup) {
    const container = document.createElement('div');
    container.style.display = 'grid';
    container.style.gridTemplateColumns = 'auto auto 1fr';
    container.style.alignItems = 'center';
    container.style.gap = '8px';

    const input = document.createElement('input');
    input.type = 'checkbox';
    input.id = category;
    input.checked = true;

    const label = document.createElement('label');
    label.setAttribute('for', category);
    label.textContent = category;

    const markerLegend = document.createElement('div');
    markerLegend.className = `marker marker-${category}`;

    container.appendChild(input);
    container.appendChild(label);
    container.prepend(markerLegend);

    filterGroup.appendChild(container);

    input.addEventListener('change', function(event) {
        toggleMarkersVisibility(category, event.target.checked);
    });
}

function createFilterUI() {
    const categories = ['vaccinated', 'notVaccinated'];
    const filterGroup = document.getElementById('filter-group') || document.createElement('div');
    filterGroup.setAttribute('id', 'filter-group');
    filterGroup.className = 'filter-group';

    document.getElementById("legend").appendChild(filterGroup);

    categories.forEach(category => {
        createCheckboxForCategory(category, filterGroup);
    });
}

function toggleMarkersVisibility(category, isVisible) {
    const markers = document.querySelectorAll(`.marker-${category}`);
    markers.forEach(marker => {
        marker.style.display = isVisible ? '' : 'none';
    });
}
css/styles.css
* {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}


html {
    background-color: aqua;
}

html, body {
    height: 80vh;
    padding: 1rem;
    box-sizing: border-box;
}

body {
    display: grid;
    grid-template-areas: 
        "header"
        "main"
        "footer";
    grid-template-rows: auto 1fr auto;
}

main {
    display: grid;
    grid-template-areas:
        "portfolio map";
    grid-template-columns: 1fr 1fr;
}

header { 
    grid-area: header;
}

main { 
    grid-area: main;
}

.portfolio {
    grid-area: portfolio;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}


#map { 
    grid-area: map;
    height: 80vh;
}

#footer {
    grid-area: footer;
    padding: 5px;
    background-color: #4677a0;
    color: #fff;
    text-align: center;
}

.marker-vaccinated, .marker-notVaccinated {
    width: 30px;
    height: 30px;
    border-radius: 50%;
}

.marker-vaccinated{
    background-color: green;
}

.marker-notVaccinated {
    background-color: #ff0000;
}

#vaccinated:checked + label {
    color: green;
}

#notVaccinated:checked + label {
    color: red;
}