Feat: Colored brew pages (#4)

* Removed graph animation

* Smoother graph by removing data point bubbles

* Added relatime button which keeps reloading every 2 sec

* Clear timeout when destroying/navigating away from page

* Added primary & secondary colors to match label per brew

* Only render graph if dataset is list of length

* Also color mobile image container primary color of brew

* Add white background on graphs because of low contrast secondary background color
This commit is contained in:
2023-06-24 19:41:50 +02:00
committed by GitHub
parent 4008b8aee9
commit 94c27b0a8d
4 changed files with 148 additions and 112 deletions

View File

@@ -1,91 +1,110 @@
[{
"beer": {
"name": "Kveldsbris",
"brewery": "Kinn Bryggeri",
"category": "Pilsner/Lys Lager",
"description": ""
[
{
"beer": {
"name": "Kveldsbris",
"brewery": "Kinn Bryggeri",
"category": "Belgian Pale Ale",
"description": ""
},
"date": "1682272800",
"by": ["Alf", "Kevin"],
"abv": "5.6",
"description": "Kveldsbris - Evening Breeze - is offered as a clean, refreshing and not-too-alcoholic Belgian ale. It has a fine balance of Belgian yeastiness with the premier hop varieties from three wildly different districts: East Kent Goldings on England's south coast, Saaz from Zatec in the Czech Republic, and Amarillo from Yakima Valley in the United States of America. Kveldsbris is a most versatile table ale that can cope with more spiciness and richness than a regular wheat beer.",
"image": "kinn_kveldsbris.png",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://oslo.bryggselv.no/finest/104923/finest-originals-utepils-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024",
"color_primary": "#FCF28F",
"color_secondary": "rgba(252, 242, 143, 0.2)"
},
"date": "1682272800",
"by": ["Alf", "Kevin"],
"abv": "5.6",
"description": "",
"image": "kinn_kveldsbris.png",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://oslo.bryggselv.no/finest/104923/finest-originals-utepils-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024"
}, {
"beer": {
"name": "FUCK YEAH IPA",
"brewery": "Finest",
"category": "American IPA",
"description": ""
{
"beer": {
"name": "FUCK YEAH IPA",
"brewery": "Finest",
"category": "American IPA",
"description": ""
},
"date": "1648922400",
"by": ["Alf", "Kevin"],
"abv": "7",
"description": "",
"image": "finest_fuck-yeah-IPA.jpg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://web.archive.org/web/20210225043236/https://www.bryggselv.no/finest/105943/fuck-yeah-ipa-ultra-american-west-coast-ipa-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024",
"color_primary": "#0169A6",
"color_secondary": "rgba(1, 105, 166, 0.2)"
},
"date": "1648922400",
"by": ["Alf", "Kevin"],
"abv": "7",
"description": "",
"image": "finest_fuck-yeah-IPA.jpg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://web.archive.org/web/20210225043236/https://www.bryggselv.no/finest/105943/fuck-yeah-ipa-ultra-american-west-coast-ipa-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024"
}, {
"beer": {
"name": "Love in a canoe",
"brewery": "Finest",
"category": "Mexican Lager",
"description": ""
{
"beer": {
"name": "Love in a canoe",
"brewery": "Finest",
"category": "Mexican Lager",
"description": ""
},
"date": "1646420400",
"by": ["Alf", "Kevin"],
"abv": "4.7",
"description": "",
"image": "finest_love-in-a-canoe.jpeg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://oslo.bryggselv.no/finest/104092/love-in-a-canoe-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024",
"color_primary": "#F7F0DF",
"color_secondary": "rgba(247, 240, 223, 0.2)"
},
"date": "1646420400",
"by": ["Alf", "Kevin"],
"abv": "4.7",
"description": "",
"image": "finest_love-in-a-canoe.jpeg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://oslo.bryggselv.no/finest/104092/love-in-a-canoe-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024"
}, {
"beer": {
"name": "Utepils",
"brewery": "Finest",
"category": "",
"description": ""
{
"beer": {
"name": "Utepils",
"brewery": "Finest",
"category": "",
"description": ""
},
"date": "1637694000",
"by": ["Alf", "Kevin"],
"abv": "5.0",
"description": "",
"image": "finest_utepils.jpeg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://www.bryggselv.no/finest/105932/kinn-kveldsbris-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024",
"color_primary": "#F4E9D3",
"color_secondary": "rgba(244, 233, 211, 0.2)"
},
"date": "1637694000",
"by": ["Alf", "Kevin"],
"abv": "5.0",
"description": "",
"image": "finest_utepils.jpeg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://www.bryggselv.no/finest/105932/kinn-kveldsbris-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024"
}, {
"beer": {
"name": "HELLES Tysk Lager",
"brewery": "Münchener Helles",
"category": "Tysk Lager",
"description": ""
{
"beer": {
"name": "HELLES Tysk Lager",
"brewery": "Münchener Helles",
"category": "Tysk Lager",
"description": ""
},
"date": "1629396000",
"by": ["Adrian", "Kevin", "Mats"],
"abv": "5.3",
"description": "",
"image": "helles_tysk-lager.jpeg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://oslo.bryggselv.no/finest/106231/finest-helles-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024",
"color_primary": "#C5893D",
"color_secondary": "rgba(197, 137, 61, 0.2)"
},
"date": "1629396000",
"by": ["Adrian", "Kevin", "Mats"],
"abv": "5.3",
"description": "",
"image": "helles_tysk-lager.jpeg",
"recipe": "https://docs.google.com/document/d/1FL7ibXxW1r_zFNLK338pyjfMiCCaTOi2fzuMoInA3dQ",
"order_page": "https://oslo.bryggselv.no/finest/106231/finest-helles-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024"
}, {
"beer": {
"name": "Lazy Days Weiss",
"brewery": "Finest",
"category": "Weissbier",
"description": ""
},
"date": "1621706400",
"by": ["Alf", "Kevin", "Kristian"],
"abv": "5.3",
"description": "",
"image": "finest_lazy-days.jpeg",
"recipe": "https://docs.google.com/document/u/0/d/1I6qX4l4jDzK51GxBt3IdEv-HyNQHAx8ijc5dMlG1Xkk",
"order_page": "https://oslo.bryggselv.no/finest/106231/finest-helles-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024"
}]
{
"beer": {
"name": "Lazy Days Weiss",
"brewery": "Finest",
"category": "Weissbier",
"description": ""
},
"date": "1621706400",
"by": ["Alf", "Kevin", "Kristian"],
"abv": "5.3",
"description": "",
"image": "finest_lazy-days.jpeg",
"recipe": "https://docs.google.com/document/u/0/d/1I6qX4l4jDzK51GxBt3IdEv-HyNQHAx8ijc5dMlG1Xkk",
"order_page": "https://oslo.bryggselv.no/finest/106231/finest-helles-allgrain-ølsett-25-liter",
"untapped": "https://untappd.com/b/kinn-bryggeri-kveldsbris/695024",
"color_primary": "#6C8D9E",
"color_secondary": "rgba(108, 141, 158, 0.2)"
}
]

View File

@@ -94,17 +94,16 @@
function renderChart() {
const context: CanvasRenderingContext2D | null = chartCanvas.getContext('2d');
if (!context) return
if (!context) return;
// create labels and singular dataset (data)
const labels: string[] = dateLabelsFormatedBasedOnResolution(dataFrames);
const data: ChartDataset = {
data: dataFrames.map((frame) => frame.value),
borderWidth: 3,
borderWidth: 3
};
// based on name, add label and color options to dataset
setDataColorAndName(data)
setDataColorAndName(data);
// create chart instance, most here is chart options
chart = new Chart(context, {
@@ -114,9 +113,12 @@
datasets: [data]
},
options: {
animation: {
duration: 0
},
elements: {
point: {
radius: 2
radius: 0
},
line: {
tension: 0.5

View File

@@ -5,8 +5,8 @@
export let data;
let brew = data.brew;
let temperatureData: IChartFrame[] = data.graphData.temperature;
let humidityData: IChartFrame[] = data.graphData.humidity;
let temperatureData: IChartFrame[] = data?.graphData?.temperature;
let humidityData: IChartFrame[] = data?.graphData?.humidity;
const dateFormat: Intl.DateTimeFormatOptions = {
weekday: 'long',
@@ -20,11 +20,11 @@
</script>
<section class="card">
<div class="desktop-only image-container" style="height: {height}px">
<div class="desktop-only image-container" style="height: {height}px; background-color: {brew.color_primary || '#93a4a0'}">
<img src="/images/{brew.image}" alt="Tuborg Sommerøl" aria-label="Tuborg Sommerøl" />
</div>
<div class="beer-container" bind:clientHeight="{height}">
<div class="beer-container" bind:clientHeight="{height}" style="background-color: {brew.color_secondary || '#DFE6E5'}">
<h1>{brew.beer.name}</h1>
<div class="links">
@@ -57,25 +57,22 @@
</tbody>
</table>
<div class="mobile-only image-container">
<div class="mobile-only image-container" style="background-color: {brew.color_primary || '#93a4a0'}">
<img src="/images/{brew.image}" alt="Tuborg Sommerøl" aria-label="Tuborg Sommerøl" />
</div>
<h3>Historie</h3>
<p>
I 1873 ble Tuborg Bryggeri grunnlagt av Carl Frederik Tietgen på Hellerud i Danmark. I 1970
ble Tuborg Bryggeri en del av Carlsberg.
</p>
<h3>Beskrivelse</h3>
<p>{brew.description}</p>
<div class="graph-container">
{#if temperatureData}
{#if temperatureData && temperatureData?.length}
<div class="graph">
<h3>Temperature during fermentation</h3>
<Graph dataFrames="{temperatureData}" name="Temperature" hideTitle="{true}" />
</div>
{/if}
{#if humidityData}
{#if humidityData && temperatureData?.length}
<div class="graph">
<h3>Humidity during carbonation</h3>
<Graph dataFrames="{humidityData}" name="Humidity" hideTitle="{true}" />
@@ -134,7 +131,6 @@
display: flex;
justify-content: center;
min-height: 1px;
background-color: #93a4a0;
padding: 3rem 1rem;
@include tablet {
@@ -144,7 +140,8 @@
}
@include mobile {
margin: 2rem 0;
width: calc(100% + 2rem);
margin: 2rem 0 2rem -1rem;
}
img {
@@ -234,4 +231,10 @@
}
}
}
:global(canvas) {
background-color: white;
border-radius: 0.5rem;
padding: 0 0.2rem;
}
</style>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { onMount } from 'svelte';
import { onDestroy, onMount } from 'svelte';
import Graph from '../../lib/components/Graph.svelte';
import type IChartFrame from '../../lib/interfaces/IChartFrame';
import type { PageData } from './$types';
@@ -21,7 +21,14 @@
return fetch(`/api/graph/${unit}`, options).then((resp) => resp.json());
}
const buttonMinutes = [
interface IButtonMinute {
value: number;
name: string;
}
let timeout: ReturnType<typeof setTimeout>;
const buttonMinutes: Array<IButtonMinute> = [
{ value: 2.4, name: 'Realtime' },
{ value: 15, name: 'Last 15 minutes' },
{ value: 60, name: 'Last hour' },
{ value: 360, name: 'Last 6 hours' },
@@ -33,8 +40,9 @@
{ value: 518400, name: 'Last year' }
];
function reload(mins: number) {
minutes = mins;
function reload(button: IButtonMinute) {
minutes = button.value;
clearTimeout(timeout);
const to: Date = new Date();
const from = new Date(to.getTime() - minutes * 60 * 1000);
const size = 40;
@@ -42,6 +50,10 @@
fetchData('temperature', from, to, size).then((resp) => (temperatureData = resp?.data));
fetchData('humidity', from, to, size).then((resp) => (humidityData = resp?.data));
fetchData('pressure', from, to, size).then((resp) => (pressureData = resp?.data));
if (button.name === 'Realtime') {
timeout = setTimeout(() => reload(button), 2000);
}
}
function scrollSelectedButtonIntoView() {
@@ -59,13 +71,13 @@
}
onMount(scrollSelectedButtonIntoView);
onDestroy(() => clearTimeout(timeout))
</script>
<div class="button-wrapper">
{#each buttonMinutes as button}
<button
on:click="{() => reload(button.value)}"
class="{button.value === minutes ? 'selected' : ''}">{button.name}</button
<button on:click="{() => reload(button)}" class="{button.value === minutes ? 'selected' : ''}"
>{button.name}</button
>
{/each}
</div>