58 lines
1.2 KiB
Svelte
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>
|