3

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
ari gold
  • 2,074
  • 3
  • 25
  • 51
  • This kinda seems like something to post in d3's github issues but I wasn't sure and didn't wanna misstep. – ari gold Mar 14 '14 at 19:28
  • 1
    Not sure what you mean. Can you show us the code for the zoom? – Lars Kotthoff Mar 14 '14 at 19:31
  • 1
    If you attach a scale to the zoom behaviour, it will change the domain when you zoom or pan. That's a convenience feature, you can always handle the scaling yourself by *not* specifying the scale when you create the zoom, but it's usually more code. What do you need the scale's domain for that the zoom is causing a problem? – AmeliaBR Mar 14 '14 at 20:41
  • @AmeliaBR while I figured it out thanks to you and Lars (lucky me y'all both responded) I might not understand this part of your comment: What do you need the scale's domain for that the zoom is causing a problem? If you're asking why I need the yScale then, well, it's how I draw things. – ari gold Mar 14 '14 at 20:49
  • 1
    The intended behaviour of the zoom is to change the scale at which you draw things, so I was confused as to how this was a problem (and wondered if you were trying to access the domain directly for other calculations). But yes, if you only want it to zoom in one direction, and not the other, then you only attach one scale to the zoom behaviour. – AmeliaBR Mar 14 '14 at 20:53
  • Well, @AmeliaBR, not that you necessarily need/want it (what with ~5,000 in two months - there's gotta be a good story in there) but feel free to copy your comment(s) into an answer and I'll accept it. You're a ninja. – ari gold Mar 14 '14 at 21:51

1 Answers1

4

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,

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

Community
  • 1
  • 1
AmeliaBR
  • 27,344
  • 6
  • 86
  • 119