Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Svg d3中力有向图的语义缩放_Svg_D3.js_Zooming_Force Layout - Fatal编程技术网

Svg d3中力有向图的语义缩放

Svg d3中力有向图的语义缩放,svg,d3.js,zooming,force-layout,Svg,D3.js,Zooming,Force Layout,通过几何缩放力有向图已经显示了许多 在几何缩放中,我只需要在缩放函数中添加一个变换属性。然而,在语义缩放中,若我只在节点中添加一个transform属性,链接将不会连接到节点。所以,我想知道是否有一个解决方案的几何缩放力定向图在d3 下面是我的例子,几何缩放与前面的案例。我有两个问题: 当我缩小,然后拖动整个图形时,图形会奇怪地消失 使用相同的重画函数 这只更新一个svg元素的“transform”属性。但是如何使函数改变节点的位置呢 但我想做的是。我尝试过修改缩放和变换功能,但不确定正确的方法

通过几何缩放力有向图已经显示了许多

在几何缩放中,我只需要在缩放函数中添加一个变换属性。然而,在语义缩放中,若我只在节点中添加一个transform属性,链接将不会连接到节点。所以,我想知道是否有一个解决方案的几何缩放力定向图在d3

下面是我的例子,几何缩放与前面的案例。我有两个问题:

  • 当我缩小,然后拖动整个图形时,图形会奇怪地消失
  • 使用相同的重画函数
  • 这只更新一个svg元素的“transform”属性。但是如何使函数改变节点的位置呢

    但我想做的是。我尝试过修改缩放和变换功能,但不确定正确的方法。这就是我所尝试的。我改变了职能:



    您必须变换节点并重新绘制路径

    “语义缩放”的概念是更改布局的比例,而不是单个元素的大小

    如果如链接示例中所示设置了缩放行为,它会自动为您更新x和y比例。然后根据这些比例重新设置节点的位置,还可以重新设置链接的位置和形状

    如果链接是直线,请使用更新的x和y刻度重新设置x1、y1、x2和y2位置。如果链接是使用d3.svg.diagonal和x和y比例创建的路径,请使用相同的函数重新设置“d”属性


    如果您需要更具体的说明,您必须发布您的代码。

    我试图找到一个好的教程链接,但找不到任何真正涵盖所有问题的内容,因此我将自己一步一步地写出来

    首先,你需要清楚地了解你想要完成什么。这对于两种类型的缩放是不同的。我真的不喜欢Mike Bostock介绍的术语(它与术语的非d3用法不完全一致),但我们还是坚持使用它,以便与其他d3示例保持一致

    在“几何缩放”中,您正在缩放整个图像。圆圈和线条变得越来越大,距离也越来越远。SVG有一种通过“transform”属性实现这一点的简单方法。当您在SVG元素上设置
    transform=“scale(2)”
    时,它会被绘制为所有元素的两倍大。对于一个圆,它的半径绘制一个大的两倍,它的
    cx
    cy
    位置绘制距离(0,0)点两倍的距离。整个坐标系都会改变,所以一个单位现在等于屏幕上的两个像素,而不是一个

    类似地,
    transform=“translate(-50100)”
    更改整个坐标系,使坐标系的(0,0)点向左移动50个单位,从左上角(默认原点)向下移动100个单位

    如果同时平移和缩放SVG元素,则顺序很重要。如果“平移”在“缩放”之前,则平移以原始单位表示。如果“平移”在缩放之后,则平移以缩放单位表示

    该方法创建一个函数,用于侦听鼠标滚轮和拖动事件,以及与缩放相关的触摸屏事件。它将这些用户事件转换为自定义的“缩放”事件

    缩放事件被赋予一个比例因子(单个数字)和一个平移因子(两个数字的数组),行为对象根据用户的移动来计算。你如何处理这些数字取决于你自己它们不会直接更改任何内容。(将比例附加到缩放行为功能时除外,如下所述。)

    对于几何缩放,通常需要在包含要缩放内容的
    元素上设置“缩放和平移变换”属性。此示例在由均匀放置的网格线组成的简单SVG上实现了几何缩放方法:

    缩放代码很简单:

    function zoom() {
        console.log("zoom", d3.event.translate, d3.event.scale);
        vis.attr("transform", 
                 "translate(" + d3.event.translate + ")" 
                    + " scale(" + d3.event.scale + ")"
                 );
    }
    
    缩放是通过在“vis”上设置transform属性来完成的,这是一个d3选择,包含一个
    元素,该元素本身包含我们要缩放的所有内容。平移和缩放因子直接来自d3行为创建的缩放事件

    结果是所有东西都变大或变小了——网格线的宽度以及它们之间的间距。线条仍有
    笔划宽度:1.5
    但是屏幕上1.5等于什么的定义对于他们和转换后的
    元素中的任何其他内容都已更改

    对于每个缩放事件,平移和缩放因子也会记录到控制台。看看这个,你会注意到如果你缩小了,比例会在0到1之间;如果放大,它将大于1。如果平移(拖动以移动)图形,则比例根本不会改变。但是,平移数字在平移和缩放时都会发生变化。这是因为translate表示图形中(0,0)点相对于SVG左上角的位置。缩放时,(0,0)与图形上任何其他点之间的距离将发生变化。因此,为了使鼠标或手指触摸下的内容保持在屏幕上相同的位置,(0,0)点的位置必须移动

    在该示例中,您还应注意一些其他事项:

    • 我已经用这个方法修改了缩放行为对象。这将设置缩放事件中行为将使用的缩放值的限制,无论用户旋转轮子多少次

    • 转换在
      元素上,而不是
      本身。这是因为SVG元素作为一个整体被视为一个HTML元素,并且具有不同的tra
      function zoom() {
        node.call(transform);
        // update link position
        update();
      }
      function transform(d){
        // change node x, y position, not sure what function to put here.
      }
      
      function zoom() {
          console.log("zoom", d3.event.translate, d3.event.scale);
          vis.attr("transform", 
                   "translate(" + d3.event.translate + ")" 
                      + " scale(" + d3.event.scale + ")"
                   );
      }
      
      zoomedPositionX = d3.event.translate[0] + d3.event.scale * dataPositionX 
      
      zoomedPositionY = d3.event.translate[1] + d3.event.scale * dataPositionY
      
      vLines.attr("x1", function(d){return d;})
          .attr("y1", 0)
          .attr("x2", function(d){return d;})
          .attr("y2", h);
      
      vLines.attr("x1", function(d){
              return d3.event.translate[0] + d*d3.event.scale;
          })
          .attr("y1", d3.event.translate[1])
          .attr("x2", function(d){
              return d3.event.translate[0] + d*d3.event.scale;
          })
          .attr("y2", d3.event.translate[1] + h*d3.event.scale);
      
      function zoom() {
          console.log("zoom", d3.event.translate, d3.event.scale);
          scaleFactor = d3.event.scale;
          translation = d3.event.translate;
          tick(); //update positions
      }
      
      function tick() {
          linkLines.attr("x1", function (d) {
                  return translation[0] + scaleFactor*d.source.x;
              })
              .attr("y1", function (d) {
                  return translation[1] + scaleFactor*d.source.y;
              })
              .attr("x2", function (d) {
                  return translation[0] + scaleFactor*d.target.x;
              })
              .attr("y2", function (d) {
                  return translation[1] + scaleFactor*d.target.y;
              });
      
          nodeCircles.attr("cx", function (d) {
                  return translation[0] + scaleFactor*d.x;
              })
              .attr("cy", function (d) {
                  return translation[1] + scaleFactor*d.y;
              });
      }
      
      function dragged(d){
          if (d.fixed) return; //root is fixed
      
          //get mouse coordinates relative to the visualization
          //coordinate system:    
          var mouse = d3.mouse(vis.node());
          d.x = mouse[0]; 
          d.y = mouse[1];
          tick();//re-position this node and any links
      }
      
      zoomedPositionX = d3.event.translate[0] + d3.event.scale * dataPositionX 
      
      zoomedPositionY = d3.event.translate[1] + d3.event.scale * dataPositionY
      
      dataPositionX = (zoomedPositionX - d3.event.translate[0]) / d3.event.scale
      
      dataPositionY = (zoomedPositionY - d3.event.translate[1]) / d3.event.scale
      
      function dragged(d){
          if (d.fixed) return; //root is fixed
      
          //get mouse coordinates relative to the visualization
          //coordinate system:
          var mouse = d3.mouse(vis.node());
          d.x = (mouse[0] - translation[0])/scaleFactor; 
          d.y = (mouse[1] - translation[1])/scaleFactor; 
          tick();//re-position this node and any links
      }
      
      /*** Configure zoom behaviour ***/
      var zoomer = d3.behavior.zoom()
                      .scaleExtent([0.1,10])
              //allow 10 times zoom in or out
                      .on("zoom", zoom)
              //define the event handler function
                      .x(xScale)
                      .y(yScale);
              //attach the scales so their domains
              //will be updated automatically
      
      function zoom() {
          console.log("zoom", d3.event.translate, d3.event.scale);
      
          //the zoom behaviour has already changed
          //the domain of the x and y scales
          //so we just have to redraw using them
          drawLines();
      }
      function drawLines() {
          //put positioning in a separate function
          //that can be called at initialization as well
          vLines.attr("x1", function(d){
                  return xScale(d);
              })
              .attr("y1", yScale(0) )
              .attr("x2", function(d){
                  return xScale(d);
              })
              /* etc. */
      
      /* Set the display size based on the SVG size and re-draw */
      function setSize() {
          var svgStyles = window.getComputedStyle(svg.node());
          var svgW = parseInt(svgStyles["width"]);
          var svgH = parseInt(svgStyles["height"]);
      
          //Set the output range of the scales
          xScale.range([0, svgW]);
          yScale.range([0, svgH]);
      
          //re-attach the scales to the zoom behaviour
          zoomer.x(xScale)
                .y(yScale);
      
          //resize the background
          rect.attr("width", svgW)
                  .attr("height", svgH);
      
          //console.log(xScale.range(), yScale.range());
          drawLines();
      }
      
      //adapt size to window changes:
      window.addEventListener("resize", setSize, false)
      
      setSize(); //initialize width and height
      
      function dragged(d){
          if (d.fixed) return; //root is fixed
      
          //get mouse coordinates relative to the visualization
          //coordinate system:
          var mouse = d3.mouse(vis.node());
          d.x = xScale.invert(mouse[0]); 
          d.y = yScale.invert(mouse[1]); 
          tick();//re-position this node and any links
      }