【问题标题】:Simple graph of nodes and links without using force layout不使用强制布局的简单节点和链接图
【发布时间】:2015-03-22 00:44:22
【问题描述】:

如何制作不使用force() 布局的基本连通图(例如两个节点和连接它们的链接)?我只想能够拖动一个节点并调整链接以在拖动节点时保持连接。我不想要force() 的任何充电或定位功能。本质上我希望每个节点都是“粘性的”。节点只有在被拖动时才会移动。

但是有没有一种简单的方法可以做到这一点?我看到的每个示例都是围绕力有向图构建的。

我看过这个例子,http://bl.ocks.org/mbostock/3750558,但它从一个力有向图开始,然后使节点变得粘稠。这种方法似乎倒退了我想要的。

在某处有一个基本的例子吗?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    我做了一个小代码sn-p。希望这会有所帮助。

    var data = {
       nodes: [{
         name: "A",
         x: 200,
         y: 150
       }, {
         name: "B",
         x: 140,
         y: 300
       }, {
         name: "C",
         x: 300,
         y: 300
       }, {
         name: "D",
         x: 300,
         y: 180
       }],
       links: [{
         source: 0,
         target: 1
       }, {
         source: 1,
         target: 2
       }, {
         source: 2,
         target: 3
       }, ]
     };
    
     var c10 = d3.scale.category10();
     var svg = d3.select("body")
       .append("svg")
       .attr("width", 1200)
       .attr("height", 800);
    
     var drag = d3.behavior.drag()
       .on("drag", function(d, i) {
         d.x += d3.event.dx
         d.y += d3.event.dy
         d3.select(this).attr("cx", d.x).attr("cy", d.y);
         links.each(function(l, li) {
           if (l.source == i) {
             d3.select(this).attr("x1", d.x).attr("y1", d.y);
           } else if (l.target == i) {
             d3.select(this).attr("x2", d.x).attr("y2", d.y);
           }
         });
       });
    
     var links = svg.selectAll("link")
       .data(data.links)
       .enter()
       .append("line")
       .attr("class", "link")
       .attr("x1", function(l) {
         var sourceNode = data.nodes.filter(function(d, i) {
           return i == l.source
         })[0];
         d3.select(this).attr("y1", sourceNode.y);
         return sourceNode.x
       })
       .attr("x2", function(l) {
         var targetNode = data.nodes.filter(function(d, i) {
           return i == l.target
         })[0];
         d3.select(this).attr("y2", targetNode.y);
         return targetNode.x
       })
       .attr("fill", "none")
       .attr("stroke", "white");
    
     var nodes = svg.selectAll("node")
       .data(data.nodes)
       .enter()
       .append("circle")
       .attr("class", "node")
       .attr("cx", function(d) {
         return d.x
       })
       .attr("cy", function(d) {
         return d.y
       })
       .attr("r", 15)
       .attr("fill", function(d, i) {
         return c10(i);
       })
       .call(drag);
    svg {
        background-color: grey;
    }
    <script src="https://d3js.org/d3.v3.min.js"></script>

    【讨论】:

    • 你是个巫师!
    • 在不手动指定 x 和 y 坐标并让 d3 计算出来的情况下是否可以工作? (我试图用大图来实现同样的效果,我想避免复杂的图布局算法)
    【解决方案2】:

    Gilsha 有一个很好的答案,但请注意,较新版本的 d3 不再使用行为模块。

    而不是这个:

    var drag = d3.behavior.drag()
       .on("drag", function(d, i) {
         d.x += d3.event.dx
         d.y += d3.event.dy
         d3.select(this).attr("cx", d.x).attr("cy", d.y);
         links.each(function(l, li) {
           if (l.source == i) {
             d3.select(this).attr("x1", d.x).attr("y1", d.y);
           } else if (l.target == i) {
             d3.select(this).attr("x2", d.x).attr("y2", d.y);
           }
         });
       });
    

    只需将 d3.behavior.drag() 更改为 d3.drag()

    var drag = d3.drag()
       .on("drag", function(d, i) {
         d.x += d3.event.dx
         d.y += d3.event.dy
         d3.select(this).attr("cx", d.x).attr("cy", d.y);
         links.each(function(l, li) {
           if (l.source == i) {
             d3.select(this).attr("x1", d.x).attr("y1", d.y);
           } else if (l.target == i) {
             d3.select(this).attr("x2", d.x).attr("y2", d.y);
           }
         });
       });
    

    【讨论】:

      猜你喜欢
      • 2015-12-04
      • 1970-01-01
      • 2014-11-20
      • 2014-08-01
      • 1970-01-01
      • 2018-10-10
      • 2013-12-18
      • 2018-02-05
      • 2014-07-22
      相关资源
      最近更新 更多