Fewer Lambdas in D3.js: How to type less and make your code simpler.
In D3.js you see a lot of functions that take an argument and return a property or method invocation on that argument, or even just the argument itself. Calls that look like this:
.data(function(d) { return d; }) .attr('title', function(d) { return d.value; }) .text(function(d) { return d.toFixed(); })
Rubyists have the sweet Symbol#to_proc
method for converting a symbol into a function that accesses that method/property; they could write the latter two as:
.attr('title',&:value) .text(&:toFixed)
We can make similar—and even more powerful—shortcuts in JavaScript so that our D3 code is easier to type, easier to read, and easier to maintain.
// Create a function that returns a particular property of its parameter. // If that property is a function, invoke it (and pass optional params). function ƒ(name){ var v,params=Array.prototype.slice.call(arguments,1); return function(o){ return (typeof (v=o[name])==='function' ? v.apply(o,params) : v ); }; } // Return the first argument passed in function I(d){ return d }
Note that the name of the first function—ƒ—is a legal JavaScript identifier that is also easy-to-type on OS X (option-f
) and unlikely to collide with other names.
With this the original code can be written far more simply:
.data(I) .attr('title', ƒ('value')) .text(ƒ('toFixed')) // round to integer .text(ƒ('toFixed',2)) // round to 2 decimal places
Gavin Kistner
05:13PM ET 2012-May-21 |
Note that if you just want to round a number to the nearest integer you can more simply use |
David Turgeon
09:24PM ET 2013-Dec-27 |
This function combines both ƒ & I doing double-duty.
|
David Turgeon
11:51AM ET 2013-Dec-28 |
Thanks for fixing the code format! (BTW: the double quoted strings got curled on lines 14,17,18 of code block.) |