I have created a Skeleton Project using the npm create svelte@latest myapp
command. Next, I installed the Chart.js with npm install svelte-chartjs chart.js
and created a simple bar chart:
<script> import { Bar } from 'svelte-chartjs'; import { Chart, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'; Chart.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale); let numbers = [10, 20, 30]; let dates = ['1/1/2024', '1/2/2024', '1/3/2024']; $: data = { labels: dates, datasets: [ { label: 'Random Number', data: numbers, backgroundColor: 'rgba(98, 182, 239,0.4)', borderColor: 'rgba(98, 182, 239, 1)', borderWidth: 2 } ] }; let options = { responsive: true, maintainAspectRatio: false }; async function generate() { const response = await fetch('/generate'); let fetchedData = await response.json(); dates = fetchedData.dates; numbers = fetchedData.numbers; }</script><h1>Fetch Data from API endpoint</h1><button on:click={generate}>Request</button><div><Bar {data} {options} /></div>
It fetches the data from the /generate
API endpoint which generates from 1 to 10 random numbers with values ranging from 10 to 30. Additionally, the dates are produced according to the length of the random numbers. If the Request button is pressed, the bar chart will update its labels and data values. The output looks like this:
The content of the routes/generate/+server.js
file (simulating the API endpoint) that updates the numbers
and dates
array is the following:
import { json } from '@sveltejs/kit';function getRandomNumber(min, max) { return Math.floor(Math.random() * (max - min) + min);}function generateDates(numDates) { var today = new Date(); var dates = [] for (let i = 0; i < numDates; i++) { let dateString = today.toLocaleDateString('en-US'); dates.push(dateString); today.setDate(today.getDate() + 1); } return dates;}export function GET() { let length = getRandomNumber(1, 10); let numberData = Array.from({ length: length }, () => getRandomNumber(10, 30)); let dateData = generateDates(length); return json({dates: dateData, numbers: numberData});}
The length of the data from the endpoint is randomly selected between 1 and 10 and the starting date begins with the current date. An example output of the API endpoint:
{"dates":["2/8/2024","2/9/2024","2/10/2024"],"numbers":[14,23,23]}
I would like to extract the Bar
chart-specific code into a separate component for more readability and reusability. However, the labels
and the datasets[0].data
attributes reactively change when fetching (generating) new data.
How to extract a Chart.js chart with reactive attributes as a separate component?