D3.js网络图使用强制定向布局和节点矩形

时间:2015-05-29 16:28:05

标签: javascript d3.js graph data-visualization force-layout

我正在尝试修改Mike的Force-Directed Graph示例,使用矩形而不是圆圈作为节点。另外,我想要矩形内的文字。

我有正确显示文字的矩形,但它们没有附在链接上,也没有移动。

这是一个代码链接:http://codepen.io/anon/pen/gpgWaz

var width = 960,
    height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

force
    .nodes(graph.nodes)
    .links(graph.links)
    .start();

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

var node = svg.selectAll(".node")
    .data(graph.nodes)
    .enter()
    .append("g")
    .attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")";
    })
    .call(force.drag);

node.append("rect")
    .attr("class", "node")
    .attr("width", 100)
    .attr("height", 35)
    .style("fill", function(d) {
        return color(d.group);
    })
    .style("stroke", "black")
    .style("stroke-width", "1px");

node.append("text")
    .text(function(d) {
        return d.name;
    })
    .style("font-size", "12px")
    .attr("dy", "1em");

node.append("title")
    .text(function(d) {
        return d.name;
    });

force.on("tick", function() {
    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("x", function(d) {
            return d.x;
        })
        .attr("y", function(d) {
            return d.y;
        });
});

更新

感谢Lars的评论,以及他的codepen现在有效。

我对代码所做的更新:

  1. 添加由Lars说明的转换
  2. 更改了在矩形中心连接的链接
  3. 为矩形添加圆角
  4. 给文本略微缩进缩进
  5. 更改为使用窗口宽度/高度
  6. 这是我的新代码:http://codepen.io/anon/pen/bdgREd

    var width = window.innerWidth,
        height = window.innerHeight,
        nodeWidth = 100,
        nodeHeight = 35;
    
    var color = d3.scale.category20();
    
    var force = d3.layout.force()
        .charge(-1500)
        .linkDistance(100)
        .friction(0.5)
        .size([width, height]);
    
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
    force
        .nodes(graph.nodes)
        .links(graph.links)
        .start();
    
    var link = svg.selectAll(".link")
        .data(graph.links)
        .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) {
            return Math.sqrt(d.value);
        });
    
    var node = svg.selectAll(".node")
        .data(graph.nodes)
        .enter()
        .append("g")
        .attr("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        })
        .call(force.drag);
    
    node.append("rect")
        .attr("class", "node")
        .attr("width", nodeWidth)
        .attr("height", nodeHeight)
        .attr("rx", 5)
        .attr("ry", 5)
        .style("fill", function(d) {
            return color(d.group);
        })
        .style("stroke", "black")
        .style("stroke-width", "1px");
    
    node.append("text")
        .attr("x", 5)
        .attr("y", 2)
        .text(function(d) {
            return d.name;
        })
        .style("font-size", "12px")
        .attr("dy", "1em");
    
    node.append("title")
        .text(function(d) {
            return d.name;
        });
    
    force.on("tick", function() {
        link.attr("x1", function(d) {
                return d.source.x + (nodeWidth / 2);
            })
            .attr("y1", function(d) {
                return d.source.y + (nodeHeight / 2);
            })
            .attr("x2", function(d) {
                return d.target.x + (nodeWidth / 2);
            })
            .attr("y2", function(d) {
                return d.target.y + (nodeHeight / 2);
            });
    
        node.attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
    });
    

1 个答案:

答案 0 :(得分:1)

您在x元素上设置yg属性以更改其位置 - 这不会做任何事情。您需要设置transform属性,就像添加g元素时一样。所以你的tick处理函数将包含

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

而不是

node.attr("x", function(d) {
        return d.x;
    })
    .attr("y", function(d) {
        return d.y;
    });

完整演示here