【问题标题】:D3 force layout: links and nodes --- z-index(?)D3 强制布局:链接和节点 --- z-index(?)
【发布时间】:2014-01-23 09:42:43
【问题描述】:

D3:节点和链接之间的问题

我创建了以下jsfiddle 以了解我想要实现的目标:

我希望节点覆盖(?)链接...

请帮助我。对不起我的英语:)

脚本如下所示:

function myGraph(el) {
this.addNode = function (id) {
    nodes.push({ "id": id });
    update();
}
this.removeNode = function (id) {
    var i = 0;
    var n = findNode(id);
    while (i < links.length) {
        if ((links[i]['source'] == n) || (links[i]['target'] == n)) links.splice(i, 1);
        else i++;
    }
    nodes.splice(findNodeIndex(id), 1);
    update();
}
this.addLink = function (source, target) {
    links.push({ "source": findNode(source), "target": findNode(target) });
    update();
}
var findNode = function (id) {
    for (var i in nodes) { if (nodes[i]["id"] === id) return nodes[i] };
}
var findNodeIndex = function (id) {
    for (var i in nodes) { if (nodes[i]["id"] === id) return i };
}
// set up the D3 svg in the specified element
var w = window.jQuery(el).innerWidth(),
    h = window.jQuery(el).innerHeight();
var svg = this.svg = d3.select(el).append("svg:svg")
    .attr("width", w)
    .attr("height", h);
var force = d3.layout.force()
    .gravity(.05)
    .distance(100)
    .charge(-120)
    .size([w, h]);
var nodes = force.nodes(),
    links = force.links();
var update = function () {
    var link = svg.selectAll(".link")
        .data(links, function (d) { return d.source.id + "-" + d.target.id; })
    link.enter().append("line")
        .attr("class", "link")
    link.exit().remove();
    var node = svg.selectAll(".node")
        .data(nodes, function (d) { return d.id; })
    node.enter().append("g")
        .attr("class", "node")
        .call(force.drag);
    node.append("circle")
        .attr("r", function (d) { return 30; })
        .style("fill", "#EFEFEF")
    node.append("text")
        .attr("text-anchor", "right")
        .text(function (d) { return d.id; });
    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("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });
    });
    // Restart the force layout.
    force.start();
}
// Make it all go
update();
}
graph = new myGraph("#graph");
// You can do this from the console as much as you like...
graph.addNode("Cause");
graph.addNode("Effect");
graph.addLink("Cause", "Effect");
graph.addNode("A");
graph.addNode("B");
graph.addLink("A", "B");

【问题讨论】:

    标签: d3.js z-index force-layout


    【解决方案1】:

    SVG 中没有 z-index 属性;元素按照指定的顺序呈现。这意味着对您而言,所有链接元素都必须位于生成的 DOM 中的节点元素之前。

    实现这一点的最简单方法是为链接和节点设置单独的 g 元素,前者在前。

    svg.append("g").attr("class", "links");
    svg.append("g").attr("class", "nodes");
    

    然后你可以像这样附加链接

    var link = svg.select(".links").selectAll(".link")
             .data(links, function (d) { return d.source.id + "-" + d.target.id; })
    // etc
    

    和节点也是如此。完成演示here。

    【讨论】:

    • 虽然这种技术对我有用,但问题是当我必须添加/删除新节点/链接时。例如,当添加一个新链接时,该链接出现在它所连接的两个节点的顶​​部。有没有办法让它总是出现在节点下方?我尝试添加一个额外的空g,但我收到与 enter() 相关的错误,我不明白为什么svg.append("g").append("g").attr("class", "nodes");
    • 我会将链接和节点保留在不同的g 元素中。然后,您可以在链接和节点中强制执行顺序,但相对于彼此,它们将保持相同的顺序。
    • 谢谢,它对我有用。我是 svg 的新手,为什么它可以解决这个问题?
    猜你喜欢
    • 2014-08-01
    • 2014-11-20
    • 2013-12-18
    • 2018-02-05
    • 2018-10-10
    • 2016-08-15
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    相关资源
    最近更新 更多