d3.jsscatter-plotsemantic-zoom

Update zoom domain for d3.js scatterplot


I'm creating a zoomable scatterplot based on the following examples:

Scatterplot

D3 Scatterplot Example

What Career Should I Invest In?

I've added a button to change the category for the x axis from Calories to Carbs and the chart is updated correctly. But when I try to zoom with the new domain the zooming uses the old domain. How can I update the zoom functionality for the new domain?

The current implementation can be found here.


Solution

  • You just need to rebind the new scales to the behavior.

    First put the zoom behaviour function in a variable so you can access it later: Your original code...

       var svg = d3.select("#scatter")
    .append("svg")
      .attr("width", outerWidth)
      .attr("height", outerHeight)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .call(d3.behavior.zoom().x(x).y(y).scaleExtent([0, 500]).on("zoom", zoom));
    

    should be this:

      var zoomBeh = d3.behavior.zoom()
          .x(x)
          .y(y)
          .scaleExtent([0, 500])
          .on("zoom", zoom);
    
      var svg = d3.select("#scatter")
        .append("svg")
          .attr("width", outerWidth)
          .attr("height", outerHeight)
        .append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
          .call(zoomBeh);
    

    Second, in your function change, you bind the scales to the behavior. So instead of:

      function change() {
        xCat = "Carbs";
        xMax = d3.max(data, function(d) { return d[xCat]; });
        xMin = d3.min(data, function(d) { return d[xCat]; });
    
        x.domain([xMin, xMax]);
    
        var svg = d3.select("#scatter").transition();
    
        svg.select(".x.axis").duration(750).call(xAxis).select(".label").text(xCat);
    
        objects.selectAll(".dot").transition().duration(1000).attr("transform", transform);
      } 
    

    you just change one line:

      function change() {
        xCat = "Carbs";
        xMax = d3.max(data, function(d) { return d[xCat]; });
        xMin = d3.min(data, function(d) { return d[xCat]; });
    
        // x.domain([xMin, xMax]);
        zoomBeh.x(x.domain([xMin, xMax])).y(y.domain([yMin, yMax]));
    
        var svg = d3.select("#scatter").transition();
    
        svg.select(".x.axis").duration(750).call(xAxis).select(".label").text(xCat);
    
        objects.selectAll(".dot").transition().duration(1000).attr("transform", transform);
      }
    

    For documentation, see http://bl.ocks.org/mbostock/3892928