Data Visualization with Svelte and D3.js

| Kristijan Barišić

Creating Interactive Data Visualizations with Svelte and D3.js

Introduction

In today's digital age, effective data visualization is essential for communicating complex information. In this blog post, we'll explore how to combine the power of Svelte and D3.js to craft engaging and interactive data visualizations.

In our recent project called AI Start combining D3.js with Svelte opened the door for us to present data in a simple visual format, giving users more interactive way to search through the data.

aistart-dashboard

Why Choose Svelte for Data Visualization?

Svelte is a modern JavaScript framework used for building user interfaces. It is designed to be highly efficient and compiles components into highly optimized vanilla JavaScript during build time. Svelte focuses on simplicity and performance. It uses a reactive paradigm, where components update in response to changes in data without the need for a virtual DOM. Svelte is well-suited for creating dynamic and interactive user interfaces.

animated-bar-chart

Why Incorporate D3.js?

D3 is a powerful JavaScript library for creating dynamic, interactive data visualizations using HTML, CSS, and SVG. It provides tools for binding data to the DOM and manipulating the DOM based on the data. D3 is commonly used for creating charts, graphs, maps, and other data visualizations. It gives fine-grained control over the appearance and behavior of visual elements.

Setup

Click here to see the project setup

Create Svelte project:

The simplest way to create Svelte project is with Vite by running command:

npm create vite@latest
# In Vite installation menu select the svelte option and follow the instructions.

Install dependencies:

npm install d3
npm install d3-geo

Building Your First Svelte Component with D3.js

Here's an example of how you might integrate D3.js to Svelte component BarChart.svelte:

<!-- BarChart.svelte -->
<script>
  // Import necessary Svelte functions and D3 library
  import {onMount} from 'svelte';
  import * as d3 from 'd3';

  // Data array for the bar chart
  let data = [7, 15, 23, 10, 18, 30, 5];

  // Function to set up the chart on component mount
  onMount(() => {
    // Select the chart container and append an SVG element
    const svg = d3
      .select('.chart-container')
      .append('svg')
      .attr('width', '100%')
      .attr('height', 200);

    // Define the width of each bar
    const barWidth = 25;

    // Bind data to rectangles and create the bars
    svg
      .selectAll('.bar')
      .data(data)
      .enter()
      .append('rect')
      .attr('class', 'bar')
      .attr('x', (d, i) => i * (barWidth + 5)) // Calculate x position for each bar
      .attr('y', d => 200 - d * 10) // Calculate y position for each bar
      .attr('width', barWidth) // Set the width of each bar
      .attr('height', d => d * 10) // Set the height of each bar
      .attr('fill', '#007acc'); // Set the fill color of each bar
  });
</script>

<!-- Container for the chart -->
<div class="chart-container"></div>

<style>
  /* Styles for the chart container */
  .chart-container {
    margin: 20px;
  }
</style>

Adding Interactivity and Enhancing UX

Interactivity is key in data visualization. With Svelte's event handling, adding interactions is a breeze. Here's an example of highlighting data points on hover:

<!-- BarChart.svelte -->
<script>
  // Import necessary modules from Svelte and D3.js
  import {onMount} from 'svelte';
  import * as d3 from 'd3';

  // Data for the bar chart
  let data = [7, 15, 23, 10, 18, 30, 5];

  // Execute code when the component is mounted
  onMount(() => {
    const svgWidth = '100%'; // Width of the SVG container
    const svgHeight = 300; // Height of the SVG container
    const barWidth = 25; // Width of each bar
    const topPadding = 50; // Padding at the top of the SVG

    // Select the chart container and append an SVG element
    const svg = d3
      .select('.chart-container')
      .append('svg')
      .attr('width', svgWidth)
      .attr('height', svgHeight + topPadding);

    // Create bars based on the data
    svg
      .selectAll('.bar')
      .data(data)
      .enter()
      .append('rect')
      .attr('class', 'bar')
      .attr('x', (d, i) => i * (barWidth + 5)) // Position each bar horizontally
      .attr('y', d => svgHeight - d * 10 + topPadding) // Position each bar vertically
      .attr('width', barWidth) // Set the width of each bar
      .attr('height', d => d * 10) // Set the height of each bar
      .attr('fill', '#007acc') // Set the fill color of bars
      .on('mouseover', function (event, d) {
        d3.select(this).attr('fill', '#ff6347'); // Change color on hover

        // Show value as tooltip
        const tooltip = svg
          .append('text')
          .attr('class', 'tooltip')
          .attr('x', parseFloat(this.getAttribute('x')) + barWidth / 2)
          .attr('y', parseFloat(this.getAttribute('y')) - 5)
          .attr('text-anchor', 'middle')
          .style('fill', '#808080')
          .text(d);
      })
      .on('mouseout', function () {
        d3.select(this).attr('fill', '#007acc'); // Restore original color

        // Remove tooltip on mouseout
        svg.select('.tooltip').remove();
      });
  });
</script>

<!-- Container for the chart -->
<div class="chart-container"></div>

<style>
  /* Styles for the chart container */
  .chart-container {
    height: 350px;
    margin: 20px;
    display: flex;
    align-items: flex-end; /* Align SVG to the bottom */
  }

  /* Styling for the tooltip */
  .tooltip {
    font-size: 12px;
    font-weight: bold;
  }
</style>

More examples

You can take a look at our public Github repository where you can find this examples and more complex charts.

Performance Best Practices

Optimizing performance for large datasets is essential. Svelte's inherent optimizations and D3.js best practices can significantly enhance rendering speed. Use techniques such as data aggregation, proper scale usage, and minimizing DOM updates.

Conclusion

Combining the strengths of Svelte and D3.js empowers developers to create impactful and interactive data visualizations. By harnessing Svelte's reactivity and D3's data manipulation capabilities, you can bring your data to life and captivate your audience with informative and engaging visual experiences.

Additional Resources