That's an interesting question. No, currently dc.js does not support multiple brushes but it would be interesting to support that in the future.
I think if you poke into the code you'll find a lot of places where there is exactly one d3.brush UI object, which might not be hard to fix. There are also many, many places where the code assumes there is exactly one filter.
It looks like the default filter handler does correctly fall back to a filterFunction for this case. But it's all the places in the coordinateGridMixin and the concrete charts that I'd worry about. If you grep for filter or filters in the code you'll see. (If you call .filter() as a getter, it returns the first of the filters; .filters() returns the whole array.)
I think you'll find that everything with a continuous / quantitative scale is expecting a single filter, and anything which supports a categorical scale (bars, pie) can handle either a single range filter or a set of individual values. The base mixin code probably, mostly is agnostic about the number and types of filters.
I definitely encourage you to try it out and report back here or in github issues with any problems you run into. It might not be hard to get one individual chart working, and I'd accept a PR as long as it doesn't break other charts in the process. But a lot of brush code is in the coordinate grid mixin, so you'll definitely have to work with that too.
Crossfilter is much more efficient when using single filterRange than filterFunction. So we have special cases in the default filter handler:
var _filterHandler = function (dimension, filters) {
if (filters.length === 0) {
dimension.filter(null);
} else if (filters.length === 1 && !filters[0].isFiltered) {
// single value and not a function-based filter
dimension.filterExact(filters[0]);
} else if (filters.length === 1 && filters[0].filterType === 'RangedFilter') {
// single range-based filter
dimension.filterRange(filters[0]);
} else {
dimension.filterFunction(function (d) {
for (var i = 0; i < filters.length; i++) {
var filter = filters[i];
if (filter.isFiltered && filter.isFiltered(d)) {
return true;
} else if (filter <= d && filter >= d) {
return true;
}
}
return false;
});
}
return filters;
};
Kind of a rambling response, sorry. I love talking about the design of dc.js. You can find me on Gitter too.