Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does d3 rescale all scales during zoom?

Tags:

d3.js

The problem is that my yScale changes upon panning.

Here's the definition of the scale:

this.yScale = d3.scale.linear()
    .domain([0, this.maxY * this.yHeader])
    .rangeRound([0, height * this.yHeightScalor]);

I need to keep hold of the scale (i.e. use this.yScale instead of just var yScale) because of my redraw function. The trick is, panning = zooming where d3.event.scale === 1 and zooming rescales domains as you can see if you put a breakpoint in D3's zoom.js rescale function.

I can get around it by making sure my yScale is defined correctly when used but it seems to me that somethings amiss.

UPDATE: I've included the code and removed the line causing the issues. Truth be told, I only needed the xScale to zoom for user feedback. I redraw everything after the zoom anyway (in zoomEndFunction).

zoom = d3.behavior.zoom()
    .x(this.xScale)
    .y(this.yScale) // <--------------------- I removed this
    .scaleExtent([0.5, 2])
    .on("zoom", zoomFunction(this))
    .on("zoomend", zoomEndFunction(this));

svg = histogramContainer.append("svg")
    .attr('class', 'chart')
    .attr('width', width)
    .attr('height', height)
    .call(zoom)
    .append('g')
    .attr('transform', 'translate(' + this.margin.left  + ' , ' +
            (height - this.margin.bottom) + ')');

// everything else is in the svg
like image 212
ari gold Avatar asked Nov 19 '25 01:11

ari gold


1 Answers

The d3 zoom behaviour primarily acts as a wrapper for handling multiple events (mousewheel, drag, and various touch gestures), and converting them into translate and scale values, which are passed to your zoom event handlers as properties of the d3.event object.

However, you can also register a quantitative (non-ordinal) scale on the zoom behaviour using zoom.x(xScale) and zoom.y(yScale). The zoom behaviour will adjust each scale's domain to reflect the translation and scale prior to triggering the zoom event, so that all you have to do is redraw your visualization with those scales.

You do not have to register your scales on the zoom behaviour, or you can register one scale but not the other. For example,

  • if you are using transformations to zoom the visualization (a "geometric zoom", in d3 parlance), you don't need to change your scales at all;
  • if you are using a polar coordinates system, instead of x/y coordinates, you'll need to calculate the adjustments directly;
  • if you have a graph with a meaningful baseline, but very dense data, you may want to zoom/pan the horizontal axis but not the vertical.

From the comments, it sounds like the last situation reflects your case.

like image 54
AmeliaBR Avatar answered Nov 22 '25 04:11

AmeliaBR