d3.js在力布局

时间:2015-09-08 14:09:01

标签: javascript d3.js collision-detection

关于力布局中的碰撞检测有几个问题,但没有一个我可以解决问题。 最接近的是:rect collision detection d3js

在下面的代码中,我确实有圆圈,但我将它们视为矩形(因为这就是我想要在最后解决的方框 - 圆形加上标签)。

以下是代码:

var graph = {
    "nodes":[
        {"name":"name-1","rating":1,"id":2951},
        {"name":"name-2","rating":2,"id":654654},
        {"name":"3","rating":3,"id":6546544},
        {"name":"4","rating":4,"id":68987978},
        {"name":"5","rating":5,"id":9878933},
        {"name":"6","rating":6,"id":6161},
        {"name":"7","rating":7,"id":64654},
        {"name":"8","rating":8,"id":354654},
        {"name":"9","rating":9,"id":8494},
        {"name":"10","rating":10,"id":6846874},
        {"name":"11","rating":11,"id":5487},
        {"name":"12","rating":12,"id":34},
        {"name":"13","rating":13,"id":65465465},
        {"name":"14","rating":14,"id":5443},
        {"name":"15","rating":15,"id":313514},
        {"name":"16","rating":16,"id":36543614},
        {"name":"17","rating":17,"id":3434},
        {"name":"18","rating":18,"id":97413},
        {"name":"19","rating":19,"id":97414},
        {"name":"27","rating":20,"id":9134371}
    ],
    "links":[
        {"source":0,"target":5,"value":6, "label":"publishedOn"},
        {"source":2,"target":5,"value":6, "label":"publishedOn"},
        {"source":7,"target":1,"value":4, "label":"containsKeyword"},
        {"source":8,"target":10,"value":3, "label":"containsKeyword"},
        {"source":7,"target":14,"value":4, "label":"publishedBy"},
        {"source":8,"target":15,"value":6, "label":"publishedBy"},
        {"source":9,"target":1,"value":6, "label":"depicts"},
        {"source":10,"target":1,"value":6, "label":"depicts"},
        {"source":7,"target":1,"value":6, "label":"manageWebsite"},
        {"source":16,"target":2,"value":5, "label":"manageWebsite"},
        {"source":5,"target":3,"value":6, "label":"manageWebsite"},
        {"source":16,"target":4,"value":6, "label":"manageWebsite"},
        {"source":12,"target":9,"value":2, "label":"postedOn"},
        {"source":13,"target":1,"value":6, "label":"childOf"},
        {"source":10,"target":8,"value":8, "label":"describes"},
        {"source":8,"target":11,"value":6, "label":"containsKeyword"},
        {"source":2,"target":5,"value":3, "label":"manageWebsite"}
    ]
}

var width = 900;
var height = 700;
var color = d3.scale.category20();

var force = d3.layout.force()
        .charge(-500)
        .linkDistance(function(d) { return d.value * 10;})
        .gravity(0.5)
        .size([width, height]);


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

var rect = svg.append("rect")
        .attr("width", width)
        .attr("height", height)
        .style("fill", "none")
        .style("pointer-events", "all");

var container = svg.append("g");

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

var links = container.append("g")
        .attr("class", "links")
        .selectAll(".link")
        .data(graph.links)
        .enter().append("path")
        .attr("class", "link")
        .style("stroke-width", 2);

var nodes = container.append("g")
        .attr("class", "nodes")
        .selectAll(".node")
        .data(graph.nodes)
        .enter().append("g")
        .attr("class", "node")
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

var circle = nodes.append("circle")
        .attr("r", function(d) { return d.weight * 2+ 12; })
        .style("fill", function(d) {
            return color(1/d.rating);
        });

nodes.append("text")
        .attr("x", function(d) { return d.weight * 2+ 12 + 4; })
        .text(function(d) { return d.name });


force.on("tick", function() {
     var xnodes = force.nodes();
     var len = xnodes.length;
     var q = d3.geom.quadtree(xnodes);
     for (i = 0; i < len; i++) {
         //does not work
         //q.visit(collideNew2(xnodes[i]));
     }

    links.attr("d", function(d) {
        var dx = d.target.x - d.source.x,
                dy = d.target.y - d.source.y,
                dr = Math.sqrt(dx * dx + dy * dy);
        return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
    });


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


function collideNew2(node) {
    var nx1, nx2, ny1, ny2, size;
    size = 250;
    nx1 = node.x;
    nx2 = nx1 + size;
    ny1 = node.y;
    ny2 = ny1 + size;
    return function(quad, x1, y1, x2, y2) {
        var dx, dy;
        if (quad.point && (quad.point !== node)) {
            if (overlap(node, quad.point)) {
                dx = Math.min(nx2 - quad.point.x, quad.point.x2 - nx1) / 2;
                node.x -= dx;
                quad.point.x -= dx;
                dy = Math.min(ny2 - quad.point.y, quad.point.y2 - ny1) / 2;
                node.y -= dy;
                quad.point.y += dy;
            }
        }
        return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
    };
};

function overlap(n, p) {
    var nx1, nx2, ny1, ny2, size;
    size = 250;
    nx1 = n.x;
    nx2 = nx1 + size;
    ny1 = n.y;
    ny2 = ny1 + size;
    var x1 = p.x;
    var x2 = x1 + size;
    var y1 = p.y;
    var y2 = y1 + size;
    if (((x1 > nx1 && x1 < nx2) || (x2 > nx1 && x2 < nx2)) && ((y1 > ny1 && y1 < ny2) || (y2 > ny1 && y2 < ny2))) {
        return true;
    }
    return false;
}

似乎重叠功能以及所选的“节点”是错误的。我该如何解决这个问题?

0 个答案:

没有答案