Wrap any code you find in a React component and meet your deadline 🤫
Ever find some good looking code online that you really want to use, but it just isn't quite React?
This happens a lot with data visualization. You find a great example, you have no idea how it works, you just wanna see how it looks in your React app.
Rewriting it all in React for a quick test is out of the question. You're not even sure how it's doing that thing you love so much.
Enter D3blackbox
.
Turn your code into a function, pass it into D3blackbox()
, voila: Self-contained React component.
👉 github.com/Swizec/d3blackbox
1. Install d3blackbox
and d3
$ npm install d3blackbox d3
2. Wrap D3 code in D3blackbox
import React from "react"
import D3blackbox from "d3blackbox"
import * as d3 from "d3"
const Barchart = D3blackbox(function (anchor, props) {
const svg = d3.select(anchor.current)
// the rest of your D3 code
})
export default Barchart
D3blackbox
is a higher order component that takes a render function.
It renders an anchor element and gives your renderer a React ref and all the props. You take over that anchor element with D3, or any other library, and do what you want.
D3blackbox
makes sure to call your renderer on mount and every component update. You're never going to see a stale render, I promise.
3. Render your component
<barchart x={10} y={10} width={300} height={200}></barchart>
Once you've created a D3blackbox'd React component, render as usual. If you want to change the anchor element, use the component
prop.
You now have a reusable declarative component. 👌
You can render anything you want. No matter how complex the code you've found, D3blackbox can take it all.
Here's an example of an interactive donut chart with tooltips. Didn't even need to read the D3 code. 😇
What about hooks?
Yep, there's a hook version too. useD3
Same principle: anchor element, call D3 code on every update. Except with hooks there's less code you have to write.
Works like this 👇
import { useD3 } from "d3blackbox";
function renderSomeD3(anchor) {
d3.select(anchor);
// ...
}
const MyD3Component = ({ x, y }) => {
const refAnchor = useD3(anchor => renderSomeD3(anchor));
return <g ref={refAnchor} transform={`translate(${x}," ${y})`} />;
};
</g>
You call useD3
, give it a render function, and receive a React ref. Your render function should take care of all the rendering, and the component where you call the hook needs to render the anchor element.
I recommend always adding a transform
so you can position your components in an SVG.
The useD3
hook takes care of setting up a useRef
and a useEffect
hook so you don't have to worry about that.
Meet your deadline in 2 minutes :)
What about other code?
You got it! There's nothing D3-specific in D3blackbox
and useD3
at all.
They're generic wrappers for 3rd party code that wants to take over rendering inside a DOM element. React controls the wrapper, 3rd party render function controls the children.
You can even use this to wrap Vue components in React components. Or jQuery plugins. Or Three.js code. Anything your heart desires.
This feels dirty
It does. It is.
You should use D3blackbox for quick prototypes, using example code that you don't want to rewrite, or small components where the performance hit doesn't matter.
Using D3blackbox you are throwing away and redrawing the entire DOM subtree of your anchor element. The more such components you have and the bigger they are, the more performance will suffer.
This can lead to redraws measured in seconds on large dashboards. When that happens, I recommend React+D3 where I teach a more scalable approach with deep understanding of what's going on.
But for quick and dirty, this is perfect. 👌
With love ❤️
Built with love this weekend and open sourced last night.
I've been teaching this method in talks, workshops, books, and courses for 3 years now. Every time, I said: "Hm, I should open source this. Why am I asking you to copy paste?”
Now I finally did. Enjoy
Continue reading about Announcing D3blackbox and useD3
Semantically similar articles hand-picked by GPT-4
- Easy D3 blackbox components with React hooks
- Livecoding Recap: A new more versatile React pattern
- This is Yak Shaving
- How you can translate any random D3 example to React
- JavaScript’s most popular dataviz library
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️