Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composite ordinal chart doesn't redraw filtered then reseted bars properly #677

Closed
ruhley opened this issue Aug 20, 2014 · 5 comments
Closed
Milestone

Comments

@ruhley
Copy link
Contributor

ruhley commented Aug 20, 2014

chart.options({
                //display
                height: 200,
                width: $('#core_range_man_cat').width(),
                margins: {
                    top: 10,
                    right: 50,
                    bottom: 30,
                    left: 40
                },
                renderHorizontalGridLines: true,
                //x-axis
                xAxisLabel: 'Category',
                x: d3.scale.ordinal(),
                xUnits: dc.units.ordinal,
                elasticX: true,
                //y-axis
                yAxisLabel: 'Compliance %',
                elasticY: true,
                rightYAxisLabel: 'Number of Units',
                brushOn: false,
                //data
                dimension: dimension,
                group: group,
                childOptions: {
                    //display
                    renderDataPoints: {
                        radius: 3
                    },
                    renderArea: false,
                    gap: 1,
                    centerBar: true,
                    //data
                    dimension: dimension,
                    group: group,
                },
                compose: [
                    dc.barChart(chart).options({
                        useRightYAxis: false,
                        colors: d3.scale.ordinal().range(['#3333AA']),
                        valueAccessor: function(d) {
                            return d.value.percentage;
                        }
                    }),
                    dc.lineChart(chart).options({
                        useRightYAxis: true,
                        colors: d3.scale.ordinal().range(['#AA3333']),
                        valueAccessor: function(d) {
                            return d.value.count;
                        }
                    }),
                    dc.lineChart(chart).options({
                        useRightYAxis: true,
                        colors: d3.scale.ordinal().range(['#33AA33']),
                        valueAccessor: function(d) {
                            return d.value.stockedCount;
                        }
                    })
                ]
            }).render()

Then if i try

chart.filterAll();
dc.redrawAll();

it doesn't redraw the bars properly.

@gordonwoodhull
Copy link
Contributor

Thanks for the report. Can you create a jsFiddle (or similar) which demonstrates the problem, or at least supply some example data?

@ruhley
Copy link
Contributor Author

ruhley commented Aug 20, 2014

After digging around in dc.js I found the problem was that the filter was being applied to the child bar chart, but when running chart.filterAll() it was trying to remove the filters from the base chart (which was already empty). So I had to copy the _chart.filter function from base mixin into composite chart and tweak it a little and everything works as expected.

_chart.filter = function (_) {
        var filters = _chart.filters();
        if (!arguments.length) return filters.length > 0 ? filters[0] : null;
        if (_ instanceof Array && _[0] instanceof Array && !_.isFiltered) {
            _[0].forEach(function(d){
                if (_chart.hasFilter(d)) {
                    _filters.splice(_filters.indexOf(d), 1);
                } else {
                    _filters.push(d);
                }
            });
            applyFilters();
            _chart._invokeFilteredListener(_);
        } else if (_ === null) {
            //resetFilters(); don't reset the filters of this chart but of it's child charts

            for (var i = 0; i < _children.length; ++i) {
                _children[i].filterAll();
            }
        } else {
            if (_chart.hasFilter(_))
                removeFilter(_);
            else
                addFilter(_);
        }

        if (_chart.root() !== null && _chart.hasFilter()) {
            _chart.turnOnControls();
        } else {
            _chart.turnOffControls();
        }

        return _chart;
    };

@OLiess
Copy link

OLiess commented Sep 3, 2014

Hi !
Had similar problem on a GUI I had to maintain, I did the following change, which consist in overriding the filterAll method for compositeChart, calling the base method on all children.

This solved my problem, and should (may?) also answers yours.

Have a nice day


diff --git a/dcjs/dc.js b/dcjs/dc.js
index 2f105f8..db872df 100644
--- a/dcjs/dc.js
+++ b/dcjs/dc.js
@@ -5164,6 +5164,17 @@ dc.compositeChart = function (parent, chartGroup) {
         return g;
     });

+    dc.override(_chart, "filterAll", function () {
+        var g = this._filterAll();
+        for (var i = 0; i < _children.length; ++i) {
+            var child = _children[i];
+
+            child.filterAll();
+        }
+
+        return g;
+    });
+
     _chart._brushing = function () {
         var extent = _chart.extendBrush();
         var brushIsEmpty = _chart.brushIsEmpty(extent);

@gordonwoodhull
Copy link
Contributor

Related: #706 #390

@gordonwoodhull
Copy link
Contributor

Fixed by #1435 in 3.0.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants