score:1
Here's a working JS Fiddle: ScatterPlot with zoom and tooltips
Major changes:
As you're appending the
brush
rect
on top of the circles, themouse
events on the circles would never work. The order of the elements matters big time here, you see! So, here's what I did (moved brush appending code ABOVE the circles:svg.append("g") .attr("class", "brush") .call(brush); svg.selectAll("circle") ...
I'm not sure why you were using
mousemove
when you want the tooltip only when you have the mouse over the circles. I changed the mouse events to this:.on("mouseover", function(d){ tooltip.html(d[3]).style("top", (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").style("visibility", "visible"); }).on("mouseout", function(){return tooltip.style("visibility", "hidden");});
You had the
div
element (used as a tooltip) within the SVG. I'm sure that might've been done in a hurry. Here: I moved it outside of SVG:var tooltip = d3.select(".two") .append("div")
It's not recommended to use static numbers while setting the axes domains. You have the data and you know the
x
andy
points to be fetched from, so just use d3.extentx0 = d3.extent(points, function (d) { return d[0]; }), y0 = d3.extent(points, function (d) { return d[1]; })
Minor changes:
- Using
domain().nice()
while setting the domains. It's really useful when you have negative values. Here's the doc Instead of using just 2 of your provided points, I generated a few random points and used it as the data: this clears up the zoom issue as well (in which I changed nothing as you had it working perfect)
function generateRandomPoints () { var points = []; for(var i=0; i<10; i++) { points.push([Math.random()*30 - 15, Math.random()*20-5, i, 'Cluster '+ (i+1)]); } return points; }
Here's a snippet putting together all of the above:
var data = [
{
"points": generateRandomPoints()
}
];
function generateRandomPoints () {
var points = [];
for(var i=0; i<10; i++) {
points.push([Math.random()*30 - 15, Math.random()*20-5, i, 'Cluster '+ (i+1)]);
}
return points;
}
var points = data[0].points;
var svg = d3.select("#cluster"),
width = +svg.attr("width"),
height = +svg.attr("height");
var k = height / width,
x0 = d3.extent(points, function (d) { return d[0]; }),
y0 = d3.extent(points, function (d) { return d[1]; }),
x = d3.scaleLinear().domain(x0).nice().range([0, width]),
y = d3.scaleLinear().domain(y0).nice().range([height, 0]),
z = d3.scaleOrdinal(d3.schemeCategory10);
var xAxis = d3.axisTop(x).ticks(12),
yAxis = d3.axisRight(y).ticks(12 * height / width);
var brush = d3.brush().on("end", brushended),
idleTimeout,
idleDelay = 350;
var tooltip = d3.select(".two")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background", "#ffffff")
.text("a simple tooltip");
svg.append("g")
.attr("class", "brush")
.call(brush);
svg.selectAll("circle")
.data(points)
.enter()
.append("circle")
.attr("cx", function(d) {
return x(d[0]);
})
.attr("cy", function(d) {
return y(d[1]);
})
.attr("r", 4)
.attr("fill", function(d) { return z(d[2]); })
.on("mouseover", function(d){
tooltip.html(d[3]).style("top", (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px").style("visibility", "visible"); })
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
svg.selectAll(".domain")
.style("display", "none");
function brushended() {
var s = d3.event.selection;
if (!s) {
if (!idleTimeout) return idleTimeout = setTimeout(idled, idleDelay);
x.domain(x0).nice();
y.domain(y0).nice();
} else {
x.domain([s[0][0], s[1][0]].map(x.invert, x));
y.domain([s[1][1], s[0][1]].map(y.invert, y));
svg.select(".brush").call(brush.move, null);
}
zoom();
}
function idled() {
idleTimeout = null;
}
function zoom() {
var t = svg.transition().duration(750);
svg.select(".axis--x").transition(t).call(xAxis);
svg.select(".axis--y").transition(t).call(yAxis);
svg.selectAll("circle").transition(t)
.attr("cx", function(d) { return x(d[0]); })
.attr("cy", function(d) { return y(d[1]); });
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="one">
<div class="two">
<svg id="cluster" width="700" height="500"></svg>
</div>
</div>
Hope this helps.
Source: stackoverflow.com
Related Query
- custom x axis tooltip for nvd3 scatter chart
- Display tooltip close to the mouse pointer using d3.js in a scatter plot
- Add tooltip to d3 scatter plot
- how can update the name of the legends and tooltip in a scatter plot?
- Add Tooltip on Scatter points, error is generated for D3.js Version 4
- d3.js (v4) Scatter w/ Tooltip
- tooltip for a scatter plot matrix - using d3
- Tooltip not working nor displaying on D3 scatter plot
- C3.js Scatter plot - how to associate third data (additional value) as part of original column data for callbacks to set radius and display in tooltip
- How to add a tooltip to an svg graphic?
- How do I show a bootstrap tooltip with an SVG object?
- How to change tooltip content in c3js
- D3 - Positioning tooltip on SVG element not working
- Multiseries line chart with mouseover tooltip
- custom no data label in nvd3 scatter chart
- Using D3 transition method with data for scatter plot
- D3 multi-line tooltip for SVG element
- D3.js: Line chart - tooltip and vertical line of hover
- d3.js: How to add labels to scatter points on graph
- Change size of bubble in Scatter Plot for c3.js
- nvd3.js tooltip position with multiple charts
- Show tooltip on the D3 map
- How to show a tooltip with value when mouseover a svg line graph using d3.js?
- Why is my tooltip flashing on and off?
- d3.js scatter plot - zoom/drag boundaries, zoom buttons, reset zoom, calculate median
- nvd3 tooltip decimal format
- D3js Grouped Scatter plot with no collision
- HTML tooltip cleanup in d3.js
- Customized tooltip for C3JS
- nvd3 scatter plot with ordinal scale
More Query from same tag
- Refresh div on each submit without ajax
- Custom animation in plottable.js line chart
- d3 - How do I find the correct projection for a country?
- D3.js Tree:How to change the node color when clicking on it?
- c3js position of data labels
- How to create a voronoi diagram inside a circle with d3.js
- Text on top of d3 vertical stacked bar chart
- d3.js text transition if string is too long
- nvd3 multiBarChart - legend click events
- Choosing a root node based on key value
- How to make rectangles arc/curved in d3.js
- Selecting JavaScript drowndown option causes D3 treemap to change
- how to update page elements with each() iteration?
- d3.js Trying to create a grid and don't know how to access certain elements or bind to columns
- How to make separate force layout render loop?
- NVD3 Discrete BarChart With Json
- Multiple selection of nodes in d3 force layout
- d3 get attribute with special character
- How to add a custom svg shape in D3.js
- D3: Sunburst chart with root node on the outside ring
- Dart D3 line using Package JS
- d3.select() Not Returning Anything
- D3 multiplying datapoints in stackedAreaChart
- Stacked Bar Chart using d3.js stack layout; the bar sections not always in correct place
- D3plus hyperlink
- How to center a map on something other than the prime meridian in d3.js?
- D3 exit().remove() on stack area chart
- transitioning rotated axis labels with D3
- Displaying a graph
- How to set y tick value in c3.js?