官术网_书友最值得收藏!

Filtering with data

Imagine you need to filter D3 selection based on the associated data elements so that you can hide/show different sub-datasets based on the user's input. D3 selection provides a filter function to perform this kind of data-driven filtering. In this recipe, we will show you how this can be leveraged to filter visual elements in a data-driven fashion.

Getting Ready

Open your local copy of the following file in your web browser:

https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter3/data-filter.html

How to do it...

The following example code shows how data-based filtering can be leveraged to highlight different visual elements based on its categorization:

<script type="text/javascript">
    var data = [ // <-A
        {expense: 10, category: "Retail"},
        {expense: 15, category: "Gas"},
        {expense: 30, category: "Retail"},
        {expense: 50, category: "Dining"},
        {expense: 80, category: "Gas"},
        {expense: 65, category: "Retail"},
        {expense: 55, category: "Gas"},
        {expense: 30, category: "Dining"},
        {expense: 20, category: "Retail"},
        {expense: 10, category: "Dining"},
        {expense: 8, category: "Gas"}
    ];
    function render(data, category) {
        d3.select("body").selectAll("div.h-bar") // <-B
                .data(data)
            .enter()
            .append("div")
                .attr("class", "h-bar")
            .append("span");

        d3.select("body").selectAll("div.h-bar") // <-C
                .data(data)
            .exit().remove();

        d3.select("body").selectAll("div.h-bar") // <-D
                .data(data)
            .attr("class", "h-bar")
            .style("width", function (d) {
                return (d.expense * 5) + "px";}
            )
            .select("span")
                .text(function (d) {
                    return d.category;
                });

        d3.select("body").selectAll("div.h-bar")
 .filter(function (d, i) { // <-E
 return d.category == category;
 })
                .classed("selected", true);
    }

    render(data);

    function select(category) {
        render(data, category);
    }
</script>

<div class="control-group">
    <button onclick="select('Retail')">
      Retail
    </button>
    <button onclick="select('Gas')">
      Gas
    </button>
    <button onclick="select('Dining')">
      Dining
    </button>
    <button onclick="select()">
      Clear
    </button>
</div>

The preceding code generates the following visual output once the Dinning button is clicked:

Data-based Filtering

How it works...

In this recipe, we have a data set consisting of a list of personal expense records with expense and category as attributes, which is shown on the block of code marked as A. On line B, C, and D, a set of horizontal bars (HTML div) were created using the standard enter-update-exit pattern to represent the expense records. So far, this recipe is similar to the Binding object literals as data recipe. Now let's take a look at line E:

filter(function (d, i) { // <-E
    return d.category == category;
})

D3 selection.filter function takes a function as its parameter. It applies the function against every element in the existing selection. The given function for filter takes two parameters with a hidden reference:

  • d: It is the datum associated with the current element
  • i: It is a zero-based index for the current element
  • this: This has the hidden reference points to the current DOM element

D3 selection.filter function expects the given function to return a Boolean value. If the returned value is true, the corresponding element will be included into the new selection being returned by the filter function. In our example, the filter function essentially selects all bars that match the user-selected category and applies a CSS class selected to each one of them. This method provides you a powerful way to filter and generate data-driven sub-selection, which you can further manipulate or dissect to generate focused visualization.

Tip

D3 selection.filter function treats the returned value using JavaScript truthy and falsy tests, thus not exactly expecting a strict Boolean value. What this means is that false, null, 0, "", undefined, and NaN (not a number) are all treated as false while other things are considered true.

主站蜘蛛池模板: 平邑县| 彭山县| 丰原市| 塘沽区| 金昌市| 阳新县| 时尚| 万安县| 镇安县| 宁波市| 河池市| 中江县| 永顺县| 澄江县| 阿鲁科尔沁旗| 翼城县| 夏邑县| 泰和县| 公主岭市| 高安市| 霍山县| 偏关县| 宝清县| 乌兰浩特市| 大冶市| 邓州市| 萍乡市| 沭阳县| 隆化县| 措勤县| 柞水县| 岳阳市| 阿巴嘎旗| 商南县| 信丰县| 贺兰县| 廉江市| 孝义市| 醴陵市| 南安市| 岳普湖县|