I am new to D3.js and I am trying to make some animation with my graph,
but I can't resolve a problem with the .get() method called on a d3.map for D3 version 6.
When I run the code it throws an error:
nodeById.get is not a function
My code is based on: https://bl.ocks.org/ctufts/bd6956a45ea69734f5909c8b526c13b5
//some fetch data in json file
d3.json("someURLjsonfile").then(function (graph) {
let nodes = graph.nodes,
nodeById = d3.map(nodes, function (d) {
return d.id;
}),
links = graph.links,
bilinks = [];
links.forEach(function (link) {
var s = nodeById.get(link.source), // <-- error
t = nodeById.get(link.target), // <-- error
i = {}; // intermediate node
nodes.push(i);
links.push({
source: s,
target: i
}, {
source: i,
target: t
});
bilinks.push([s, i, t]);
});
Your problem is caused by some rather unfortunate re-design of the API. As of D3 v6 the
d3-collectionmodule was deprecated and removed from the D3 bundle. That module contained thed3.map()constructor method that would create ad3.mapobject, i.e. one of D3's internal map implementations mimicking the native JavaScriptMap. This method has been around a while but has lost importance once ES6 feature became available and was therefore removed.Sadly, with version 2 of the
d3-arraymodule a method with the same name was introduced which is basically equivalent to the nativearray.map()orArray.from()methods:Since
d3-arrayv2 was introduced to the bundle with the same version 6 that also removedd3-collectionthed3.mapproperty is still available, however, its meaning has changed.Your code seems to have been written for D3 <v6 and breaks because of the changes laid out above. The new
d3.map()is a mapper function not a constructor; it returns an array which does not feature a.get()method, hence, the error.To fix the issue you can change your code to directly use the built-in
Mapobject instead:With the rest untouched your code should be running as expected.