D3力有向图问题:节点堆叠在坐标(0,0)

D3 force directed graph issue: nodes are stacked at coordinate (0,0)

本文关键字:坐标 有向图 问题 节点 D3      更新时间:2023-09-26

我正在制作d3力定向图,它工作得很好(这是codepen上的工作版本),直到我尝试为节点添加标签。

根据我的理解,节点必须由'g'元素包裹,但是当我尝试它时,所有的节点都堆叠在左上角。我对JavaScript非常不熟悉,显然我遗漏了一些东西。如果有人能帮我改正我的错误,我会很感激的。我从类似的主题尝试解决方案:标签不会显示在d3受力图

 var dataURL = "https://raw.githubusercontent.com/Aeternia-ua/temp1/c50fa778c12c6d355fe08b54cb3f1ce24acfa4e9/graphtest.json";
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20c);
var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) {
        return d.id;
    }))
    .force("charge", d3.forceManyBody().strength(-150))
    .force("center", d3.forceCenter(width / 2, height / 2));
d3.json(dataURL, function(error, graph) {
    if (error) throw error;
    simulation.nodes(graph.nodes);
    simulation.force("link").links(graph.links);
    var link = svg.append("g")
        .attr("class", "links")
        .selectAll("line")
        .data(graph.links)
        .enter().append("line");
    var node = svg.append("g")
        .attr("class", "nodes")
        .selectAll("circle")
        .data(graph.nodes)
        .enter().append("circle")
    //Setting node radius by group value. If 'group' key doesn't exist, set radius to 8
    .attr("r", function(d) {
            if (d.hasOwnProperty('group')) {
                return d.group * 2;
            } else {
                return 9;
            }
        })
        //Colors by 'group' value
        .style("fill", function(d) {
            return color(d.group);
        })
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));
    node.append("svg:title")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .text(function(d) {
            return d.id
        });
    var labels = svg.append("g")
        .attr("class", "label")
        .selectAll("text")
        .data(graph.nodes)
        .enter().append("text")
        .attr("dx", 6)
        .attr("dy", ".35em")
        .style("font-size", 10)
        .text(function(d) {
            return d.id
        });

    simulation
        .nodes(graph.nodes)
        .on("tick", ticked);
    simulation.force("link")
        .links(graph.links);
});
function ticked() {
    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("cx", function(d) {
            return d.x;
        })
        .attr("cy", function(d) {
            return d.y;
        });
    labels
        .attr("x", function(d) {
            return d.x;
        })
        .attr("y", function(d) {
            return d.y;
        });
}
function dragstarted(d) {
    if (!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
}
function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
}
function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
}

codepen的完整代码

将函数ticked()移动到d3.json回调中:

d3.json(dataURL, function(error, graph) {
    //...
    function ticked(){
        //...
    };
};

同时,将链接的类别从.links更改为.link:

var link = svg.append("g")
    .attr("class", "link")

这是你更新的CodePen: http://codepen.io/anon/pen/ORejme?editors=0110

linknodelabels是在d3.json()调用中的匿名函数的本地定义的,因此在ticked()中不可用。