简体   繁体   中英

D3 Force Directed Zoom Issue

I'm trying to setup a force directed D3 plot with labels and zoom capability. Everything works until I try to zoom at which point it throws the following error:

d3.v4.js:7637 Error: Invalid value for <svg> attribute transform="translate(undefined) scale(undefined)"(anonymous function) @ d3.v4.js:7637selection_each @ d3.v4.js:7616selection_attr @ d3.v4.js:7673(anonymous function) @ (index):36dispatch.apply @ d3.v4.js:4536customEvent @ d3.v4.js:7280Gesture.emit @ d3.v4.js:12207Gesture.zoom @ d3.v4.js:12195wheeled @ d3.v4.js:12239(anonymous function) @ d3.v4.js:7204

Bellow is the d3 code, any suggestions would be much appreciated:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">


<html>

    <head>
        <script src="https://d3js.org/d3.v4.js"></script> 
    </head>

<style>
        .node text {
                pointer-events: none;
                font: 10px sans-serif;
                }

        .links line {
                stroke-opacity: 0.9;
                }

        .nodes circle {
                stroke: #fff;
                stroke-width: 5.5px;
                }

</style>

<body>

                <svg width="1000" height="800"></svg>


                <script>


                        var svg = d3.select("svg").call(d3.zoom().on("zoom", function () {
    svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
  })),
                        width = +svg.attr("width"),
                        height = +svg.attr("height");

                        var color = d3.scaleOrdinal(d3.schemeCategory20);

                        var simulation = d3.forceSimulation()
                        .force("link", d3.forceLink().id(function(d) { return d.id; }))
                        .force("charge", d3.forceManyBody())
                        .force("center", d3.forceCenter(width / 2, height / 2));

                        d3.json("static/graphFile.json", function(error, graph) {
                                if (error) throw error;

                        var link = svg.append("g")
                .attr("class", "links")
                                .selectAll("line")
                                .data(graph.links)
                                .enter().append("line")
                                .attr("stroke", function(d) { return color(d.value); })
                                .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

                  var node = svg.selectAll(".node")
                        .data(graph.nodes)
                        .enter().append("g")
                        .attr("class", "node")
                        .call(d3.drag()
                        .on("start", dragstarted)
                        .on("drag", dragged)
                        .on("end", dragended));

          node.append("text")
                .attr("dx", 12)
                .attr("dy", ".35em")
                .text(function(d) { return d.id });

                  node.append("circle").attr("r", 10)
                .attr("fill", function(d) { return color(d.group); })

                  simulation
                .nodes(graph.nodes)
                .on("tick", ticked);

                  simulation.force("link")
                .links(graph.links);

                  function ticked() {
                        link
                                .attr("x1", function(d) { return d.source.x; })
                                .attr("y1", function(d) { return d.source.y; })
                                .attr("x2", function(d) { return d.target.x; })
                                .attr("y2", function(d) { return d.target.y; });

          node
                        .attr("cx", function(d) { return d.x; })
                        .attr("cy", function(d) { return d.y; });
                  node
                                .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });                 
                  }




                  });

                  function dragstarted(d) {
                                if (!d3.event.active) simulation.alphaTarget(0.3).restart();
                                        d.fx = d.x;
                                        d.fy = d.y;
                  }

                  function dragged(d) {
                                        d.fx = d3.event.x;
                                        d.fy = d3.event.y;
                  }

                  function dragended(d) {
                                        if (!d3.event.active) simulation.alphaTarget(0);
                                        d.fx = null;
                                        d.fy = null;
                  }


                </script>

</body>
</html>

Apparently you can't zoom when you have bounds set on a D3 diagram. I solved this by removing those bounds. (Credits to: Jeremy Fields)

var svg = d3.select("svg").call(d3.zoom().on("zoom", function () {svg.attr("transform", d3.event.transform)})).append("g"),
                width = +svg.attr("width"),
                height = +svg.attr("height");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM