2016-09-23 2 views
3

Bitte schauen Sie sich ; Ich würde Sie bitten, auf das Svg-Objekt zu klicken, um zu sehen, dass die Simulations-Ticks instanziiert sind und daher der Übergang stattfindet. Ich benutze eine einfache Funktion zu tun, so:d3js v4: Wie kann ich Onclick auf Knoten anwenden und es wie ein Tween aussehen lassen?

function transitionTo() { 
    simulation 
    .on("tick", ticked); 
} 

Sie können jedoch aus der Demo sehen, dass die „Tweens“ nicht existent ist. Um ein Beispiel für das Tweening zu sehen, das ich vorschlage, siehe here!

Wo bin ich falsch gelaufen? Kennt die ticked() Funktion, wo meine Knoten sind? Muss ich anstelle der Knoten meine Positionen für die Simulation angeben?

Key Code (im oben Demo Link):

var data = { 
    nodes:d3.range(0, range).map(function(d){ return {label: "l"+d ,r: config.radius,color: d3.scaleOrdinal(d3.schemeCategory10)}})  
} 
svg 
    .attr("width", config.canvas.width) 
    .attr("height", config.canvas.height) 
    .attr("id", "canvas") 
    .style("border", "1px solid black") 
    .attr("onclick", "transitionTo()"); 
} 

var simulation = d3.forceSimulation() 
    .force("collide",d3.forceCollide(function(d){return d.r + 1 }).iterations(15)) 
    .force("charge", d3.forceManyBody().strength(1)) 
    .force("center", d3.forceCenter(config.canvas.width/2, config.canvas.height/2)) 
    .force("y", d3.forceY(0)) 
    .force("x", d3.forceX(0)); 

var node = svg.append("g") 
    .attr("class", "nodes") 
    .selectAll("circle") 
    .data(data.nodes) 
    .enter().append("circle") 
    .attr("r", function(d){ return d.r }) 
    .attr('cx', function(d, i) { return i % 10 * (config.canvas.width - config.margin.x*2)/10 + config.radius + config.margin.x; }) 
    .attr('cy', function(d, i) {return (Math.floor(i/10) * (config.canvas.height - config.margin.y*2)/10) + config.margin.y + config.radius}); 

var ticked = function() { 
    node 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }); 
} 

simulation 
    .nodes(data.nodes); 

function transitionTo() { 
    simulation 
    .on("tick", ticked); 
} 

Ich ziehe es Antworten, die für d3 v4 sind, aber alle Ideen würden sehr willkommen! Danke von diesem d3 noob.

Antwort

0

Ich denke, der Grund, warum Sie kein Tween sehen, ist, dass die Lösung sehr schnell konvergiert - d. H. Die ersten Iterationen der "ticked" -Funktion berechnen x und y sehr nahe an der Endlösung. Sie können die Punkte am Ende der Simulation ein wenig schimmern sehen, wenn sie ihre endgültigen Positionen finden.

Also ja - angekreuzt weiß, wo die Knoten sind (über d.x und d.y) und Sie sollten ihre Positionen nicht für die Simulation angeben müssen.

Um Ihre Knoten von der ursprünglichen Position bis zur Endlösung animieren zu lassen, wäre eine Option, Ihre Simulationseinstellungen auf etwas weniger effizientes zu optimieren.

z.B. Ich habe eine velocityDecay und änderte die forceCollide Iterationen 1.

var simulation = d3.forceSimulation() 
    .velocityDecay(0.05) 
    .force("collide",d3.forceCollide(function(d){return d.r + 1 }).iterations(1)) 
    .force("charge", d3.forceManyBody().strength(1)) 
    .force("center", d3.forceCenter(config.canvas.width/2, config.canvas.height/2)) 
    .force("y", d3.forceY(0)) 
    .force("x", d3.forceX(0)); 

Hier ist ein updated codepen

Es ist wahrscheinlich eine sauberere Lösung mit d3.transition().

Verwandte Themen