javascript - d3: Multi-Foci Force key code component understanding -


the real magic multi-foci force done here;

function tick(e) {     var k = .1 * e.alpha;      // push nodes toward designated focus.     nodes.foreach(function(o, i) {         o.y += (foci[o.id].y - o.y) * k;         o.x += (foci[o.id].x - o.x) * k;     });      node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); }    

but i'd appreciate clarification what's going on.

alpha, believe, force method controls rate @ force comes rest, accepting values in range [0, 1] - higher values cause force slow halt slower, lower values faster.

we iterate through original array , increment x , y locations (which don't exist initially, these assigned first time on first iteration of foreach loop) k * x , y components of focus point.

ultimately they'll moving towards designated x , y positions, how guarantee them there based on k value based on alpha? extent nodes move along x , y axes controlled .1 constant? setting higher/lower implies more/less drift towards focus points?

finally why transform nodes? understand

node.attr("cx", function(d) { return d.x}) , same y. why transform?

thanks in adv.

jfiddle - https://jsfiddle.net/hiwilson1/dl9r22ny/

update: suspect last part of question, why transform nodes, because we're moving g elements rather circle elements , can't use cx , cy on g element. still unsure why translate them d.x , d.y though, wouldn't move them arbitrarily assigned d.x , d.y values double these locations? (if start @ [10, 10] , translate [10, 10] end @ [20, 20]?)

the animation driven alpha. it's geometric series same: set 0.1 in .start() , multiplied 0.99 @ each tick, animation stops when less 0.005

alpha: 0.0990 alpha: 0.0980 alpha: 0.0970 alpha: 0.0961 alpha: 0.0951 alpha: 0.0941 

...etc.

force.tick = function() {     if ((alpha *= .99) < .005) {         event.end({             type: "end",             alpha: alpha = 0         });         return true;     }     //other code... }; 

it represents "heat" in layout because used determine velocity of nodes. in analogous temperature in gas, proportional average kinetic energy of it's molecules. "cooling" pre-programmed be -1% of current "temperature".

the initial positions of elements set in .start() function math.random() * size x , y, size width , height respectively. done before first foreach in tick function.

function tick(e) {     //var k = .1 * e.alpha;   var k = .1 * e.alpha;   log.text('alpha: ' + d3.format(".4f")(e.alpha * 1000))     // push nodes toward designated focus.     nodes.foreach(function (o, i) {         o.y += (foci[o.id].y - o.y) * k;         o.x += (foci[o.id].x - o.x) * k;     }); 

in above, foreach statement, if element y position greater focus y position, given smaller y, similar x positions. means move towards foci @ speed proportional distance it. proportionality constant k 0.1*alpha decreasing geometrically k = 0.1*0.1 k = 0.1*0.005, animation proceeds. final positions function of initial positions , k , other forces of gravity, charge , friction.

the nodes g elements have no positioning other reference (positioning context) child elements. origin (top left corner) of containing svg element , it's position result of page flow , css positioning. positioning context of g elements can altered transform property , inherited of child elements. without g elements, circles , text elements both have positioned separately work halved way. without transforms, of circles , text positioned, centered on top, left corner of svg element.

the new positions calculated each tick absolute values, not changes in value.

the change in node position (foci[o.id].y - o.y) * k , move them towards foci. "added" existing value (although negative) , stored on node datum (o.x , o.y), statement

node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }); 

uses new datum (d) update translation, still relative svg origin. transform, not move, doesn't translate relative current position, changes translation relative svg element origin (which positioning context g). if start @ [10,10] , new calculation [10,10] position remain @ [10,10] relative svg positioning context.


Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

node.js - How to abort query on demand using Neo4j drivers -