简体   繁体   中英

Connect SVG circles using Javascript

I am trying to connect SVG circles and rectangles by drawing lines between source circles and target rectangles. Here is the format of my json file:

    [{"sourceNode":"1","type":"sourceNode"},
     {"sourceNode":"3","type":"sourceNode"},
     {"sourceNode":"8","type":"sourceNode"},
     .....
     {"targetNode":"1","type":"targetNode"},
     {"targetNode":"7","type":"targetNode"},
     {"targetNode":"1","type":"targetNode"},
     .....
     {"type":"link","source":"1","target":"2"},
     {"type":"link","source":"3","target":"4"},
     {"type":"link","source":"3","target":"5"}]

I am using a tick function to give attributes to circles and the line. The circles work just fine, but I don't get lines with no attributes when I inspect my SVG in html.

Here is the code :

var nodeSource = g.selectAll("circle")
    .data(data.filter(function (d){ return d.type == "sourceNode"; }))
    .enter().append("circle")
    .attr("r", 5)
    .style("fill", "blue")
        .call(force.drag);

 var nodeTarget = g.selectAll("rect")
    .data(data.filter(function (d){ return d.type == "targetNode"; }))
    .enter().append("rect")
    .attr("width", 10)
    .attr("height", 10)
    .style("fill", "green")
        .call(force.drag);

    var link = g.selectAll("line")
    .data(data.filter(function (d){ return d.type == "link"; }))
    .enter().append("line")
        .style("stroke-width", "2")
        .style("stroke", "grey")
        .call(force.drag);

function tick(e) {
    nodeSource
      .attr("cx", function(d) { return d.x = Math.max(radius(), Math.min(width() - radius(), d.x)); })
      .attr("cy", function(d) { return d.y = Math.max(radius(), Math.min(height() - radius(), d.y)); });

    nodeTarget
      .attr("x", function(d) { return d.x = Math.max(radius(), Math.min(width() - radius(), d.x)); })
      .attr("y", function(d) { return d.y = Math.max(radius(), Math.min(height() - radius(), d.y)); });

    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; });

         chart.draw()

}

When you're assigning x1 , x2 , etc. coordinates to your line, you're not actually giving them a value. In your json file, the data for links has:

"source": "1"

for example. Using d.source.anything won't return a value because "1" doesn't have any properties attached to it. If you want to get a reference to the node which has this number, you have to use d3 to find it:

line.attr('x1', function (d) {
        return d3.selectAll('circle').filter(function (k) {
            return d.source === k.sourceNode;
        }).attr('cx');
    })

Then, when you want to do the target nodes:

line.attr('x2', function(d) {
        return d3.selectAll('rect').filter(function (k) {
            return d.target === k.targetNode;
        }).attr('x');
    })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM