You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
4.1 KiB

<script lang="ts">
import { onMount } from "svelte";
import type { Stat } from "../api";
import randomColor from "randomcolor";
import { Chart, registerables } from "chart.js";
Chart.register(...registerables);
export let stats: Stat[] = [];
const transformStats = (ostats) => {
const chartData = ostats.reduce((agg, x) => {
let root = agg[x.Header] || {
labels: [],
dataset: {
label: x.Header,
borderColor: randomColor({
luminosity: "dark",
}), //"rgb(75,192,192)",
data: [],
},
};
root.dataset.data = root.dataset.data.concat(x.Count);
root.labels = root.labels.concat(x.Time);
agg[x.Header] = root;
return agg;
}, {});
const finalChartData = Object.keys(chartData).map((x) => chartData[x]);
const finalChartLabels =
finalChartData.length > 0 ? finalChartData[0].labels : [];
return {
labels: finalChartLabels,
datasets: finalChartData.map((x) => x.dataset),
};
};
const generateChartOptions = (s: [], empty: Boolean = false) => {
let labels = [];
let datasets = [];
if (s && s.length > 0) {
({ labels, datasets } = transformStats(s));
}
var delayed;
return {
type: "line",
data: {
labels,
datasets,
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
// x: {
// type: "time",
// ticks: {
// source: "auto",
// // Disabled rotation for performance
// maxRotation: 0,
// autoSkip: true,
// },
// },
y: {
stacked: true,
},
},
hoverRadius: 5,
interaction: {
mode: "nearest",
intersect: false,
axis: "x",
},
plugins: {
decimation: {
enabled: true,
algorithm: "lttb",
samples: 60,
},
},
animations: {
radius: {
duration: 150,
easing: "linear",
loop: (c) => c.active,
},
},
// animation: {
// onComplete: () => {
// delayed = true;
// },
// delay: (context) => {
// let delay = 0;
// if (
// context.type === "data" &&
// context.mode === "default" &&
// !delayed
// ) {
// delay =
// context.dataIndex * 30 +
// context.datasetIndex * 10;
// }
// return delay;
// },
// },
},
};
};
let canvas = null;
let chartInstance = null;
onMount(async () => {
const ctx = canvas.getContext("2d");
chartInstance = new Chart(ctx, generateChartOptions(stats, true));
});
const update = (s) => {
if (chartInstance) {
const { options, data } = generateChartOptions(s, false);
chartInstance.options = options;
chartInstance.data = data;
chartInstance.update();
}
};
$: update(stats);
</script>
<div style="position: relative; max-height: 384px; height: 384px; width: 100%;">
<canvas width="100%" height="100%" bind:this={canvas} />
</div>