在d3.js中绘制节点错误之间的曲线

时间:2014-01-07 18:56:43

标签: d3.js curve

我试图使用d3.js在两个节点之间绘制曲线。                  

 <meta charset="utf-8">

<!-- ----------------- -->
<!-- THIS PART IS CSS -->
<!-- ----------------- -->
<style>
body
{
    background: lightskyblue;
}

.node {
    stroke: black;
    stroke-width: 4.0px;
}

.link {
    stroke: slategray;
    stroke-opacity: 0.6;
}
</style>

</head>

<body>

<!-- ------------------------ -->
<!-- THIS PART IS JAVASCRIPT  -->
<!-- ------------------------ -->
<script src="d3.v3.js"></script>
<script>
////////////////////////////////////////////////////////////////
// Function to prepare topology background 
////////////////////////////////////////////////////////////////
var width = 1280, height = 630;
var color = d3.scale.category20();
var svg   = d3.select("body")
              .append("svg")
              .attr("width", width)
              .attr("height", height)
              .style("border","7px solid black")
              ;

var nodes = [], links = [];
var graph = test_case();
    nodes = graph.nodes;
    links = graph.links;

for(var i = 0; i < nodes.length; i++)
{
    element = nodes[i];
    if(element.group == 0)
    {
        element.x = width/2;
        element.y = height/2;
        element.fixed = true;
    }
}

var force = d3.layout.force()
                     .charge(-400)
                     .linkDistance(300)
                     .size([width, height])
                     .links(links)
                     .nodes(nodes)
                     .on("tick", tick);

var node = svg.selectAll(".node"),
    link = svg.selectAll(".link");

drawGraph();

function test_case()  
{
    graph = 
    {
      "nodes":[
        {"name":0,"group":0,"pos":[216,140]},
        {"name":1,"group":1,"pos":[350,200]},
        {"name":2,"group":1,"pos":[478,438]},
        {"name":3,"group":1,"pos":[596,498]},
        {"name":4,"group":1,"pos":[422,295]},
        {"name":5,"group":1,"pos":[597,357]},
        {"name":6,"group":1,"pos":[530,238]},
        {"name":7,"group":1,"pos":[506,100]},
        {"name":8,"group":1,"pos":[793,265]},
        {"name":9,"group":1,"pos":[972,228]}   
      ],
      "links":[
        {"source":1,"target":2,"rssi":25,"lqi":25,"lr":120},
        {"source":2,"target":0,"rssi":50,"lqi":50,"lr":80},
        {"source":3,"target":0,"rssi":12,"lqi":12,"lr":200},
        {"source":3,"target":2,"rssi":65,"lqi":65,"lr":40},
        {"source":4,"target":0,"rssi":80,"lqi":80,"lr":170},
        {"source":5,"target":0,"rssi":60,"lqi":60,"lr":110},
        {"source":6,"target":7,"rssi":30,"lqi":30,"lr":64},
        {"source":7,"target":0,"rssi":21,"lqi":21,"lr":97},
        {"source":8,"target":3,"rssi":57,"lqi":57,"lr":190},
        {"source":9,"target":0,"rssi":72,"lqi":72,"lr":12}
      ]
    };
    return graph; 
}

////////////////////////////////////////////////////////////////
// Function to draw topology, including nodes and links
////////////////////////////////////////////////////////////////
function drawGraph()
{
    //Add links
    link = link.data(force.links());
    link.enter()
        .append("path")
     // .insert("line", ".gnode")
        .attr("class", "link")
     //   .style("stroke", function(d) {
       //     if(d.rssi<=25) return "crimson";
          //   else if(d.rssi<=50) return "orange";
          //   else if(d.rssi<=75) return "royalblue";
          //   else return "green"; })
    //.style("stroke-dasharray" ,function(d) { if(d.target==0) return "10,10"; else return "";})
    // .style("stroke-width", function(d) { return d.lqi/20 + 5; })
    // .style("stroke-opacity", function(d) { return (d.lr/51)*0.1 + 0.5; });
    link.exit().remove();

    //Add nodes with texts in them
    node = node.data(force.nodes());
    node.enter().append("g").attr("class", "gnode").call(force.drag);
    node.append("circle")
        .attr("class", function(d) { return "node group" + d.group })
        .attr("r", 25)
        .style("fill", function(d) { if(d.group==0) return "mediumaquamarine"; else return "beige" });
    node.append("text")
        .attr("text-anchor", "middle")
        .attr("dy", "+7")
        .text(function(d) { return d.name; })
        .attr("font-size", "22px")
        .attr("font-weight", "bold")
        .style("fill", "black");
    node.exit().remove();


    force.start();
}

function tick()
{
    node.attr("transform", function(d) { return "translate(" + d.pos + ")";});
       link.attr("d", function(d) {
                   var dx = d.target.pos[0] - d.source.pos[0],
                       dy = d.target.pos[1] - d.source.pos[1],
                       dr = Math.sqrt(dx * dx + dy * dy);
   return "M" + d.source.pos[0] + "," + d.source.pos[1] + "A" + dr + "," + dr + " 0 0,1 " + d.target.pos[0] + "," + d.target.pos[1];
     });

}



</script>

</body>
</html>

但代码的结果并不像我预期的那样,应该像http://bl.ocks.org/d3noob/5155181这样添加颜色,不透明度和宽度。我也想画箭头。有人可以解决这个问题吗? 对不起,我对stackoverflow很新;这是我第一次写这个话题。

2 个答案:

答案 0 :(得分:2)

用于在以下步骤中添加箭头:

追加标记:

svg.append("svg:defs").selectAll("marker")
    .data(["end"])      // Different link/path types can be defined here
  .enter().append("svg:marker")    // This section adds in the arrows
    .attr("id", String)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 45)
    .attr("refY",-5.2)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
  .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5");

在路径中添加箭头

      link = link.data(force.links());
      link.enter()
        .append("path")
        .attr("class", "link")
       .attr("marker-end", "url(#end)");

路径CSS:

    .link {
       stroke: slategray;
       stroke-opacity: 0.6;
       fill: none;
       stroke-width: 1.5px;
      }
您的代码

DEMO

根据半径,您想要更改箭头位置,请参阅 this ,这将有助于拖动节点

答案 1 :(得分:0)

第一步:

make fill none:)

.link {
    stroke: slategray;
    fill: none;
    stroke-opacity: 0.6;
}

使用箭头

<强> JSFIDDLE