My talk at Boston Code Camp 23 will be
How to Write a JavaScript Masterpiece. We will see two ways to write a function that can create an SVG path for a line graph. The first way is the clunky way, illustrated by bcc_02.js through bcc_04.js in the Plunker below. (bcc_01.js is the hard-coded way, just to get things started.)
The idiomatic, elegant way is bcc_05.js. The line-generator in that file is an abridged version of Mike Bostock's similar function in his masterpiece, the
D3 JavaScript library. The full source for D3's line function is at
https://github.com/mbostock/d3/blob/master/src/svg/line.js. It is well worth studying, and bcc_05.js has used the same variable names in most cases, so you'll be able to find your way around the full version after you digest the smaller one.
The elegant bcc_05 improves on the clunky bcc_02 through bcc_04 in several ways:
- It artfully uses nested functions to control scope.
- It treats functions as first-class objects.
- They can be return values.
- They can be arguments to other functions.
- They can even have properties.
- It takes advantage of JavaScript's
call
function. Related functions are apply
and bind
. - It uses the built-in
arguments
variable to enable function overloading. - It supports a fluent (chaining) interface.
- It anticipates duck-typing.
- It takes advantage of JavaScript closures.
And the two most important points:
- It follows the DRY Principle (Don't Repeat Yourself).
- It follows the Single Responsibility Principle. The generator's single responsibility is producing an SVG path from an array. It is remarkable how little the function "knows," especially considering how flexible it is. To put it another way, it's very hard to think of a reason the function would have to change, aside from a breaking change to the SVG spec.
You can edit the Plunker directly from this post by pressing the Edit button. To use different versions of bcc_01j.s through bcc_05.js, just change the <script> tag in index.html. Within bcc_05.js, you can use the bcc.svc.line() function in different ways by commenting and un-commenting the blocks of code at the bottom of bcc_05.js.