简体   繁体   中英

D3 - How can I show/hide a text element when hovering a circle element created from different attributes of the same data entry?

I have some data with 2 attributes: colour and value

I use the D3 enter selection to create circle elements, and append them to the body of the page. Their fill colour is determined by the "colour" attribute.

Then, I append text elements to the page. The text contents are determined by the "value" attribute.

Here is what I am working with:

// Set up svg element
var svg = d3.select("body")
    .append("svg")
    .attr("width", 300)
    .attr("height", 300)
    .style("background", "lightblue");

var dataset = [
    {"colour":"red", "value":"First set of text"},
    {"colour":"green", "value":"Second attempt"},
    {"colour":"blue", "value":"Third and final!"}
];

// Create circles from the data
// On mouseover, give them a border (remove on mouseout)
svg.selectAll("circle")
    .data(dataset)
    .enter()
    .append("circle")
    .attr("r", 40)
    .attr("cy", function(d, i) { return i*80 + 40; })
    .attr("cx", 50)
    .style("fill", function(d) {return d.colour;})

  // HERE
  // Can I somehow show and hide the text component that is
  // associated with this circle when the circle is hovered, rather
  // than the text itself?
  .on("mouseover", function(d) {
          d3.select(this).style("stroke", "black")
                         .style("stroke-width", 2)
  })
  .on("mouseout", function(d) {d3.select(this).style("stroke", "none")});

// Now add the text for each circle
// Same thing with mouseover and mouseout
svg.selectAll("text")
    .data(dataset)
    .enter()
    .append("text")
    .attr("text-anchor", "middle")
    .attr("y", function(d, i) { return i*80 + 40; })
    .attr("x", 50)
    .style("opacity", 0)
    .on("mouseover", function(d) {d3.select(this).style("opacity", 1)})
    .on("mouseout", function(d) {d3.select(this).style("opacity", 0)})
    .text(function(d) { return d.value;});

I would like for the text to be hidden, until the associated circle is hovered over. How can I connect the text element with a particular circle, so that I can toggle whether the text is shown by hovering over the circle?

This fiddle below is an outline of what I am trying to do, and what I have got so far. I have the text showing up only when hovered, but not when the circle is hovered.

https://jsfiddle.net/aj4zpn6z/

There are several ways for achieving this. Since both circles and texts use the same dataset, my solution uses filter .

First, let's name the variables for the texts and circles:

var circles = svg.selectAll("circle")
    //etc...

var texts = svg.selectAll("text")
    //etc...

Then, inside the circles mouseover function, we filter the texts that have the same colour attribute:

.on("mouseover", function(d){
    d3.select(this).style("stroke", "black").style("stroke-width", 2);
    var tempTexts = texts.filter(function(e){
        return e.colour === d.colour
    });
    tempTexts.style("opacity", 1);
});

This is your updated fiddle: https://jsfiddle.net/wxh95e9u/

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