End points of the links of the force directed graph always stuck to left corner of the rectangular node












0















I am creating a force directed graph using v4 of d3.js. The links in the graph are always pointing to the left hand corner of the rectangular nodes.



I think the problem is either in my tick function or my drag handlers. I am not really sure which one is it and what is the problem.



var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

var simulation = d3.forceSimulation().nodes(nodes_data);
simulation
.force("centre_force", d3.forceCenter(width / 2, height / 2))
.force("charge_force", d3.forceManyBody().strength(-90))

var nodes = svg.append("g")
.attr("class", "nodes")
.selectAll("rect")
.data(nodes_data)
.enter()
.append("g");

var rect_width = 80;
var rect_height = 50;

nodes.append("rect")
.attr("width", rect_width)
.attr("height", rect_height)
.attr("rx", 10)
.attr("ry", 10)
.style("stroke", "black");

nodes.append("text")
.attr("text-anchor", "middle")
.attr("x", rect_width / 2)
.attr("y", rect_height / 2)
.attr("dy", "0.35em")
.text(function (d) { return d.name; });

var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2);

//defining force for links
var link_force = d3.forceLink(links_data)
.id(function (d) { return d.name; })
.distance(150)
.strength(0.5);

//calling the defined force
simulation.force("links", link_force);

simulation.on("tick", function () {
nodes.attr("transform", function (d) { return "translate(" + d.x + "," + 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; });

nodes.attr("x", (d) => { return d.x; })
.attr("y", (d) => { return d.y; });

})

//drag function definitions
function drag_start(d) {
simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function drag_end(d) {
simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
//drag function binding
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);
drag_handler(nodes);


I want them to point at the edge of the rectangle and the edge should change dynamically if the position is changed so.



Following is the actual result:



Link pointing to left



Following is the expected result:



enter image description here










share|improve this question




















  • 1





    the top left of the rectangle is the position of your nodes. Inside the tick function you must construct a line from rect-center to rect-center and determine which side is crossed and then calculate the intersection and draw a line between the intersection points

    – rioV8
    Jan 3 at 14:36













  • The example I am referring to for the actual results doesn't do anything like that and yet achieve the result that i want

    – Akhilesh Bhatia
    Jan 4 at 10:29











  • then draw your rectangles centered around the node position

    – rioV8
    Jan 4 at 10:30











  • How do i do that?

    – Akhilesh Bhatia
    Jan 4 at 10:51











  • I think I am getting a more clear understanding of my problem. The example that I am referring to for the actual results contains directly the rect element within the svg and the x and y co-ordinates of the rect element changes because of the tick function and thus the corresponding link changes too. In my case, there is an outer g element for each rect and it is the x and y of this g element that changes as opposed to that of the rect element. Since the x and y of rect doesn't change, they link remains bound to the left corner

    – Akhilesh Bhatia
    Jan 4 at 10:57


















0















I am creating a force directed graph using v4 of d3.js. The links in the graph are always pointing to the left hand corner of the rectangular nodes.



I think the problem is either in my tick function or my drag handlers. I am not really sure which one is it and what is the problem.



var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

var simulation = d3.forceSimulation().nodes(nodes_data);
simulation
.force("centre_force", d3.forceCenter(width / 2, height / 2))
.force("charge_force", d3.forceManyBody().strength(-90))

var nodes = svg.append("g")
.attr("class", "nodes")
.selectAll("rect")
.data(nodes_data)
.enter()
.append("g");

var rect_width = 80;
var rect_height = 50;

nodes.append("rect")
.attr("width", rect_width)
.attr("height", rect_height)
.attr("rx", 10)
.attr("ry", 10)
.style("stroke", "black");

nodes.append("text")
.attr("text-anchor", "middle")
.attr("x", rect_width / 2)
.attr("y", rect_height / 2)
.attr("dy", "0.35em")
.text(function (d) { return d.name; });

var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2);

//defining force for links
var link_force = d3.forceLink(links_data)
.id(function (d) { return d.name; })
.distance(150)
.strength(0.5);

//calling the defined force
simulation.force("links", link_force);

simulation.on("tick", function () {
nodes.attr("transform", function (d) { return "translate(" + d.x + "," + 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; });

nodes.attr("x", (d) => { return d.x; })
.attr("y", (d) => { return d.y; });

})

//drag function definitions
function drag_start(d) {
simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function drag_end(d) {
simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
//drag function binding
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);
drag_handler(nodes);


I want them to point at the edge of the rectangle and the edge should change dynamically if the position is changed so.



Following is the actual result:



Link pointing to left



Following is the expected result:



enter image description here










share|improve this question




















  • 1





    the top left of the rectangle is the position of your nodes. Inside the tick function you must construct a line from rect-center to rect-center and determine which side is crossed and then calculate the intersection and draw a line between the intersection points

    – rioV8
    Jan 3 at 14:36













  • The example I am referring to for the actual results doesn't do anything like that and yet achieve the result that i want

    – Akhilesh Bhatia
    Jan 4 at 10:29











  • then draw your rectangles centered around the node position

    – rioV8
    Jan 4 at 10:30











  • How do i do that?

    – Akhilesh Bhatia
    Jan 4 at 10:51











  • I think I am getting a more clear understanding of my problem. The example that I am referring to for the actual results contains directly the rect element within the svg and the x and y co-ordinates of the rect element changes because of the tick function and thus the corresponding link changes too. In my case, there is an outer g element for each rect and it is the x and y of this g element that changes as opposed to that of the rect element. Since the x and y of rect doesn't change, they link remains bound to the left corner

    – Akhilesh Bhatia
    Jan 4 at 10:57
















0












0








0








I am creating a force directed graph using v4 of d3.js. The links in the graph are always pointing to the left hand corner of the rectangular nodes.



I think the problem is either in my tick function or my drag handlers. I am not really sure which one is it and what is the problem.



var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

var simulation = d3.forceSimulation().nodes(nodes_data);
simulation
.force("centre_force", d3.forceCenter(width / 2, height / 2))
.force("charge_force", d3.forceManyBody().strength(-90))

var nodes = svg.append("g")
.attr("class", "nodes")
.selectAll("rect")
.data(nodes_data)
.enter()
.append("g");

var rect_width = 80;
var rect_height = 50;

nodes.append("rect")
.attr("width", rect_width)
.attr("height", rect_height)
.attr("rx", 10)
.attr("ry", 10)
.style("stroke", "black");

nodes.append("text")
.attr("text-anchor", "middle")
.attr("x", rect_width / 2)
.attr("y", rect_height / 2)
.attr("dy", "0.35em")
.text(function (d) { return d.name; });

var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2);

//defining force for links
var link_force = d3.forceLink(links_data)
.id(function (d) { return d.name; })
.distance(150)
.strength(0.5);

//calling the defined force
simulation.force("links", link_force);

simulation.on("tick", function () {
nodes.attr("transform", function (d) { return "translate(" + d.x + "," + 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; });

nodes.attr("x", (d) => { return d.x; })
.attr("y", (d) => { return d.y; });

})

//drag function definitions
function drag_start(d) {
simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function drag_end(d) {
simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
//drag function binding
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);
drag_handler(nodes);


I want them to point at the edge of the rectangle and the edge should change dynamically if the position is changed so.



Following is the actual result:



Link pointing to left



Following is the expected result:



enter image description here










share|improve this question
















I am creating a force directed graph using v4 of d3.js. The links in the graph are always pointing to the left hand corner of the rectangular nodes.



I think the problem is either in my tick function or my drag handlers. I am not really sure which one is it and what is the problem.



var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

var simulation = d3.forceSimulation().nodes(nodes_data);
simulation
.force("centre_force", d3.forceCenter(width / 2, height / 2))
.force("charge_force", d3.forceManyBody().strength(-90))

var nodes = svg.append("g")
.attr("class", "nodes")
.selectAll("rect")
.data(nodes_data)
.enter()
.append("g");

var rect_width = 80;
var rect_height = 50;

nodes.append("rect")
.attr("width", rect_width)
.attr("height", rect_height)
.attr("rx", 10)
.attr("ry", 10)
.style("stroke", "black");

nodes.append("text")
.attr("text-anchor", "middle")
.attr("x", rect_width / 2)
.attr("y", rect_height / 2)
.attr("dy", "0.35em")
.text(function (d) { return d.name; });

var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2);

//defining force for links
var link_force = d3.forceLink(links_data)
.id(function (d) { return d.name; })
.distance(150)
.strength(0.5);

//calling the defined force
simulation.force("links", link_force);

simulation.on("tick", function () {
nodes.attr("transform", function (d) { return "translate(" + d.x + "," + 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; });

nodes.attr("x", (d) => { return d.x; })
.attr("y", (d) => { return d.y; });

})

//drag function definitions
function drag_start(d) {
simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function drag_end(d) {
simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
//drag function binding
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);
drag_handler(nodes);


I want them to point at the edge of the rectangle and the edge should change dynamically if the position is changed so.



Following is the actual result:



Link pointing to left



Following is the expected result:



enter image description here







javascript d3.js






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 11:24







Akhilesh Bhatia

















asked Jan 3 at 12:36









Akhilesh BhatiaAkhilesh Bhatia

2719




2719








  • 1





    the top left of the rectangle is the position of your nodes. Inside the tick function you must construct a line from rect-center to rect-center and determine which side is crossed and then calculate the intersection and draw a line between the intersection points

    – rioV8
    Jan 3 at 14:36













  • The example I am referring to for the actual results doesn't do anything like that and yet achieve the result that i want

    – Akhilesh Bhatia
    Jan 4 at 10:29











  • then draw your rectangles centered around the node position

    – rioV8
    Jan 4 at 10:30











  • How do i do that?

    – Akhilesh Bhatia
    Jan 4 at 10:51











  • I think I am getting a more clear understanding of my problem. The example that I am referring to for the actual results contains directly the rect element within the svg and the x and y co-ordinates of the rect element changes because of the tick function and thus the corresponding link changes too. In my case, there is an outer g element for each rect and it is the x and y of this g element that changes as opposed to that of the rect element. Since the x and y of rect doesn't change, they link remains bound to the left corner

    – Akhilesh Bhatia
    Jan 4 at 10:57
















  • 1





    the top left of the rectangle is the position of your nodes. Inside the tick function you must construct a line from rect-center to rect-center and determine which side is crossed and then calculate the intersection and draw a line between the intersection points

    – rioV8
    Jan 3 at 14:36













  • The example I am referring to for the actual results doesn't do anything like that and yet achieve the result that i want

    – Akhilesh Bhatia
    Jan 4 at 10:29











  • then draw your rectangles centered around the node position

    – rioV8
    Jan 4 at 10:30











  • How do i do that?

    – Akhilesh Bhatia
    Jan 4 at 10:51











  • I think I am getting a more clear understanding of my problem. The example that I am referring to for the actual results contains directly the rect element within the svg and the x and y co-ordinates of the rect element changes because of the tick function and thus the corresponding link changes too. In my case, there is an outer g element for each rect and it is the x and y of this g element that changes as opposed to that of the rect element. Since the x and y of rect doesn't change, they link remains bound to the left corner

    – Akhilesh Bhatia
    Jan 4 at 10:57










1




1





the top left of the rectangle is the position of your nodes. Inside the tick function you must construct a line from rect-center to rect-center and determine which side is crossed and then calculate the intersection and draw a line between the intersection points

– rioV8
Jan 3 at 14:36







the top left of the rectangle is the position of your nodes. Inside the tick function you must construct a line from rect-center to rect-center and determine which side is crossed and then calculate the intersection and draw a line between the intersection points

– rioV8
Jan 3 at 14:36















The example I am referring to for the actual results doesn't do anything like that and yet achieve the result that i want

– Akhilesh Bhatia
Jan 4 at 10:29





The example I am referring to for the actual results doesn't do anything like that and yet achieve the result that i want

– Akhilesh Bhatia
Jan 4 at 10:29













then draw your rectangles centered around the node position

– rioV8
Jan 4 at 10:30





then draw your rectangles centered around the node position

– rioV8
Jan 4 at 10:30













How do i do that?

– Akhilesh Bhatia
Jan 4 at 10:51





How do i do that?

– Akhilesh Bhatia
Jan 4 at 10:51













I think I am getting a more clear understanding of my problem. The example that I am referring to for the actual results contains directly the rect element within the svg and the x and y co-ordinates of the rect element changes because of the tick function and thus the corresponding link changes too. In my case, there is an outer g element for each rect and it is the x and y of this g element that changes as opposed to that of the rect element. Since the x and y of rect doesn't change, they link remains bound to the left corner

– Akhilesh Bhatia
Jan 4 at 10:57







I think I am getting a more clear understanding of my problem. The example that I am referring to for the actual results contains directly the rect element within the svg and the x and y co-ordinates of the rect element changes because of the tick function and thus the corresponding link changes too. In my case, there is an outer g element for each rect and it is the x and y of this g element that changes as opposed to that of the rect element. Since the x and y of rect doesn't change, they link remains bound to the left corner

– Akhilesh Bhatia
Jan 4 at 10:57














1 Answer
1






active

oldest

votes


















0














I solved the problem.



First of all, I removed the following code



nodes.attr("x", (d) => { return d.x; })
.attr("y", (d) => { return d.y; });


There was no need for it.



Next, I changed the x and y co-ordinates of the rect element to point to the center of the rect. The default values for x and y is 0 and 0.
In my case, I changed the x to -40 and to y to -25 as following



let rect_width = 80;
let rect_height = 50;

nodes.append("rect")
.attr("width", rect_width)
.attr("height", rect_height)
.attr("rx", 10)
.attr("ry", 10)
.attr("x", -(rect_width / 2))
.attr("y", -(rect_height / 2))
.style("stroke", "black");


Following is my result now



Link pointing to the center



Possibly unecessary information- but to move the links behind my node, I drew the links first and then the nodes later in my code. Referred this answer






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54022426%2fend-points-of-the-links-of-the-force-directed-graph-always-stuck-to-left-corner%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I solved the problem.



    First of all, I removed the following code



    nodes.attr("x", (d) => { return d.x; })
    .attr("y", (d) => { return d.y; });


    There was no need for it.



    Next, I changed the x and y co-ordinates of the rect element to point to the center of the rect. The default values for x and y is 0 and 0.
    In my case, I changed the x to -40 and to y to -25 as following



    let rect_width = 80;
    let rect_height = 50;

    nodes.append("rect")
    .attr("width", rect_width)
    .attr("height", rect_height)
    .attr("rx", 10)
    .attr("ry", 10)
    .attr("x", -(rect_width / 2))
    .attr("y", -(rect_height / 2))
    .style("stroke", "black");


    Following is my result now



    Link pointing to the center



    Possibly unecessary information- but to move the links behind my node, I drew the links first and then the nodes later in my code. Referred this answer






    share|improve this answer




























      0














      I solved the problem.



      First of all, I removed the following code



      nodes.attr("x", (d) => { return d.x; })
      .attr("y", (d) => { return d.y; });


      There was no need for it.



      Next, I changed the x and y co-ordinates of the rect element to point to the center of the rect. The default values for x and y is 0 and 0.
      In my case, I changed the x to -40 and to y to -25 as following



      let rect_width = 80;
      let rect_height = 50;

      nodes.append("rect")
      .attr("width", rect_width)
      .attr("height", rect_height)
      .attr("rx", 10)
      .attr("ry", 10)
      .attr("x", -(rect_width / 2))
      .attr("y", -(rect_height / 2))
      .style("stroke", "black");


      Following is my result now



      Link pointing to the center



      Possibly unecessary information- but to move the links behind my node, I drew the links first and then the nodes later in my code. Referred this answer






      share|improve this answer


























        0












        0








        0







        I solved the problem.



        First of all, I removed the following code



        nodes.attr("x", (d) => { return d.x; })
        .attr("y", (d) => { return d.y; });


        There was no need for it.



        Next, I changed the x and y co-ordinates of the rect element to point to the center of the rect. The default values for x and y is 0 and 0.
        In my case, I changed the x to -40 and to y to -25 as following



        let rect_width = 80;
        let rect_height = 50;

        nodes.append("rect")
        .attr("width", rect_width)
        .attr("height", rect_height)
        .attr("rx", 10)
        .attr("ry", 10)
        .attr("x", -(rect_width / 2))
        .attr("y", -(rect_height / 2))
        .style("stroke", "black");


        Following is my result now



        Link pointing to the center



        Possibly unecessary information- but to move the links behind my node, I drew the links first and then the nodes later in my code. Referred this answer






        share|improve this answer













        I solved the problem.



        First of all, I removed the following code



        nodes.attr("x", (d) => { return d.x; })
        .attr("y", (d) => { return d.y; });


        There was no need for it.



        Next, I changed the x and y co-ordinates of the rect element to point to the center of the rect. The default values for x and y is 0 and 0.
        In my case, I changed the x to -40 and to y to -25 as following



        let rect_width = 80;
        let rect_height = 50;

        nodes.append("rect")
        .attr("width", rect_width)
        .attr("height", rect_height)
        .attr("rx", 10)
        .attr("ry", 10)
        .attr("x", -(rect_width / 2))
        .attr("y", -(rect_height / 2))
        .style("stroke", "black");


        Following is my result now



        Link pointing to the center



        Possibly unecessary information- but to move the links behind my node, I drew the links first and then the nodes later in my code. Referred this answer







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 4 at 13:47









        Akhilesh BhatiaAkhilesh Bhatia

        2719




        2719
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54022426%2fend-points-of-the-links-of-the-force-directed-graph-always-stuck-to-left-corner%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas

            Can't read property showImagePicker of undefined in react native iOS