show all info on graph

This commit is contained in:
David Senoner 2025-06-13 09:04:05 +02:00
parent e29c6db908
commit 1841746f6a
Signed by: kada49
GPG key ID: 92BABE6B7E63C6CA
2 changed files with 63 additions and 35 deletions

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from "svelte"; import { onMount, onDestroy } from "svelte";
import { Thermometer, Droplets, Gauge, Mountain, Cpu } from "@lucide/svelte"; import { Thermometer, Droplets, Gauge, Mountain, Cpu, DownloadIcon } from "@lucide/svelte";
import { Button, buttonVariants } from "$lib/components/ui/button/index.js"; import { Button, buttonVariants } from "$lib/components/ui/button/index.js";
import { Input } from "$lib/components/ui/input/index.js"; import { Input } from "$lib/components/ui/input/index.js";
import { Label } from "$lib/components/ui/label/index.js"; import { Label } from "$lib/components/ui/label/index.js";
@ -169,24 +169,58 @@
); );
const chartConfig = { const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" }, temperature: { label: "Temperature", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" }, humidity: { label: "Humidity", color: "var(--chart-2)" },
altitude: { label: "Altitude", color: "var(--chart-1)" },
pressure: { label: "Pressure", color: "var(--chart-2)" },
} satisfies Chart.ChartConfig; } satisfies Chart.ChartConfig;
const table = $state([ const table = $state([
{ visible: true, id: "temperature" }, {
{ visible: true, id: "altitude" }, visible: true,
{ visible: true, id: "humidity" }, key: "altitude",
label: chartConfig.altitude.label,
color: chartConfig.altitude.color,
},
{
visible: true,
key: "humidity",
label: chartConfig.humidity.label,
color: chartConfig.humidity.color,
},
{
visible: true,
key: "pressure",
label: chartConfig.pressure.label,
color: chartConfig.pressure.color,
},
{
visible: true,
key: "temperature",
label: chartConfig.temperature.label,
color: chartConfig.temperature.color,
},
]); ]);
const tables = $derived(
table
.filter((item) => {
if (item.visible) return true;
return false;
})
.map((item) => {
return { key: item.key, label: item.label, color: item.color };
}),
);
let onOpenChange = $state(async (open: boolean) => { let onOpenChange = $state(async (open: boolean) => {
if (open) { if (open) {
const response = await fetch("/" + data.slug + "/stats"); const response = await fetch("/" + data.slug + "/stats");
const number = await response.json(); const number = await response.json();
console.log(number); console.log(number);
chartData = number.map((obj) => { chartData = number.map((obj: any) => {
return { date: new Date(obj.date), desktop: obj.temp, mobile: obj.pressure }; return { ...obj, date: new Date(obj.date) };
}); });
} }
}); });
@ -284,12 +318,19 @@
<Dialog.Trigger class={buttonVariants({ variant: "outline" })}>Statistics</Dialog.Trigger> <Dialog.Trigger class={buttonVariants({ variant: "outline" })}>Statistics</Dialog.Trigger>
<Dialog.Content class="sm:max-h-2/3 sm:max-w-2/3"> <Dialog.Content class="sm:max-h-2/3 sm:max-w-2/3">
<Dialog.Header> <Dialog.Header>
<div class="grid flex-1 gap-1 text-center sm:text-left">
<Card.Title>Statistics for floor {data.slug}</Card.Title>
<Card.Description>Showing total data for the last 3 months</Card.Description>
</div>
</Dialog.Header>
<div class="flex items-center gap-2">
<DropdownMenu.Root> <DropdownMenu.Root>
<DropdownMenu.Trigger> <DropdownMenu.Trigger class="rounded-lg sm:ml-auto">
{#snippet child({ props })} {#snippet child({ props })}
<Button variant="outline" size="sm" {...props}> <Button variant="outline" size="sm" {...props}>
<Columns2 /> <Columns2 />
<span class="hidden lg:inline">Customize Columns</span> <span class="hidden lg:inline">Customize Data</span>
<span class="lg:hidden">Columns</span> <span class="lg:hidden">Columns</span>
<ChevronDownIcon /> <ChevronDownIcon />
</Button> </Button>
@ -297,20 +338,13 @@
</DropdownMenu.Trigger> </DropdownMenu.Trigger>
<DropdownMenu.Content align="end" class="w-56"> <DropdownMenu.Content align="end" class="w-56">
{#each table as column} {#each table as column}
<DropdownMenu.CheckboxItem <DropdownMenu.CheckboxItem class="capitalize" bind:checked={column.visible}>
class="capitalize" {column.key}
checked={column.visible}
onCheckedChange={(value) => (column.visible = !value)}
>
{column.id}
</DropdownMenu.CheckboxItem> </DropdownMenu.CheckboxItem>
{/each} {/each}
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>
<div class="grid flex-1 gap-1 text-center sm:text-left">
<Card.Title>Data for floor {data.slug}</Card.Title>
<Card.Description>Showing total data for the last 3 months</Card.Description>
</div>
<Select.Root type="single" bind:value={timeRange}> <Select.Root type="single" bind:value={timeRange}>
<Select.Trigger class="w-[160px] rounded-lg sm:ml-auto" aria-label="Select a value"> <Select.Trigger class="w-[160px] rounded-lg sm:ml-auto" aria-label="Select a value">
{selectedLabel} {selectedLabel}
@ -321,26 +355,20 @@
<Select.Item value="7d" class="rounded-lg">Last 7 days</Select.Item> <Select.Item value="7d" class="rounded-lg">Last 7 days</Select.Item>
</Select.Content> </Select.Content>
</Select.Root> </Select.Root>
</Dialog.Header>
<ChartContainer config={chartConfig} class="aspect-auto h-[250px] w-full"> <Button variant="outline" size="sm">
<DownloadIcon />
<span class="hidden lg:inline">Export Data</span>
</Button>
</div>
<ChartContainer config={chartConfig} class="aspect-auto h-[800px] w-full">
<AreaChart <AreaChart
legend legend
data={filteredData} data={filteredData}
x="date" x="date"
xScale={scaleUtc()} xScale={scaleUtc()}
series={[ series={tables}
{
key: "mobile",
label: "Mobile",
color: chartConfig.mobile.color,
},
{
key: "desktop",
label: "Desktop",
color: chartConfig.desktop.color,
},
]}
seriesLayout="stack" seriesLayout="stack"
props={{ props={{
area: { area: {

View file

@ -2,7 +2,7 @@ import { db } from "$lib/server/db";
import * as table from "$lib/server/db/schema" import * as table from "$lib/server/db/schema"
export const GET = async () => { export const GET = async () => {
const data = await db.select({ date: table.sensorData.time, temp: table.sensorData.temperature, pressure: table.sensorData.pressure }).from(table.sensorData); const data = await db.select({ altitude: table.sensorData.altitude, humidity: table.sensorData.humidity, pressure: table.sensorData.pressure, temperature: table.sensorData.temperature, date: table.sensorData.time, }).from(table.sensorData);
console.log(data); console.log(data);
return new Response(JSON.stringify(data), { return new Response(JSON.stringify(data), {