D3: How to handle zooming and tooltips in a single chart?
Asked Answered
A

4

10

I have a visualization that is essentially a series of stacked bar charts, each of which contains several panels. For example, here are three such bar charts, each with four panels.

I have managed to implement pan/zoom functionality that is coordinated across the charts. This is what it looks like if I zoom into the third panel from the last image, for example. The zoom behavior is called from an invisible rectangle that is placed over each chart.

My problem is that I want to enable tooltip functionality based on the location of the user's cursor within a plot. Since the zoom-rectangles are placed on top of the charts, however, no mouse events are registered for any SVG elements in the actual charts themselves.

Des anyone know a way around this?

Addax answered 1/7, 2016 at 17:26 Comment(2)
Did you solve this issue? If so, how?Tangy
I have exactly the same issue here...hope someone can help us outNonrecognition
E
7

I was following Mike Bostock's example, and like you placing a rect across my whole chart and then calling the zoom behaviour on that, and like you found that it was consuming all the pointer events.

I found an example here that seemed to be achieving what I wanted, and I found that if I scrap the rect and just call the zoom behaviour on the svg element directly, I still get pointer events for the child elements.

I'm a noob here, I don't really understand why this works. I also guess this might have its own ramifications e.g. I guess this stops you limiting the area of your graphic in which mouse events cause a zoom. You may notice that the example I linked creates a sub-svg; I don't know, but perhaps this is to solve that problem.

Eldreda answered 6/6, 2018 at 21:22 Comment(0)
H
1

In your css put the style ponter-events:none for your zooming rectangles. That way the cursor events will be sensed by the elements blow.

Hooten answered 2/7, 2016 at 7:53 Comment(2)
Thanks for your answer. The problem is that I need the zoom-rectangles to still register pointer events. Their whole purpose is to trigger zoom behavior when the user places their cursor over the chart and does a page scroll. So while setting pointer-events: none allows the below elements to sense mouse events, it breaks the zoom functionality.Addax
@Addax i have stuck in the same issue, is there any solution?Milkweed
M
0

You can probably put the mouseevent on the same rectangle you are using for detecting your zoom. Hard to say for sure without a code sample, but I would expect you can do something along these lines:

 svg.select("rect.overlay")
     .on("mouseover.tooltip", function() { tooltip.style("display", null); })
     .on("mouseout.tooltip", function() { tooltip.style("display", "none"); })
     .on("mousemove.tooltip", mousemoveFunc);

Adding the ".tooltip" to the event adds a namespace to the event, so if you end up having any collision with your zoom listeners, you can add a namespace to them too.

Margo answered 2/7, 2016 at 1:32 Comment(0)
B
0

I know this is way too late, but I've just figured out a workaround. For me the crucial thing is order of adding bits to the svg.

svg1.append("rect")//put the rectangle for zoom events on the bottom
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all")
.call(d3.zoom()
    .scaleExtent([0.5, 10])
    .on("zoom", zoomed));

var g = svg1.append("g"); //add g element for visualisation (above the rectangle).

function zoomed() { //zoom around the g's (g has to be before this, but after the rectangle)
g.attr("transform", d3.event.transform)  
}

Then a little bit later on add my force elements to the g

 var nodes = g.append("g")
    .attr("class", "nodes")
    .selectAll("circles")
    .attr('id', function(d) {
        return d.n_id
    })

etc. Slight issue here is I can't actually zoom with my mouse over the circles, but I have loads of white space. I'm going to try and allow propagation of zoom events, or call zoom events from the circles

Bludgeon answered 13/3, 2019 at 23:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.