Show data on mouseover of circle

前端 未结 5 1251
我寻月下人不归
我寻月下人不归 2020-11-22 10:05

I have a set of data that I am plotting in a scatter. When I mouseover one of the circles I would like it to popup with data (like x, y values, maybe more). Here is what I

相关标签:
5条回答
  • 2020-11-22 10:08

    I assume that what you want is a tooltip. The easiest way to do this is to append an svg:title element to each circle, as the browser will take care of showing the tooltip and you don't need the mousehandler. The code would be something like

    vis.selectAll("circle")
       .data(datafiltered).enter().append("svg:circle")
       ...
       .append("svg:title")
       .text(function(d) { return d.x; });
    

    If you want fancier tooltips, you could use tipsy for example. See here for an example.

    0 讨论(0)
  • 2020-11-22 10:17

    A really good way to make a tooltip is described here: Simple D3 tooltip example

    You have to append a div

    var tooltip = d3.select("body")
        .append("div")
        .style("position", "absolute")
        .style("z-index", "10")
        .style("visibility", "hidden")
        .text("a simple tooltip");
    

    Then you can just toggle it using

    .on("mouseover", function(){return tooltip.style("visibility", "visible");})
    .on("mousemove", function(){return tooltip.style("top",
        (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
    .on("mouseout", function(){return tooltip.style("visibility", "hidden");});
    

    d3.event.pageX / d3.event.pageY is the current mouse coordinate.

    If you want to change the text you can use tooltip.text("my tooltip text");

    Working Example

    0 讨论(0)
  • 2020-11-22 10:21

    You can pass in the data to be used in the mouseover like this- the mouseover event uses a function with your previously entered data as an argument (and the index as a second argument) so you don't need to use enter() a second time.

    vis.selectAll("circle")
    .data(datafiltered).enter().append("svg:circle")
    .attr("cx", function(d) { return x(d.x);})
    .attr("cy", function(d) {return y(d.y)})
    .attr("fill", "red").attr("r", 15)
    .on("mouseover", function(d,i) {
        d3.select(this).append("text")
            .text( d.x)
            .attr("x", x(d.x))
            .attr("y", y(d.y)); 
    });
    
    0 讨论(0)
  • 2020-11-22 10:31

    There is an awesome library for doing that that I recently discovered. It's simple to use and the result is quite neat: d3-tip.

    You can see an example here:

    enter image description here

    Basically, all you have to do is to download(index.js), include the script:

    <script src="index.js"></script>
    

    and then follow the instructions from here (same link as example)

    But for your code, it would be something like:

    define the method:

    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-10, 0])
      .html(function(d) {
        return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
      })
    

    create your svg (as you already do)

    var svg = ...
    

    call the method:

    svg.call(tip);
    

    add tip to your object:

    vis.selectAll("circle")
       .data(datafiltered).enter().append("svg:circle")
    ...
       .on('mouseover', tip.show)
       .on('mouseout', tip.hide)
    

    Don't forget to add the CSS:

    <style>
    .d3-tip {
      line-height: 1;
      font-weight: bold;
      padding: 12px;
      background: rgba(0, 0, 0, 0.8);
      color: #fff;
      border-radius: 2px;
    }
    
    /* Creates a small triangle extender for the tooltip */
    .d3-tip:after {
      box-sizing: border-box;
      display: inline;
      font-size: 10px;
      width: 100%;
      line-height: 1;
      color: rgba(0, 0, 0, 0.8);
      content: "\25BC";
      position: absolute;
      text-align: center;
    }
    
    /* Style northward tooltips differently */
    .d3-tip.n:after {
      margin: -1px 0 0 0;
      top: 100%;
      left: 0;
    }
    </style>
    
    0 讨论(0)
  • 2020-11-22 10:33

    This concise example demonstrates common way how to create custom tooltip in d3.

    var w = 500;
    var h = 150;
    
    var dataset = [5, 10, 15, 20, 25];
    
    // firstly we create div element that we can use as
    // tooltip container, it have absolute position and
    // visibility: hidden by default
    
    var tooltip = d3.select("body")
      .append("div")
      .attr('class', 'tooltip');
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h);
    
    // here we add some circles on the page
    
    var circles = svg.selectAll("circle")
      .data(dataset)
      .enter()
      .append("circle");
    
    circles.attr("cx", function(d, i) {
        return (i * 50) + 25;
      })
      .attr("cy", h / 2)
      .attr("r", function(d) {
        return d;
      })
      
      // we define "mouseover" handler, here we change tooltip
      // visibility to "visible" and add appropriate test
      
      .on("mouseover", function(d) {
        return tooltip.style("visibility", "visible").text('radius = ' + d);
      })
      
      // we move tooltip during of "mousemove"
      
      .on("mousemove", function() {
        return tooltip.style("top", (event.pageY - 30) + "px")
          .style("left", event.pageX + "px");
      })
      
      // we hide our tooltip on "mouseout"
      
      .on("mouseout", function() {
        return tooltip.style("visibility", "hidden");
      });
    .tooltip {
        position: absolute;
        z-index: 10;
        visibility: hidden;
        background-color: lightblue;
        text-align: center;
        padding: 4px;
        border-radius: 4px;
        font-weight: bold;
        color: orange;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>

    0 讨论(0)
提交回复
热议问题