Files
Website/src/components/FightStatsChart.svelte
2025-04-05 15:21:36 +02:00

111 lines
3.6 KiB
Svelte

<!--
- This file is a part of the SteamWar software.
-
- Copyright (C) 2023 SteamWar.de-Serverteam
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<script lang="ts">
import {onDestroy, onMount} from "svelte"
import {
Chart,
LineController,
LineElement,
PointElement,
LinearScale,
TimeScale,
Tooltip,
Legend,
Title
} from "chart.js"
import type {FightStats} from "@type/stats.ts"
import 'chartjs-adapter-dayjs-4'
interface Props {
data: FightStats;
}
let { data }: Props = $props();
let chart: Chart<"line", {x: string; y: number}[], unknown>;
let canvas: HTMLCanvasElement = $state();
onMount(async () => {
Chart.register(LineController, LineElement, PointElement, LinearScale, TimeScale, Tooltip, Legend, Title)
if (document.body.parentElement!.classList.contains("dark")) {
Chart.defaults.color = "#fff"
}
const colors = ["#abfa91", "#279900", "#00ffbe", "#9297fb", "#050b9d", "#b60fff", "#8dddfc", "#0880ad", "#41ff00", "#039973", "#96fce2", "#0009ff", "#7501a4", "#e2a2fb", "#00b9ff", "#372a42", "#dee0da", "#dec5ed", "#e1be89", "#330c3d"];
const map = new Map<string, { x: string, y: number }[]>()
for (const point of data) {
const dataset = map.get(point.gamemode) ?? []
dataset.push({
x: point.date,
y: point.count
})
map.set(point.gamemode, dataset)
}
chart = new Chart(
canvas,
{
type: "line",
data: {
datasets: Array.from(map.entries()).map(([gamemode, data]) => {
const color = colors.pop()
return {
label: gamemode,
fill: false,
borderColor: color,
backgroundColor: color,
spanGaps: true,
cubicInterpolationMode: "monotone",
data
};
})
},
options: {
maintainAspectRatio: false,
scales: {
x: {
type: "time",
time: {
unit: "day",
displayFormats: {
day: "DD.MM.YYYY"
}
}
},
y: {
beginAtZero: true
}
}
}
}
)
})
onDestroy(() => {
chart.destroy()
})
</script>
<div>
<canvas height="500" bind:this={canvas}></canvas>
</div>