How to filter data using DC, D3, and Crossfilter to produce a bar chart?

与世无争的帅哥 提交于 2019-12-23 02:39:18

问题


The following produces a bar chart that shows 4 people on the x axis and the number of times they show up on the y-axis.However I'd like to filter this data to only count the owner's if they have an ID of "A."

Also, would it be possible to apply this filter with a button or an onClick handler so that the data is only filtered for ID of "A" upon pressing the button.

See code below and jsfiddle here: http://jsfiddle.net/chrisguzman/y9xt2/

var data = [{
    Owner: "Alyssa",
    ID: "A"
}, {
    Owner: "Alyssa",
    ID: "A"
}, {
    Owner: "Alyssa",
    ID: "A"
}, {
    Owner: "Alyssa",
    ID: "A"
}, {
    Owner: "Alyssa",
    ID: "B"
}, {
    Owner: "Bob",
    ID: "A"
}, {
    Owner: "Bob",
    ID: "A"
}, {
    Owner: "Bob",
    ID: "C"
}, {
    Owner: "Bob",
    ID: "C"
}, {
    Owner: "Bob",
    ID: "C"
}, {
    Owner: "Bob",
    ID: "C"
}, {
    Owner: "Bob",
    ID: "C"
}, {
    Owner: "Bob",
    ID: "D"
}, {
    Owner: "Joe",
    ID: "A"
}, {
    Owner: "Joe",
    ID: "A"
}, {
    Owner: "Joe",
    ID: "D"
}, {
    Owner: "Joe",
    ID: "D"
}, {
    Owner: "Joe",
    ID: "E"
}];

var ndx = crossfilter(data);


var XDimension = ndx.dimension(function (d) {
    return d.Owner;
});
var YDimension = XDimension.group().reduceCount(function (d) {
    return d.Owner;
});
dc.barChart("#Chart")
    .width(480).height(300)
    .dimension(XDimension)
    .group(YDimension)
    .centerBar(true)
    .gap(56)
    .x(d3.scale.ordinal().domain(XDimension))
    .xUnits(dc.units.ordinal)
    .xAxisLabel("Market Developer")
    .yAxisLabel("Unique Counts")
    .elasticY(true)
    .xAxis().tickFormat(function (v) {
    return v;
});
dc.renderAll();

回答1:


Simply create another dimension based on ndx and have it return the field that needs to be filtered. Then, before dc.renderAll(), apply filter() and the key to filter by.

See JS Fiddle here: http://jsfiddle.net/chrisguzman/eL2XG/

var ndx = crossfilter(data);


var XDimension = ndx.dimension(function (d) {
    return d.Owner;
});
var YDimension = XDimension.group().reduceCount(function (d) {
    return d.Owner;
});

Create that new dimension

var FilterDimension = ndx.dimension(function (d) {
    return d.ID;
});

//

dc.barChart("#Chart")
    .width(480).height(300)
    .dimension(XDimension)
    .group(YDimension)
    .centerBar(true)
    .gap(56)
    .x(d3.scale.ordinal().domain(XDimension))
    .xUnits(dc.units.ordinal)
    .xAxisLabel("Market Developer")
    .yAxisLabel("Unique Counts")
    .elasticY(true)
    .xAxis().tickFormat(function (v) {
    return v;
});

Then filter by that new dimension

FilterDimension.filter("A");
dc.renderAll();

Also, see https://groups.google.com/forum/#!msg/dc-js-user-group/UFxvUND7hmY/btbAjqIIzl8J for more in-depth explanation

The reason this is because

"a grouping intersects the crossfilter's current filters, except for the associated dimension's filter. Thus, group methods consider only records that satisfy every filter except this dimension's filter. So, if the crossfilter of payments is filtered by type and total, then group by total only observes the filter by type."




回答2:


I'm not sure if you still needed to know how to add this to a button. If so just create a button with the following anchor.

<a class="filter" href="javascript:FilterDimension.filter("A");dc.redrawAll();" style="display: none;">filter</a>

<a class="reset" href="javascript:FilterDimension.filterAll();dc.redrawAll();" style="display: none;">reset</a>


来源:https://stackoverflow.com/questions/25109936/how-to-filter-data-using-dc-d3-and-crossfilter-to-produce-a-bar-chart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!