Reputation: 2433
d3.js verison 4: I have a line chart, which should have a rectangle zoom. I used this example: http://bl.ocks.org/jasondavies/3689931
I don't want to apply the rectangle data to the scales, like in the example
Instead I want to apply this to my normal zoom Element.
For that I have the math:
.on("mouseup.zoomRect", function() {
d3.select(window).on("mousemove.zoomRect", null).on("mouseup.zoomRect", null);
d3.select("body").classed("noselect", false);
var m = d3.mouse(e);
m[0] = Math.max(0, Math.min(width, m[0]));
m[1] = Math.max(0, Math.min(height, m[1]));
if (m[0] !== origin[0] && m[1] !== origin[1]) {
//different code here
//I have the scale factor
var zoomRectWidth = Math.abs(m[0] - origin[0]);
scaleFactor = width / zoomRectWidth;
//Getting the translation
var translateX = Math.min(m[0], origin[0]);
//Apply to __zoom Element
var t = d3.zoomTransform(e.node());
e.transition()
.duration(that.chart.animationDuration)
.call(that.chart.zoomX.transform, t
.translate(translateX, 0)
.scale(scaleFactor)
.translate(-translateX, 0)
);
}
rect.remove();
refresh();
}, true);
So I actually get the scaleFactor right and it zooms in smoothly. Only problem is, that I don't seem to get the translation correct. So it zooms in to the wrong position.
Upvotes: 0
Views: 693
Reputation: 2433
So, now I got it right: All transformations by earlier zooms need to be undone.
so that k = 1, x = 0, y = 0; This is the d3.zoomIdentity. From that point the current zoom needs to be applied and afterwards the translation.
After that the old transform needs to be applied, first translate and then scale
var t = d3.zoomTransform(e.node());
//store x translation
var x = t.x;
//store scaling factor
var k = t.k;
//apply first rect zoom scale and then translation
//then old translate and old zoom scale
e.transition()
.call(that.chart.zoomX.transform, d3.zoomIdentity
.scale(scaleFactor)
.translate(-translateX, 0)
.translate(x)
.scale(k)
);
Working Fiddle only for X-Axis here: https://jsfiddle.net/9j4kqq1v/3/
Working fiddle for X and Y-axis here: https://jsfiddle.net/9j4kqq1v/5/
Upvotes: 1