How can I use d3.js filter to assign different css classes to elements?


Tags: javascript,css,d3.js,filter

Problem :

For my first little d3.js project, I am adapting the "Filtering with Data" recipe from the Data Visualization with d3.js Cookbook (available at https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter3/data-filter.html).

My dataset contains offbeat words paired with types of "animal", "vegetable", or "mineral." The words are displayed in black type when the page is loaded. When the user clicks a "show animals" button, the animal words turn red. Ditto for the other two types: clicking the button for a particular word type turns the corresponding words red. All words currently turn red.

What I'm trying to do, though, is have the words turn different colors based on their type: brown for animals, green for vegetables, gray for minerals. I know I need to build and fit in a conditional framework somewhere, but the specifics are evading me. I imagine this exercise would be easy-peasy in straight Javascript, but I'm trying to learn d3!

Can anybody help?

The relevant CSS:

    .word {
        color: black;
        font-size: 2em;
        line-height: 30%;
        }

    .word .animal {
        color: brown;
        }

    .word.vegetable {
        color: green;
        }

    .word .mineral {
        color: lightslategray;
        }

    .selected {
        color: red;
        }

The entire script (it's rather short):

    var dataset = [
        {name: "aegirine", type: "mineral"},
        {name: "burdock", type: "vegetable"},
        ...
        {name: "yantok", type: "vegetable"},
        {name: "zingel", type: "animal"}
        ];


function render(dataset, type) {

    d3.select("body")
        .select("div")
        .attr("id", "worddiv")
        .selectAll("p.word")
        .data(dataset)
        .enter()
        .append("p")
        .attr("class", "word")
        .text(function(d) {
        return d.name;
        }); 

    d3.select("body")
        .selectAll("p")
        .filter(function (d,i) {

        return d.type == type;
        })

        .classed("selected", true);

    } // end function render


render(dataset);


function select(type) {
     render(dataset, type);
} // end function select


function clearAll() {
    d3.select("body")
        .selectAll("p")
        .attr("class", "word");
        }

The only relevant HTML is in the button div:

<button onclick = "select('animal')">
show animals
</button>

<button onclick = "select('vegetable')">
show vegetables
</button>

<button onclick = "select('mineral')">
show minerals
</button>

<button onclick = "clearAll()">
clear
</button>



Solution :

You can add a class to each item bassed on the type attribute using the d3.selection.classed method:

function render(dataset, type) {

    d3.select("body")
        .select("div")
        // ... more code
        .text(function(d) { return d.name; }); 

    // Adds a class to each element based on its type
    d3.select('body').selectAll('p.word')
       .each(function(d) { d3.select(this).classed(d.type, true); });

    d3.select("body")
        // ... more code
        .classed("selected", true);

} // end function render

Regards,


    CSS Howto..

    How Do I Get A Border From YUI GRID Tool?

    how to show section of a CSS sprite within a set position on the whole html body

    How can I memorize all CSS shorthands?

    How to vertically align images inside a list

    How can I align an image to the center in a Bootstrap column?

    How to get On/Off FlipSwitch to trigger function

    how do i change image width in jCarousel?

    How to change text colour on a child structure HTML5

    How do I create a mobile version of Nav Bar [closed]

    How to make a image stay at the bottom but not rise up

    How can I get drop-down functionality working with CSS?

    How do I place a
    beside an image?

    How can I align the checkboxes in a form when using table display with CSS?

    How to get rid of spacing between Bootstrap panels?

    How can I get my menu/logo to be centered instead of all the way to the right?

    How can I put three elements in the same column, with the first on top, second and third in the center of the remaining space, using Flexbox?

    How to achieve Expand collapse Side Nav with icon using jquery and boostrap css

    how to draw a shape by using canvas or css? [closed]

    How can I expand a div to compensate for removing the bordering div's margin?

    Skeleton CSS - how to span the width of the screen?

    how do you center and left align columns, at the same time, in bootstrap or regular html5?

    CSS - How to break long words in a table td?

    How do you make an input element fill parent?

    How to position two blocks side by side with CSS

    JqueryUi Autocomplete shown in wrong place when using input field in div with position:fixed

    How to find out DOM and CSS address to an element for Selenium?

    CSS HTML : stumped on how to center this piece of text

    CSS help, how to target this link inside of div

    How to write css for alt attribute of img tag (word-break: break-all property doesn't work in IE)

    How to locate element on a map by xpath or css selector