D3 Mouseenter vs Mouseover - javascript

I wrote a D3 widget a while back based on the sunburst example on the D3 site - http://bl.ocks.org/kerryrodden/7090426.
The widget was fine and I even submitted it to an open source project (several other people viewed it and tested it). However now, when I try to view the same widget with a different computer (same browser version), I am experiencing an inconsistent behavior with mouseover and mouseenter. When I hover over items, only the first item I hovered over has the opacity set, when I move the mouse within the widget, opacity is not updated.
Here is the broken version:
http://jsfiddle.net/wrdrvr/f5tvsv5v/
var path = svg.datum(data).selectAll("path")
.data(partition.nodes)
.enter().append("path")
.attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
.attr("d", arc)
.attr('id',function(d) {
return d.name+"-"+d.value;
})
.style("stroke", "#fff")
.style("fill", function(d) {
if (d.depth > 0) {
return color(d.name);
}
}) .each(stash)
.on("mouseover", mouseover)
//.on("mouseenter",mouseover)
.on("mouseleave", mouseleave)
I was able to get it to work as it was supposed to by including a mouseenter, however I did not use it previously and it was not used in the example and I am not sure why I need it here. Can someone please help clarify this?

Updated http://jsfiddle.net/f5tvsv5v/2/
.on("mouseleave", mouseleave)
//.on("mouseover", mouseover)
.on("mouseenter",mouseover)
You should use mouseenter instead of mouseover since mouseover does not buble (http://www.quirksmode.org/dom/events/mouseover.html)

Related

d3.js dendogram how to add links to leaf nodes and change colors [duplicate]

I am trying to add a link to the text elements of this D3 visualisation:
http://bl.ocks.org/1093025
I would like to be able to click on "flare", "analytics" and navigate to another page or click in the rectangle and perform the normal action, which is expanding the sub-trees.
I tried a few things that didn't work:
on event
I tried to add an on event to the svg:text element:
nodeEnter.append("svg:text")
.attr("dy", 3.5)
.attr("dx", 5.5)
.text(function(d) { return d.name; })
.on("click",function(d,i) { alert("Clicked on the text");});
foreignObject element
I tried to add the foreignObject element like this:
nodeEnter.append("svg:foreignObject")
.style("float","right")
.attr("height", 100)
.attr("width", 100)
.append("div")
.html("<a href='#'>link</a>")
Even though it creates the link, it is an extra link, though (not the text element in the rectangle).
link with xlink:href attribute
Finally, I also tried the following (in some combinations):
<a xlink:href="/svg/index.html">
<text x="10" y="20">/svg/index.html</text>
</a>
But it didn't work either.
Any suggestions?
I agree with Matt's answer re: pointer-events... change this to pointer-events: all in the css.
And this is how I made the link in the force directed graph:
svg = d3.select("body").append("svg");
svg.selectAll(".node")
.append("svg:a").attr("xlink:href", function(d){ return "generic.php?url=" + d.url })
.append("svg:text")
.text(function(d) { return d.name; })
.attr("dy", 3.5)
.attr("dx", 5.5)
.attr("text-anchor", "middle");
//The End ;-)
.on('click', function () {}) should work as long as you
have selected the right nodes
haven't disabled pointer events on text elements with css
The pointer events seems to be catching people out as quite a lot of the examples have pointer-events: none for the text nodes.

d3 mouseover/touchstart not trigger event on mobile

I have simple d3 code binding data with circles. An event is fired when mouse hover over the circles. The mouseOver function is also very simple. It just makes tooltip div visible.
It's a client work so I cannot share the full code. But it has the simple structure like below:
function mouseOver() {
tooltip.style("visibility", "visible")
.style("top", d3.event.pageY + "px")
.style("left", d3.event.pageX +"px")
.html('<p>'+'</p>')
}
var circles = g
.selectAll('.circles')
.data(data)
.join('circle')
.attr('class', 'circles')
.attr('cx', d => x(d))
.attr('cy', d => y(d))
.attr('r', r)
.attr('fill', d => colour(d.type))
.attr('fill-opacity', 0.6)
.on('mouseover', mouseOver)
.on('mouseleave', mouseLeave)
circles.exit().remove()
It works well on desktop. But for some reasons, the tooltip doesn't show up on mobile.
I changed the 'mouseover' into 'touchstart' in case it's the reason. To capture if the window ontouchstart, I made like this.
var hover = ('ontouchstart' in window) ?
'touchstart click' : 'mouseover';
Then, in the selection, I changed as below:
.on(hover, mouseOver)
But it still doesn't trigger the event on mobile.
On a side note, I also have bars(rect) with the same setting as circles above but the mouseover event is trigerred on mobile as well as desktop.
I really have no idea why one event works well on mobile although it's fired by 'mouseover' event handler while the other doesn't work at all despite the same setting as the other.
Does anyone have ideas??

D3: Keep mouseover Open While Mouse is Over Tooltip

I'm using d3-tip for tooltips on my graph. And am trying to work out if there's an easy way to keep the tooltips open for a brief period of time?
Once I mouseout on the node, it fires the .hide() method, I can never actually hover over the tooltip.
I think I need a way to mouseover the tooltip element so I can fire the .show() method, like so:
tip.on('mouseover', function(d) {
tip.show(d);
}
But I'm not sure how to do this...
I've set up a JSFiddle here.
Any ideas if this is possible?
Thanks in advance!
Here's the result: http://jsfiddle.net/hx8pjwdu/9/
.on('mouseover', function(d) {
d3.select(".d3-tip").transition().style("opacity", "1");
tip.show(d);
})
.on('mouseout', function(d) {
d3.select(".d3-tip").transition().duration(1000).style("opacity", "0").each("end", tip.hide);
});
d3.select(".d3-tip").on('mouseover', function(d) {
d3.select(".d3-tip").transition().style("opacity", "1");
}).on('mouseout', function(d) {
d3.select(".d3-tip").transition().duration(1000).style("opacity", "0").each("end", tip.hide);
});
I added a mouseover event for your d3-tip and made its hide event a fadeout.

On mouseover cursor changes to button form

I need some help with my d3.js. Could someone help me in implementing a feature that on mouse over your cursor turns into the "click" cursor form? For example when you click hover over a button on stack overflow the cursor changes.
.on("mouseover", function() {
d3.select(this)
.style("fill", "#3b6887");
})
See the different cursors available you can use cursor CSS | MDN
Try the following
.on('mouseover', function() {
d3.select(this)
.style('fill', '#3b6887')
.style('cursor', 'pointer');
});

How to include links in a D3 visualisation's text element?

I am trying to add a link to the text elements of this D3 visualisation:
http://bl.ocks.org/1093025
I would like to be able to click on "flare", "analytics" and navigate to another page or click in the rectangle and perform the normal action, which is expanding the sub-trees.
I tried a few things that didn't work:
on event
I tried to add an on event to the svg:text element:
nodeEnter.append("svg:text")
.attr("dy", 3.5)
.attr("dx", 5.5)
.text(function(d) { return d.name; })
.on("click",function(d,i) { alert("Clicked on the text");});
foreignObject element
I tried to add the foreignObject element like this:
nodeEnter.append("svg:foreignObject")
.style("float","right")
.attr("height", 100)
.attr("width", 100)
.append("div")
.html("<a href='#'>link</a>")
Even though it creates the link, it is an extra link, though (not the text element in the rectangle).
link with xlink:href attribute
Finally, I also tried the following (in some combinations):
<a xlink:href="/svg/index.html">
<text x="10" y="20">/svg/index.html</text>
</a>
But it didn't work either.
Any suggestions?
I agree with Matt's answer re: pointer-events... change this to pointer-events: all in the css.
And this is how I made the link in the force directed graph:
svg = d3.select("body").append("svg");
svg.selectAll(".node")
.append("svg:a").attr("xlink:href", function(d){ return "generic.php?url=" + d.url })
.append("svg:text")
.text(function(d) { return d.name; })
.attr("dy", 3.5)
.attr("dx", 5.5)
.attr("text-anchor", "middle");
//The End ;-)
.on('click', function () {}) should work as long as you
have selected the right nodes
haven't disabled pointer events on text elements with css
The pointer events seems to be catching people out as quite a lot of the examples have pointer-events: none for the text nodes.

Categories

Resources