Build zoomable and pannable SVG canvas

I think we would end up with multiple `filter`s, a new one being appended each time `dropShadow` is called. Same goes for most of the other `.append()`s happening in this module, excluding the `.enter().append()`s. I've found what works pretty well for this kind of thing is to separate out the code that should happen on the first draw from the code that should happen every draw:

```javascript
function someComponent(selection) {
  function enter() {
    selection.append('div')
      .attr('class', 'foo')
      .append('div')
        .attr('class', 'bar')
        .append('div')
          .attr('class', 'baz');
  }

  function component() {
    if (!selection.node().hasChildNodes()) enter();

    selection.select('.foo')
      .attr('a', 1)
      .attr('b', 2);

    selection.select('.bar')
      .attr('c', 3)
      .attr('d', 4);

    selection.select('.baz')
      .attr('e', 5)
      .attr('f', 6);
  }

  // component();  // if it should be drawn immediately
  return component;
}
```