wsalesky
wsalesky

Reputation: 87

d3js v4 Create filter function from node values that include arrays

I am trying to create a filter function on node values that sometimes include an array, but can not figure out how to extract the array values as individual values. I have a force directed graph and would like to be able to filter (highlight) the nodes based on the occupation. In some cases a single node has multiple occupations. When I try to create a list of unique values for occupation I get the nodes with multiple occupations as a comma separated list, not as two distinct values. They are listed in the data as an array. How can I extract them, so I can use them in my filter. I have tried map() and nest():

d3.map(graph.nodes, function(d){return(d.occupation)}).keys(); returns: ["agent", "undefined", "physician", "emir", "physician,govenor"]

d3.nest().key(function(d) { return d.occupation;}).entries(graph.nodes);

Neither of these separates out the occupations in the array. I would like to return an array like this: ["agent", "undefined", "physician", "emir", "govenor"]

Thank you for any pointers in the right direction, I am still new to d3js.

Here is my data:

{
    "nodes": [
        {
            "id": "https://usaybia.net/person/2",
            "type": "person",
            "label": "al-ʿAbbās",
            "occupation": "agent",
            "degree": "primary"
        },
        {
            "id": "https://usaybia.net/person/1184",
            "type": "person",
            "label": "Ibrāhīm I ibn al-Aghlab",
            "degree": "first"
        },
        {
            "id": "https://usaybia.net/person/1263",
            "type": "person",
            "label": "Isḥāq ibn ʿImrān",
            "occupation": "physician",
            "degree": "first"
        },
        {
            "id": "https://usaybia.net/person/2377",
            "type": "person",
            "label": "Ziyādat Allāh ibn al-Aghlab al-Tamīmī",
            "occupation": "emir",
            "degree": "first"
        },
        {
            "id": "https://usaybia.net/person/1975",
            "type": "person",
            "label": "Saʿīd ibn Tawfīl",
            "occupation": [
                "physician",
                "govenor"
            ],
            "degree": "first"
        },
        {
            "id": "https://usaybia.net/person/418",
            "type": "person",
            "label": "Person 418",
            "degree": "first"
        }
    ],
    "links": [
        {
            "source": "https://usaybia.net/person/1184",
            "target": "https://usaybia.net/person/2",
            "relationship": "agent-of",
            "value": "0"
        },
        {
            "source": "https://usaybia.net/person/1263",
            "target": "https://usaybia.net/person/2",
            "relationship": "13.1",
            "value": "0"
        },
        {
            "source": "https://usaybia.net/person/2377",
            "target": "https://usaybia.net/person/2",
            "relationship": "13.1",
            "value": "0"
        },
        {
            "source": "https://usaybia.net/person/1975",
            "target": "https://usaybia.net/person/2",
            "relationship": "13.1",
            "value": "0"
        },
        {
            "source": "https://usaybia.net/person/1184",
            "target": "https://usaybia.net/person/2",
            "relationship": "13.1",
            "value": "0"
        },
        {
            "source": "https://usaybia.net/person/418",
            "target": "https://usaybia.net/person/2",
            "relationship": "13.1",
            "value": "0"
        }
    ]
}

Upvotes: 0

Views: 49

Answers (1)

Mark
Mark

Reputation: 108537

I wouldn't use d3.map for this. There are built-in JavaScript methods that'll give better performance. In fact d3-collection is deprecated for this very reason.

// flat map will flatten the inner arrays
let fm = graph.nodes.flatMap((d) => d.occupation);
// get distinct values
let dis = [... new Set(fm)];

Produces:

["agent", undefined, "physician", "emir", "govenor"]

Upvotes: 1

Related Questions