1

Can someone advise me with the issue. I need to get html element on which mouse pointer is located in the end of d3.xhr request processing. And this d3.xhr should calls within queue: async.queue

define([
    "d3",
    "lodash",
    "async",

], function (d3, _, async) {

var html = d3.select("html");
async.queue(function (cell, callback) {
   d3.xhr("/myurl", function (error, data) {

     var data = _.merge(JSON.parse(data.response), cellDetails);
     //processing data

     console.log(d3.mouse(html)); //this line fails
    }
}

The error that appears in console

Uncaught TypeError: Cannot read property 'sourceEvent' of null
k                    @ d3.v3.min.js:1
aa.mouse             @ d3.v3.min.js:3
(anonymous function) @ myJSfile.js:77
(anonymous function) @ d3.v3.min.js:1
t                    @ d3.v3.min.js:1
u                    @ d3.v3.min.js:1

Generally task is hide tooltip properly, because now it doesn't disappear every time. In more details. We have a table:

<table>
    <tr>
        <td class="fav">Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
    <tr>
        <td class="fav">Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
    <tr>
        <td class="fav">Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
</table>
<div class="tooltip" style="visibility:hidden"></div>

We should be able to navigate to the cell in the table, when mouseenter on cell then js sends request via d3.xhr within async queue. And as a result we have to show response in tooltip if mouse is still over the same cell. This verification needed because request/response takes some time and user may navigate to another cell or even go out of table borders. In that case we should hide tooltip.

I tried to add event like 'mouseenter', 'mouseleave' on the table, html and others element on page but it doesn't work ok for me. Easier to verify where mouse is on. Please help.

Volodymyr
  • 113
  • 1
  • 8

3 Answers3

0

You can solve your problem with elementFromPoint. First, create an event handler for the mouse, and then use x and y position to determine over what element the mouse is:

d3.select("body").on("mouseover", function() {
    var x = d3.event.pageX, y = d3.event.pageY,
    elementMouseIsOver = document.elementFromPoint(x, y);

    console.log(elementMouseIsOver);
});

In this fiddle, you can see the elements in the console when you hover over them: http://jsfiddle.net/y9yj8kxq/. I hope that this is what you want.

If you write console.log(elementMouseIsOver.id) in my example, it will log the ID of the HTML element the mouse is over. I believe you can compare this ID with the ID before the call, to check if the mouse is still over the same element. See this fiddle: http://jsfiddle.net/43c1h3a0/ . You can see the ID in the console when you hover over the elements.

Here is the API: https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
0

In fact, you are trying to get mouse position without a mouse-* event, it is related to this question (and is not possible): How to get the mouse position without events (without moving the mouse)?

Your first solution of tracking enter and leave on each cell is more feasible. With this solution ,you can track if you are on a cell, and which one.

Then in the xhr callback, check if you still are on the same and then display popup.

You could also try this : https://stackoverflow.com/a/4517215/2372765. The trick here is to add a global event listener and to track the mouse globally, and save its position at each move. (maybe more CPU consuming)

Community
  • 1
  • 1
codename44
  • 867
  • 9
  • 19
0

Thank you all for reply. I've resolved the issue.

The way is following. I added flag like 'global' variable, named 'isMouseOutOfTable' which indicates whether mouse is within tbody or out. Also I added event on

tbody.on('mouseleave', function(){tooltip.mouseOutOfTable(); tooltip.hideTooltip();})
cell.on('mouseenter', function(){tooltip.showTooltip(); tooltip.mouseWithinTable();})

So when mouse is out of tbody we set flag as true and hide tooltip (and set false if mouse on cell). If we have a queue of request/response then we check just flag

define([
    "d3",
    "lodash",
    "async",

], function (d3, _, async) {

var isMouseOutOfTable = true;

async.queue(function (cell, callback) {
   d3.xhr("/myurl", function (error, data) {

     var data = _.merge(JSON.parse(data.response), cellDetails);
     //processing data
     tooltip.setData(data);

    if(isMouseOutOfTable == false){
            toolTip.style("visibility", "visible");
     } else {
            toolTip.style("visibility", "hidden");
     }
  }
}

This piece of code resolve issue when mouse is out of table when responses still processing and you have to decide whether to show tooltip or not, according to mouse position.

Volodymyr
  • 113
  • 1
  • 8