Reputation: 396
First of all, here is a simple fiddle that I did in order to aid in my question:
jsfiddle.net/rogeraleite/xbd0zpzn/4
...based on the chart displayed on fiddle, the task that I am trying to do is:
turn into red the bars which the owners had at least one "approved_flag == 0" (for this data, Mike`s bar would became red).
It looks simple, but I still not able to do that =/.
Code I am using:
var experiments = [
{ Name: "Mike", amount: 26.9, approved_flag: 1 },
{ Name: "Mike", amount: 2.9, approved_flag: 1 },
{ Name: "Mike", amount: 14.9, approved_flag: 0 },
{ Name: "John", amount: 22.5, approved_flag: 1 },
{ Name: "John", amount: 13.5, approved_flag: 1 },
{ Name: "Firen", amount: 44.3, approved_flag: 1 },
{ Name: "Firen", amount: 24.3, approved_flag: 1 }
];
var ndx = crossfilter(experiments);
var all = ndx.groupAll();
var nameDimension = ndx.dimension(function (d) { return d.Name; });
var nameGroup = nameDimension.group().reduceSum(function (d) { return d.amount; });
var chart1 = dc.barChart('#rowChart');
chart1.width(600)
.height(250)
.margins({ top: 10, right: 10, bottom: 20, left: 40 })
.dimension(nameDimension)
.group(nameGroup)
.transitionDuration(500)
.colors('teal')
.elasticY(false)
.brushOn(false)
.valueAccessor(function (d) {
return d.value;
})
.title(function (d) {
return "\nNumber of Povetry: " + d.key;
})
.x(d3.scale.ordinal().domain(nameDimension.top(Infinity).map(function(d) {return d.Name})))
.xUnits(dc.units.ordinal)
.legend(dc.legend().x(45).y(20).itemHeight(8).gap(4));
dc.renderAll();
thanks in advance for helping me, --Roger
Upvotes: 3
Views: 70
Reputation: 20150
You're essentially reducing two values for each group, so you'll need a custom reduction to do this. What's interesting is that you have to track whether another filter causes the last false approved_flag
to be removed from a group. But this is really not more complex once you're using a custom reduction: we'll just keep a count of the number of false approved_flag
.
It is probably easier with reductio, but here is the straight crossfilter way:
var nameGroup = nameDimension.group().reduce(
function (p, v) { // add
p.amount += v.amount
if(!v.approved_flag)
p.unapproved++;
return p;
},
function (p, v) { // remove
p.amount -= v.amount
if(!v.approved_flag)
p.unapproved--;
return p;
},
function () { // initialize
return {amount: 0, unapproved: 0};
}
);
By default the bar chart only assigns colors based on the stacking layer. For this simple two-color case we can just short-circuit the colors
scale and return the color name from the colorAccessor
:
.colors(function(x) { return x; })
.colorAccessor(function(d) {
return (!this.name && d.value.unapproved) ? 'red' : 'teal';
})
Fork of your fiddle with these additions here: http://jsfiddle.net/gordonwoodhull/6L2kryvq/17/
EDIT: updated fiddle and colorAccessor because first try was breaking the legend, which passes a layer instead of datum.
Upvotes: 2