Dynamic getter/setter generation
Tired of writing a getter/setter for every variable in your D3 components? Give this trick a shot.
JavaScript
/*
* Dynamic getter/setter generation example!
*
* Idea by Rory Hardy [GneatGeek]
*/
viz = window.viz || {};
/**
* getSet creates a getter/setter function for a re-usable D3.js component.
*
* @method getSet
* @param {string} option - the name of the object in the string you want agetter/setter for.
* @param {function} component - the D3 component this getter/setter relates to.
*
* @return {mixed} The value of the option or the component.
*/
function getSet(option, component) {
return function (_) {
if (! arguments.length) {
return this[option];
}
this[option] = _;
return component;
};
}
(function () {
viz.bar = function () {
var opts = {
width : 200,
height : 50,
color : '#000'
};
function bar(svg) {
svg.append('rect')
.attr('width', opts.width)
.attr('height', opts.height)
.attr('fill', opts.color);
}
/*
* Loop over all the values in opts to create a getter and setter dynamically.
* Bind the opts object to each getter/setter function.
* Note, opts becomes this in the getter/setter function
*/
for (var key in opts) {
bar[key] = getSet(key, bar).bind(opts);
}
return bar;
};
}());
/*
* Add a function call of color to bar. Works right?
* Now add one for ratio. Oops, console error right?
* Add ratio as a value in the opts object. You'll find the error went away.
* That's the goal, if I declare it, I have a getter and setter immediately!
*
* Note that no getter/setter functions were manually written for these functions
*/
var bar = viz.bar()
.width(350)
.height(30);
d3.select('body')
.append('svg')
.call(bar);