【问题标题】:D3 forced layout zoom function isn't workingD3 强制布局缩放功能不起作用
【发布时间】:2018-09-30 07:05:02
【问题描述】:

我尝试添加缩放功能,但没有成功。

我不知道是什么问题。我想知道是什么问题以及如何解决。

我尝试使用本站的源码(https://bl.ocks.org/puzzler10/91a6b53d4237c97752d0e466443dad0b)

这是我的代码:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="https://d3js.org/d3.v3.js"></script>
    <style>
      body{ font-family: 'Hanna' 12px; text-align: center;}

      .link {
        stroke: #ccc;
      }

      .node text {
        pointer-events: none;
        font: sans-serif;
      }
    </style>
    <link rel="stylesheet" type="text/css" href="main.css">
  </head>
  <body>
  <script type="text/javascript">
  //Set margins and sizes
  var margin = {
    top: 20,
    bottom: 50,
    right: 30,
    left: 50
  };
  var width = 960 - margin.left - margin.right;
  var height = 700 - margin.top - margin.bottom;


  var zoom = d3.behavior.zoom()
    .scaleExtent([0.1, 10])
    .on("zoom", zoomed);
  //Load Color Scale
  var c10 = d3.scale.category10();
  //Create an SVG element and append it to the DOM
  var svgElement = d3.select("body")
            .append("svg")
            .attr({"width": width+margin.left+margin.right, "height": height+margin.top+margin.bottom})
            .append("g")
            .attr("transform","translate("+margin.left+","+margin.top+")")
            .call(zoom);
  //Load External Data
  d3.json("idol_gen1.json", function(dataset){
    //Extract data from dataset
    var nodes = dataset.nodes,
      links = dataset.links;
    //Create Force Layout
    var force = d3.layout.force()
            .size([width, height])
            .nodes(nodes)
            .links(links)
            .gravity(0.05)
            .charge(-200)
            .linkDistance(200);
    //Add links to SVG
    var link = svgElement.selectAll(".link")
          .data(links)
          .enter()
          .append("line")
          .attr("stroke-width", function(d){ return d.value*0.5; })
          .attr("class", "link");
    //Add nodes to SVG
    var node = svgElement.selectAll(".node")
          .data(nodes)
          .enter()
          .append("g")
          .attr("class", "node")
          .call(force.drag);
    //Add labels to each node
    var label = node.append("text")
            .attr("dx", 12)
            .attr("dy", "0.35em")
            .attr("font-size", function(d){ return Math.max(9, d.impor * 1.5);  })
            .text(function(d){ return d.name; });
    //Add circles to each node
    var circle = node.append("circle")
            .attr("r", function(d){ return Math.max(5, Math.sqrt(d.impor || 0)); })
            .attr("fill", function(d){ return c10(d.type); });
    //This function will be executed for every tick of force layoutz
    force.on("tick", function(){
      //Set X and Y of node
      node
        .attr("cx", function(d){ return d.x; })
        .attr("cy", function(d){ return d.y; });
      //Set X, Y of link
      link.attr("x1", function(d){ return d.source.x; })
      link.attr("y1", function(d){ return d.source.y; })
      link.attr("x2", function(d){ return d.target.x; })
      link.attr("y2", function(d){ return d.target.y; });
      //Shift node a little
        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    });

    function zoomed() {
      svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    }

    force.start();

  });
  </script>
  </body>
</html>

图表不显示。但是当我删除与缩放相关的代码时,它显示得很好。有什么好主意吗?

【问题讨论】:

  • 移到 D3v4/5,然后你就可以应用来自 Puzzler 的示例
  • @rioV8 还是不行:(

标签: javascript d3.js zooming


【解决方案1】:

您的 zoomed 函数在 d3.json() 回调块中定义,您需要像这样拆分缩放代码 sn-p 以使缩放函数对 d3.zoom 可见

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="https://d3js.org/d3.v3.js"></script>
    <style>
      body{ font-family: 'Hanna' 12px; text-align: center;}

      .link {
        stroke: #ccc;
      }

      .node text {
        pointer-events: none;
        font: sans-serif;
      }
    </style>
    <link rel="stylesheet" type="text/css" href="main.css">
  </head>
  <body>
  <script type="text/javascript">
  //Set margins and sizes
  var margin = {
    top: 20,
    bottom: 50,
    right: 30,
    left: 50
  };
  var width = 960 - margin.left - margin.right;
  var height = 700 - margin.top - margin.bottom;

 var zoom = d3.behavior.zoom()
    .scaleExtent([0.1, 10])

  //Load Color Scale
  var c10 = d3.scale.category10();
  //Create an SVG element and append it to the DOM
  var svgElement = d3.select("body")
            .append("svg")
            .attr({"width": width+margin.left+margin.right, "height": height+margin.top+margin.bottom})
            .append("g")
            .attr("transform","translate("+margin.left+","+margin.top+")")
            .call(zoom);
  //Load External Data
  d3.json("idol_gen1.json", function(dataset){


 zoom
    .on("zoom", zoomed);

    //Extract data from dataset
    var nodes = dataset.nodes,
      links = dataset.links;
    //Create Force Layout
    var force = d3.layout.force()
            .size([width, height])
            .nodes(nodes)
            .links(links)
            .gravity(0.05)
            .charge(-200)
            .linkDistance(200);
    //Add links to SVG
    var link = svgElement.selectAll(".link")
          .data(links)
          .enter()
          .append("line")
          .attr("stroke-width", function(d){ return d.value*0.5; })
          .attr("class", "link");
    //Add nodes to SVG
    var node = svgElement.selectAll(".node")
          .data(nodes)
          .enter()
          .append("g")
          .attr("class", "node")
          .call(force.drag);
    //Add labels to each node
    var label = node.append("text")
            .attr("dx", 12)
            .attr("dy", "0.35em")
            .attr("font-size", function(d){ return Math.max(9, d.impor * 1.5);  })
            .text(function(d){ return d.name; });
    //Add circles to each node
    var circle = node.append("circle")
            .attr("r", function(d){ return Math.max(5, Math.sqrt(d.impor || 0)); })
            .attr("fill", function(d){ return c10(d.type); });
    //This function will be executed for every tick of force layoutz
    force.on("tick", function(){
      //Set X and Y of node
      node
        .attr("cx", function(d){ return d.x; })
        .attr("cy", function(d){ return d.y; });
      //Set X, Y of link
      link.attr("x1", function(d){ return d.source.x; })
      link.attr("y1", function(d){ return d.source.y; })
      link.attr("x2", function(d){ return d.target.x; })
      link.attr("y2", function(d){ return d.target.y; });
      //Shift node a little
        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    });

    function zoomed() {
      svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    }

    force.start();

  });
  </script>
  </body>
</html>

【讨论】:

  • 感谢您的帮助。但是这段代码还是不能缩放。
  • 如果你提供工作的 JSfiddle 来解决问题,我会尝试修复它,否则,我不能只用我的眼睛远程调试它 :) 我需要你正在使用的数据,即未在问题中表示
猜你喜欢
  • 2015-07-08
  • 1970-01-01
  • 2013-04-20
  • 2012-12-01
  • 1970-01-01
  • 2015-05-27
  • 2020-01-20
  • 2012-06-22
  • 2015-05-26
相关资源
最近更新 更多