👱‍♂️ Adds layout manager

This commit is contained in:
Rune Harlyk
2024-08-18 01:06:21 +02:00
committed by Rune Harlyk
parent 5e2f34f792
commit d8659f8ed5
7 changed files with 219 additions and 20 deletions
@@ -0,0 +1,36 @@
<script lang="ts">
import { WidgetComponents, type WidgetContainerConfig, isWidgetConfig } from './LayoutManager';
import Widget from './Widget.svelte';
export let container: WidgetContainerConfig;
</script>
<div class="w-full h-full flex flex-col">
{#if container.header}
<div class="bg-base-300">
<div class="bg-base-100 p-2 w-min">{container.header}</div>
</div>
{/if}
<div
class="flex w-full h-full"
class:flex-row={container.layout === 'column'}
class:flex-col={container.layout === 'row'}
>
{#each container.widgets as widget, index (widget.id + '-' + index)}
<Widget size={widget.size ?? 1}>
{#if isWidgetConfig(widget)}
<svelte:component this={WidgetComponents[widget.component]} {...widget.props} />
{:else if widget.widgets}
<svelte:self container={widget} />
{/if}
</Widget>
{#if index !== container.widgets.length - 1}
<div
class="divider bg-base-300 m-0"
class:divider-horizontal={container.layout === 'column'}
></div>
{/if}
{/each}
</div>
</div>
@@ -0,0 +1,60 @@
import { persistentStore } from '$lib/utilities';
import Visualization from '$lib/components/Visualization.svelte';
import Stream from '$lib/components/Stream.svelte';
import CpuUsageChart from '$lib/components/widget/CpuUsageChart.svelte';
import type { Writable } from 'svelte/store';
export interface WidgetConfig {
id: string | number;
component: keyof typeof WidgetComponents;
size?: number;
props?: Record<string, any>;
}
export interface WidgetContainerConfig {
id: string | number;
layout: 'row' | 'column';
header?: string;
size?: number;
widgets: Array<WidgetConfig | WidgetContainerConfig>;
}
export const isWidgetConfig = (
widget: WidgetConfig | WidgetContainerConfig
): widget is WidgetConfig => 'component' in widget;
export const WidgetComponents = {
Visualization,
Stream,
CpuUsageChart
};
export const controllerLayout: Writable<WidgetContainerConfig> = persistentStore(
'controller_layout',
{
id: 'root',
layout: 'column',
widgets: [
{
id: 'visualization',
layout: 'column',
header: 'Visualization',
size: 2,
widgets: [
{ id: 1, component: 'Visualization', size: 2, props: { debug: true } },
{ id: 2, component: 'Stream' }
]
},
{
id: 'charts',
layout: 'row',
header: 'Charts',
widgets: [
{ id: 3, component: 'CpuUsageChart' },
{ id: 4, component: 'CpuUsageChart' },
{ id: 5, component: 'CpuUsageChart' }
]
}
]
} as WidgetContainerConfig
);
@@ -0,0 +1,7 @@
<script>
export let size = 1;
</script>
<div class="box-border overflow-hidden" style="flex: {size}">
<slot></slot>
</div>
@@ -0,0 +1,99 @@
<script lang="ts">
import { daisyColor } from "$lib/DaisyUiHelper";
import { Chart, registerables } from "chart.js";
import { onMount } from "svelte";
import { cubicOut } from "svelte/easing";
import { slide } from "svelte/transition";
let chartElement: HTMLCanvasElement;
let chart: Chart;
export let label
export let data:number[]
export let title
Chart.register(...registerables);
onMount(() => {
chart = new Chart(chartElement, {
type: 'line',
data: {
labels: data,
datasets: [
{
label,
borderColor: daisyColor('--p'),
backgroundColor: daisyColor('--p', 50),
borderWidth: 2,
data,
yAxisID: 'y'
},
]
},
options: {
maintainAspectRatio: false,
responsive: true,
plugins: {
legend: {
display: true
},
tooltip: {
mode: 'index',
intersect: false
}
},
elements: {
point: {
radius: 0
}
},
scales: {
x: {
grid: {
color: daisyColor('--bc', 10)
},
ticks: {
color: daisyColor('--bc')
},
display: false
},
y: {
type: 'linear',
title: {
display: true,
text: title,
color: daisyColor('--bc'),
font: {
size: 16,
weight: 'bold'
}
},
position: 'left',
min: 0,
max: 100,
grid: { color: daisyColor('--bc', 10) },
ticks: {
color: daisyColor('--bc')
},
border: { color: daisyColor('--bc', 10) }
}
}
}
});
setInterval(() => {
chart.data.labels = data
chart.data.datasets[0].data = data
}, 500);
})
</script>
<div class="w-full h-full overflow-x-auto">
<div
class="flex w-full flex-col space-y-1 h-60"
transition:slide|local={{ duration: 300, easing: cubicOut }}
>
<canvas bind:this={chartElement} />
</div>
</div>
@@ -0,0 +1,8 @@
<script lang="ts">
import ChartBase from "./ChartBase.svelte";
let CpuData:number[] = [1,2,3,4,5,6,7,8,9,]
</script>
<ChartBase data={CpuData} label="CPU usage" title="CPU usage"></ChartBase>