Techno Blender
Digitally Yours.

Svelte & Data Visualisation. Creating interactive bar chart with… | by Sutan Mufti | Mar, 2023

0 44


Svelte Bar Chart (source: author, 2023)

Creating interactive bar chart with Svelte

Data visualisation draws insight to what lives in our data. The usual way is to make graphs or maps. We can do this, usually in a spreadsheet software such as Microsoft Excel or Google Sheets. Usually this is enough, but we can make it fancier by adding interactivity. A simple example of adding interactivity is by adding a slicer which filters our data based on the category. In Microsoft Excel, we can activate the “developer” tab and add form elements such as buttons, check lists, etc.

With modern software technology, the classic tool to create such an interactive data experience is using d3.js in a vanilla javascript. It’s amazing how simple it works yet the result can be beautiful. However, the vanilla javascript feels outdated compared to modern frameworks such as React, Angluar, Vue, etc. People know these frameworks, but I feel like there is one UI framework for data visualisation that is underrated; you guessed it by the title, this is Svelte. Considering its young ecosystem, I think this amazing framework needs to be popularised to reach more people to either employ it or develop it; particularly for data science.

This article demonstrate Svelte in visualising data interactively (code link in the following github link). First, I will briefly explain its feature that distinguishes itself from other frameworks. Second, I will brief the data we are going to visualise, and our features. Finally, I will explain some snippets of how the code works; I am more focusing on the ideas rather to the syntaxes. At the end, we will make the interactive data UI like the article’s main gif image.

Code

Code is available in the following link.

Demo

you can find the demo here:

Svelte is a framework to create User Interface by compiling its files into plain vanilla html + javascript and css. Svelte-kit is the fresh meta-framework to develop a svelte application. It just reached v1.0 just last december (2022). This is the great tool to start and manage svelte application.

After months of using Svelte, I have fallen in love with the framework because of its amazing features. Personally, these features make them stand out and give amazing developing experience. For data science & visualisation, I think these features are the most useful:

  • HMR (Hot-Module Replacement): when developing, the app persists its state while we change our code. This means live changes directly reflected in the browser while keeping the variable.
  • Native Reactivity: This will be demonstrated as the main feature of our app in this article! We do not have to manage the state in svelte. If you are familiar with React, this replaces the useState hook. Although, we still have to manage the connectivity between states in many components. A very small code to demonstrate this feature; click a button, generate a random number, and display it in an html element:
<!-- ./randomiser.svelte -->
<script lang='ts'>
let theValue: number = 40;
function randomiser(){theValue = Math.floor(Math.random() * 100);}
</script>
<button on:click={randomiser}>random!</button><br>
<p>the value: {theValue}</p>
Randomiser App (source: author, 2023)

You can paste the above code into a svelte file as is!

Randomiser App Code (source: author, 2023)
  • Data Binding: like Document.querySelector , the bind syntax attaches an element to the script’s variable. I think it’s easier to manage HTML element this way. I’ve given an example in looping and binding in the github repository.
binding (source: author, 2023)

Building the interface requires a knowledge in HTML, Javascript and CSS. I prefer typescript to mitigate bug development as it makes us writing our code stricter than plain javascript. Now, let’s use the features (binding, reactivity, and HMR). The steps that I will discuss are:

  • setting up the theme using +layout.svelte
  • setting up the data to be imported using ES6 syntax
  • putting things together

Setting up the Theme

First, I like to start with the root layout’s style. the +layout.svelte file defines the behaviour of all the svelte file. In this file, I only set the fonts, color, margin, and background colour. This is basically the “theme” of the app. Let’s keep it simple for this demo, at least it’s not the default.

<!-- +layout.svelte -->
<svelte:head>

<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #303030;
margin: 0;
background-color: #ebebeb;

}

</style>
</svelte:head>

<slot></slot>

Setting up the Data

For this demo, we will use population data from the Greater London Area, UK. You can find the data here. The data comes in csv format, and it is advisable to convert it into JSON format. Using pandas this is very simple thanks to the to_json("data.json", orient="record") . Please note the orient argument as this is the structure that is simpler to work with; which is a schema-less style data like MongoDB. This way, we can use forEach or map method in Javascript to only one array.

In the ES6 syntax, we can use import to import variables or objects from other script files. As our data is basically a JSON, we can define this as a variable like this example:

// data.ts
export const data = [
{name: "sutan", article: "Visualising Data with Svelte"},
{name: "sutan", article: "Spatial Data Science"},
{name: "someone", article: "somedata"}
//... and many more rows
]

then we can import and de-structure the data into the main script file

// main.ts

import {data} from './data.ts'

interface Record {
name: string;
article: string;
}

function main(data: Record[]){
data.forEach(record=>console.log(`${record.name} wrote ${record.article}`))
}
main(data)

In my example, we store the London population data in ./src/routes/population_london.ts under the variable name LondonData.

Let’s divide this section to two subsections: handling the user’s events and actually visualising the data.

Binding & the User’s Events

First, we create an option form field that user can use to select a borough. Look at the following code, we use bind the form value into the selectionIndex . In the future components, we can use selectionIndex that dynamically changes following the user’s events.

<div>
density of
<select bind:value={selectionIndex}>
{#each data as d,i}
<option value={i}>{d.Name}</option>
{/each}
</select>
is {selectedDensity} per square km
</div>

Visualising the Data

borrowing the idea in d3.js development paradigm, I am using the SVG to visualise the graph. Svelte comes with the native each syntax to loop over the variables. For each record in our population data, we want to create a rectangle and set the height to the density data. Look at the height attribute of the rect.

Then, the on:click attribute handles the click event when the user clicks on a bar. It’s callback that executes a function that takes the index of the rectangle’s argument. The activateSelection(index: number) basically sets the binded selectionIndex in the previous subsection. when the selectionIndex changes, the select-option form’s value also changes.

<svg width={data.length * barwidth / 100} height={maxHeight} >
<g >
{#each data as d,i}
<rect height={d.Population_per_square_kilometre / scaling} y={maxHeight - d.Population_per_square_kilometre / scaling} width={barwidth/100*0.8} x={(i * barwidth / 100 * 1)} fill={(i == selectionIndex)? "black": "grey"} on:click={()=>{return activateSelection(i)}} on:keydown={()=>{}}></rect>
{/each}
</g>
</svg>

The equivalent code in d3.js is as follows:

// usingD3.js
const graph = d3
.select("svg")
.selectAll("rect")
.data(LondonData)
.enter()
.append("rect")
.attr("width", (d)=>d.Population_per_square_kilometre)
.on("click",handleClick)

Using the static adapter, we can build this into an ordinary index.html file to be served statically in a web-server such as apache httpd. The following link is the published demo; which is also this article main image at the top.

I think Svelte is an underrated tool in general, moreover for interactive data visualisation. In this demo, we do not even require additional libraries for data visualisation in a svelte app. I literally just imported the data and… display it using svelte. For now everything is static as I think this is enough to demonstrate the visualisation bit. What’s more interesting is that we haven’t explored the full exent of what svelte can do in this article. For instance, utilising +server.js to build API and integrate it into our app; or using the transition effects; or building components to enhance how the graph looks. One thing is for sure:

The future of data visualisation with Svelte is exciting.

I hope you found this article useful. Thank you for reading.


Svelte Bar Chart (source: author, 2023)

Creating interactive bar chart with Svelte

Data visualisation draws insight to what lives in our data. The usual way is to make graphs or maps. We can do this, usually in a spreadsheet software such as Microsoft Excel or Google Sheets. Usually this is enough, but we can make it fancier by adding interactivity. A simple example of adding interactivity is by adding a slicer which filters our data based on the category. In Microsoft Excel, we can activate the “developer” tab and add form elements such as buttons, check lists, etc.

With modern software technology, the classic tool to create such an interactive data experience is using d3.js in a vanilla javascript. It’s amazing how simple it works yet the result can be beautiful. However, the vanilla javascript feels outdated compared to modern frameworks such as React, Angluar, Vue, etc. People know these frameworks, but I feel like there is one UI framework for data visualisation that is underrated; you guessed it by the title, this is Svelte. Considering its young ecosystem, I think this amazing framework needs to be popularised to reach more people to either employ it or develop it; particularly for data science.

This article demonstrate Svelte in visualising data interactively (code link in the following github link). First, I will briefly explain its feature that distinguishes itself from other frameworks. Second, I will brief the data we are going to visualise, and our features. Finally, I will explain some snippets of how the code works; I am more focusing on the ideas rather to the syntaxes. At the end, we will make the interactive data UI like the article’s main gif image.

Code

Code is available in the following link.

Demo

you can find the demo here:

Svelte is a framework to create User Interface by compiling its files into plain vanilla html + javascript and css. Svelte-kit is the fresh meta-framework to develop a svelte application. It just reached v1.0 just last december (2022). This is the great tool to start and manage svelte application.

After months of using Svelte, I have fallen in love with the framework because of its amazing features. Personally, these features make them stand out and give amazing developing experience. For data science & visualisation, I think these features are the most useful:

  • HMR (Hot-Module Replacement): when developing, the app persists its state while we change our code. This means live changes directly reflected in the browser while keeping the variable.
  • Native Reactivity: This will be demonstrated as the main feature of our app in this article! We do not have to manage the state in svelte. If you are familiar with React, this replaces the useState hook. Although, we still have to manage the connectivity between states in many components. A very small code to demonstrate this feature; click a button, generate a random number, and display it in an html element:
<!-- ./randomiser.svelte -->
<script lang='ts'>
let theValue: number = 40;
function randomiser(){theValue = Math.floor(Math.random() * 100);}
</script>
<button on:click={randomiser}>random!</button><br>
<p>the value: {theValue}</p>
Randomiser App (source: author, 2023)

You can paste the above code into a svelte file as is!

Randomiser App Code (source: author, 2023)
  • Data Binding: like Document.querySelector , the bind syntax attaches an element to the script’s variable. I think it’s easier to manage HTML element this way. I’ve given an example in looping and binding in the github repository.
binding (source: author, 2023)

Building the interface requires a knowledge in HTML, Javascript and CSS. I prefer typescript to mitigate bug development as it makes us writing our code stricter than plain javascript. Now, let’s use the features (binding, reactivity, and HMR). The steps that I will discuss are:

  • setting up the theme using +layout.svelte
  • setting up the data to be imported using ES6 syntax
  • putting things together

Setting up the Theme

First, I like to start with the root layout’s style. the +layout.svelte file defines the behaviour of all the svelte file. In this file, I only set the fonts, color, margin, and background colour. This is basically the “theme” of the app. Let’s keep it simple for this demo, at least it’s not the default.

<!-- +layout.svelte -->
<svelte:head>

<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #303030;
margin: 0;
background-color: #ebebeb;

}

</style>
</svelte:head>

<slot></slot>

Setting up the Data

For this demo, we will use population data from the Greater London Area, UK. You can find the data here. The data comes in csv format, and it is advisable to convert it into JSON format. Using pandas this is very simple thanks to the to_json("data.json", orient="record") . Please note the orient argument as this is the structure that is simpler to work with; which is a schema-less style data like MongoDB. This way, we can use forEach or map method in Javascript to only one array.

In the ES6 syntax, we can use import to import variables or objects from other script files. As our data is basically a JSON, we can define this as a variable like this example:

// data.ts
export const data = [
{name: "sutan", article: "Visualising Data with Svelte"},
{name: "sutan", article: "Spatial Data Science"},
{name: "someone", article: "somedata"}
//... and many more rows
]

then we can import and de-structure the data into the main script file

// main.ts

import {data} from './data.ts'

interface Record {
name: string;
article: string;
}

function main(data: Record[]){
data.forEach(record=>console.log(`${record.name} wrote ${record.article}`))
}
main(data)

In my example, we store the London population data in ./src/routes/population_london.ts under the variable name LondonData.

Let’s divide this section to two subsections: handling the user’s events and actually visualising the data.

Binding & the User’s Events

First, we create an option form field that user can use to select a borough. Look at the following code, we use bind the form value into the selectionIndex . In the future components, we can use selectionIndex that dynamically changes following the user’s events.

<div>
density of
<select bind:value={selectionIndex}>
{#each data as d,i}
<option value={i}>{d.Name}</option>
{/each}
</select>
is {selectedDensity} per square km
</div>

Visualising the Data

borrowing the idea in d3.js development paradigm, I am using the SVG to visualise the graph. Svelte comes with the native each syntax to loop over the variables. For each record in our population data, we want to create a rectangle and set the height to the density data. Look at the height attribute of the rect.

Then, the on:click attribute handles the click event when the user clicks on a bar. It’s callback that executes a function that takes the index of the rectangle’s argument. The activateSelection(index: number) basically sets the binded selectionIndex in the previous subsection. when the selectionIndex changes, the select-option form’s value also changes.

<svg width={data.length * barwidth / 100} height={maxHeight} >
<g >
{#each data as d,i}
<rect height={d.Population_per_square_kilometre / scaling} y={maxHeight - d.Population_per_square_kilometre / scaling} width={barwidth/100*0.8} x={(i * barwidth / 100 * 1)} fill={(i == selectionIndex)? "black": "grey"} on:click={()=>{return activateSelection(i)}} on:keydown={()=>{}}></rect>
{/each}
</g>
</svg>

The equivalent code in d3.js is as follows:

// usingD3.js
const graph = d3
.select("svg")
.selectAll("rect")
.data(LondonData)
.enter()
.append("rect")
.attr("width", (d)=>d.Population_per_square_kilometre)
.on("click",handleClick)

Using the static adapter, we can build this into an ordinary index.html file to be served statically in a web-server such as apache httpd. The following link is the published demo; which is also this article main image at the top.

I think Svelte is an underrated tool in general, moreover for interactive data visualisation. In this demo, we do not even require additional libraries for data visualisation in a svelte app. I literally just imported the data and… display it using svelte. For now everything is static as I think this is enough to demonstrate the visualisation bit. What’s more interesting is that we haven’t explored the full exent of what svelte can do in this article. For instance, utilising +server.js to build API and integrate it into our app; or using the transition effects; or building components to enhance how the graph looks. One thing is for sure:

The future of data visualisation with Svelte is exciting.

I hope you found this article useful. Thank you for reading.

FOLLOW US ON GOOGLE NEWS

Read original article here

Denial of responsibility! Techno Blender is an automatic aggregator of the all world’s media. In each content, the hyperlink to the primary source is specified. All trademarks belong to their rightful owners, all materials to their authors. If you are the owner of the content and do not want us to publish your materials, please contact us by email – [email protected]. The content will be deleted within 24 hours.

Leave a comment