Start at Mike Bostock's Towards Reusable Charts.
I’d like to propose a convention for encapsulating reusable charts in D3. Wait for it…
A function; the standard unit of code reuse!
Reusable charts are self-contained functions.
They have a defined "API" that's passed configuration options through getter-setter methods.
// A function encapsulating all your chart logic
import ReusableChart from 'my-reusable-chart';
// Create a new instance of the chart
const myChart = ReusableChart();
// Set some configuration
myChart.height(300);
myChart.width(600);
// (...also, get configuration)
myChart.height();
// 300
// Draw it
d3.select('#chart').call(myChart);
Component charts are just reusable charts that are guaranteed to render idempotently.
Idempotent? Elevator buttons!
"Idempotence" just means we can call the chart function over and over and the chart will only change/re-render when it's passed new configuration like this:
({ height, width }) => < Renders >
({ height, width }) => # nothing
({ height, width }) => # nothing
({ newHeight, width }) => < Re-Renders >
({ newHeight, width }) => # nothing
🔑 Idempotence is the key to integrating with reactive frameworks.