Accepted answer

To start with the median function just takes an array and an optional accessor. So you can use it the same way you use max:

var med = d3.median(data, function(d) { return +d.TotalEmployed2011; });

As for the others if you pull out your zoom behaviour you can control it a bit better. So for example instead of

var svg = 


var zm = d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom);
var svg =;

Then you can set the zoom level and translation directly:

function zoomIn() {
   // probably need to compute a new translation also

function reset() {

Restricting the panning range is a bit trickier. You can simply not update when the translate or scale is not to your liking inside you zoom function (or set the zoom's "translate" to what you need it to be). Something like (I think in your case):

function zoom() {
    if(y.domain()[0] < 0) {
        // To restrict translation to 0 value
        zm.translate([d3.event.translate[0], height * (1 - zm.scale())]);

Keep in mind that if you want zooming in to allow a negative on the axis, but panning not to you will find you get into some tricky scenarios.

This might be dated, but check out Limiting domain when zooming or panning in D3.js

Note also that the zoom behaviour did have functionality for limiting panning and zooming at one point. But the code was taken out in a later update.


I don't like to reinvent the wheel. I was searching for scatter plots which allow zooming. Highcharts is one of them, but there's plotly, which is based on D3 and not only allows zooming, but you can also have line datasets too on the scatter plot, which I desire with some of my datasets, and that's hard to find with other plot libraries. I'd give it a try:

Using such nice library can save you a lot of time and pain.

More Query from same tag