Typically you still want to associate the mousemove and mouseup events
with the window, even if you have multiple charts; this allows these
events to continue to work if the mouse goes outside of the chart that
started the event. For example, I might start brushing a selection and
then go slightly outside the chart (or window) boundary; it's nice if
the selection extent continues to update as I move the mouse, being
bounded by the chart size.
The problem, though, is that you can no longer assume that each event
listener is uniquely bound to a single chart. That can only be true of
the mousedown event. So the solution is to store some global state
that records where the mousedown originated. For example, imagine that
`svg` is a selection containing multiple SVG elements. I can record
which element started the mousedown in a global variable:
var dragging;
svg.on("mousedown", function() { var dragging = this; });
Then, I can register mousemove and mouseup listeners on the window,
that check against this global:
d3.select(window).on("mousemove", function() { if (!dragging)
return; console.log("dragging: " + dragging); });
In this case, `dragging` stores the SVG element. You can then
d3.select(dragging) to create a selection from the element. If you
prefer, you could store the data (d) associated with the SVG element
in a global variable instead.
But, getting back to the missing mouseup events, it's difficult to say
why that might occur without seeing the code. If the mouseup event
handler is registered on the SVG element, then you wouldn't receive
mouseup events if the mouseup occurs while the mouse is outside the
bounds of the SVG element (that's the motivation for listening to the
window—this guarantees you always receive the mouseup event).
Another possibility is something else is consuming the event. For
example, the force layout's drag behavior prevents click events from
firing if you drag nodes (so that you can drag nodes without
triggering clicks). Also, in the unlikely event that you register
multiple mouseup listeners, only the last listener is used (unless you
use a namespace, such as "mouseup.foo").
Mike
.on("mousedown", function() { var dragging = 1 }).on("mouseup", function() { var dragging = 0 }).on("mousemove", function() { var m = d3.svg.mouse(this); if (dragging == 1) d3.select(this).select(".className").attr("y1", m[1]) });
Mike