On mouseover cursor changes to button form - javascript

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');
});

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.

D3 Mouseenter vs Mouseover

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)

Zoom event overrides Drag behavior in d3js

I'm trying to implement both dragging and zooming event handlers for a circle item using d3js. I've added behaviors for both events as given below
var circle = svg.append("circle")
.attr("fill", "green")
.attr("opacity", 0.6)
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 13)
.call(d3.behavior.drag().on("drag", drag))
.call(d3.behavior.zoom().on("zoom", zoom));
without zooming the object, dragging works fine. after zooming in/out of the object, dragging does not work, yet all events containing a mousedown is caught as "zoom" event.
For full source please see http://jsfiddle.net/xTaDC/
Seems that i did not understand the "d3.behavior". https://github.com/mbostock/d3/blob/master/examples/mercator/mercator-zoom-constrained.html provides only zoom handler and handles both dragging and zooming.
What am i doing wrong here?
As far as I know, d3's zoom behavior already handles dragging, so the drag thing is redundant. Try making use of the zoom's d3.event.translate (which is a 2 element array, so if you want to get the x value only, you can go d3.event.translate[0]) to replicate the functionality in your Drag into your Zoom.
Additional tip: To make things easier on yourself, make sure that you apply your call(zoom) on the parent of whatever it is that you're trying to drag. This will prevent jittery and shaky behavior.
Source is of course, the d3 wiki.
"This behavior automatically creates event listeners to handle zooming and panning gestures on a container element. Both mouse and touch events are supported."
https://github.com/mbostock/d3/wiki/Zoom-Behavior
I faced similar problem and solved it by overriding other sub events of zoom.
Add below code after zoom and drag event listeners
.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
So the full code will look like
var circle = svg.append("circle")
.attr("fill", "green")
.attr("opacity", 0.6)
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 13)
.call(d3.behavior.drag().on("drag", drag))
.call(d3.behavior.zoom().on("zoom", zoom))
.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
Append your graph with sensitive event area (must be the last append) :
var rect = svg.append("svg:rect")
.attr("class", "pane")
.attr("width", w)
.attr("height", h);
AFTER (not include) add event management on this area
rect.call(d3.behavior.zoom().x(x).scaleExtent([0.5, 4]).on("zoom", draw));
and the draw function is
function draw() {
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
svg.select("path.area").attr("d", area);
svg.select("path.line").attr("d", line);
}
see this exemple : https://groups.google.com/forum/?fromgroups=#!topic/d3-js/6p7Lbnz-jRQ%5B1-25-false%5D
In 2020, use d3.zoom to enable zooming and panning: https://observablehq.com/#d3/zoom
If you want to enable panning for the background, while allowing to drag the circle, see the official example where d3.drag and d3.zoom are used on different elements: https://observablehq.com/#d3/drag-zoom

Categories

Resources