dimensionlab-website/src/lib/ui/components/Sparkline.svelte
2026-06-18 18:53:48 +02:00

58 lines
1.2 KiB
Svelte

<script lang="ts">
import type { UiSeverity } from "../types";
let {
values = [],
severity = "neutral",
}: {
values?: number[];
severity?: UiSeverity;
} = $props();
let points = $derived(toPoints(values));
</script>
<svg class="sparkline" data-severity={severity} viewBox="0 0 100 24" aria-hidden="true">
{#if points}
<polyline {points} />
{/if}
</svg>
<style>
.sparkline {
width: 100%;
height: 1.5rem;
color: var(--ui-color-accent);
}
.sparkline[data-severity="warning"] {
color: var(--ui-color-warning);
}
.sparkline[data-severity="danger"] {
color: var(--ui-color-danger);
}
polyline {
fill: none;
stroke: currentColor;
stroke-linecap: square;
stroke-linejoin: miter;
stroke-width: 2;
}
</style>
<script lang="ts" module>
function toPoints(values: number[]): string {
if (values.length === 0) return "";
const max = Math.max(...values, 1);
const step = values.length > 1 ? 100 / (values.length - 1) : 100;
return values
.map((value, index) => {
const x = index * step;
const y = 24 - (Math.max(0, value) / max) * 22;
return `${x.toFixed(2)},${y.toFixed(2)}`;
})
.join(" ");
}
</script>