D3 Bar Chart 'mouseover' unexpected behaviour

Hi all,
Thanks for having a look into this one.

I’m trying to solve first challenge in Data Visualisation module. I’m done with everything apart from the damned tooltip which just won’t display the data I want it to.
My current understanding of creating object attributes with d3 is that in, let’s say :

.attr("height", (d,i)=>d)

second variable can be a function and within that function d would be the data/value and i would be the index of the given value, taken from dataset provided in .data().
And this should work the same for everything in:

  .attr("y", (d,i)=>{console.log(d+', '+i);return h-d})
  .attr("x", (d,i)=>scaleX(realDates[i]))
  .attr("height", (d,i)=>d)
  .attr("width", barW)
  .attr("data-date", (d,i)=>stringDates[i])
  .attr("data-gdp", (d,i)=>values[i])
  .attr("transform", "translate(50,0)")
  .attr("class", "bar")
  .on("mouseover", (d,i)=>{
    console.log(d + ', ' + i);
    tooltip.transition().duration(300).style("opacity", 0.9);
    .style("left", 200 + "px")
    .style("top", h-100 + "px")
    .html(prettyDates[i] + '<br>' + values[i] + ' Billions')
  .on('mouseout', (d,i)=>{

In the code above, I have inserted 2 console.log() commands. One in:

.attr("y", (d,i)=>{console.log(d+', '+i);return h-d})

to see values and indexes of my dataset. Console log shows me this:

And this works just as expected.

However, console.log() from the:

 .on("mouseover", (d,i)=>{
    console.log(d + ', ' + i);
    tooltip.transition().duration(300).style("opacity", 0.9);

shows me that d has become the [object MouseEvent] and i is the value from the dataset now.


I did try to add the 3rd variable to the second argument of .on() function hoping that it would be the index from the dataset but it didn’t work.

When I look at the example solution under:

The issue I encounter is non existent.

Here’s my own code:

I fail most of the tests at the moment, as I’m not bothered by the user stories yet

Would someone be able to explain why is this happening?

As you noticed, the arguments to callback function are event and data. I don’t know from which version (probably v4), but those are the arguments for D3 v6. If you change the version to v3, your code probably will work okay, but I’m not sure as I didn’t test it.

To make it work with v6, you need to make two changes. First, inside the callback function, you have an access to ‘this’ that refers to the rect object. There’s two properties we added to each rect, data-date and data-gdp. So you code becomes something like

.html(this.getAttribute('data-date') + '<br>' + this.getAttrbute('data-gdp')+ ' Billions')

with necessary adjustment for pretty formatting the date.

Second, you define the function in a traditional way. This was something I searched the Internet for a while. You need to define it like (I use the same variables but you might call them e and d)

.on("mouseover", function(d,i) {

I’m sure there are other ways, but this is how I implemented the tooltip.

1 Like

you can also give an id attribute to your each data

.attr('id', function(d,i){
    return i

and reach it with event.currentTarget.id inside the function.

1 Like

Yes, assigning ‘id’ is a clean solution, requiring minimal changes to the existing code.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.