Problem with handlig event in d3

hallo,

I am working on a project using d3 .
https://codepen.io/ranran212/pen/VwpmbBN?editors=1111

I need to add an event (mouse over) and have a tooltip box to appear with some text but I cannot make it perform what I want with this method
It works if I use this snippet

      selection.append("title")
                         .text("something")

but I would like to use the .on(“mouseover”, function(){})

thank you

Hi @francesca.giammichel ,

Did you try using .on("mouseover…) ?
Could you please share the code so that we can see what could’ve thrown the error.

ok, with .on(“mouseover”, etc) I tried different approaches, that is I tried to attach the .on event handler on the “rect” and also on the “title” but none of them worked
this is the code for the .on

(tooltip is defined at the beginning of the page as a var)

 .on('mouseover', function (d, i) {
    tooltip.transition().duration(200).style('opacity', 0.9);
       .text((d) => {
        let quarter = ""
        if (d[0].substring(5,7) == "01"){
          quarter = "Q1"
        } else if (d[0].substring(5,7) == "04"){
          quarter = "Q2"
        } else if (d[0].substring(5,7) == "07"){
          quarter = "Q3"
        } else if (d[0].substring(5,7) == "10"){
          quarter = "Q4"
        } 
        return d[0].substring(0,4)+" "+quarter+"\n"+ d[1]+"$"
        })

@francesca.giammichel ,

You don’t need to pass the input argument d inside the text again as it’s already available. Just change the code inside .text to

.text(function()
{
code
}
)

i am afraid that is not the problem

as a test I used a simple

text("test")

and the tooltip was not working

unless I misunderstood, in this case you should please write the complete code in order to have the tooltip happening on the .on(“mouseover”) event

@francesca.giammichel ,

I removed the title and append lines and tried the below in your code; it displays “test” at the top of the “svg” element just below the main heading on mouse over:

.attr('class', 'bar')
.on('mouseover', function (d, i) {
    tooltip.transition().duration(200).style('opacity', 0.9)
           .text("test")
})

Yup one more thing, the semi-colon in your code here should be removed; it marks the end of code whereas in the next line, .text is being called.
tooltip.transition().duration(200).style('opacity', 0.9);<----

ok, I can see the word “test” but the whole thing is not behaving like a "normal tooltip. I am expecting to have the tooltip box appearing when i hove the bar and disappearing when i mouseout
I get this effect using the “title way” but for some reason i cannot pass the test

@francesca.giammichel

Yeah sadly the “title way” does not pass the test although it works. I too was stuck on this test. But the other method is alright too and the code can be reused for other projects.

In your code you have appended the #tooltip div on the svg, instead append it on the body or another div and set its position to absolute.

on mouse over, set its below properties:

   d3.select("#tooltip")
     .style("visibility","visible")
     .style("left", "...px")
      .style("top", ".....px")
      .text(...)

and on mouseout, you can set its visibility to hidden.

.on("mouseout",function(d,i){
    d3.select("#tooltip")
      .style("visibility","hidden")
      })

It’s top and left attributes can be set according to where you want it to be displayed( selected rect shape’s x, y attributes can be used here if needed - d3.select(this).attr("") )

Check out this link too, I think it uses opacity to control visibility:

Hope this helps

thank you very much :slight_smile:
and sorry for my late reply as I was working on the following project and with your tip i can try to fix my code and pass the tests, even though there is something else that is not working but honestly I do not understand the requirement… may I ask to you?

Sure, please feel free to post your queries here. I’ve recently completed this project, so hopefully I should be able to help. Even otherwise this forum is quite helpful and somebody would definitely guide you.

thanks :slight_smile:
this is one of the works not passing all the tests

Hey @francesca.giammichel ,

If you click on the red button on tests failed, it will display the tests executed and the error messages.

The error message says:

The bar elements’ “data-date” properties should match the order of the provided data.
Bars should have date data in the same order as the provided data : expected ‘Sat Feb 01 1947 00:00:00 GMT+0000 (Greenwich Mean Time)’ to equal ‘1947-01-01’

There are 2 problems here:

  1. The format - your rect shape’s data-date attribute value is in date format whereas expected is a string:
    The values in the original array dataArr was changed in date format. You can use d3.timeFormat to store this date into a string in the data-date attribute.
    Also, the tooltip 's attr (data-date) has the same format error. It needs the same fix.

  2. Notice the month - in the date format, it says Feb whereas in the string,the month is equal to ‘01’.
    The reason is because JavaScript counts months from 0 to 11.
    so, Jan is 0, Feb is 1. When the string is converted to date, ‘1947-01-01’ is changed to Feb 1947 instead of Jan 1947.

You could subtract the month by 1 in your code dataArr.forEach(…) to fix this.

ok,
first of all thanks for your assistance
I fixed the date format and month counting but there are still errors on the tooltip related to some “event”… that is another issue that I cannot understand :frowning:

https://codepen.io/ranran212/pen/jOBmLPa?editors=1111

Just change the tooltip.attr(‘data-date’) to the below:

tooltip.attr('data-date', formatTime(d[0]));

d is already being passed on ‘mouseover’, it can be used directly.

done, but I still get the same error on tooltip :frowning:

@francesca.giammichel ,

From your code, I can still see (dataArr[i][0])) while setting the data-date attribute of the tooltip.
Change that to simply d[0] as below:
tooltip.attr(‘data-date’, formatTime(d[0]));

OR

simply pass i as well to the . on ‘mouseover’ function as below (currently only d is being passed)

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

I do not remember if I passed you the link of the project I was working on
However i double checked and still same error (about the even studd :frowning:
https://codepen.io/ranran212/pen/jOBmLPa?editors=1111

hey ,

In the above link, the one test which isn’t passing is regarding the tooltip’s data-date attribute, and its description is as below:

Tooltip’s “data-date” property should be equal to the active area’s “data-date” property: expected ‘0NaN-NaN-NaN’ to equal ‘1982-07-01’

The line of code setting this property in your link is

tooltip.attr(‘data-date’, formatTime(dataArr[0])); <---- dataArr[0] is the first array element which consists of both date and gdp.

change this to dataArr[i][0] <---- dataArr[i][0] will give you just the date for the index i

I am able to pass the tests by making this change.

Also, you could try logging on the console, dataArr[0] and dataArr[i][0] inside the mouseover function to understand its values.

ok, that’s weird and embarassing.
Before replying to you, yesterday, I had 2 errors (regarding "dispatching event) whereas you the wrote you had only one, related to the data-date attibute.
Then I soon changed accordingly to what you wrote (which made sense to me) but something got wrong and I got TWELVE errors.
I commented out the tooltip events , reran the test and I went back to only 2 errors.
I uncommented the tooltip part, again 2 errors only, which are those belows

#TooltipTests

  1. I can mouse over an area and see a tooltip with a corresponding id=“tooltip” which displays more information about the area
    Failed to execute ‘dispatchEvent’ on ‘EventTarget’: parameter 1 is not of type ‘Event’.
    TypeError: Failed to execute ‘dispatchEvent’ on ‘EventTarget’: parameter 1 is not of type ‘Event’.
    at fe (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:116071)
    at a. (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:116438)
    at l (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:98461)
    at Generator._invoke (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:98214)
    at Generator.forEach.e. [as next] (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:98818)
    at r (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1054)
    at i (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1265)
    at https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1324
    at new Promise ()
    at a. (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1205)
  2. My tooltip should have a “data-date” property that corresponds to the “data-date” of the active area.
    Failed to execute ‘dispatchEvent’ on ‘EventTarget’: parameter 1 is not of type ‘Event’.
    TypeError: Failed to execute ‘dispatchEvent’ on ‘EventTarget’: parameter 1 is not of type ‘Event’.
    at fe (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:116071)
    at https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:117167
    at l (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:98461)
    at Generator._invoke (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:98214)
    at Generator.forEach.e. [as next] (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:657:98818)
    at r (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1054)
    at i (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1265)
    at https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1324
    at new Promise ()
    at a. (https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:1:1205)

that’s strange…I just checked your link and all the tests pass.

I am not sure what could be causing this…the browser?
Hope you haven’t changed the d3 version…

If this is persisting, I would suggest creating a new query in this forum so that others can have a look and the specific problem can be addressed.

1 Like