aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorJakob Stendahl <jakobste@uio.no>2020-10-13 20:28:52 +0200
committerJakob Stendahl <jakobste@uio.no>2020-10-13 20:28:52 +0200
commite53bddfc71d70eb9f2b7a2910b4b191bc43088ab (patch)
tree6074f957be167995845588352ce4108b9759fa00 /src/components
downloadAurora-data-e53bddfc71d70eb9f2b7a2910b4b191bc43088ab.tar.gz
Aurora-data-e53bddfc71d70eb9f2b7a2910b4b191bc43088ab.zip
First commit
Diffstat (limited to 'src/components')
-rw-r--r--src/components/Nav.svelte60
-rw-r--r--src/components/PredictedSpaceWeather.svelte174
-rw-r--r--src/components/PredictedSpaceWeatherThing.svelte64
-rw-r--r--src/components/WeatherCurrent.svelte210
4 files changed, 508 insertions, 0 deletions
diff --git a/src/components/Nav.svelte b/src/components/Nav.svelte
new file mode 100644
index 0000000..3240ecf
--- /dev/null
+++ b/src/components/Nav.svelte
@@ -0,0 +1,60 @@
+<script lang="ts">
+ export let segment: string;
+</script>
+
+<style>
+ nav {
+ border-bottom: 1px solid rgba(255,62,0,0.1);
+ font-weight: 300;
+ padding: 0 1em;
+ }
+
+ ul {
+ margin: 0;
+ padding: 0;
+ }
+
+ /* clearfix */
+ ul::after {
+ content: '';
+ display: block;
+ clear: both;
+ }
+
+ li {
+ display: block;
+ float: left;
+ }
+
+ [aria-current] {
+ position: relative;
+ display: inline-block;
+ }
+
+ [aria-current]::after {
+ position: absolute;
+ content: '';
+ width: calc(100% - 1em);
+ height: 2px;
+ background-color: rgb(255,62,0);
+ display: block;
+ bottom: -1px;
+ }
+
+ a {
+ text-decoration: none;
+ padding: 1em 0.5em;
+ display: block;
+ }
+</style>
+
+<nav>
+ <ul>
+ <li><a aria-current="{segment === undefined ? 'page' : undefined}" href=".">home</a></li>
+ <li><a aria-current="{segment === 'about' ? 'page' : undefined}" href="about">about</a></li>
+
+ <!-- for the blog link, we're using rel=prefetch so that Sapper prefetches
+ the blog data when we hover over the link or tap it on a touchscreen -->
+ <li><a rel=prefetch aria-current="{segment === 'blog' ? 'page' : undefined}" href="blog">blog</a></li>
+ </ul>
+</nav>
diff --git a/src/components/PredictedSpaceWeather.svelte b/src/components/PredictedSpaceWeather.svelte
new file mode 100644
index 0000000..9194447
--- /dev/null
+++ b/src/components/PredictedSpaceWeather.svelte
@@ -0,0 +1,174 @@
+<script lang="ts">
+ // import { onMount } from 'svelte';
+ import PredictedSpaceWeatherThing from './PredictedSpaceWeatherThing.svelte';
+
+ let predictions;
+ // async function haschange() {
+ // let data = await fetch(`https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=${latitude}&lon=${longitude}`).then(res => res.json());
+ // let data = await fetch("https://services.swpc.noaa.gov/products/noaa-planetary-k-index-forecast.json").then(res => res.json());
+ // data.shift();
+ // let updatedPredictions = [];
+ // data.forEach((pred, i) => {
+ // if (pred[2] != "observed") {
+ // updatedPredictions.push(pred);
+ // }
+ // });
+ // predictions = updatedPredictions;
+ // }
+ //
+ // onMount(haschange);
+
+
+
+ import { onMount } from 'svelte';
+ const monthNames = ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ ];
+
+ let longitude;
+ let latitude;
+ let locationSupported;
+ let dataLoading = true;
+ let defaultLocation = false;
+ let weather;
+ let days = Array();
+
+ async function getWeather(longitude, latitude) {
+ let yr_data = await fetch(`https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=${latitude}&lon=${longitude}`).then(res => res.json());
+
+ let kp_data = await fetch("https://services.swpc.noaa.gov/products/noaa-planetary-k-index-forecast.json").then(res => res.json());
+ kp_data.shift();
+ let updatedPredictions = [];
+ kp_data.forEach((pred, i) => {
+ if (pred[2] != "observed") {
+ let temp;
+ let clouds;
+ let cDate = new Date(pred[0]);
+ let closestDate = new Date(0,0,0);
+ yr_data["properties"]["timeseries"].forEach((pred, i) => {
+ let predDate = new Date(pred["time"]);
+ if (Math.abs(predDate.getTime() - cDate.getTime()) < Math.abs(closestDate.getTime() - cDate.getTime())) {
+ closestDate = predDate;
+ temp = (pred["data"]["instant"]["details"]["air_temperature"]);
+ clouds = pred["data"]["instant"]["details"]["cloud_area_fraction"];
+ }
+ })
+
+ updatedPredictions.push({
+ "time": pred[0],
+ "kp": pred[1],
+ "temp": temp,
+ "clouds": clouds
+ });
+ }
+ });
+ predictions = updatedPredictions;
+ }
+ function getDays(daily) {
+ var data = daily.data.slice(0,5)
+ data.forEach(element => {
+ var a = new Date(element.time*1000)
+ var dayStrings = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
+ days.push(dayStrings[a.getDay()])
+ });
+ }
+ function getLocation() {
+ if (navigator.geolocation) {
+ dataLoading = true
+ locationSupported = true
+ navigator.geolocation.getCurrentPosition(setLocation, locationError)
+ } else {
+ locationSupported = false
+ noLocation()
+ }
+ }
+
+ function setLocation(position) {
+ longitude = position.coords.longitude
+ latitude = position.coords.latitude
+ getWeather(longitude, latitude)
+ }
+
+ function locationError(err) {
+ noLocation()
+ }
+
+ function noLocation() {
+ longitude = 28.283333
+ latitude = -15.416667
+ toggleLoading()
+ }
+ function toggleLoading() {
+ dataLoading = !dataLoading
+ }
+ function toggleDefault() {
+ defaultLocation = !defaultLocation
+ }
+ onMount(getLocation);
+</script>
+
+<style>
+ .predicted-weather {
+ --bg-opacity: 1;
+ background-color: #f7fafc;
+ background-color: rgba(247, 250, 252, var(--bg-opacity));
+ padding: 1.5rem;
+ --text-opacity: 1;
+ color: #1a202c;
+ color: rgba(26, 32, 44, var(--text-opacity));
+ height: 100%;
+ overflow: hidden;
+
+ /* border-top-left-radius: 1rem;
+ border-top-right-radius: 1rem;
+ transform: translatey(-1rem); */
+ }
+
+ @media (min-width: 640px), (min-height: 720px) {
+ .predicted-weather {
+ padding: 2rem;
+ padding-top: 1.5rem;
+ }
+ }
+
+ @media (min-width: 640px) {
+ .predicted-weather {
+ border-bottom-right-radius: 1rem;
+ border-bottom-left-radius: 1rem;
+ }
+ }
+
+ .predicted-weather h2 {
+ text-transform: uppercase;
+ font-size: 0.875rem;
+ letter-spacing: 0.1em;
+ font-weight: 700;
+ margin-top: 0.25rem;
+ margin-bottom: 0.5rem;
+ }
+
+ .prediction-table {
+ height: 100%;
+ overflow-y: scroll;
+ padding-bottom: 1rem;
+ }
+
+ .prediction-table::-webkit-scrollbar {
+ display: none;
+ }
+</style>
+
+<div class="predicted-weather">
+ <div className="flex flex-row justify-between items-top">
+ <h2>Predicted</h2>
+ </div>
+ <div class="prediction-table">
+ {#if predictions}
+ {#each predictions as prediction, i}
+ <PredictedSpaceWeatherThing {prediction}/>
+ {/each}
+ {:else}
+ Cannot connect to NOAA
+ {/if}
+ </div>
+</div>
diff --git a/src/components/PredictedSpaceWeatherThing.svelte b/src/components/PredictedSpaceWeatherThing.svelte
new file mode 100644
index 0000000..0a40e79
--- /dev/null
+++ b/src/components/PredictedSpaceWeatherThing.svelte
@@ -0,0 +1,64 @@
+<script>
+ export let prediction;
+
+ const monthNames = ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ ];
+
+ let kp = prediction["kp"];
+ let dateTime = prediction["time"].split(" ");
+ let date = Number(dateTime[0].split("-")[2]) + ". " + monthNames[Number(dateTime[0].split("-")[1])];
+ let time = dateTime[1].substring(0,5);
+ let temp = prediction["temp"];
+ let clouds = prediction["clouds"];
+</script>
+
+<style>
+ .prediction-details {
+ display: flex;
+ justify-content: space-between;
+ border-bottom-width: 1px;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ font-size: 0.75rem;
+ letter-spacing: 0.05em;
+ }
+
+ .prediction-details:last-of-type {
+ border-width: 0;
+ padding-bottom: 0;
+ }
+
+ .prediction-details h3 {
+ font-size: 0.875rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ margin-right: 0.5rem;
+ }
+
+ .prediction-details .data {
+ display: flex;
+ flex-direction: row;
+ }
+
+ .prediction-details .data h2 {
+ margin-right: 1rem;
+ font-size: 1.5rem;
+ }
+
+</style>
+
+<div class="prediction-details">
+ <div>
+ <h3>{time}</h3>
+ <p>{date}</p>
+ </div>
+ <div class="data">
+ <h2>{kp}</h2>
+ <div>
+ <p><i class="fas fa-thermometer-half"></i> {temp}°C</p>
+ <p><i class="fas fa-cloud"></i> {clouds}%</p>
+ </div>
+ </div>
+</div>
diff --git a/src/components/WeatherCurrent.svelte b/src/components/WeatherCurrent.svelte
new file mode 100644
index 0000000..6f92b20
--- /dev/null
+++ b/src/components/WeatherCurrent.svelte
@@ -0,0 +1,210 @@
+<script lang="ts">
+ import { onMount } from 'svelte';
+ const monthNames = ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ ];
+
+ let longitude;
+ let latitude;
+ let locationSupported;
+ let dataLoading = true;
+ let defaultLocation = false;
+ let weather;
+ let days = Array();
+
+ let location = "The earth";
+ let date = "-";
+ let kp_now = "-";
+ let kp_min = "-";
+ let kp_max = "-";
+ let bz = "-";
+ let clouds = "-";
+
+ async function getWeather(longitude, latitude) {
+ let yr_data = await fetch(`https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=${latitude}&lon=${longitude}`).then(res => res.json());
+ clouds = yr_data["properties"]["timeseries"][0]["data"]["instant"]["details"]["cloud_area_fraction"];
+ bz = (await fetch("https://services.swpc.noaa.gov/products/summary/solar-wind-mag-field.json").then(res => res.json()))["Bz"];
+ //console.log (await fetch(`http://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&sensor=true`).then(res => res.json()));
+ let kp_data = await fetch('https://services.swpc.noaa.gov/products/noaa-planetary-k-index-forecast.json').then(res => res.json());
+ kp_data.shift();
+ let cDate = new Date();
+ let closestDate = new Date(0,0,0);
+ let minkp = 1000; // Just a larger number than any plausable value
+ let maxkp = 0;
+
+ kp_data.forEach((pred, i) => {
+ if (pred[1] > maxkp) {
+ maxkp = pred[1];
+ }
+ if (pred[1] < minkp) {
+ minkp = pred[1];
+ }
+ let predDate = new Date(pred[0]);
+ if (Math.abs(predDate.getTime() - cDate.getTime()) < Math.abs(closestDate.getTime() - cDate.getTime())) {
+ closestDate = predDate;
+ kp_now = pred[1];
+ }
+ });
+ kp_min = minkp.toString();
+ kp_max = maxkp.toString();
+
+ date = cDate.getDay() + ". " + monthNames[cDate.getMonth()] + " " + cDate.getHours() + ":" + cDate.getMinutes();
+ }
+ function getDays(daily) {
+ var data = daily.data.slice(0,5)
+ data.forEach(element => {
+ var a = new Date(element.time*1000)
+ var dayStrings = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
+ days.push(dayStrings[a.getDay()])
+ });
+ }
+ function getLocation() {
+ if (navigator.geolocation) {
+ dataLoading = true
+ locationSupported = true
+ navigator.geolocation.getCurrentPosition(setLocation, locationError)
+ } else {
+ locationSupported = false
+ noLocation()
+ }
+ }
+
+ function setLocation(position) {
+ longitude = position.coords.longitude
+ latitude = position.coords.latitude
+ getWeather(longitude, latitude)
+ }
+
+ function locationError(err) {
+ noLocation()
+ }
+
+ function noLocation() {
+ longitude = 28.283333
+ latitude = -15.416667
+ toggleLoading()
+ }
+ function toggleLoading() {
+ dataLoading = !dataLoading
+ }
+ function toggleDefault() {
+ defaultLocation = !defaultLocation
+ }
+ onMount(getLocation);
+</script>
+
+<style>
+
+ .weatherCurrent-wrapper {
+ height: 100%;
+ font-family: Roboto, sans-serif;
+ font-size: 1rem;
+ letter-spacing: 0.05em;
+ --bg-opacity: 1;
+ background-color: #1a202c;
+ background-color: rgba(26, 32, 44, var(--bg-opacity));
+ background:
+ linear-gradient(
+ rgba(0, 0, 0, 0.5),
+ rgba(0, 0, 0, 0.5)
+ ), url(/aurora.jpg);
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+
+ .weatherCurrent-data {
+ width: 100%;
+ padding: 1.5rem;
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ height: 100%;
+ --text-opacity: 1;
+ color: #fff;
+ color: rgba(255, 255, 255, var(--text-opacity));
+ text-align: center;
+ letter-spacing: 0.05em;
+ text-shadow: 1px 1px 2px rgba(0,0,0,.75);
+ }
+
+ .weatherCurrent-data-location {
+ display: flex;
+ justify-content: center;
+ align-content: center;
+ }
+
+ .weatherCurrent-data-location .symbol {
+ width: 1.5rem;
+ height: 1.5rem;
+ margin-right: 1rem;
+ }
+
+
+ .weatherCurrent-data-location h1 {
+ text-transform: uppercase;
+ font-family: Roboto Condensed, sans-serif;
+ font-size: 1.125rem;
+ letter-spacing: 0.1em;
+ margin-bottom: 0;
+ }
+
+ .weatherCurrent-data-kp h2 {
+ font-weight: 700;
+ font-size: 3rem;
+ letter-spacing: 0.05em;
+ line-height: 1.25;
+ }
+
+ .current-details {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ grid-gap: 1rem;
+ gap: 1rem;
+ text-shadow: 1px 1px 2px rgba(0,0,0,.75);
+ }
+
+ .current-details p {
+ line-height: 1.375;
+ }
+
+
+</style>
+
+<div class="weatherCurrent-wrapper">
+ <div class="weatherCurrent-data">
+ <div class="weatherCurrent-data-location">
+ <i class="symbol fas fa-map-marker-alt"></i>
+ <h1>{location}</h1>
+ </div>
+
+ <div class="weatherCurrent-data-date">
+ <p>{date}</p>
+ </div>
+
+ <div class="weatherCurrent-data-kp">
+ <h2>KP {kp_now}</h2>
+ <p>
+ <span className="pr-2">&uarr; KP {kp_max}</span>
+ <span className="pl-2">&darr; KP {kp_min}</span>
+ </p>
+ </div>
+
+ <div class="current-details">
+ <div>
+ <p>BZ</p>
+ <p>{bz}</p>
+ </div>
+ <div>
+ <p>Probability</p>
+ <p>10%</p>
+ </div>
+ <div>
+ <p>Clouds</p>
+ <p>{clouds}%</p>
+ </div>
+ </div>
+
+ </div>
+</div>