Add coloring

This commit is contained in:
2024-06-12 18:35:10 +02:00
parent 0b26198b3b
commit 7f033b9358
5 changed files with 103 additions and 16 deletions

View File

@@ -30,24 +30,19 @@
item.food = name item.food = name
item.amount = parseInt(amount) item.amount = parseInt(amount)
item.description = description item.description = description
const [dbFood, err]: [Food[], Err] = await FoodService.Create(item) const [dbFood, err]: [Food, Err] = await FoodService.Create(item)
name = '' name = ''
amount = '' amount = ''
description = '' description = ''
per100 = '' per100 = ''
per100Edited = false per100Edited = false
if (dbFood.length == 0) {
toast.error('Creating food returned 0 rows')
return
}
if (err) { if (err) {
toast.error(err) toast.error(err)
return return
} }
foodStore.update((food) => { foodStore.update((food) => {
// @ts-ignore food.unshift(dbFood)
food.unshift(dbFood[0])
return food return food
}) })
} }
@@ -64,7 +59,7 @@
</script> </script>
<template> <template>
<tr class="border-b border-gray-200 dark:border-gray-700"> <tr class="border-b border-gray-200 dark:border-gray-700 text-lg font-bold">
<th class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap bg-gray-50 dark:text-white dark:bg-gray-800" <th class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap bg-gray-50 dark:text-white dark:bg-gray-800"
scope="row"> scope="row">
</th> </th>

View File

@@ -2,6 +2,9 @@
import { type Food, FoodService } from '$lib/database/food' import { type Food, FoodService } from '$lib/database/food'
export let item: Food export let item: Food
export let energyColor: string
export let nameColor: string
let amount: string = item.amount.toString() let amount: string = item.amount.toString()
let per100: string = item.per100?.toString() ?? '' let per100: string = item.per100?.toString() ?? ''
let description: string = item.description ?? '' let description: string = item.description ?? ''
@@ -34,12 +37,13 @@
</script> </script>
<template> <template>
<tr class="border-b border-gray-200 dark:border-gray-700"> <tr class="border-b border-gray-200 dark:border-gray-700 font-bold text-lg">
<th class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap bg-gray-50 dark:text-white dark:bg-gray-800" <th class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap bg-gray-50 dark:text-white dark:bg-gray-800"
scope="row"> scope="row">
{item.date} {item.date}
</th> </th>
<td class="px-6 py-4" <td class="px-6 py-4"
style="color: {nameColor}"
contenteditable="true" contenteditable="true"
bind:innerText={name} bind:innerText={name}
on:keydown={update}> on:keydown={update}>
@@ -59,7 +63,7 @@
bind:innerText={per100} bind:innerText={per100}
on:keydown={update}> on:keydown={update}>
</td> </td>
<td class="px-6 py-4"> <td class="px-6 py-4" style="color: {energyColor}">
{item.energy} {item.energy}
</td> </td>
</tr> </tr>

View File

@@ -2,8 +2,43 @@
import EmptyFoodComp from '$components/Food/EmptyFoodComp.svelte' import EmptyFoodComp from '$components/Food/EmptyFoodComp.svelte'
import FoodComp from '$components/Food/FoodComp.svelte' import FoodComp from '$components/Food/FoodComp.svelte'
import type { Food } from '$lib/database/food' import type { Food } from '$lib/database/food'
import { GenerateColor } from '$lib/utils'
export let items: Food[] = [] export let items: Food[] = []
let minCal = 1e5
let maxCal = 0
for (let item of items) {
if (!item.energy) continue
if (item.energy > maxCal) maxCal = item.energy
if (item.energy < minCal) minCal = item.energy
}
const start = '#99ff99'
const end = '#ff9999'
function lerp(item: Food) {
if (!item) return start
if (!item.energy) return start
const t = (item.energy - minCal) / (maxCal - minCal)
const r = parseInt(start.slice(1, 3), 16) * (1 - t) + parseInt(end.slice(1, 3), 16) * t
const g = parseInt(start.slice(3, 5), 16) * (1 - t) + parseInt(end.slice(3, 5), 16) * t
const b = parseInt(start.slice(5, 7), 16) * (1 - t) + parseInt(end.slice(5, 7), 16) * t
return `rgb(${r}, ${g}, ${b})`
}
const itemColors: Map<string, string> = new Map<string, string>()
function getNameColor(item: Food): string {
if (!item) return GenerateColor()
if (!item.food) return GenerateColor()
if (!itemColors.has(item.food)) itemColors.set(item.food, GenerateColor())
// THERE'S NOTHING UNDEFINED HERE
// WE GOT RID OF UNDEFINED ON LINE 33
// ASSHOLE
// @ts-ignore
return itemColors.get(item.food)
}
</script> </script>
<template> <template>
@@ -35,7 +70,7 @@
<tbody> <tbody>
<EmptyFoodComp /> <EmptyFoodComp />
{#each items as f} {#each items as f}
<FoodComp item="{f}" /> <FoodComp item="{f}" energyColor="{lerp(f)}" nameColor="{getNameColor(f)}" />
{/each} {/each}
</tbody> </tbody>
</table> </table>

View File

@@ -38,14 +38,18 @@ or strftime('%Y-%m-%d', date) = strftime('%Y-%m-%d', date('2024-06-12', '-1 day'
order by date DESC; order by date DESC;
`, [date]) `, [date])
}, },
async Create(food: Food): Promise<[Food[], Err]> { async Create(food: Food): Promise<[Food, Err]> {
if (!food.food) return [[food], 'food.food is required'] if (!food.food) return [food, 'food.food is required']
if (!food.amount) throw [[food], 'food.amount is required'] if (!food.amount) throw [food, 'food.amount is required']
const res = await db.execute(`insert into food (food, description, amount) values ($1, $2, $3)`, [food.food, food.description, food.amount]) const res = await db.execute(`insert into food (food, description, amount) values ($1, $2, $3)`, [food.food, food.description, food.amount])
const row = await db.select<Food[]>(`select ${columns.join(', ')} from foodView where rowid = $1`, [res.lastInsertId]) const rows = await db.select<Food[]>(`select ${columns.join(', ')} from foodView where rowid = $1`, [res.lastInsertId])
return [row, null] if (!rows) return [food, 'no data found']
if (rows.length == 0) return [food, 'no data found']
// Its not undefined mannnnnnnnnnnnnnnnnnnnnnnnnn............
// @ts-ignore
return [rows[0], null]
}, },
async GetLatestPer100(food: string): Promise<[number, Err]> { async GetLatestPer100(food: string): Promise<[number, Err]> {
if (!food) return [-1, 'food is required'] if (!food) return [-1, 'food is required']

View File

@@ -60,3 +60,52 @@ export const flyAndScale = (
easing: cubicOut easing: cubicOut
} }
} }
type Color = {
h: number
s: number
l: number
}
function ColorDistance(color1: Color, color2: Color) {
return Math.abs(color1.h - color2.h)
}
function GenerateRandomHSL(): Color {
const hue = Math.floor(Math.random() * 360)
const saturation = 70
const lightness = 60
return { h: hue, s: saturation, l: lightness }
}
const existingColors: Color[] = []
function GenerateColor(): string {
const minDistance = 200
let newColor: Color
let isDistinct = false
let iterations = 0
while (!isDistinct) {
iterations++
if (iterations > 100) {
console.error('Failed to generate a distinct color after 100 iterations')
break
}
newColor = GenerateRandomHSL()
isDistinct = true
for (const color of existingColors) {
if (ColorDistance(newColor, color) < minDistance) {
isDistinct = false
break
}
}
}
// We can not reach this point without having a color generated
// @ts-ignore
return `hsl(${newColor.h}, ${newColor.s}%, ${newColor.l}%)`
}
export { GenerateColor }