I have a written a plugin for D3.js called d3-marcon that implements Mike Bostock's margin conventions. For example, rather than having to write:
var margin = {top: 10, bottom: 10, left: 10, right: 10},
width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.top - margin.bottom,
svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
You can write:
var setup = d3.marcon({top: 10, bottom: 10, left: 10, right: 10, width: window.innerWidth, height: window.innerHeight}),
margin = setup.margin,
width = setup.width,
height = setup.height,
svg = setup.svg;
As you can see, it works by passing an options object to the marcon() function. If you specify no options, it defaults to 0 for all margins, 900 for the width, 600 for the height, and appends the svg element to the "body". So you can get up and running very quickly with just one line of code, var setup = d3.marcon(), and then pass options later when you want to change your viz.
This is useful, but it still doesn't feel like a real D3 function. Real D3 functions allow for chaining functions together, rather than passing options objects. So instead of d3.marcon({element: ".viz"}), D3 code looks like d3.marcon().element(".viz").
D3 code also lets you pass additional functions to the chained functions (e.g. d3.method().chainedFunction(function(d) { return d.value; })), so you can update the attributes of an object based on data.
Obviously, my plugin does none of these things. I've spent a few hours looking at existing D3 modules to try to figure out how they work, but I'm not getting anywhere. Can anyone suggest how to get my code to work like a proper D3 module? Or, failing that, a good tutorial to read?
I linked to the repository above, but here it is again. And here is a block showing how it works.