简体   繁体   中英

Mouse events and brush in D3

I'm currently attempting to customize the example of a time serie chart found at http://nvd3.com/ghpages/lineWithFocus.html . This is implemented using nvd3, a library on top of d3. I would like to have tooltips for data points as in the top graph but would also like be able to select a range in the same graph like in the bottom "view finder" graph in the example.

To that end, I've added a "brush" to the example of a basic line chart (see http://nvd3.com/ghpages/line.html ). The range selection works like a charm, however, tooltips for data points don't work anymore, except for points which are just out of the range of the axes. It seems, that the data points lying in the brush area don't get the mouse events anymore and that the brush absorbs them all.

What needs to be changed that the data points of the lines receive mouse events (in particular mouseover, I don't care about click)?

An attempt would be to catch all events using

d3.select(window).on("...", function) 

and then trigger some "mouseover" event over data points if applicable. How could this be achieved (I don't wan't go through all data points and then check which one is closest to the mouseevent...)? Is there a more straightforward way?

If you will Inspect element (Chorme) anywhere on the 'brush' you will notice the element that is built after your other graphical elements that you're trying to catch events on.

The d3.brush function is creating a hidden background to catch the mouse events.

// An invisible, mouseable area for starting a new brush.
      bg.enter().append("rect")
          .attr("class", "background")
          .style("visibility", "hidden")
          .style("cursor", "crosshair");

So the solution is to call the brush before plotting your data (lines, paths, scatter plot circles etc.).

Since the brush overlay will grab your mouse events - and you need it to - I am not sure you can get around this. Ultimately event bubbling only works for the DOM tree, and these elements will be siblings at best.

Possibly instead of iterating over all data points you can iterate only those that are selected by the brush. Check out d3.touches(container)

I have had the same issue. I realized that the brush overlaid the other objects (in my case were circles). So, first I created the brush rect, Then I created other objects. This way I could access to other objects' events as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM