1

I am creating a population map of the US. I have the map and legend working, but I made a drop down menu that allows me to filter by race. This works and changes the data on the map and legend, but I am having an issue where the legend text shows the new range, and all previous ranges as I change the drop down menu. Is there a way to have it so that it doesn't overlap the previous text but instead shows only the one correct text? I am using D3 with React.

This is the code to my legend:

svg.append("g")
    .attr("transform", "translate(580,20)")
    .append(() => Legend(color, {title: `2019 Population (x10^${exp})`, width: 300,tickFormat: ".1f"}))

The code to my color variable:

const color = d3.scaleQuantile([start/divider,end/divider], d3.schemeYlOrRd[9])

start and end change depending on how big the population sizes are

Edit/Update: I found a work around to solving my issue, I'm just not sure if its best practice or if there's another way of doing it. I gave it a background color so that the previous info gets covered up

code:

svg.append("g")
    .attr("transform", "translate(580,20)")
    .append(() => Legend(color, {title: `2019 Population (x10^${exp})`, width: 300,tickFormat: ".1f"}))
    .append("rect")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("fill", "grey")
    
    svg.append("g")
    .attr("transform", "translate(580,20)")
    .append(() => Legend(color, {title: `2019 Population (x10^${exp})`, width: 300,tickFormat: ".1f"}))

1 Answer 1

0

Every time you do svg.append('g').transform(...).append(() => Legend()) you are adding a new <g> element.

Instead store the <g> selection in a variable and then remove its contents before adding a new legend.

const legendG = svg.append('g').attr('transform', 'translate(580, 20)')

function renderLegend(legendOptions) {
  
  legendG.selectAll('*').remove() // removes everything inside 

  legendG.append(() => Legend(legendOptions))
}

// now call the `renderLegend` function every time you change something from the menu

And to answer your question if what you did is a good practice. I would say it is not, because you're just adding elements every time the user chooses something in the menu and it's just taking up more and more memory for storing the DOM. Not good for performance.

1
  • Thank you so much! Makes sense and also explains why it would slow down the more changes I made thru the selection menu. Commented Jan 24, 2022 at 7:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.