如何避免cola.js / d3.js中的标记和节点重叠

时间:2018-09-21 11:16:05

标签: javascript d3.js webcola

我正在研究cola.js示例enter link description here

,我在链接末尾添加了标记(箭头)。但是,由于节点是矩形,所以箭头重叠。我试图通过更改标记的“ refX”来解决此问题,但效果并不理想。

标记的代码是:

// define arrow markers for graph links
    svg.append('svg:defs').append('svg:marker')
    .attr('id', 'end-arrow')
        .attr('viewBox', '0 -5 10 10')
        .attr('refX', 30)
        //.attr("refY", -1.5)
        .attr('markerWidth', 6)
        .attr('markerHeight', 6)
        .attr('orient', 'auto')
        .append('svg:path')
        .attr('d', 'M0,-5L10,0L0,5')
        .attr('fill', '#000');

,然后将其添加到链接的末尾:

`cola.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; })
            .attr("marker-end","url(#end-arrow)");  
`

2 个答案:

答案 0 :(得分:0)

如果我可能建议另一种创建边缘的方法。

在此示例here之后-免责声明:由于im假定代码中有错字,实际示例似乎已损坏。

长话短说。重要的部分是您的cola.on(“ tick” function(){

            link.each(function (d) {
            d.route = cola.makeEdgeBetween(d.source.innerBounds, d.target.innerBounds, 5);
        });

        link.attr("x1", d => d.route.sourceIntersection.x)
            .attr("y1", d => d.route.sourceIntersection.y)
            .attr("x2", d => d.route.arrowStart.x)
            .attr("y2", d => d.route.arrowStart.y);

makeEdgeBetween的第三个参数(5)(如果我没有记错的话)是考虑到箭头长度的间距,如果您查看源代码,则应将其称为ah。而且非常确定makeEdgeBetween函数将创建边缘直到节点的矩形边界而不是中心。

答案 1 :(得分:0)

有同样的问题,但我采取了不同的方法。我不喜欢只在侧面有箭头,所以我做了一个函数来计算目标和源节点的相对位置,并相应地放置链接目标。

function calculateRelativePosition(d){
        let relative = {"x2":0,"y2":0};
        const pixels = 3;
        const relativex = d.source.x - d.target.x;
        const relativey = d.source.y - d.target.y;

        if(Math.abs(relativex) > Math.abs(relativey)){
            if((d.source.x - d.target.x)>0)
            {
                relative.x2 = d.target.x + d.target.width /2 - pad +pixels;
                relative.y2 = d.target.y;
                return relative;
            }
            else
            {
                relative.x2 = d.target.x- d.target.width/2  + pad - pixels;
                relative.y2 = d.target.y;
                return relative;

            }
        }
        if((d.source.y - d.target.y)>0)
        {
            relative.x2 = d.target.x
            relative.y2 = d.target.y + d.target.height /2 - pad + pixels
            return relative;

        }
        else
        {
            relative.x2 = relative.x2 = d.target.x;
            relative.y2 = d.target.y - d.target.height/2  + pad - pixels
            return relative;
        }

    }

然后在 cola.on("tick") 上

 cola.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 calculateRelativePosition(d).x2 })
            .attr("y2", function (d) { return calculateRelativePosition(d).y2 });

该方法将比较节点的相对位置,并将箭头放置在矩形的 4 条边之一,即与另一个节点的角距离最小的一条边。