D3.js - 重叠箭头

问题描述:

我想在D3.js - 重叠箭头

http://bl.ocks.org/mbostock/1153292

适应代码以提供工作流状态。

这里是小提琴

var links = [{ 
    source: "Start", 
    target: "Dept Approver", 
    type: "approve", 
    staus: "completed" 
}, { 
    source: "Dept Approver", 
    target: "Amount>20", 
    type: "approve", 
    staus: "completed" 
}, { 
    source: "Amount>20", 
    target: "Div Approver", 
    type: "approve", 
    staus: "completed" 
}, { 
    source: "Amount>20", 
    target: "Section Approver", 
    type: "approve", 
    staus: "completed" 
}, { 
    source: "Amount>20", 
    target: "Dept Approver", 
    type: "reject", 
    staus: "completed" 
}, { 
    source: "Div Approver", 
    target: "End", 
    type: "approve", 
    staus: "dormant" 
}, { 
    source: "Section Approver", 
    target: "End", 
    type: "approve", 
    staus: "pending" 
}]; 


var nodes = {}; 

// Compute the distinct nodes from the links. 
links.forEach(function (link) { 
    link.source = nodes[link.source] || (nodes[link.source] = { 
     name: link.source 
    }); 
    link.target = nodes[link.target] || (nodes[link.target] = { 
     name: link.target 
    }); 
}); 

var width = 960, 
    height = 500; 

var force = d3.layout.force() 
    .nodes(d3.values(nodes)) 
    .links(links) 
    .size([width, height]) 
    .linkDistance(80) 
    .charge(-300) 
    .on("tick", function (d) { 
    path.attr("d", function (d) { 
     var dx = d.target.x - d.source.x, 
      dy = d.target.y - d.source.y, 
      dr = 0; 
     return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
    }); 
    circle.attr("transform", function (d) { 
     return "translate(" + d.x + "," + d.y + ")"; 
    }); 
    text.attr("transform", function (d) { 
     return "translate(" + d.x + "," + d.y + ")"; 
    }); 
}) 
    .start(); 

var svg = d3.select("#chart").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

// Per-type markers, as they don't inherit styles. 
svg.append("defs").selectAll("marker") 
    .data(["approve", "reject"]) 
    .enter().append("marker") 
    .attr("id", function (d) { 
    return d; 
}) 
    .attr("viewBox", "0 -5 10 10") 
    .attr("refX", 15) 
    .attr("refY", -1.5) 
    .attr("markerWidth", 8) 
    .attr("markerHeight", 8) 
    .attr("orient", "auto") 
    .append("path") 
    .attr("d", "M0,-5L10,0L0,5"); 

var path = svg.append("g").selectAll("path") 
    .data(force.links()) 
    .enter().append("path") 
    .attr("class", function (d) { 
    return "link " + d.type; 
}) 
    .attr("marker-end", function (d) { 
    return "url(#" + d.type + ")"; 
}); 

var circle = svg.append("g").selectAll("circle") 
    .data(force.nodes()) 
    .enter().append("circle") 
    .attr("r", 8) 
    .call(force.drag); 

var text = svg.append("g").selectAll("text") 
    .data(force.nodes()) 
    .enter().append("text") 
    .attr("x", ".40em") 
    .attr("y", 12) 
    .text(function (d) { 
    return d.name; 
}); 

var drag = force.drag() 
    .on("dragstart", function (d) { 
    d3.select(this).classed("fixed", d.fixed = true); 
}); 
.link { 
    fill: none; 
    stroke: #666; 
    stroke-width: 1.5px; 
} 

#licensing { 
    fill: green; 
} 

.link.licensing { 
    stroke: green; 
} 

.link.reject { 
    stroke-dasharray: 0,2 1; 
    stroke: red; 
} 

circle { 
    fill: #ccc; 
    stroke: #333; 
    stroke-width: 1.5px; 
} 

text { 
    font: 11px sans-serif; 
    pointer-events: none; 
    text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; 
} 
.fixed { 
/* fill: #00B2EE; */ 
} 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
<body> 
    <div id="chart"></div> 
</body> 

http://jsfiddle.net/g3yq9z6g/3/

我已经改变了弧线直线。但是,这有一个问题。如果存在从NodeA到NodeB,然后从NodeB到NodeA的连接器(拒绝,以红色突出显示),则两条线重叠。

我想知道是否有管理这一个聪明的办法,例如,甩线(红色的)是几个像素从其他行了,让他们不重叠。

谢谢

+0

谢谢。这个例子使用弧,但是,我需要使用直线。对于有两条弧线的节点来说,会很好。但是,所有其他节点都需要有直线连接器。 – kayasa

+0

另外,我将永远不会在两个节点之间有两个以上的连接器。 – kayasa

事情是这样的:

path.attr("d", function(d) { 
    var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = 0; 
    var yFudge = d.type === "reject" ? 5 : 0; 
    return "M" + d.source.x + "," + (d.source.y + yFudge) + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + (d.target.y + yFudge); 
}); 

更新example

+0

谢谢马克,那就是诀窍。 – kayasa

+0

有没有办法将箭头更改为红色 – kayasa

+0

@ kayasa,当然,请参阅此[更新](http://jsfiddle.net/g3yq9z6g/9/)。 – Mark