D3 "mouseover" troubleshooting

I’m working on the first of the projects for the Data Visualization course, and I’m trying to get the “mouseover” part of the graph to work, but so far no good.

I’m just trying to get the blue bars to turn orange when hovered over, then back to blue when moved away, not using CSS since I’m going to have to eventually get the data text to show up too (which I have no idea how to do but I suppose that’s for later…)

Here is the pen, any help appreciated:

This code

    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       ...
       .append("title")
       .text((d) => d)
       .on("mouseover", handleMouseOver)
       .on("mouseout", handleMouseOut);

attaches the mouseover/mouseout events to the title element, not the rect element like you need. You can’t mouseover the title elements since d3 doesn’t place them under the pointer and moves them when the pointer moves, so those events never fire.
In your handler functions, passing an object to .attr() does not appear to be supported; just use a regular call to it like .attr('fill', 'blue').

I noticed in your code that you call these handlers with (d, i) and while irrelevant for this issue, is the old style of calling these functions. Since you’re using D3v7, they are called with (event, datum) which is the firing event object and the current datum; the index is not available automatically like it used to be. Just be aware when you use these functions to create your tooltip so that you can find the data you wish to display.

1 Like

Thank you for the reply! During the FCC course, we never learned how to do tooltips outside of the simple “.title” one, so I’m struggling with this.

Because of that, I’m not sure how to do the handler functions. I’ve tried a bunch of trial-and-error versions (and looked up other ones but they’re way beyond me), and none of them do anything. How do I format the functions to work with the “mouseover/mouseout” sections?

Your handlers were actually fine, except for providing the correct arguments to .attr(). If you attach them to the rect and not the title and fix the arguments, they work, so now you just need the code for the tooltips (and you could actually remove the titles if you like).

The tooltip problem is a common issue. If you look at the test output, it hints strongly (maybe not so strongly on the bar graph) at using a div with the appropriate attributes attached. There are two common approaches I see here: use the D3 tooltips package or append an invisible div and use the mouse event functions to make that div visible or invisible and set the correct attributes and move it, etc. Just don’t use any transitions as they tend to cause the tests to fail because the tooltip isn’t immediately visible.

On the bars for instance, you would want to append a div and when the mouse enters a bar, it sets the div to visible (multiple style/attr methods for that) and give it a data-date attribute equal to the bar’s date. When the mouse leaves the bar, set the div back to invisible.

1 Like

Thank you so much for your help. I really appreciate it.

I got the tooltip to show up and display html, but how do I access the date/amount data into the function?

When I try to use the “d” variable in the “.html” section of “handleMouseMove” it either displays “[object mouse event]” if I use d, or “undefined” if I use d[0] or d[1], or just a blank if I use d.value or d[1/0].value.

D3 has tons of articles and documentation and most of it is outdated except for the stuff at the D3 github repo and a few other places. You’re using D3v7, which calls event functions with signatures like function(event, datum) {...}. Old versions of D3 (4 and back maybe) used a different signature like function(datum, index) {...}. The problem is that lots of the documentation on the web is not up to date.

So when D3 calls your handleMouseOver function, it will call it with the event in the first argument and the current datum in the second even if your function definition says handleMouseOver(d, i) (JS cares not what you call your variables…). Your GDP and date data will be attached to the second argument to your handler function. You can add a console.log(d) and console.log(i) in your handleMouseOver to see it in action.

1 Like

Thanks so much! I know you mentioned that in the first reply, but I didn’t really understand what that meant until now XD

Would’ve never figured that out with your help!

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