score:2
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.
score:10
One 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.org/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
Source: stackoverflow.com
Related Query
- How can I keep a d3 mouseover open while my mouse is over the tooltip?
- D3: Keep mouseover Open While Mouse is Over Tooltip
- How can I get the value at the corresponding place while mouseover in d3.js?
- How can I iterate through an array over and over again while assigning each of its values to all the svgs in my DOM
- Google Chrome: How can I watch the state of the DOM while holding the mouse button
- d3.js - How can I set the cursor to hand when mouseover these elements on SVG container?
- How to show and hides nodes when you move the mouse over a node in D3 Javascript
- How can I connect two parent node into one child node and how to make a tooltip for each node in the tree pragmatically? in D3 js (SVG)
- How do you find the distance while drawing line on mouse vertical axis or horizontal?
- mouse over the center text in the doughnut chart is not displaying the tooltip
- In a d3 scatterplot using data from a csv file, how do i draw lines connecting related points when the mouse is over a point?
- In d3.js, while importing csv files using a row conversion, how can I "slice" the data to only include a range of rows?
- how can update the name of the legends and tooltip in a scatter plot?
- How can I draw a continuous line using d3 without needing to click&drag the mouse, but rather just use the mouseover event?
- Button with text label: How do I keep the hover color even when over text label?
- How can i Show values over the NVD3 historical bar?
- How to keep mouse over object when using drag and snap to with d3.js
- How can I continue displaying a tooltip when it hovers over text in a d3 map
- Javascript: How to show tooltip by hovering mouse over axis lable
- How can I bring a circle to the front with d3?
- How can I get the D3.js axis ticks and positions as an array?
- MultiBar chart with nvd3 / d3 only shows labels for every other tick on the x-axis. How can I get them all to show up?
- How to set the origin while drag in d3.js in v4
- How can I change the radius and opacity of a circle in d3?
- How can I keep tick marks from repeating when I have a small number of dates on an nvd3 chart
- New to nvD3 - how can I make my unix timestamps appear as dates on the x-axis?
- how to display name of node when mouse over on node in collapsible tree graph
- How can I start with all the nodes collapsed in d3js?
- How to show a tooltip with value when mouseover a svg line graph using d3.js?
- How can I toggle the class of all elements in a selection?
More Query from same tag
- D3: Why doesn't the heatmap color legend appear?
- d3.js Update Bar Chart Tooltip with Buttons
- d3.js : attribute setting not working after binding data and entering elements
- D3 Update bar chart
- Make D3 Stacked Bar Chart fill parent SVG container
- Best practices for filtering data
- D3 JS: Create a page index.html to run the js project
- Best practice : Remove table row with d3.js or css
- D3 custom attributes not being selected
- How do i plot multiple lines in the same line graph using the D3 framework?
- D3 Tree Diagram Curved Line Start Position
- Get all paths in JSON object
- Updating D3 streamgraph with new data
- How to obtain percentage in tooltips of an nvd3 pie chart?
- Horizontal Bar Chart D3, .txt file
- Can I merge new and existing data in a D3 join?
- Zooming to a clicked node on a D3 Force Directed Graph
- How to map data such that I can use it to generate pie chart?
- Calendar heatmap: how to define the range of % for each color instead of using quantiles
- d3 v4 drag line chart with x and y axes
- Anomalous mouseover handling with D3.js in Internet Explorer 11
- Group a HTML tabulation from multidimensional array with data driven documents
- d3 grouped bar chart inconsistent items alignment
- D3 placing nodes labels inside circles in Mobile Patent Suits
- D3 line graph getting error and not getting plotted
- D3 highlight corresponding table entry when hovering over donut chart slice
- Reset Button for NVD3 Parallel Coordinate Plot
- Changing a pie chart into an arrow ring chart
- d3.js: Change (drill-down) data bound in selection.each()
- How can I make a line between 2 elements dynamically (without knowing their coordinates)?