Reputation: 87
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
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