title: Chaining functions in a D3.js plugin
body: <p>I have a written a plugin for D3.js called <a href="https://github.com/HarryStevens/d3-marcon" rel="nofollow noreferrer"><code>d3-marcon</code></a> that implements <a href="https://bl.ocks.org/mbostock/3019563" rel="nofollow noreferrer">Mike Bostock's margin conventions</a>. For example, rather than having to write:</p>
  
  <pre><code>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 + ")");
  </code></pre>
  
  <p>You can write:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>As you can see, it works by passing an options object to the <code>marcon()</code> function. If you specify no options, it defaults to <code>0</code> for all margins, <code>900</code> for the width, <code>600</code> for the height, and appends the svg element to the <code>"body"</code>. So you can get up and running very quickly with just one line of code, <code>var setup = d3.marcon()</code>, and then pass options later when you want to change your viz.</p>
  
  <p>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 <code>d3.marcon({element: ".viz"})</code>, D3 code looks like <code>d3.marcon().element(".viz")</code>.</p>
  
  <p>D3 code also lets you pass additional functions to the chained functions (e.g. <code>d3.method().chainedFunction(function(d) { return d.value; })</code>), so you can update the attributes of an object based on data.</p>
  
  <p>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?</p>
  
  <p>I linked to the repository above, but <a href="https://github.com/HarryStevens/d3-marcon" rel="nofollow noreferrer">here it is again</a>. And <a href="https://bl.ocks.org/HarryStevens/de1069536e00256d7aa82299fac0f3d5" rel="nofollow noreferrer">here is a block</a> showing how it works.</p>