Skip to content

Instantly share code, notes, and snippets.

Last active May 20, 2019
What would you like to do?
D3 v4 - Scatter Plot - Semantic Zooming

This code shows how to use zoom in d3.js v4, for a scatter plot, without changing in points size.

<!DOCTYPE html>
<meta charset="utf-8">
<svg width="500" height="500"></svg>
<script src=""></script>
var n = 50; // number of points
var max = 100; // maximum of x and y
// dimensions and margins
var svg ="svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
width = 0.8*width;
height = 0.8*height;
var margin = {top: (0.1*width), right: (0.1*width), bottom: (0.1*width), left: (0.1*width)};
// create a clipping region
.attr("id", "clip")
.attr("width", width)
.attr("height", height);
// create scale objects
var xScale = d3.scaleLinear()
.domain([0, max])
.range([0, width]);
var yScale = d3.scaleLinear()
.domain([0, max])
.range([height, 0]);
// create axis objects
var xAxis = d3.axisBottom(xScale)
.ticks(20, "s");
var yAxis = d3.axisLeft(yScale)
.ticks(20, "s");
// Draw Axis
var gX = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + ( + height) + ')')
var gY = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + + ')')
// Draw Datapoints
var points_g = svg.append("g")
.attr('transform', 'translate(' + margin.left + ',' + + ')')
.attr("clip-path", "url(#clip)")
.classed("points_g", true);
data = genRandomData (n, max);
var points = points_g.selectAll("circle").data(data);
points = points.enter().append("circle")
.attr('cx', function(d) {return xScale(d.x)})
.attr('cy', function(d) {return yScale(d.y)})
.attr('r', 5);
// Pan and zoom
var zoom = d3.zoom()
.scaleExtent([.5, 20])
.extent([[0, 0], [width, height]])
.on("zoom", zoomed);
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all")
.attr('transform', 'translate(' + margin.left + ',' + + ')')
function genRandomData (n, max){
var data = [];
var datapoint = {};
for (i = 0; i < n; i++){
datapoint = {};
datapoint["x"] = Math.random() * max;
datapoint["y"] = Math.random() * max;
return data
function zoomed() {
// create new scale ojects based on event
var new_xScale = d3.event.transform.rescaleX(xScale);
var new_yScale = d3.event.transform.rescaleY(yScale);
// update axes;;
.attr('cx', function(d) {return new_xScale(d.x)})
.attr('cy', function(d) {return new_yScale(d.y)});
Copy link

Ram0987 commented May 19, 2019

Thank you very much @aleereza for sharing your work. It is really great!!. I have a question. Is it possible to add tool tips on the above graph?
Thank you.

Copy link

Hi @Ram0987, It's been a long time since I used d3, actually I am not sure if it is possible. I found this example which has both zoom and tool tip.

Copy link

Ram0987 commented May 20, 2019

@aleereza, Thank you very much for your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment