D3 Force layout, problem in with new added links, link label and link arrow is not working for

54 views
Skip to first unread message

sayed israr

unread,
Jun 17, 2017, 2:55:35 AM6/17/17
to d3-js
Need help I new in D3 force layout
i want to click on a node and add new node with link and link should have label and arrow,
problem 
is that link label and link arrow is not working properly i have added a function with name restart(); please view my restart function and let me know what mistake i made. here is my code.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Force Layout with labels on links</title>

    
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style type="text/css">
</style>
</head>
<body>

<script type="text/javascript">

    var w = 1000;
    var h = 600;
    var linkDistance = 200;

    var colors = d3.scale.category10();

    var dataset = {

        nodes: [
    { name: "Adam" },
    { name: "Bob" },
    { name: "Carrie" },
    { name: "Donovan" },
    { name: "Edward" }

    ],
        links: [
    { source: 0, target: 1 },
    { source: 0, target: 2 },
    { source: 0, target: 3 }
    ]
    };


    var svg = d3.select("body").append("svg").attr({ "width": w, "height": h });

    var force = d3.layout.force()
        .nodes(dataset.nodes)
        .links(dataset.links)
        .size([w, h])
        .linkDistance([linkDistance])
        .charge([-500])
        .theta(0.1)
        .gravity(0.05)
        .start();



    var links = svg.selectAll("line")
      .data(dataset.links)
      .enter()
      .append("line")
      .attr("id", function (d, i) { return 'edge' + i })
      .attr('marker-end', 'url(#arrowhead)')
      .style("stroke", "#ccc")
      .style("pointer-events", "none");

    var nodes = svg.selectAll("circle")
      .data(dataset.nodes)
      .enter()
      .append("circle")
      .attr({ "r": 15 })
      .style("fill", function (d, i) { return colors(i); })
      .call(force.drag)

            .on("click", function () {
                // ON CLICK I WANT TO ADD A NEW LINK AND A NEW NODE I DON'T KNOW HOW
                var trg = dataset.nodes.length - 1;

                dataset.links.push({ source: 0, target: trg });
                dataset.nodes.push({ name: "ABA" });

                restart();



            }); //end Click
      


    var nodelabels = svg.selectAll(".nodelabel")
       .data(dataset.nodes)
       .enter()
       .append("text")
       .attr({ "x": function (d) { return d.x; },
           "y": function (d) { return d.y; },
           "class": "nodelabel",
           "stroke": "black"
       })
       .text(function (d) { return d.name; });

    var edgepaths = svg.selectAll(".edgepath")
        .data(dataset.links)
        .enter()
        .append('path')
        .attr({ 'd': function (d) { return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y },
            'class': 'edgepath',
            'fill-opacity': 0,
            'stroke-opacity': 0,
            'fill': 'blue',
            'stroke': 'red',
            'id': function (d, i) { return 'edgepath' + i } 
        })
        .style("pointer-events", "none");

    var edgelabels = svg.selectAll(".edgelabel")
        .data(dataset.links)
        .enter()
        .append('text')
        .style("pointer-events", "none")
        .attr({ 'class': 'edgelabel',
            'id': function (d, i) { return 'edgelabel' + i },
            'dx': 80,
            'dy': 0,
            'font-size': 10,
            'fill': '#aaa'
        });

    edgelabels.append('textPath')
        .attr('xlink:href', function (d, i) { return '#edgepath' + i })
        .style("pointer-events", "none")
        .text(function (d, i) { return 'label ' + i });


    svg.append('defs').append('marker')
        .attr({ 'id': 'arrowhead',
            'viewBox': '-0 -5 10 10',
            'refX': 25,
            'refY': 0,
            //'markerUnits':'strokeWidth',
            'orient': 'auto',
            'markerWidth': 10,
            'markerHeight': 10,
            'xoverflow': 'visible'
        })
        .append('svg:path')
            .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
            .attr('fill', '#ccc')
            .attr('stroke', '#ccc');
   
        function restart() {

            links = links.data(dataset.links);
            links.exit().remove();
            links.enter()
            .insert("line", "nodes")
            .attr("class", "link")
            .style("stroke", "#ccc");

            nodes = nodes.data(dataset.nodes);
            nodes.enter()
            .insert("circle", ".cursor")
            .attr("class", "node")
            .attr("r", 15)
            .style("fill", "yellow")
            .call(force.drag);
            force.start();
            
            nodelabels = nodelabels.data(dataset.nodes);
            nodelabels.enter()
            .insert("text", "lines")
            .attr("class", "nodelabel")
          .text(function (d) { return d.name; });
          //Above fine

            edgepaths = edgepaths.data(dataset.links);
            edgepaths.enter()
            .insert("text", "links")
             .attr("class", "edgepath")
                    .append('path')
                    .attr({ 'd': function (d) { return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y },
                        'class': 'edgepath',
                        'fill-opacity': 0,
                        'stroke-opacity': 0,
                        'fill': 'blue',
                        'stroke': 'red',
                        'id': function (d, i) { return 'edgepath' + i }
                    })
                    .style("pointer-events", "none");

            // Test Start

                    edgelabels = edgelabels.data(dataset.links);
                    edgelabels.enter()
                  .insert("text", "links")
                    .append('text')
        .style("pointer-events", "none")
        .attr({ 'class': 'edgelabel',
            'id': function (d, i) { return 'edgelabel' + i },
            'dx': 80,
            'dy': 0,
            'font-size': 10,
            'fill': '#aaa'
        })

//           edgelabels = svg.selectAll(".edgelabel")
//        .data(dataset.links)
//        .enter()
//        .append('text')
//        .style("pointer-events", "none")
//        .attr({ 'class': 'edgelabel',
//            'id': function (d, i) { return 'edgelabel' + i },
//            'dx': 80,
//            'dy': 0,
//            'font-size': 10,
//            'fill': '#aaa'
//        });

            edgelabels.append('textPath')
        .attr('xlink:href', function (d, i) { return '#edgepath' + i })
        .style("pointer-events", "none")
        .text(function (d, i) { return 'label ' + i });


            svg.append('defs').append('marker')
        .attr({ 'id': 'arrowhead',
            'viewBox': '-0 -5 10 10',
            'refX': 25,
            'refY': 0,
            //'markerUnits':'strokeWidth',
            'orient': 'auto',
            'markerWidth': 10,
            'markerHeight': 10,
            'xoverflow': 'visible'
        })
        .append('svg:path')
            .attr('d', 'M 0,-5 L 10 ,0 L 0,5')
            .attr('fill', '#ccc')
            .attr('stroke', '#ccc');


            //Test End

        } // End of click

    force.on("tick", function () {

        links.attr({ "x1": function (d) { return d.source.x; },
            "y1": function (d) { return d.source.y; },
            "x2": function (d) { return d.target.x; },
            "y2": function (d) { return d.target.y; }
        });

        nodes.attr({ "cx": function (d) { return d.x; },
            "cy": function (d) { return d.y; }
        });

        nodelabels.attr("x", function (d) { return d.x; })
                  .attr("y", function (d) { return d.y; });

        edgepaths.attr('d', function (d) {
            var path = 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
            //console.log(d)
            return path
        });

        edgelabels.attr('transform', function (d, i) {
            if (d.target.x < d.source.x) {
                bbox = this.getBBox();
                rx = bbox.x + bbox.width / 2;
                ry = bbox.y + bbox.height / 2;
                return 'rotate(180 ' + rx + ' ' + ry + ')';
            }
            else {
                return 'rotate(0)';
            }
        });
    });

</script>

</body>
</html>

Curran

unread,
Jun 17, 2017, 3:21:05 AM6/17/17
to d3-js
Greetings,

The first step for others to help you is to be able to reproduce the problem by running the code. As it is, it's nearly impossible to tell what might be going wrong, just by looking at your code, without the ability to run it.

Please post a running example to bl.ocks.org, which will allow more people to help you. There is a great tool for doing this - http://blockbuilder.org/

Best regards,
Curran

sayed israr

unread,
Jun 17, 2017, 3:42:03 AM6/17/17
to d3...@googlegroups.com
Dear Sir here is the links
if possible please help me.

--
You received this message because you are subscribed to a topic in the Google Groups "d3-js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/d3-js/2hJLo5VPSLQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to d3-js+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages