How To Use D3 In Svelte with TypeScript

No Comments
Published: 15.10.2023

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!

Don’t want to read? Watch the video instead!

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:

KOFI Logo

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!

Discussion (0)

Add Comment

Your email address will not be published. Required fields are marked *