70 lines
1.7 KiB
Vue
70 lines
1.7 KiB
Vue
<template>
|
|
<div :id="id" class="chart">
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { Dataset } from './Dataset';
|
|
import { TimeScale, LinearScale, LineController, PointElement, LineElement, Chart, Filler, type ChartConfiguration } from 'chart.js';
|
|
import 'chartjs-adapter-moment';
|
|
|
|
Chart.register(TimeScale)
|
|
Chart.register(LinearScale)
|
|
Chart.register(PointElement)
|
|
Chart.register(LineController)
|
|
Chart.register(LineElement)
|
|
Chart.register(Filler)
|
|
|
|
|
|
const id = Math.random().toString().replaceAll(".", "");
|
|
|
|
const props = defineProps<{
|
|
datasets: Dataset,
|
|
config: any
|
|
}>();
|
|
|
|
onMounted(() => {
|
|
watch(props, () => {
|
|
renderChart();
|
|
}, { immediate: true })
|
|
})
|
|
|
|
function renderChart()
|
|
{
|
|
const wrapper = document.getElementById(id);
|
|
if (wrapper != null)
|
|
{
|
|
wrapper.replaceChildren();
|
|
let data = {
|
|
labels: [] as string[],
|
|
datasets: [{
|
|
data: [] as number[],
|
|
borderColor: '#574BFF',
|
|
backgroundColor: 'rgba(0, 0, 255, 0.2)', // area fill color
|
|
fill: 'origin',
|
|
pointRadius: 1,
|
|
borderWidth: 2,
|
|
tension: 0.3
|
|
}]
|
|
}
|
|
for (const dataset of props.datasets.data)
|
|
{
|
|
data.labels.push(new Date(dataset.label).toISOString());
|
|
data.datasets.at(0)!.data.push(dataset.value);
|
|
}
|
|
const canvas = document.createElement('canvas');
|
|
new Chart(canvas, getConfig(data, props.datasets.unit));
|
|
wrapper.appendChild(canvas)
|
|
}
|
|
}
|
|
|
|
function getConfig(data: any, unit: string): ChartConfiguration {
|
|
const c = props.config;
|
|
c.data = data;
|
|
c.options.scales.y.ticks.callback = function(value: number) {
|
|
return value + " " + unit;
|
|
}
|
|
return c;
|
|
}
|
|
</script> |