Pierre GUILLAUME
Pierre GUILLAUME

Reputation: 449

How to create interaction with selectMenu in dc.js

I'm trying to create a dashboard with a date chooser.

I did it for other figures, but it doesn't work here. I'm quite new with dc and I can't figure out if it's a problem of the group or a problem of the date format (or something else).

Here is my code :

        d3.csv("data/saccr_realloc_test.csv", function (error, saccr) {

                var parser = d3.time.format("%d.%m.%Y");
                //var formatter=d3.time.format("%d.%m.%Y");
                saccr.forEach(function(d) {
                        d.date   = parser.parse(d.date);
                        d.ead = +d.ead;
                    });


            var cptyChart = dc.barChart("#dc-cpty-chart");
            var lineChart = dc.lineChart("#volume-chart");

            var ndx = crossfilter(saccr);

            var dimdate = ndx.dimension(function(d) { return d.date;});
            var dimline = ndx.dimension(function(d) { return d.date;});
            var minDate = dimdate.bottom(1)[0].date;
            var maxDate = dimdate.top(1)[0].date;
            var dimcpty = ndx.dimension(function(d) { return d.cpty;});
            var dimcptyC = ndx.dimension(function(d) { return d.cpty;});

            var groupdate = dimline.group().reduceSum(function(d){return d.ead/1000000;});
            var groupline = dimline.group().reduceSum(function(d){return d.ead/1000000;});
            var groupcpty = dimcpty.group().reduceSum(function(d){return d.ead/1000000;});
            var spendhisto=dimcptyC.group().reduceSum(function(d){return d.ead/1000000;});
            var groupcptyC = remove_empty_bins(spendhisto);

            //a dropdown widget
            selectField=dc.selectMenu('#menuselect')
                    .multiple(true)
                    .dimension(dimcpty)
                    .group(groupcpty)
                    .numberVisible(10);

            selectField2=dc.selectMenu('#menuselect2')
                    .dimension(dimdate)
                    .group(groupdate);


            //a line chart
            lineChart
                    .height(350)
                    .width(450)
                    .margins({top:10, right:50, bottom: 30, left: 50})
                    .dimension(dimline)
                    .group(groupline)
                    .renderArea(true)
                    .transitionDuration(500)
                    .x(d3.time.scale().domain([minDate,maxDate]))
                    .elasticY(true)
                    .renderHorizontalGridLines(true);


            var barTip2=[]; //define some tips
            cptyChart
                    .ordering(function(d){return -d.value;})
                    .height(154)
                    .width(1300)
                    .transitionDuration(500)
                    .dimension(dimcptyC)
                    .group(groupcptyC)
                    .margins({top:10, right:10, bottom: 2, left: 60})
                    .gap(1)
                    .elasticY(true)
                    .elasticX(true)
                    .x(d3.scale.ordinal().domain(dimcptyC))
                    .xUnits(dc.units.ordinal)
                    .renderHorizontalGridLines(true)
                   .yAxis().tickFormat(d3.format("s"))


                dc.renderAll();

                function remove_empty_bins(source_group) {
                    return {
                        all:function () {
                            return source_group.all().filter(function(d) {
                                return d.value > 0.00001;
                            });
                        }
                    };
                }                    
            });

https://fiddle.jshell.net/qxL2a6ev/

If someone has an answer, I'll be grateful. Many thanks in advance.

Upvotes: 1

Views: 1990

Answers (1)

Gordon
Gordon

Reputation: 20130

There are two bugs here, one in dc.js and one in your code.

First, it looks like the selectMenu has not been debugged for non-string keys. It is filtering on the value it retrieves from the <option> tag, which has been converted to a string.

As usual, there is a workaround. You can explicitly convert the strings to dates before they get to the dimension by changing the filterHandler:

var oldHandler = selectField2.filterHandler();
selectField2.filterHandler(function(dimension, filters) {
  var parseFilters = filters.map(function(d) { return new Date(d);})
  oldHandler(dimension, parseFilters);
  return filters;
});

Second, you have a copy-paste bug in your code. You've got the right idea assigning a fresh dimension and group to each chart, but groupdate and groupline should each draw from the corresponding dimension:

var groupdate = dimdate.group().reduceSum(function(d){return d.ead/1000000;});
var groupline = dimline.group().reduceSum(function(d){return d.ead/1000000;});

Working fork of your fiddle: http://jsfiddle.net/gordonwoodhull/uterbmhd/9/

Upvotes: 2

Related Questions