[tooltip] Show data on mouseover of circle

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 tried using:

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() {
        d3.select(this).enter().append("text")
            .text(function(d) {return d.x;})
            .attr("x", function(d) {return x(d.x);})
            .attr("y", function (d) {return y(d.y);}); });

I suspect I need to be more informative about what data to enter?

This question is related to tooltip mouseover d3.js

The answer is


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

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


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

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>

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


Examples related to tooltip

Add tooltip to font awesome icon Adding a tooltip to an input box Tooltip with HTML content without JavaScript HTML-Tooltip position relative to mouse pointer Styling the arrow on bootstrap tooltips How do you change the width and height of Twitter Bootstrap's tooltips? Can I use complex HTML with Twitter Bootstrap's Tooltip? Tooltip on image Show data on mouseover of circle How to add a tooltip to an svg graphic?

Examples related to mouseover

Change color of Button when Mouse is over How to perform mouseover function in Selenium WebDriver using Java? How do you change Background for a Button MouseOver in WPF? Text on image mouseover? Show data on mouseover of circle google maps v3 marker info window on mouseover Image Greyscale with CSS & re-color on mouse-over? How to remove default mouse-over effect on WPF buttons? Change background color on mouseover and remove it after mouseout iPad/iPhone hover problem causes the user to double click a link

Examples related to d3.js

D3.js: How to get the computed width and height for an arbitrary element? D3 Appending Text to a SVG Rectangle How to get coordinates of an svg element? d3.select("#element") not working when code above the html element Resize svg when window is resized in d3.js How to add an image to an svg container using D3.js d3 add text to circle Python equivalent of D3.js How do I shut down a python simpleHTTPserver? D3 transform scale and translate