3djs, force diagram. How to preserve zoom level

2019-08-11 00:32发布

I am trying to save to database a zoom and scale level. I made progress, but there is something I have issues solving.

This is how it goes. On my force diagram initial render, my zoom levels are exact. So in other words this is what I do:

 svg.append("defs").selectAll("marker")
.data(["suit", "licensing", "resolved"])
.enter().append("marker")
.attr("id", function (d) {
    return d;
})
.attr("viewBox", "0 -5 10 10")
.attr("refX", 25)
.attr("refY", 0)
.attr("markerWidth", 4)
.attr("markerHeight", 4)
.attr("orient", "auto")
.append("path")    
.attr("d", "M 0,0 m -5,-5 L 5,0 L -5,5 Z")
.style("stroke", "#4679BD")
.style("opacity", "0.6")
.attr("transform", "translate(" + zoomWidth + "," + zoomHeight + ") scale(" + 
 scale + ")");
//This line restores the zoom
svg.attr("transform", "translate(" + graph.zoomTranslateX + "," + 
 graph.zoomTranslateY + ") scale(" + graph.scale + ")")

This is the line of code that sets the initial zoom and scale levels, and it works just fine:

 svg.attr("transform", "translate(" + graph.zoomTranslateX + "," + 
 graph.zoomTranslateY + ") scale(" + graph.scale + ")")

As soon as thediagram is loaded if I inspect the SVG element in my html, I can see it is properly set:

<g transform="translate(-12632.3077320904,-830.9843396749) scale(24.25)"

Problem happens when I use mouse wheel to zoom in or out. What happens my initial values are overwritten, and some (default?) other values are set.

This is my zoom function:

function zoomed() {
    var zoomLevels = sessionStorage.getItem("graphdata");
    var storedGraphJSON = JSON.parse(zoomLevels.replace(/\bNaN\b/g, 'null'));
    //Calculation of zoom properties:
    //d3.event.translate[0] = d3.event.translate[0] - 
    storedGraphJSON.zoomTranslateX;
    //d3.event.translate[1] = d3.event.translate[1] - 
    storedGraphJSON.zoomTranslateY;
    //d3.event.scale = d3.event.scale - storedGraphJSON.scale;
    svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + 
   d3.event.scale + ")");

    graph.zoomTranslateX = storedGraphJSON.zoomTranslateX = 
   d3.event.translate[0];
    graph.zoomTranslateY = storedGraphJSON.zoomTranslateY = 
    d3.event.translate[1];
    graph.scale = storedGraphJSON.scale = d3.event.scale;

    sessionStorage.setItem("graphdata", JSON.stringify(storedGraphJSON));
}

As far as I can tell, d3.event.translate and d3.event.scale should pick up initial value that is set on svg element.... but it does not.

Any insight is appreciated.

1条回答
叼着烟拽天下
2楼-- · 2019-08-11 01:33

When making initial zoom variable, it must have predefined values so it can continue, like this:

var zoom = d3.behavior.zoom()
.scaleExtent([-40, 100])
.on("zoom", zoomed);
//Make sure zoom picks from the initial value that is set on DOM!!!
zoom.scale(graph.scale);
zoom.translate([graph.zoomTranslateX, graph.zoomTranslateY]);

Works like charm :)

查看更多
登录 后发表回答