The first variation shows the quick and dirty approach which essentially bypasses the nice, reusable structures I spent time implementing in the first demo. I simply added a method named ‘addCircles()’ to the canvas which takes an array and creates a data-bound selection of circles. Then that selection is passed to the forcelayout:
The second variation tries something a little different. The commenter wanted to take advantage of the ‘addItem()’ method in the canvas. This means that we need to modularize the circles themselves rather than work with a typical d3 selection which is referenced by the force layout. I added a forcecircle.js class which represents each circle being shown on the canvas. This lets us create each one individually and we can add them at runtime whenever we want. In the demo below you can see I start with a group of circles and the ‘add’ button can be used to append new ones at runtime:
There are lots of improvements that I think could be made here. While this setup works, it lacks that ‘d3-feel’ where we can take advantage of selections and their inherent ‘enter/update/exit’ lifecycle. Also, I have yet to determine if it is better to require calls of the ‘render()’ method to redraw the component (in this case, our forcecircle component) or if that should happen anytime a relevant accessor is executed. For example, should an cx/cy update to the circle be done like this:
or like this:
(second way assumes accessors call render() internally when the values changes)
The second way is cleaner, but results in two calls to the render() method: one for the cx() accessor call and one for the cy() accessor call. I’m hopeful that, over time, we will find a better way to build reusable d3 components. Right now it feels like the more modular things get, the further away we get from using the selections and lifecycles that make d3 so great.