"use strict";
// HAMBURGERMENY
//Visar meny vid klick av hamburgerikon i tablet och desktop
//Hämtar element för hamburge-ikonen
const hamburger = document.querySelector('.hamburger');
//Hämtar element för menynlistan i navbaren
const menu = document.querySelector('.navbar ul');
//Eventlyssnare som lyssnar på klick av hamburgaren
//Arrow-funktion som körs när det klickas
hamburger.addEventListener('click',
//Arrow-funktion som körs när det klickas
() => {
//Classlist hanterar klasser som finns i elementet
//Toggle växlar synligheten beroende på om elementet har klassen show
//CSS styr ul med "show" och om och hur menyn ska visas
menu.classList.toggle('show');
});
///////////////////////////////////////////////////////////////////////////////////////
// ANIMATION
//Trigger för animation på knapp (animation.html)
//Hämtar id för knapp
const animatedButton = document.querySelector('.animatedbutton');
//Händelselyssnare. Lyssnar på klick av knapp
if (animatedButton) {
animatedButton.addEventListener('click', () => {
animatedButton.classList.add('clicked');
});
}
/////////////////////////////////////////////////////////////////////////////////////
// DIAGRAM (APEX)
import ApexCharts from "apexcharts";
/**
* Globala variabler för mest sökta kurser och program
* topCourses används för stapeldiagrammet
* topPrograms används för cirkeldiagrammet
*
* @typedef {Object} topResult
* @property {string} name - Namn på kurs/program
* @property {number} applicants - Antal sökande
*/
/**
* Array med de mest sökta kurserna (för stapeldiagrammet)
* @type {topResult[]} */
let topCourses = [];
/**
* Array med de mest sökta programmen (för cirkeldiagrammet)
* @type {topResult[]} */
let topPrograms = [];
/**
* Tar fram statistik över mest sökta kurser och program
* Funktion hämtar statistik från en extern källa. JSOn-fil.
* Sorterar kurser och program efter antal sökande
* Renderar diagram med Apexcharts.
*
* @returns {void} Funktion returnerar inget värde men uppdaterar sidan med stapel och cirkeldiagram.
*/
async function getStatistics() {
try {
//Väntar in svar från url med kurser
const response = await fetch(
"https://mallarmiun.github.io/Frontend-baserad-webbutveckling/Moment%205%20-%20Dynamiska%20webbplatser/statistik_sokande_ht25.json"
);
/**
* Variabel för att spara svar från fetch-anrop i JSON-format
* statistics
*
* @type {object[]}
*/
const statistics = await response.json();
/**
* Variabler för arrayer att samla info om kurser och program
* Data som används för att filtera fram topresultaten
* courseStat för kursstatistik
* programStat för programstatistik
*
* @typedef {Object} allStat
* @property {string} name - Namn på kurs/program
* @property {number} applicants - Antal sökande
*/
/**
* Array med statistik över kurser
* @type {allStat[]} */
const courseStat = [];
/**
* Array med statistik över kurser
* @type {allStat[]} */
const programStat = [];
for (let i = 0; i < statistics.length; i++) {
if (statistics[i].type === "Kurs") {
//pushar objekt med kursstatistik till array
courseStat.push({
name: statistics[i].name,
applicants: Number(statistics[i].applicantsTotal.trim())
});
} else if (statistics[i].type === "Program") {
//Pushar objekt med programstatistik till array
programStat.push({
name: statistics[i].name,
applicants: Number(statistics[i].applicantsTotal.trim())
});
}
}
//Sortering av toppval
//Sorterar i mest sökande kurser först
courseStat.sort((a, b) => b.applicants - a.applicants);
//Plockar ut de 6 första och lägger i array
topCourses = courseStat.slice(0, 6);
//...program
programStat.sort((a, b) => b.applicants - a.applicants);
//Lägger till top fem i array
topPrograms = programStat.slice(0, 5);
//RITAR UT DIAGRAM
/**
* Variabel för stapeldiagram
* @type {HTMLElement}
*/
const chartOne = document.querySelector(".barchart");
if (chartOne) {
let options = {
chart: {
type: 'bar',
height: 700,
width: '100%',
toolbar: {
show: false
}
},
//plockar ut värden från objektet i topCourses(map)
series: [{
name: 'Antal sökande',
data: topCourses.map(course => course.applicants)
}],
xaxis: {
categories: topCourses.map(course => course.name)
},
colors: ['#621694'],
tooltip: {
theme: 'dark'
}
};
let chart = new ApexCharts(chartOne, options);
chart.render();
}
/**
* Variabel för cirkeldiagram
* @type {HTMLElement}
*/
const chartTwo = document.querySelector(".piechart");
if (chartTwo) {
let options = {
chart: {
type: 'pie',
height: 500,
},
//plockar ut värden från objektet i topPrograms(map)
series: topPrograms.map(programs => programs.applicants),
labels: topPrograms.map(programs => programs.name),
colors: ['#800080', '#FF69B4', '#9233ff', '#340d7e', '#b936da']
}
let chart = new ApexCharts(chartTwo, options);
chart.render();
}
//Felmeddelande som visas om datan inte läses in korrekt. eller annat fel
} catch (error) {
console.error("Fel vid hämtning av statistik", error);
}
}
//Kallar på funktionen
getStatistics();
////////////////////////////////////////////////////////////////////////////
// KARTA //
/**
* Funktion tillåter användare att söka plats som visas på kartan.
*
* @param {string} location - Namn på plats som söks
* @returns {void} Returnerar inget värde, men uppdaterar kartan med sökt plats
*/
async function searchLocation(location) {
// Url till Nominatim. Parameter q tillåter fri text. Tar värdet av sökinput. encodeURI tillåter mellanslag och specialtecken
const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(location)}&format=json&`;
try {
// Hämtar svar från api
const response = await fetch(url);
/**
* Variabel för array att samla data om sökt plats från hämtad data i JSON-format
*
* @type {object[]}
*/
const locationInfo = await response.json();
/* If-sats som kontrollerar värdena från locationInfo
parseFloat gör om textstängarna till "flytande" nummer
*/
if (locationInfo.length > 0) {
/**
* Variabel som spar data från första träffen i arrayen från locationInfo och hämtar dess kordinater
* latitude och longitude
*
* @type {number}
*/
const latitude = parseFloat(locationInfo[0].lat);
const longitude = parseFloat(locationInfo[0].lon);
//bbox zoomar in på platsen och visar minsta och max lat och long för platsen som ska visas
const bbox = `${longitude - 0.02},${latitude - 0.02},${longitude + 0.02},${latitude + 0.02}`;
//Url som visar kartan i iframe från openstreetmap. Med bbox som inzoomat, och lat och long där markör sitter
document.querySelector("#map").src = `https://www.openstreetmap.org/export/embed.html?bbox=${bbox}&marker=${latitude},${longitude}`;
//Om plats inte kan hittas på kartan (visas för användare)
} else {
alert("Platsen kunde inte hittas.");
}
//Om något blir fel vid hämtning av datan
} catch (error) {
console.error("Fel vid hämtning av plats", error);
}
}
/**
* Hanterar sökfunktionen i sökformulätet
*
* @param {SubmitEvent} showLocation - Händelsen som triggas vid klick av sök.
* @returns {void} Returnerar inget värde. Stoppar sidan från att laddas om och kallar på searchLocation (visar plats på karta).
*/
//Eventlyssnare för vad som händer vid inmatning och sök i formuläret
document.querySelector("#searchinput").addEventListener("submit", function (showLocation) {
// Gör så att sidan inte laddas om vid sök
showLocation.preventDefault();
// Hämtar värdet från inputfältet
const location = document.querySelector("#search").value;
// Kallar på funktionen
searchLocation(location);
});