I tried to remove the circles having the values of top twenty percents & bottom twenty percents.
So I got the data bound to each element by d3.selectAll().data().
However, once I iterate through the elements, it returns an error message saying selection.data() is not a function why it doesn’t work when I iterate them, while it worked fine when I firstly generated the array?
The code is as below.
function leavingQuarter() {
let years = d3.range(1980, 2022, 1);
years.forEach((t) => {
let targetYear = d3.selectAll(`.year${t}`);
let targetYearData = targetYear.data()
let values = [];
let twenty;
let eighty;
for (let year of targetYearData) {
values.push(year.wordcount);
}
let ascending = values.sort(d3.ascending);
let numberofEl = ascending.length;
let twentyper = Math.floor(numberofEl * 0.2);
let eightyper = Math.floor(numberofEl * 0.8);
twenty = ascending[twentyper];
eighty = ascending[eightyper];
for (let years of targetYear) {
// Uncaught (in promise) TypeError: years.data is not a function
if (years.data().wordcount < twenty || years.data().wordcount > eighty) {
years.transition().duration(500).style('opacity', 0)
}
}
})
Advertisement
Answer
I figured out the reason and want to share the reason with someone who is going to have a similar problem oneday.
The solution for this is using selection.each instead.
I solved the problem with the syntax below.
targetYear.each(function(t) {
if (d3.select(this).data()[0].wordcount < twenty || d3.select(this).data()[0].wordcount > eighty) {
d3.select(this).transition().duration(1000).style('opacity', 0)
}
})