* the display attribute
* the opacity style
* the fill-opacity and stroke-opacity styles
If you really want to hide something, then style("display", "none") is
probably the way to go, as it tells the browser to treat the element
as if it didn't exist. With visibility, it's possible to have child
elements that are visible, and still receive input events; thus,
setting the display style to "none" is faster if you want something to
disappear.
Using opacity is nice for fading in and out, because unlike the
attributes, it takes a numeric value in the range [0,1]. The
fill-opacity and stroke-opacity styles are much faster to render, so
use them if you can; on the other hand, opacity is more useful if you
want to fade an svg:g element and all of its contents.
I think your race condition has something to do with you setting the
visibility attribute in multiple places. Also, D3 doesn't know how to
interpolate the visibility attribute from the value "inherit" to the
value "visible"; there isn't a way to interpolate this value smoothly.
So instead it's just setting the value to "visible" as soon as the
transition starts. Thus, you probably don't want to include this
attribute in your transition, and instead do it before (or after) the
transition.
A good way to debug this might be to use opacity rather than
visibility; this way you can slow the transition down and watch what
happens.
Mike