blob: 9a224e2f3937972668070481a08b9fff15fb7fcc [file] [log] [blame]
<script lang="ts">
import type { ChartType, LegendItem } from "chart.js";
import { Chart } from "chart.js/auto";
import { onMount } from "svelte";
import { writable, type Writable } from "svelte/store";
import type { Data } from "../types/chart.js";
import { LegendPlugin } from "../plugins.js";
import Legend from "./Legend.svelte";
import { saveToClipboard as save } from "../clipboard.js";
export let data: Data;
export let chartType: ChartType = "line";
export let isExperimental: boolean = false;
$: {
if ($chart) {
$chart.data = data;
$chart.update();
}
}
// State
let element: HTMLCanvasElement;
let chart: Writable<Chart | null> = writable(null);
let items: Writable<LegendItem[] | null> = writable(null);
// Effects
onMount(() => {
const onUpdate = (chart: Chart) => {
$chart = chart;
// Bad typings.
const legend = chart.options.plugins.legend as any;
$items = legend.labels.generateLabels(chart);
};
const plugins = {
legend: {
display: false,
},
benchmark: {
onUpdate: onUpdate,
},
};
$chart = new Chart(element, {
data: data,
type: chartType,
plugins: [LegendPlugin],
options: {
plugins: plugins,
},
});
});
// Copy to clip board
async function copy(event: Event) {
if ($chart) {
await save($chart);
}
}
</script>
<article>
<div class="toolbar">
<button
class="btn outline"
data-tooltip="Copy chart to clipboard."
on:click={copy}
>
</button>
</div>
<canvas class="chart" bind:this={element} />
{#if isExperimental}
<footer class="slim">
<section class="experimental">
<kbd>Experimental</kbd>
</section>
</footer>
{/if}
</article>
{#if $items}
<Legend chart={$chart} items={$items} />
{/if}
<style>
.chart {
width: 100%;
}
.toolbar {
padding: 0;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.toolbar .btn {
width: auto;
height: auto;
border: none;
padding: 5px;
}
.slim {
margin-bottom: 0px;
padding: 0;
}
.experimental {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
margin-bottom: 0px;
}
</style>