Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 manually zoom,how to set the translate for zoom

Tags:

d3.js

I need to do a transition manually, as I know about d3 zoom, the zoom will not listen my manual zoom, so after manually zoom, when I use mouse to drag or mouse wheel to scroll, the d3 zoom will start event from the previous position(translate) and scale value that the d3 zoom stored, it is so terrible for my map. So I need to set the zoom translate and scale after my manual zoom, and I can set the zoom scale, but I don't know the value to set the zoom translate.

       g.transition()
        .duration(1000)
        .attr("transform", "translate(" + (window_width / 2 + translateX) + "," + (window_height / 2 ) + ")scale(" + zoomLevel + ")translate(" + (-x + 10) + "," + -y + ")")
        .each("end", function () {
            if (zoomLevel > 1) {
                $("#zoom_control").show();
                showCenteredTextInCircle();
                // zoom.scale(zoomLevel);
                // zoom.translate([x*zoomLevel, y*zoomLevel]);
            }
        });

This code is reference from d3-zoom-example

Any one know the right zoom translate value after my transition manually ?Thanks!!!

like image 673
Awakening Avatar asked Sep 11 '14 01:09

Awakening


1 Answers

The zoom scale and zoom translate are stored in your zoom object. I'm guessing you have a line of code that looks like:

var zoom = d3.behavior.zoom()
             .translate([0, 0])
             .scale(1).scaleExtent([1, 3])
             .on("zoom", zoomed);

You can initial scale and translate values for first time, This type of definition could help you to restrict zoom scale and initial translate if zoom scale is 1 or when zoom event start. Attention all of this are optional, you can just use this kind of definition:

var zoom = d3.behavior.zoom();

So getting the scale and translate from that object is simple:

var scale=zoom.scale(); var position=zoom.translate();

If you looking for some method to do a transition manually or do a scale manually you have to use this function:

function interpolateZoom(translate, scale) {

                return d3.transition().duration(150).tween("zoom", function() {
                    var iTranslate = d3.interpolate(zoom.translate(), translate),
                        iScale = d3.interpolate(zoom.scale(), scale);

                    return function(t) {
                        zoom.scale(iScale(t)).translate(iTranslate(t));
                    };
                });
            };

zoomed is a function I defined to call on zoom event, you can add your translate to this function looks like:

function zoomed() {
      g.transition().duration(1000)
        .attr("transform", "translate(" + (window_width / 2 + translateX) + "," + (window_height / 2 ) + ")scale(" + zoomLevel + ")translate(" + (-x + 10) + "," + -y + ")")
        .each("end", function () {
            if (zoomLevel > 1) {
                $("#zoom_control").show();
                showCenteredTextInCircle();
                interpolateZoom([x*zoomLevel, y*zoomLevel],zoomLevel);
                // zoom.scale(zoomLevel);
                // zoom.translate([x*zoomLevel, y*zoomLevel]);
            }
        });
    }

I hope this helps you out.

like image 90
Gabriel Avatar answered Nov 13 '22 00:11

Gabriel