Ok, I'm going to give you an update as I'm not completely finished with it, but I have some progress for you.
The problem with the way you are doing filtering, every dimension you create is an array of two values ([time, meterId]). This is not going to work for the chart, because your key accessor (which triggers the filter), is just returning the time. Thus, when it goes to crossfilter, just the time, will not match any dimension key of [time, meterid].
That being said, the work around is to instead make meterId part of the crossfilter grouping functionality:
1. The dimension is just time (as is your x-axis, and keyAccessor)
2. You'll need to implement custom reducer functions for crossfilter that can maintain the sum for each meterId separately.
I got you're jsfiddle working, and I have it working the way you need it to be, but the filtering doesn't work as it should yet. Effectively this is the correct route, just needs some more debugging love.
Some of the things I've done thus far:
- I put all of your CSV into the HTML ( so I could get it work)
- I created accessor functions for all properties, just so they can be reused
- I created custom reducer functions, that can take 2 accessors, one being the dimension accessor, the other is you're standard sum reducer accessor. This functionality create's an associative array for each dimension key. In the end, the data will look like:
[{ key: time1, value: { meterId1: frequencySum1, meterId2: frequencySum2 }} ....]
var reduceSumInit = function() {
return function() {
return {};
};
};
var reduceSumAdd = function(dimensionAccessor, reducerAccessor) {
return function(p, v) {
var dimValue = dimensionAccessor(v);
p[dimValue] = (p[dimValue] || 0) + reducerAccessor(v);
return p;
};
};
var reduceSumRemove = function(dimensionAccessor, reducerAccessor) {
return function(p, v) {
var dimValue = dimensionAccessor(v);
p[dimValue] = (p[dimValue] || 0) - reducerAccessor(v);
return p;
};
};
- dc.js can't handle list accessors, so we provide a custom data function to each chart to blow out the group values. All this does is take the data from each reduce iteration and blows it out:
i.e.
[{ key: time1, value: { meterId1: frequencySum1, meterId2: frequencySum2 }} ....]
becomes:
[ {key:time1, value:[ meterId1, frequencySum1]},
{key:time1, value:[ meterId2, frequencySum2]}
]
// Custom data function explodes the data
var dataFunction = function(group) {
var all = group.all();
return all.reduce(function(previous, current) {
for(var k in current.value) {
previous.push({
key: current.key,
value: [+k, +current.value[k]]
});
}
return previous;
}, []);
};
I know this is complicated, but to get around the array dimension problem, you'll have to push the meterId into the grouping.
Now when you filter, it should just be filtering the time. Thus crossfilter should be correctly filtering the keys, but it didn't seem to work, so maybe I'm missing something.