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

时间:2016-10-30 10:29:32

标签: javascript d3.js visualization

我正在制作d3力导向图,它可以正常工作 (this is the working version on codepen)直到我尝试为节点添加标签。

根据我的理解,节点必须用'g'元素包裹,但是当我尝试它时,所有节点都会堆叠在左上角。我对JavaScript非常不熟悉,显然我错过了一些东西。如果有人能帮助我解决我的错误,我将不胜感激 我尝试了类似主题的解决方案:labels wont show up on d3 force diagram

 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;
}

Full code on codepen

2 个答案:

答案 0 :(得分:2)

linknodelabelsd3.json()调用中的匿名函数本地定义,因此无法从ticked()内获取。< / p>

答案 1 :(得分:2)

将功能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