marcel marcel - 23 days ago 20
Javascript Question

d3.js filter nodes based on dynamic data taken from json file

I have display/hide the links/nodes of my force layout graph.
However I want to dynamically read my categories list from file, I don't want to hardcode them. So I already have this:

function createFilter()
{

d3.select(".filterContainer").selectAll("div")
.data(["category1", "category2", "category3"])
.enter()
.append("div")
.attr("class", "checkbox-container")
.append("label")
.each(function(d) {
// create checkbox for each data
d3.select(this)
.append("input")
.attr("type", "checkbox")
.attr("id", function(d) {return "chk_" + d;})
.attr("checked", true)
.on("click", function(d, i) {
// register on click event
var lVisibility = this.checked? "visible":"hidden";
filterGraph(d, lVisibility);
})
d3.select(this).append("span")
.text(function(d){return d;});
});

}


How can i change the data to read the categories from my
CategList
which holds an array of object, each object containing, for example:

{
"nodes": [
{"country": "US", "name": "saint peter's"},
{"country": "Brazil", "name": "saint joseph's"}
...
],
"links": [ ... ],
"CategList": [
{
"categ": "category1",
"id": "US"
},
{
"categ": "category2",
"id": "BR"
},
{
"categ": "category3",
"id": "DE"
},
]
}


how can I loop through all objects and extract the
"categ"
and pass it to the
.data
of the d3?

update:



how to pass it into the dropdown menu of the multiselector, instead of passing it into
".filterContainer"
as a checkbox?:

<div class="checkbox new-check check-primary">
<input type="checkbox" id="type_filter" />
<label for="type_filter">Types</label>
<br>
</div>
<select class="selectpicker" id="type_multiselector" multiple>
<option>category1</option>
<option>category2</option>
<option>category3</option>
</select>

Answer

Just map over your data to create a new variable containing only the categories, and then pass that to d3.

Something like this:

const json = {
  "nodes": [
    {"country": "US", "name": "saint peter's"},
    {"country": "Brazil", "name": "saint joseph's"}        
  ],
  "links": [  ],
  "CategList": [
        {
          "categ": "category1",
          "id": "US"
        },
        {
          "categ": "category2",
          "id": "BR"
        },
        {
          "categ": "category3",
          "id": "DE"
        },
      ]   
}

const myData = json.CategList.map(o => o.categ)

function createFilter()
{

    d3.select(".filterContainer").selectAll("div")
        .data(myData)
        .enter()
        .append("div")
        .attr("class", "checkbox-container")
        .append("label")
        .each(function(d) {
            // create checkbox for each data
            d3.select(this)
                .append("input")
                .attr("type", "checkbox")
                .attr("id", function(d) {return "chk_" + d;})
                .attr("checked", true)
                .on("click", function(d, i) {
                    // register on click event
                    var lVisibility = this.checked? "visible":"hidden";
                    filterGraph(d, lVisibility);
                })
            d3.select(this).append("span")
                .text(function(d){return d;});
        });

}