0

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"
        }
    ]
}

1 Answer 1

1

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"]
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! This does exactly what I need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.