d3 / d3

Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:
https://d3js.org
ISC License
108.44k stars 22.87k forks source link

Why using current x and y instead of px and px when calculating forces between links in force layout? #1465

Closed suyongxin4 closed 11 years ago

suyongxin4 commented 11 years ago

Hi,

I have been studying d3's force layout recently and I got a question.

    // gauss-seidel relaxation for links
    for (i = 0; i < m; ++i) {
      o = links[i];
      s = o.source;
      t = o.target;
      x = t.x - s.x;//why not x = t.px - s.px;
      y = t.y - s.y;//why not y = t.py - s.py;
      if (l = (x * x + y * y)) {
        l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
        x *= l;
        y *= l;
        t.x -= x * (k = s.weight / (t.weight + s.weight));
        t.y -= y * k;
        s.x += x * (k = 1 - k);
        s.y += y * k;
      }
    }

This paragraph is quoted from your source code. My question is that why not using px and py to calculate the distance between the nodes but using current x and y?

Hope you could help me understand your algorithm.

Thanks, Yongxin.

jasondavies commented 11 years ago

Hello, we’d prefer if you ask these kinds of questions on the d3-js mailing list, and only use GitHub for reporting bugs/feature requests.

The algorithm requires the current distance between nodes during any time step. This means that externally, you can modify node positions by listening for the tick event and setting d.x and d.y. The previous node positions are only there for position verlet integration.

suyongxin4 commented 11 years ago

Hi Jason,

Sorry for your trouble. That was my first time to raise a question at github. I will pay attention to this next time.

Actually I understood the whole progress when using tick event to change elements' positions externally. Maybe you have misunderstood my question. Let me explain it again.

Say there is two links in the graph, Link 1 is node A to node B and Link 2 is node A to node C. In the algorithm, we will iterate the link array and calculate the spring force applied on the nodes. After first iteration, node A and node B's position has been changed according to the calculation result. And in the next iteration when we try to calculate the distance between node A and node C, node A's new position will be used because we changed A,x and A,y in the last iteration. If we change the sequence of the links like link 1 is A to C and link 2 is A to B. The final position of A, B and C would be different after the calculation of spring force. My question is that, why not using the previous position to calculate the distance to keep the final the same even the sequence of links is different?

Thanks, Alex.

2013/8/16 Jason Davies notifications@github.com

Hello, we’d prefer if you ask these kinds of questions on the d3-jshttps://groups.google.com/d/forum/d3-js%E2%80%8Emailing list, and only use GitHub for reporting bugs/feature requests.

The algorithm requires the current distance between nodes during any time step. This means that externally, you can modify node positions by listening for the tick event and setting d.x and d.y. The previous node positions are only there for position verlet integration.

— Reply to this email directly or view it on GitHubhttps://github.com/mbostock/d3/issues/1465#issuecomment-22758440 .

Best Regards, Alex.