如何将Zoom + Drag Behavior添加到加载到D3.js中的外部SVG?

时间:2018-01-27 18:47:29

标签: javascript html xml d3.js svg

我想要做的是将现有的SVG(XML格式)加载到D3中。

它工作正常,直到我开始将缩放+拖动行为添加到SVG。

实际上添加行为似乎有效,但是当我在SVG中拖动对象时,会出现奇怪的跳跃(或闪烁)。一次放大后情况会变得更糟,然后物体移动得比它应该的要多得多。

我想你会在尝试代码示例后立即理解我的意思。

如何使Zoom + Drag表现得如此?

提前致谢



var main_chart_svg = document.body;

d3.xml("https://upload.wikimedia.org/wikipedia/commons/a/a0/Circle_-_black_simple.svg", function(error, documentFragment) {
        if (error) {console.log(error); return;}
    
        var svgNode = documentFragment
                    .getElementsByTagName("svg")[0];
    
        main_chart_svg.appendChild(svgNode);
        
        d3.selectAll('circle').style('fill', 'green'); //only in order to show, that selections work

        //this is where my problem happens
        d3.select('svg').call(d3.zoom().on("zoom", function () {
          d3.select('svg').attr("transform", d3.event.transform)
        }));
    });

<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

您正在svg元素上执行缩放/平移转换。它通常应用于包含缩放内容的g元素。要使用g,在您的情况下,您需要将此元素插入已存在的svg

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
    var main_chart_svg = document.body;

    d3.xml("https://upload.wikimedia.org/wikipedia/commons/a/a0/Circle_-_black_simple.svg", function(error, documentFragment) {
      if (error) {
        console.log(error);
        return;
      }

      var svgNode = documentFragment
        .getElementsByTagName("svg")[0];

      main_chart_svg.appendChild(svgNode);

      var svg = d3.select('svg'),
        g = svg.append('g');

      g.node().appendChild(svg.select('circle').node());

      d3.selectAll('circle').style('fill', 'green'); //only in order to show, that selections work

      //this is where my problem happens
      d3.select('svg').call(d3.zoom().on("zoom", function() {
        g.attr("transform", d3.event.transform)
      }));
    });
  </script>
</body>

</html>

或者,如果您不想这样做,可以直接将缩放应用于圆圈:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
    var main_chart_svg = document.body;

    d3.xml("https://upload.wikimedia.org/wikipedia/commons/a/a0/Circle_-_black_simple.svg", function(error, documentFragment) {
      if (error) {
        console.log(error);
        return;
      }

      var svgNode = documentFragment
        .getElementsByTagName("svg")[0];

      main_chart_svg.appendChild(svgNode);

      var svg = d3.select('svg'),
        c = d3.select('circle');


      c.style('fill', 'green'); //only in order to show, that selections work

      //this is where my problem happens
      d3.select('svg').call(d3.zoom().on("zoom", function() {
        c.attr("transform", d3.event.transform)
      }));
    });
  </script>
</body>

</html>