简体   繁体   中英

D3 map legend issue

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"}))

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM