Typescript: D3’s Loyal Sidekick
My roadmap to becoming a D3 Wonder Woman
If D3.js was a superhero, Typescript would be its loyal sidekick. Let me tell you why through two case studies in my D3 learning roadmap.
There is a stack of desirable benefits to using typed languages when coding:
- Ability to write JavaScript with libraries and frameworks you barely know
- Easier programmability when working with large and unfamiliar codebases
- Code suggestions from the editor
- Improved data organization, planning, and readable code for yourself and your collaborators
- A reminder of the code you wrote and are already forgetting
In Typescript, you plan out what variables you are working with before they are defined, transforming you into the well-organized coder that you’ve been too lazy to pursue. I’ll work on persuading you of a couple of the above points, starting with an example from my first case study. Below I introduce a my first villan point with a name and weight, which I call a “Villan” type.
type Villan = {name: string;
fortune: number;}function getVillansFortune(villan: Villan){return `${villan.name} is worth ${villan.fortune} billion dollars.`;}
Now, our function only accepts objects that match our definition of ‘Ingredient’. If we pass something else, we get an error:
getVillansFortune({name: “C. Montgomery Burns”, fortune: 1.5}) // Returns “C. Montgomery Burns is worth 1.5 billion dollars”getVillansFortune({}) // Argument of type ‘{}’ is not assignable to parameter of type ‘Villan’. Type ‘{}’ is missing the following properties from type ‘Villan’: name, fortune.
No more vague bugs! In fact, research shows that just by using typed languages you will get 15 percent fewer bugs in your code. Airbnb, which has adopted Typescript company-wide, found that 38 percent of bugs would have been preventable with Typescript.
I opted for visx, a data visualization library from Airbnb that brings together D3, React, and Typescript (aka my Holy Trinity) and thus allows a gentle introduction to D3. In honesty, I credit visx with my discovery of the glorious Typescript/Data Visualization Engineering pairing and the subsequent use of Typescript to learn unfamiliar libraries.
The MisoDonut Example (😋)
This example starts in the MisoDonut component (😋) of an application I created that calculates fermentation brine ratios and uses data visualizations to visualize them. Anyone who works with D3 knows how many lines of code it takes to get the end of the D3 code. Whether in D3 or with visx, the data visualization I made was between 200–300 lines of code! All that for a pie without a center, or a fancy line in a half-opened box. You can imagine it would be easy to get lost in all the functions, declarations, and especially the new D3 methods I was learning. Enter Typescript. It won’t let you forget what you’ve already defined and includes its definition when you hover over the word.
Without having to refer to existing code, I knew what “misoKeys” could contain: an id, koji, legume, salt, label, type, time, and it would be an array.
This feature was an asset while learning visx and unfamiliar D3 syntax, which I accomplished through code snippets and playgrounds rather than tutorials. I methodically went through each line of sample code, hovering over each type, and subsequently replicating them with my own dataset. I observed how my data matched the sample data or changed if I altered the syntax. It’s easy to get overwhelmed when faced with 300 lines of unfamiliar code and concepts. Luckily, Typescript’s definitions and suggestions significantly eased the learning curve and the potential bugs that were bound to appear. All I had to do was hover over each variable, or type to see what it contained, or should contain — kind of like a built-in annotator.
By hovering over the above function snippet, I knew that for ‘fromLeaveTransition’ to work, I’d need to give it an end angle, which would be attached to my PieArc data, and I’d use three numbers, which manifest as a start angle, end angle, and opacity, in order to calculate the transitions. Knowing the structure of similar functions made understanding them, and adapting them to my needs, all that much easier.
In a previous article, a musing from my boot camp days, I talked about how you might spend more time than you’d like to admit searching for a bug in your “correct” code only to find that you misspelled something. Typescript has your back.
Thanks Typescript! I did mean ‘fromLeaveTransition’! Who needs copy editors anymore if Typescript corrects your syntax and logic in the editor?
Now for the final pie:
Pretty sweet, huh?
Joining Forces with D3
I learned D3 in ultimately the same fashion as visx.
- Find sample code in Observable or Vizhub
- Conduct a first pass going through the code line by line to find unfamiliar syntax or methods
- Lookup any unfamiliar syntax in the docs
- Import my own dataset
- Replicate the sample code to render my own dataset
The above method worked extremely well for me, although everyone has different learning strategies. Nevertheless, I was aware of D3’s reputation of having a steep learning curve even before I started coding. Let me tell you, I was not disappointed.
The problem I encountered while learning D3, is that it’s like an iceberg. About 80 percent of your code doesn’t seem to get rendered; it’s just a few magical lines that do the trick. As such, I spent hours fighting for any sign of a line to appear for my first graph. Once my single-joint line rendered, the rest came together within 30 minutes.
I found the most trying concept of D3 to be scale functions, which are a vital organ of D3. Essentially, scales map data to a visual representation — translating say 20 grams to a sized SVG container and ensuring proportions are respected. When working with online editors such as Observable and VizHub, I found myself constantly looking up definitions for various scales and accessory functions. However, once I installed D3 types into my project, definitions were only a hover away and more explicit to boot.
In my D3 ‘scaleBand’ function, Typescript tells me it takes a string and can take a range, which is always a number. Sure enough, scale bands are often used for charts with categorical data, mapping strings to numbers, which is how I’m using it above by passing in a string. Typescript even provides me with an in-line definition of the method. How convenient! Thank you, Typescript.
Although I’d used Typescript before, it was only after learning D3 that I unlocked its potential. AirBnB’s company-wide Typescript conversion seems like a no-brainer now: fewer bugs, easy to onboard unfamiliar code to new developers, all the while providing helpful reminders. Whether it be D3 or the next technology on my bucket list, I’m glad that I have my faithful tutor, Typescript.
My Favorite Typescript & D3.js Learning Resources
Typescript
D3.js
- Vizhub (especially for combining D3 & React)
- Observable
- Amelia Wattenberger & her book and now video course Fullstack Data Visualization with D3
Max is a life-long learner, former linguist turned data visualization engineer. Looking to tie her biology, research, linguistic, and museum experiences together she found an intersection with data visualization. She believes strongly in making research and data accessible to all.