This is a blog post describing how I put the "Demonstration of Reusable D3" demo together.
So this write-up describes the components and modules, the structure(s) I used to work with those components & modules, and how this all enabled me to pretty straightforwardly re-use various bits of code.
Before we get going, a bit of terminology:
- From the book: We will call a "component" a reusable piece of code generating graphics, which doesn't represent a complete chart, but a part meant to be composed with other elements.
And finally, a brief word on objects and object orientation. This approach embraces 'composition' rather than inheritance. So rather than rather than build creaky Heath-Robinson-like vertical contraptions (inheritance), we build onion-like structures (composition) that embrace other components. Just something to keep in mind.
Description of the SVG Elements in Use:
I'm hoping that the above illustration is pretty-much self-sufficient, but in case it isn't:
- We've got two SVG elements, each within their own DIV.
- Each 'face' (including the Corgi's), is a 'g' element.
- Each pie chart, is a 'g' element.
Each 'face' 'g' element is pretty simple. Contains a circle element, an image element, and then two further 'g' elements, one for each eye. Each eye 'g' element contains two circles, one for the actual eye, and one for the pupil.
The pie chart 'g' elements are equally pretty straightforward: a 'g' for each slice, a path element rendering the actual slice, and a text element for the slice text.
Model-View-Controller, and Code Re-Use:
One of the most powerful aspects of D3 is the ability to bind data to an on-screen element, but then update that data without directly needing to update the element. What? For example, let's assume I bind an array of three elements ['dog', 'cat', 'sock'] to a pie chart. Provided I hold onto that data in a variable, I can then update that data in a completely separate distance piece of code, then at some point in the future (lets say a timer event), the code that renders the chart has access to this data via the binding.
How does this help? Because it allows us to move towards a model-view-controller type pattern. I know that there are many MVC purists out there, which is why I caged the above with "type pattern". The code behind this demo broadly follows the MVC pattern.
And following (however broadly) the MVC pattern in the above demo helps us move towards reusable code - which is the key goal after all. We can start to think about: "which code does the rendering?" "what manipulates the data?" "what code responds to timers" ..... so on - and thus start to build distinct blocks of code, code that in the future we can re-use.
Components and Modules:
So what components did we create? (remembering that components are reusable bits of code that generate graphics). Two components:
- A pie chart component.
- A face manager component.
Each of the components is pretty simple: all they do is take the data given and render it. Each has a 'transform' function which is used to move the elements, but that's pretty much it. They're actually pretty simple.
Finally there are the controller modules. These are by far the largest blocks of code, and are the heart of the application. All events are directed to the controllers, all data is manipulated by the controllers, and all rendering is kicked off by the controllers.
Most and Least Reusable:
So has this actually produced reusable code?
The most reusable bits of code are the timer and json modules, the faceManager I've used elsewhere (in another application I'm putting together), and the pie chart should be reusable.
The least reusable bits are the controllers, but their structures are certainly something I can use again.
So, I'd say yes. For me yes.
Thanks is Due
I've been slowly ploughing my way through D3 books and examples for well over a year or so, and many people's examples, snippets, bits'n'bobs are all in someway incorporated in all of this. So, much thanks to: Mike Bostock and Jason Davies for creating D3; fellow authors: Christophe Viau, Andrew Thornton and Ger Hobbelt - from whom I learnt buckets; Mike Dewar for the book and samples; Scott Murray for the book and samples; Ian Johnson for the various examples out there; and https://bl.ocks.org/j0hnsmith for the pie examples. And the many others I've forgotten. Thanks!