Javascript D3强制布局将链接更改为路径,并将箭头放置在节点边缘而不是中心

Javascript D3强制布局将链接更改为路径,并将箭头放置在节点边缘而不是中心,javascript,d3.js,Javascript,D3.js,我目前正试图让我的d3节点链接结束于节点边缘,而不是节点中心(rect)。由于链接被绘制到中心,我对箭头的放置有问题。很明显,它们都混淆了,因为链接的长度和角度不同 如何将它们成功放置到节点边缘而不是中心?我也很好奇如何将我的链接改为“弯曲”路径,我已经加入了“路径”变量,但它目前不起作用 截至目前,这是代码的一部分: var graphWrapper = jQuery("#outputContainerFlowchart").append("<svg id='graphWrapper'&

我目前正试图让我的d3节点链接结束于节点边缘,而不是节点中心(rect)。由于链接被绘制到中心,我对箭头的放置有问题。很明显,它们都混淆了,因为链接的长度和角度不同

如何将它们成功放置到节点边缘而不是中心?我也很好奇如何将我的链接改为“弯曲”路径,我已经加入了“路径”变量,但它目前不起作用

截至目前,这是代码的一部分:

var graphWrapper = jQuery("#outputContainerFlowchart").append("<svg id='graphWrapper'></svg>");
var svg = d3.select("#graphWrapper").attr("width", width).attr("height", height);

var simulation = d3.forceSimulation(graph.nodes)
    .force("charge", d3.forceManyBody().strength(-30000))
    .force("center", d3.forceCenter(width / 2, height / 2))
    .force("link", d3.forceLink(graph.links).id(function(d) {return d.id; }).distance(50).strength(1))
    .force("x", d3.forceX(width / 2).strength(1))
    .force("y", d3.forceY(height / 2).strength(1))
    .stop();

graph.nodes[0].fixed = true;
graph.nodes[0].fx = width / 2;
graph.nodes[0].fy = height / 2;

d3.timeout(function() {
   let rectWidth = 180;
   let rectHeight = 60;
   for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
         simulation.tick();
   }

   var g = svg.append("g")
       .attr("class", "everything");

   var arrow = g.append("defs").append("marker")
       .attr("id", "arrow")
       .attr("viewBox", "0 -5 10 10")
       .attr("refX", 80)
       .attr("refY", 0)
       .attr("markerWidth", 4)
       .attr("markerHeight", 4)
       .attr("orient", "auto")
       .append("svg:path")
       .attr("d", "M0,-5L10,0L0,5");


   var links = g.append("g")
       .attr("stroke", "#bbb")
       .attr("stroke-width", 3)
       .selectAll("line")
       .data(graph.links)
       .enter().append("line")
       .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(#arrow)");


   var path = g.append("svg:g")
       .selectAll("line")
       .data(graph.links)
       .enter().append("svg:path")
       .attr("class", "link")
       .style("stroke-width", "10")
       .style("stroke", "red")
       .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(#arrow)");


   var nodes = g.selectAll("foreignObject")
        .data(graph.nodes)
        .enter()
        .append("foreignObject")
        .attr("x", function(d) {
             return d.x - rectWidth / 2;
        })
        .attr("y", function(d) {
             return d.y - rectHeight / 2;
        })
        .attr("width", rectWidth)
        .attr("height", rectHeight)
        .attr("class", function(d) {
             return ("graphNode "+d.group)
        })
        .style("background-color", function(d) {
             return colors[d.group];
        })
        .append("xhtml:div")
             .classed("graphNodeDiv", true)
             .html(function(d) {
                  return d.id;
             })
});
var-graphWrapper=jQuery(#outputContainerFlowchart”).append(“”);
var svg=d3.select(“#graphWrapper”).attr(“宽度”,宽度).attr(“高度”,高度);
var模拟=d3.forceSimulation(图形节点)
.力量(“冲锋”,d3.力量人体().力量(-30000))
.力(“中心”,d3.力中心(宽度/2,高度/2))
.force(“link”,d3.forceLink(graph.links).id(函数(d){return d.id;}).距离(50).强度(1))
.力(“x”,d3.力x(宽度/2).强度(1))
.力(“y”,d3.力(高度/2).强度(1))
.停止();
graph.nodes[0]。fixed=true;
graph.nodes[0].fx=width/2;
graph.nodes[0].fy=height/2;
d3.超时(函数(){
让矩形宽度=180;
高度=60;
对于(var i=0,n=Math.ceil(Math.log(simulation.alphaMin())/Math.log(1-simulation.alphaDecay());i
我还创建了一个JSFIDLE,其中包含完整的代码:

SVG包含
marker mid
指令,用于将标记放置在路径和多段线的中点上,但不放置在直线上,因为它不包含中点

我已将您的代码更改为:

var arrow = g.append("defs").append("marker")
    .attr("id", "arrow")
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 0)    // here i was placed 0
    .attr("refY", 0)
    .attr("markerWidth", 4)
    .attr("markerHeight", 4)
    .attr("orient", "auto")
    .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5");


 var links = g.append("g")
    .attr("stroke", "#bbb")
    .attr("stroke-width", 3)
    .selectAll("polyline") // selecting polylines instead of lines
    .data(graph.links)
    .enter().append("polyline") // adding polylines instead of lines
    .attr("points", function(d) { 
           return [
                d.source.x, d.source.y,
                // here i calculate midpoints where markers need to appear
                d.source.x/2+d.target.x/2, d.source.y/2+d.target.y/2,
                d.target.x, d.target.y
           ].join(','); 
    })
    .style("marker-mid", "url(#arrow)"); // here i changed type of marker

结果图像:


工作代码段:

var-width=jQuery(“#outputContainerFlowchart”).width();
var height=jQuery(“#outputContainerFlowchart”).height();
变量颜色={
dummyprodVip:#1eb543“,
dummyaccVip:#30cc30“,
dummyprodLtmp:“3be264”,
dummyaccLtmp:“#74e874”,
dummyprodPool:“#82ffa0”,
dummyaccPool:“#bcffbc”,
dummy2prodBVip:#ff8438,
dummy2accAVip:“becc6a”,
dummy2prodBLtmp:#ffac39“,
dummy2accALtmp:“d9e590”,
dummy2prodBPool:#ffdb3a“,
dummy2accAPool:#f6ffc1“,
}
变量图={
“节点”:[
{
“id”:“dummyvip1”,
“组”:“dummyPrdVip”
},
{
“id”:“DummyLTP1”,
“组”:“dummyPrdLtmp”
},
{
“id”:“dummypool1”,
“组”:“dummyPrdPool”
},
{
“id”:“dummypool2”,
“组”:“dummyPrdPool”
},
{
“id”:“dummy2vip1”,
“组”:“dummy2PrdVip”
},
{
“id”:“dummy2vip2”,
“组”:“dummy2PrdVip”
},
{
“id”