📅 3 years ago 🕒 10 min read 🙎♂️ by Madza
Data has always been easier to perceive in a visual way. Visualization of the data allows us to see the tendencies over periods of time, allows us to compare different data as well makes it easier to see the totals, highlights, lows, and so on.
One of the most common ways to visualize data in software is analytics panels. We see them in most backend systems to display the visitor engagement data, user activity metrics, server stats, and other metrics.
In this article, we will build an analytics dashboard in Svelte. We will focus on how to create the components, separate the data from the code and implement the logic.
For reference here is the source code for the final project.
We will create a server statistics dashboard, that will display statistics via three different types of charts. There will be one line chart, two bar charts, and three doughnut charts.
The line chart will display the visitor stats across the six-month period. The bar charts will display the most visited pages as well as top referrers that bring traffic to the site. Finally, the doughnut charts will display user OS, browser, and device usages.
The layout of the analytics dashboard is shown in the wireframe below:
To scaffold a new Svelte project we will use degit, a tool that is used to set up the fully functional Svelte app using the minimal template. Open up your terminal and run the following command: npx degit sveltejs/template svelte-analytics
.
After that change your working directory to the newly created folder by running cd svelte-analytics
. Then install all the necessary dependencies for the Svelte project to work by running the command npm install
.
Then run npm run dev
in your terminal and navigate to https://localhost:8080
in your browser. You should be presented with a Svelte project preview that looks like this:
We will also install an external npm library chart.js that will help us to to create modern-looking and interactive charts. Run npm install chart.js
and wait while the terminal finishes installing the package.
Normally the data would be fetched from the database. Since we will be focusing on how to create the analytics components themselves, we will create a sample data in a separate file and then import it where necessary.
Navigate to the src
folder and create a new file called data.js
inside it. Next, make sure to include the following code in it:
const colors = ["tomato", "gold", "limegreen"]; export const visits = { title: "Unique visitors", type: "line", backgroundColor: colors[0], labels: ["January", "February", "March", "April", "May", "June"], data: [275, 254, 261, 279, 262, 268] }; export const pages = { title: "Top pages", type: "bar", backgroundColor: colors[0], labels: ["/gallery", "/blog", "/about", "/pricing", "/contact"], data: [220, 176, 132, 88, 44] }; export const referrers = { title: "Top referrers", type: "bar", backgroundColor: colors[0], labels: ["google", "twitter", "facebook", "linkedin", "dev.to"], data: [23, 14, 6, 5, 2] }; export const os = { title: "OS usage", type: "doughnut", backgroundColor: colors, labels: ["Win", "MacOS", "Linux"], data: [400, 100, 200] }; export const browsers = { title: "Browser usage", type: "doughnut", backgroundColor: colors, labels: ["Chrome", "Firefox", "Safari"], data: [240, 100, 60] }; export const devices = { title: "Device usage", type: "doughnut", backgroundColor: colors, labels: ["Phone", "Desktop"], data: [220, 260] };
We first created a colors array, that will define the background color for the charts. We used predefined HTML color names "tomato", "gold" and "limegreen", but you can adjust them to any custom color palettes you want to fit your specific project.
Then we created a separate object for each chart consisting of the title, type, background color, labels, and data of the chart. We used export
statements for each variable so we can later import them into the main file App.svelte
and pass them in as props.
To create a chart component that will visualize our data, create a new folder components
in the project root and make a new file Chart.svelte
inside it. Now add the following code in the newly created file:
<script> import Chart from "chart.js/auto"; import { onMount } from "svelte"; let ctx; let chartCanvas; export let type; export let labels; export let data; export let title; export let backgroundColor; export let showLegends = false; onMount(async () => { ctx = chartCanvas.getContext("2d"); const chart = new Chart(ctx, { type, data: { labels, datasets: [ { backgroundColor, data } ] }, options: { plugins: { title: { display: true, text: title }, legend: { display: showLegends, position: "bottom" } } } }); }); </script> <canvas bind:this={chartCanvas}></canvas>
We first imported the Chart
component from the chart.js library. Then we imported the built-in onMount
function from Svelte, which runs after the component is first rendered to the DOM.
Then we created context and canvas variables (ctx
and chartCanvas
) for the chart itself and created variables for the values that we will need to pass in when we import the Chart
component in the main App.svelte
file.
Finally, inside the onMount
functions we created type
, data
, and options
parameters, that we will be used to construct all of the charts. In order to render the Chart
component to the screen, we bound chartCanvas
to the canvas
element.
Now let's put the data and chart component together. Navigate to the src
folder and open the file App.js
. Add the following code inside it:
<script> import Chart from "../components/Chart.svelte"; import { visits, pages, referrers, os, browsers, devices } from "./data.js"; </script> <main> <h3>Monthly Visitors</h3> <section> <Chart {...visits}/> </section> <h3>Top pages and Referrers</h3> <div id="pages"> <section> <Chart {...pages}/> </section> <section> <Chart {...referrers}/> </section> </div> <h3>OS, Browsers and Devices</h3> <div id="devices"> <section> <Chart {...os} showLegends={true}/> </section> <section> <Chart {...browsers} showLegends={true}/> </section> <section> <Chart {...devices} showLegends={true}/> </section> </div> </main>
We first imported the Chart
component and all the data objects we created earlier. Since we used export
statements for each object variable, it was easy to import everything in a single line.
Next, we used a main
wrapper around the whole app, created the h3
titles for the dashboard sections, and used grid layout wrappers for pages
and devices
sections, which will include 2 and 3 charts, respectively.
We then included all the planned Chart
components. Notice we wrapped each Chart
component inside a section
tag. This is because Chart.js needs a parent element to define the width and adjust for responsiveness when viewed on different screen widths.
Finally, we used a JavaScript spread syntax to pass in the required props for the Chart
components. For the last three charts, we will also display the legends, so an additional prop was added that enabled that option.
Now let's add some stylesheet rules to our app so the elements are being displayed as expected. While still on the App.svelte
file, add the following code under the previously written Script tags and HTML:
<style> @import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap"); :global(*) { margin: 0; padding: 0; } :global(body) { background-color: rgb(255, 137, 116); font-family: "Montserrat", sans-serif; } main { max-width: 800px; min-height: 100vh; margin: 0 auto; padding: 0 20px; background-color: rgb(245, 245, 245); } h3 { padding: 20px 0; } section { min-width: 100%; background-color: white; border-radius: 10px; } #pages { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; } #devices { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; padding-bottom: 20px; } @media only screen and (max-width: 560px) { #pages, #devices { grid-template-columns: 1fr; } } </style>
First, we imported Montserrat font and set it to be used throughout the whole app. We also used reset rules for the padding and margin, so the dashboard looks the same on the different browsers. We set the background color of the page to be orange.
For the dashboard itself, we set the width to never exceed 800px
and centered it in the viewport. We also used some padding and set the background color to be light grey. We set some top and bottom padding for the section titles, as well as defined the width, background color as well border-radius for the sections themselves.
For the wrappers that will include multiple charts, we set the layout to be grid and use the grid-template-columns
, that divide the available width of the main wrapper into 2 or 3 columns with equal width, with a 20px
gap between them.
Finally, we created a CSS media rule for both grid wrappers. If the screen width is 560px
or smaller, the grid layout for pages
and devices
switches to 1 column, meaning all the included charts are shown directly below each other.
The last thing left to do after styling would be to test the app. Check if the development server is still running. If it is not, run npm run dev
in your terminal again and visit the https://loclahost:8080
in your browser. You should be presented with the final dashboard, that looks like this:
In this tutorial, we learned how to create reusable chart components. During the process of making the analytics dashboard, we got to know how to separate the data from the code and how to import, export, and pass in the type, data, and options for the charts.
Feel free to adapt and use this template in your own projects. Also, if you want, you can move the data to the database and implement the backend so the data gets updated when the project is being used.
Hopefully, you gained some knowledge and from now on you will feel more comfortable implementing dashboards while working with Svelte.