How To Use D3 In Svelte with TypeScript
Do you want to learn how to use D3 inside your Svelte with TypeScript application? In this quick guide, we will learn exactly that. As an example, we will create a line and a bar chart!
- Install D3
- Use D3 in Svelte with TypeScript – Line Chart
- Use D3 in Svelte with TypeScript – Bar Chart
- Add transition to a chart in Svelte
- Conclusion
Install D3
To install D3 we have to simply install the npm package and in addition its types. For that, we will run:
pnpm install d3
and then:
pnpm install --save-dev @types/d3
Next, we will use it for a line and a bar chart.
Use D3 in Svelte with TypeScript – Line Chart
For showcasing purposes, I will run all of it inside a single page. In case you want to use it in your application you might want to extract the chart into its own Svelte component.
Inside the file, we will import d3, then specify some variables and use them to create the chart. The following code shows an example of a line chart:
Need help or want to share feedback? Join my discord community!
<script lang="ts">
import * as d3 from 'd3';
let data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
export let width = 640;
export let height = 400;
export let marginTop = 20;
export let marginRight = 20;
export let marginBottom = 20;
export let marginLeft = 20;
$: x = d3.scaleLinear([0, data.length - 1], [marginLeft, width - marginRight]);
$: y = d3.scaleLinear(d3.extent(data) as [number, number], [height - marginBottom, marginTop]);
$: line = d3.line((d, i) => x(i), y);
let gx: any;
let gy: any;
$: d3.select(gy).call(d3.axisLeft(y));
$: d3.select(gx).call(d3.axisBottom(x));
</script>
<!-- Add chart -->
<svg width={width} height={height}>
<!-- Add x-axis -->
<g bind:this={gx} transform="translate(0,{height - marginBottom})" color="white" />
<!-- Add y-axis -->
<g bind:this={gy} transform="translate({marginLeft},0)" color="white" />
<!-- Add line -->
<path stroke-width="1.5" d={line(data)} stroke="white" />
<!-- Add data points -->
<g stroke-width="1.5">
{#each data as d, i}
<circle cx={x(i)} cy={y(d)} r="2.5" fill="white" />
{/each}
</g>
</svg>
Next, we will create a simple bar chart.
Use D3 in Svelte with TypeScript – Bar Chart
The following code contains an example of a D3 bar chart implemented:
If this guide is helpful to you and you like what I do, please support me with a coffee!
<script lang="ts">
import * as d3 from 'd3';
let data = [
{ name: "Peter", age: 20 },
{ name: "John", age: 30 },
{ name: "Mary", age: 40 }
];
export let width = 640;
export let height = 400;
export let marginTop = 20;
export let marginRight = 20;
export let marginBottom = 20;
export let marginLeft = 20;
$: x = d3.scaleBand().domain(d3.groupSort(data, ([d]) => -d.age, (d) => d.name)).range([marginLeft, width - marginRight]).padding(0.1);
$: y = d3.scaleLinear().domain([0, d3.max(data, d => d.age) as number]).range([height - marginBottom, marginTop]);
let gx: any;
let gy: any;
$: d3.select(gy).call(d3.axisLeft(y));
$: d3.select(gx).call(d3.axisBottom(x).tickSizeOuter(0));
</script>
<svg width={width} height={height}>
<g bind:this={gx} transform="translate(0,{height - marginBottom})" />
<g bind:this={gy} transform="translate({marginLeft},0)" />
<g fill="transparent" stroke-width="1.5">
{#each data as d, i}
<rect fill="white" x={x(d.name)} y={y(d.age)} height={y(0) - y(d.age)} width={x.bandwidth()} />
{/each}
</g>
</svg>
Add transition to a D3 chart in Svelte
Now that we’ve looked at some examples let’s make them a little fancier using svelte transitions! For that, we will go back to the line chart example. We will create a show
boolean set to false and then change it to true inside the onMount
function. To start the transition we will wrap the path and the circles in if statements and add the transition to the tags:
<script lang="ts">
import * as d3 from 'd3';
import { onMount } from 'svelte';
import { draw, fade } from 'svelte/transition';
let data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
export let width = 640;
export let height = 400;
export let marginTop = 20;
export let marginRight = 20;
export let marginBottom = 20;
export let marginLeft = 20;
$: x = d3.scaleLinear([0, data.length - 1], [marginLeft, width - marginRight]);
$: y = d3.scaleLinear(d3.extent(data) as [number, number], [height - marginBottom, marginTop]);
$: line = d3.line((d, i) => x(i), y);
let gx: any;
let gy: any;
$: d3.select(gy).call(d3.axisLeft(y));
$: d3.select(gx).call(d3.axisBottom(x));
let show = false;
onMount(() => show = true);
</script>
<!-- Add chart -->
<svg width={width} height={height}>
<!-- Add x-axis -->
<g bind:this={gx} transform="translate(0,{height - marginBottom})" color="white" />
<!-- Add y-axis -->
<g bind:this={gy} transform="translate({marginLeft},0)" color="white" />
<!-- Add line -->
{#if show}
<path stroke-width="1.5" d={line(data)} stroke="white"
transition:draw={{easing: t => t, duration: data.length * 200}}/>
{/if}
<!-- Add data points -->
<g stroke-width="1.5">
{#each data as d, i}
{#if show}
<circle cx={x(i)} cy={y(d)} r="2.5" fill="white"
transition:fade={{delay: i * 200}}/>
{/if}
{/each}
</g>
</svg>
Conclusion
With that, we know how to create different charts using D3 inside of Svelte with TypeScript. I hope this guide was helpful to you and if you have any questions feel free to ask!
In case you want to get updated on my newest posts subscribe to my monthly newsletter!
[convertkit form=2303042]