Maps with D3 and Svelte

This blog is fourth in a series of (unofficial) course notes for the Data Visualization with React and D3 series by Curran Kelleher. Read the introductory blog post here.

The next chart in the series is a simple map of the world. In this chart Curra…


This content originally appeared on DEV Community and was authored by AnupJoseph

This blog is fourth in a series of (unofficial) course notes for the Data Visualization with React and D3 series by Curran Kelleher. Read the introductory blog post here.

The next chart in the series is a simple map of the world. In this chart Curran actually uses a Topojson file, then converts it into Geojson and then plots it. I am not planning to do that as it seems complicated and also for some reason the topojson library does not play nice with Node on my computer and I was too lazy to actually debug it 😬. So instead I are going to use a simple geojson I found on D3 Graph Gallery.

I am going to start from a fresh Svelte project instead of carrying on from the last. To do and install d3 along with its:

npx degit sveltejs/template world-map
cd word-map
npm install
npm install d3

And to run the app itself:

npm run dev

Let clean everthing in the App.svelte. The dataset for the map is available here. Let's use the d3 json method to load in the data and use it.

import { json } from  "d3";

let  dataset  =  [];
json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson"
).then((data)  => {
    dataset  =  data.features;
});

I am only using the features array in the geojson and this contains everything we need to draw the map. Let's start by making an SVG in the markup and adding a width and height property to it.

<script>
    const  width  =  1200,
    height  =  600;
</script>
<main>
    <svg  {width}  {height}>
    </svg>
</main>

If you console.log the dataset at this point (and well go deeper and deeper into the json tree) you'll notice that the geojson contains the boundary information using a construct called geometry. The only problem with this is that, this construct is not a svg path and is instead of course a co-ordinate you can plot. To solve this problem D3 provides a powerful geographic path generator, d3.geoPath which can take in a given GeoJSON feature or geometry to generate an SVG path.

D3 also provides a lot of geographical projections as well to transform how the map looks like. I am going to split out this logic to drawing the paths themeselves into a different component called Marks. So let import the new component into App.svelte like so:

import Marks from "./Marks.svelte"

And pass the dataset to the component like so:

<Marks  {dataset} />

Now of course this component does not exist, so lets go about making it real. We'll also import the projections and path generator,

<script>
    import { geoPath, geoNaturalEarth1 } from  "d3";
    export let  dataset  =  [];
    const  projection  =  geoNaturalEarth1();
    const  path  =  geoPath(projection);
</script>

Afterwards its really easy. We just need to iterate over the dataset and pass the data to the path function:

{#each  dataset  as data}
    <path  d={path(data)} />
{/each}

And now we have it, a perfectly horrible world map,
World map basic
I actually kind of like the stark, edgy nature of the map. I was going to style this, but this is actually rather nice.

So of course the next part will be dedicated to showing off a cool svelte feature I just found. Let first remove all the fill colour from the map and add a stroke.

<style>
    path {
        fill: none;
        stroke:darkgreen;
    }
</style>

Simple styled world map

Svelte has great support for styling. One thing I like in particular are the transition directives. These are tools for using motion more effectively and gracefully in your app and generally making it look smoother.
Lets import the draw function from svelte/transitons and add it to the path tag.

<script>
    import { draw } from  "svelte/transition";
</script>
<path  transition:draw={{ duration: 5000, delay: 0 }}  d={path(data)} />

Map draw gif

These transition directives actually pack in a lot of flexibility. We can pass in custom easing function to control the speed of the transition and we can even pass in custom CSS and JS to control the transtitions.

import { quadInOut } from  "svelte/easing";
<path
    transition:draw={{ duration: 5000, delay: 0, easing: quadInOut }}
    d={path(data)}
/>

Image description

Personally I think that's just awesome 🚀. Here's the final code.

Well that's it for today. Hope you have a nice day!


This content originally appeared on DEV Community and was authored by AnupJoseph


Print Share Comment Cite Upload Translate Updates
APA

AnupJoseph | Sciencx (2021-11-15T07:30:35+00:00) Maps with D3 and Svelte. Retrieved from https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/

MLA
" » Maps with D3 and Svelte." AnupJoseph | Sciencx - Monday November 15, 2021, https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/
HARVARD
AnupJoseph | Sciencx Monday November 15, 2021 » Maps with D3 and Svelte., viewed ,<https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/>
VANCOUVER
AnupJoseph | Sciencx - » Maps with D3 and Svelte. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/
CHICAGO
" » Maps with D3 and Svelte." AnupJoseph | Sciencx - Accessed . https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/
IEEE
" » Maps with D3 and Svelte." AnupJoseph | Sciencx [Online]. Available: https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/. [Accessed: ]
rf:citation
» Maps with D3 and Svelte | AnupJoseph | Sciencx | https://www.scien.cx/2021/11/15/maps-with-d3-and-svelte/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.