JSFiddle - React, Tailwind, and code Playground

by Igor Cuckovic

HTML

<link rel="stylesheet" type="text/css" href="http://dc-js.github.io/dc.js/css/dc.css" />
<div>
    <p>When filtering items in a crossfilter data set with dc.js, items are filtered using an || filter. For example, if you click "Mr. A" and "Mr. B" on the row chart, all the items that have "Mr. A" || "Mr. B" with be selected. But in the case of items grouped by tags, we want an && filtering. So we use the crossfilter dimension.filterFunction with dynamically created filter functions to create this effect.</p>
</div>
<div id="tags">
    <label>
        <input type="checkbox" id="tag1" class="tags" checked/>Tag 1</label>
    <label>
        <input type="checkbox" id="tag2" class="tags" checked/>Tag 2</label>
    <label>
        <input type="checkbox" id="tag3" class="tags" checked/>Tag 3</label>
    <a href="#" id="selectAll">Select All</a>
        <a href="#" id="deselectAll">Deselect All</a>
</div>
<div id="chart-ring-year"></div>
<div id="chart-row-spenders"></div>
<script type="text/javascript" src="http://dc-js.github.io/dc.js/js/d3.js"></script>
<script type="text/javascript" src="http://dc-js.github.io/dc.js/js/crossfilter.js"></script>
<script type="text/javascript" src="http://dc-js.github.io/dc.js/js/dc.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>

CSS

p {
    font-size: 12px;
}
#tags {
    margin-bottom:10px;
}

JavaScript

function toggleArrayItem(a, v) {
        var i = a.indexOf(v);
        if (i === -1) a.push(v);
        else a.splice(i, 1);
    }

    function createFilter(filters) {
        return function (d) {
            for (var i = 0, len = filters.length; i < len; i++) {
                if ($.inArray(filters[i], d) == -1) return false;
            }
            return true;
        }
    }

    $('#tag1').click(function () {
        toggleArrayItem(filter_list, 'tag1');

        tags.filterAll();
        tags.filterFunction(createFilter(filter_list));

        dc.redrawAll();
    });

    $('#tag2').click(function () {
        $(this).toggleClass('active');
        toggleArrayItem(filter_list, 'tag2');

        tags.filterAll();
        tags.filterFunction(createFilter(filter_list));

        dc.redrawAll();
    });

    $('#tag3').click(function () {
        $(this).toggleClass('active');
        toggleArrayItem(filter_list, 'tag3');

        tags.filterAll();
        tags.filterFunction(createFilter(filter_list));

        dc.redrawAll();
    });

d3.select("#selectAll").on("click", function () {
    d3.selectAll('.tags').property('checked', true);
    tags.filterAll();
    dc.redrawAll();
    console.log("selectAll")
})

d3.select("#deselectAll").on("click", function () {
    d3.selectAll('.tags').property('checked', false);
    tags.filterAll();
    
    tags.filterFunction(createFilter([]));
    dc.redrawAll();
    console.log("deselectAll")
})


    var yearRingChart = dc.pieChart("#chart-ring-year"),
        spenderRowChart = dc.rowChart("#chart-row-spenders"),
        filter_list = [],
        spendData = [{
            Name: 'Mr A',
            Spent: 40,
            Year: 2011,
            "tags": ["tag1", "tag2"]
        }, {
            Name: 'Mr B',
            Spent: 10,
            Year: 2011,
            "tags": ["tag1", "tag2"]
        }, {
            Name: 'Mr C',
            Spent: 40,
            Year: 2011,
            "tags": ["tag2"]
        },...