Reputation: 175
I'm working on my first treemap and i am unable to get the rect objects to render. The console is telling me that the length and width of each rect is NaN. Here's my code for the map:
//tree map
const drawTreeMap = (data) => {
const hierarchy = d3.hierarchy(data)
.sum((d) => d.value)
.sort((a, b) => b.value - a.value);
const treeMap = d3.treemap().size(height, width);
const root = treeMap(hierarchy)
console.log(root.leaves())
const map = svg
.selectAll("g")
.data(root.leaves())
.enter()
.append("g")
.attr("transform", (item) => {
"translate(" + item["x0"] + ", " + item["y0"] + ")";
});
map
.append("rect")
.attr("class", "tile")
.attr("fill", (item) => {
let category = item.data.category;
let color = categories.filter((c, i) => {
if (category == c) {
return colors[i];
}
});
return color;
})
.attr("data-name", (item) => item.data.name)
.attr("data-category", (item) => item.data.category)
.attr("data-value", (item) => item.data.value)
.attr("width", (item) => item["x1"] - item["x0"])
.attr("height", (item) => item["y1"] - item["y0"])
}
drawTreeMap(data);
});
I know that the json file is being read properly and I can see when I console log the root.leaves() that x1 and y1 values are NaN. I've consulted 4-5 different tutorials on treemaps and I am unable to find anything that works. I am using d3 v6.6 and the json file is here:
Can anyone tell me what I'm doing wrong?
Upvotes: 2
Views: 280
Reputation: 102218
Your self-answer is not the solution: both your original code and the code in your answer produce exactly the same array. You can see it here (using v5, but that doesn't matter):
const data = {
"name": "Movies",
"children": [{
"name": "Action",
"children": [{
"name": "Avatar ",
"category": "Action",
"value": "760505847"
}, {
"name": "Jurassic World ",
"category": "Action",
"value": "652177271"
}, {
"name": "The Avengers ",
"category": "Action",
"value": "623279547"
}, {
"name": "The Dark Knight ",
"category": "Action",
"value": "533316061"
}, {
"name": "Star Wars: Episode I - The Phantom Menace ",
"category": "Action",
"value": "474544677"
}, {
"name": "Star Wars: Episode IV - A New Hope ",
"category": "Action",
"value": "460935665"
}, {
"name": "Avengers: Age of Ultron ",
"category": "Action",
"value": "458991599"
}, {
"name": "The Dark Knight Rises ",
"category": "Action",
"value": "448130642"
}, {
"name": "Pirates of the Caribbean: Dead Man's Chest ",
"category": "Action",
"value": "423032628"
}, {
"name": "Iron Man 3",
"category": "Action",
"value": "408992272"
}, {
"name": "Captain America: Civil War ",
"category": "Action",
"value": "407197282"
}, {
"name": "Spider-Man ",
"category": "Action",
"value": "403706375"
}, {
"name": "Transformers: Revenge of the Fallen ",
"category": "Action",
"value": "402076689"
}, {
"name": "Star Wars: Episode III - Revenge of the Sith ",
"category": "Action",
"value": "380262555"
}, {
"name": "The Lord of the Rings: The Return of the King ",
"category": "Action",
"value": "377019252"
}, {
"name": "Spider-Man 2",
"category": "Action",
"value": "373377893"
}, {
"name": "Deadpool ",
"category": "Action",
"value": "363024263"
}, {
"name": "Transformers: Dark of the Moon ",
"category": "Action",
"value": "352358779"
}, {
"name": "American Sniper ",
"category": "Action",
"value": "350123553"
}, {
"name": "Furious 7",
"category": "Action",
"value": "350034110"
}, {
"name": "The Lord of the Rings: The Two Towers ",
"category": "Action",
"value": "340478898"
}, {
"name": "Spider-Man 3",
"category": "Action",
"value": "336530303"
}, {
"name": "Minions ",
"category": "Action",
"value": "336029560"
}, {
"name": "Guardians of the Galaxy ",
"category": "Action",
"value": "333130696"
}, {
"name": "Batman v Superman: Dawn of Justice ",
"category": "Action",
"value": "330249062"
}, {
"name": "Transformers ",
"category": "Action",
"value": "318759914"
}, {
"name": "Iron Man ",
"category": "Action",
"value": "318298180"
}, {
"name": "Indiana Jones and the Kingdom of the Crystal Skull ",
"category": "Action",
"value": "317011114"
}, {
"name": "The Lord of the Rings: The Fellowship of the Ring ",
"category": "Action",
"value": "313837577"
}, {
"name": "Iron Man 2",
"category": "Action",
"value": "312057433"
}, {
"name": "Star Wars: Episode II - Attack of the Clones ",
"category": "Action",
"value": "310675583"
}, {
"name": "Pirates of the Caribbean: At World's End ",
"category": "Action",
"value": "309404152"
}, {
"name": "Star Wars: Episode VI - Return of the Jedi ",
"category": "Action",
"value": "309125409"
}, {
"name": "Independence Day ",
"category": "Action",
"value": "306124059"
}, {
"name": "Pirates of the Caribbean: The Curse of the Black Pearl ",
"category": "Action",
"value": "305388685"
}, {
"name": "Skyfall ",
"category": "Action",
"value": "304360277"
}, {
"name": "Inception ",
"category": "Action",
"value": "292568851"
}, {
"name": "Man of Steel ",
"category": "Action",
"value": "291021565"
}, {
"name": "Star Wars: Episode V - The Empire Strikes Back ",
"category": "Action",
"value": "290158751"
}, {
"name": "The Matrix Reloaded ",
"category": "Action",
"value": "281492479"
}, {
"name": "The Amazing Spider-Man ",
"category": "Action",
"value": "262030663"
}, {
"name": "The Incredibles ",
"category": "Action",
"value": "261437578"
}, {
"name": "Captain America: The Winter Soldier ",
"category": "Action",
"value": "259746958"
}, {
"name": "The Lego Movie ",
"category": "Action",
"value": "257756197"
}, {
"name": "Star Trek ",
"category": "Action",
"value": "257704099"
}, {
"name": "Batman ",
"category": "Action",
"value": "251188924"
}, {
"name": "Night at the Museum ",
"category": "Action",
"value": "250863268"
}]
}, {
"name": "Drama",
"children": [{
"name": "Titanic ",
"category": "Drama",
"value": "658672302"
}, {
"name": "The Sixth Sense ",
"category": "Drama",
"value": "293501675"
}, {
"name": "I Am Legend ",
"category": "Drama",
"value": "256386216"
}]
}, {
"name": "Adventure",
"children": [{
"name": "Shrek 2",
"category": "Adventure",
"value": "436471036"
}, {
"name": "The Hunger Games: Catching Fire ",
"category": "Adventure",
"value": "424645577"
}, {
"name": "The Lion King ",
"category": "Adventure",
"value": "422783777"
}, {
"name": "Toy Story 3",
"category": "Adventure",
"value": "414984497"
}, {
"name": "The Hunger Games ",
"category": "Adventure",
"value": "407999255"
}, {
"name": "Frozen ",
"category": "Adventure",
"value": "400736600"
}, {
"name": "Finding Nemo ",
"category": "Adventure",
"value": "380838870"
}, {
"name": "The Jungle Book ",
"category": "Adventure",
"value": "362645141"
}, {
"name": "Jurassic Park ",
"category": "Adventure",
"value": "356784000"
}, {
"name": "Inside Out ",
"category": "Adventure",
"value": "356454367"
}, {
"name": "The Hunger Games: Mockingjay - Part 1",
"category": "Adventure",
"value": "337103873"
}, {
"name": "Alice in Wonderland ",
"category": "Adventure",
"value": "334185206"
}, {
"name": "Shrek the Third ",
"category": "Adventure",
"value": "320706665"
}, {
"name": "Harry Potter and the Sorcerer's Stone ",
"category": "Adventure",
"value": "317557891"
}, {
"name": "The Hobbit: An Unexpected Journey ",
"category": "Adventure",
"value": "303001229"
}, {
"name": "Harry Potter and the Half-Blood Prince ",
"category": "Adventure",
"value": "301956980"
}, {
"name": "The Twilight Saga: Eclipse ",
"category": "Adventure",
"value": "300523113"
}, {
"name": "The Twilight Saga: New Moon ",
"category": "Adventure",
"value": "296623634"
}, {
"name": "Up ",
"category": "Adventure",
"value": "292979556"
}, {
"name": "The Twilight Saga: Breaking Dawn - Part 2",
"category": "Adventure",
"value": "292298923"
}, {
"name": "The Twilight Saga: Breaking Dawn - Part 2",
"category": "Adventure",
"value": "292298923"
}, {
"name": "Harry Potter and the Order of the Phoenix ",
"category": "Adventure",
"value": "292000866"
}, {
"name": "The Chronicles of Narnia: The Lion, the Witch and the Wardrobe ",
"category": "Adventure",
"value": "291709845"
}, {
"name": "Harry Potter and the Goblet of Fire ",
"category": "Adventure",
"value": "289994397"
}, {
"name": "Monsters, Inc. ",
"category": "Adventure",
"value": "289907418"
}, {
"name": "The Hunger Games: Mockingjay - Part 2",
"category": "Adventure",
"value": "281666058"
}, {
"name": "Gravity ",
"category": "Adventure",
"value": "274084951"
}, {
"name": "Monsters University ",
"category": "Adventure",
"value": "268488329"
}, {
"name": "Shrek ",
"category": "Adventure",
"value": "267652016"
}, {
"name": "Harry Potter and the Chamber of Secrets ",
"category": "Adventure",
"value": "261970615"
}, {
"name": "Jaws ",
"category": "Adventure",
"value": "260000000"
}, {
"name": "The Hobbit: The Desolation of Smaug ",
"category": "Adventure",
"value": "258355354"
}, {
"name": "The Hobbit: The Battle of the Five Armies ",
"category": "Adventure",
"value": "255108370"
}, {
"name": "Men in Black ",
"category": "Adventure",
"value": "250147615"
}]
}, {
"name": "Family",
"children": [{
"name": "E.T. the Extra-Terrestrial ",
"category": "Family",
"value": "434949459"
}]
}, {
"name": "Animation",
"children": [{
"name": "Despicable Me 2",
"category": "Animation",
"value": "368049635"
}, {
"name": "The Secret Life of Pets ",
"category": "Animation",
"value": "323505540"
}, {
"name": "Despicable Me ",
"category": "Animation",
"value": "251501645"
}]
}, {
"name": "Comedy",
"children": [{
"name": "Forrest Gump ",
"category": "Comedy",
"value": "329691196"
}, {
"name": "Home Alone ",
"category": "Comedy",
"value": "285761243"
}, {
"name": "Meet the Fockers ",
"category": "Comedy",
"value": "279167575"
}, {
"name": "The Hangover ",
"category": "Comedy",
"value": "277313371"
}, {
"name": "How the Grinch Stole Christmas ",
"category": "Comedy",
"value": "260031035"
}, {
"name": "The Hangover Part II ",
"category": "Comedy",
"value": "254455986"
}]
}, {
"name": "Biography",
"children": [{
"name": "The Blind Side ",
"category": "Biography",
"value": "255950375"
}]
}]
};
const height = 100, width = 100;
const hierarchy = d3.hierarchy(data)
.sum((d) => d.value)
.sort((a, b) => b.value - a.value);
const treeMap = d3.treemap().size([height, width]);
const root = treeMap(hierarchy)
console.log(root.leaves())
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
As you can see, there is no NaN
.
The real issue is that in your original code you're not passing width
and height
to the size()
method as an array...
const treeMap = d3.treemap().size(height, width);
//no array here ------------------^------------^
...which you are in your answer (by the way, in the reversed order):
d3.treemap().size([width, height])(hierarchy);
//array here -----^-------------^
Upvotes: 1
Reputation: 175
Just got it working by combining the lines:
const treeMap = d3.treemap().size(height, width);
const root = treeMap(hierarchy)
with one line:
d3.treemap().size([width, height])(hierarchy);
full replacement:
//tree map
const drawTreeMap = () => {
const hierarchy = d3.hierarchy(data, (node) => node.children)
.sum((node) => node.value)
.sort((node1, node2) => node2.value - node1.value);
d3.treemap().size([width, height])(hierarchy);
const tiles = hierarchy.leaves();
const block = svg
.selectAll("g")
.data(tiles)
.enter()
.append("g")
.attr("transform", (item) => "translate(" + item.x0 + ", " + item.y0 + ")");
block
.append("rect")
.attr("class", "tile")
.attr("fill", (item) => {
let category = item.data.category;
console.log(item)
let color = categories.filter((c, i) => {
if (category == c) {
return colors[i];
}
});
return color[0];
})
.attr("data-name", (item) => item.data.name)
.attr("data-category", (item) => item.data.category)
.attr("data-value", (item) => item.data.value)
.attr("width", (item) => item["x1"] - item["x0"])
.attr("height", (item) => item["y1"] - item["y0"])
}
drawTreeMap();
});
Upvotes: 1