0

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.

Jonas Petersson
  • 685
  • 1
  • 13
  • 24

1 Answers1

1

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

ee2Dev
  • 1,938
  • 20
  • 29