mbostock/d3 — pull request #1072 by karmi (2013-02-11 09:00:24+00:00)
Title: Allow passing class names as functions to `classed()`

This patch allows to set class names based on bound data. I often found myself adding classes based on data properties, such as `status`, `country_id`, etc.

For example, let's have a data set:

var data = [
{ value: 1.2, status: 'finished' },
{ value: 3.4, status: 'initializing' },
]

Without this patch, the only way how to add classes based on the `status` property I am aware of, is to explicitely list them:

d3.select('body')
.selectAll('div')
.data( data )
.enter()
.append('div')
.classed({
finished: function(d,i) { return d.status == 'finished' },
initializing: function(d,i) { return d.status == 'initializing' }
})

With this patch, it's possible to pass a function to the `classed()` method, which will be passed the corresponding data and evaluated:

d3.select('body')
.selectAll('div')
.data( data )
.enter()
.append('div')
.classed( function(d,i) { return d.status} )

Not sure how this use-case is common, but I find it a lot in my projects, and this patch makes the code much more succinct and nice.

-----

Notes:

* Added tests to the `test/core/selection-classed-test.js`
* Slightly refactored the code within the `d3_selection_classed()` function, introduced the `classNameManipulator` function to evade code duplication (`name.trim().split ...`)
* Will happily revert this refactoring or rewrite the code as per any suggestions