admin管理员组文章数量:1293220
I have a d3 scatterplot. I have a tooltip which shows when I mouseover a point. I want to do two things.
1) I want the mouseover to stay open as long as my mouse is either over the point or the tooltip. 2) I want to put a clickable link in the tooltip. I believe that #1 is required in order to make this work.
How can I do this?
Here is my code: .js
I have a d3 scatterplot. I have a tooltip which shows when I mouseover a point. I want to do two things.
1) I want the mouseover to stay open as long as my mouse is either over the point or the tooltip. 2) I want to put a clickable link in the tooltip. I believe that #1 is required in order to make this work.
How can I do this?
Here is my code: https://github./laran/eisenhower/blob/master/ponents/plot/scatterplot.js
Share asked Feb 24, 2015 at 19:04 Laran EvansLaran Evans 1,3135 gold badges16 silver badges31 bronze badges2 Answers
Reset to default 11One idea may be to create a delayed transition on the mouseout of the circle to allow the user time to mouse to the tooltip. If they mouseover the circle in time, you cancel the transition and hide the tooltip on mouseout of tooltip div:
// create tooltip
var tip = d3.select('body')
.append('div')
.attr('class', 'tip')
.html('I am a tooltip...')
.style('border', '1px solid steelblue')
.style('padding', '5px')
.style('position', 'absolute')
.style('display', 'none')
.on('mouseover', function(d, i) {
tip.transition().duration(0); // on mouse over cancel circle mouse out transistion
})
.on('mouseout', function(d, i) {
tip.style('display', 'none'); // on mouseout hide tip
});
...
// mouseover and out of circle
.on('mouseover', function(d, i) {
tip.transition().duration(0); // cancel any pending transition
tip.style('top', y(d.y) - 20 + 'px');
tip.style('left', x(d.x) + 'px');
tip.style('display', 'block');
})
.on('mouseout', function(d, i) {
tip.transition()
.delay(500)
.style('display', 'none'); // give user 500ms to move to tooltip
});
Here's a quick example.
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<script>
// data that you want to plot, I've used separate arrays for x and y values
var data = [{
x: Math.random() * 10,
y: Math.random() * 10
},
{
x: Math.random() * 10,
y: Math.random() * 10
},
{
x: Math.random() * 10,
y: Math.random() * 10
},
{
x: Math.random() * 10,
y: Math.random() * 10
}
];
xdata = [5, 10, 15, 20],
ydata = [3, 17, 4, 6];
// size and margins for the chart
var margin = {
top: 20,
right: 15,
bottom: 60,
left: 60
},
width = 500 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 10])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 10])
.range([height, 0]);
var tip = d3.select('body')
.append('div')
.attr('class', 'tip')
.html('I am a tooltip...')
.style('border', '1px solid steelblue')
.style('padding', '5px')
.style('position', 'absolute')
.style('display', 'none')
.on('mouseover', function(d, i) {
tip.transition().duration(0);
})
.on('mouseout', function(d, i) {
tip.style('display', 'none');
});
var chart = d3.select('body')
.append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.attr('class', 'chart')
var main = chart.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.attr('width', width)
.attr('height', height)
.attr('class', 'main')
// draw the x axis
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
main.append('g')
.attr('transform', 'translate(0,' + height + ')')
.attr('class', 'main axis date')
.call(xAxis);
// draw the y axis
var yAxis = d3.svg.axis()
.scale(y)
.orient('left');
main.append('g')
.attr('transform', 'translate(0,0)')
.attr('class', 'main axis date')
.call(yAxis);
// draw the graph object
var g = main.append("svg:g");
g.selectAll("scatter-dots")
.data(data)
.enter().append("svg:circle")
.attr("cy", function(d) {
return y(d.y);
})
.attr("cx", function(d, i) {
return x(d.x);
})
.attr("r", 10)
.style("opacity", 0.6)
.on('mouseover', function(d, i) {
tip.transition().duration(0);
setTimeout(() => {
tip.style('top', y(d.y) - 20 + 'px');
tip.style('left', x(d.x) + 'px');
tip.style('display', 'block');
}, 500);
})
.on('mouseout', function(d, i) {
tip.transition()
.delay(500)
.style('display', 'none');
})
</script>
</body>
</html>
LICENSE
There is probably no easy way to do it.
One option is to nest the tooltip inside the same container as the circle (i.e. an svg <g>
) and attach the mouse events to that parent, so that when the mouse goes between the tooltip and circle it won't trigger mouseout. That'll make it hard to transition the tooltip between circles, because it would involve detaching it from one parent and attaching to the other.
Probably the simpler option is to attach a mouseover and mouseout events to the tooltip, and set a flag (like isOverTooltip = true
or false
) to keep track of where the mouse is. Then check this flag in the mouseout of the circle to determine whether or not to hide the tooltip. In this case, inside the mouseout of the circle, you would want to hide the tooltip from within a setTimeout
(and of course only when !isOverTooltip
), in order to allow time for the mouse to travel between circle and tooltip without the tooltip disappearing.
本文标签: javascriptHow can I keep a d3 mouseover open while my mouse is over the tooltipStack Overflow
版权声明:本文标题:javascript - How can I keep a d3 mouseover open while my mouse is over the tooltip? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741573402a2386141.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论