2016-09-23 3 views
3

this codepen demo을 살펴보십시오. 나는 svg 객체를 클릭하여 인스턴스가 생성 된 시뮬레이션 틱을보고 전환이 발생하는지 확인합니다. 간단한 함수를 사용합니다 :d3js v4 : onclick 노드에 강제로 적용하여 트위닝처럼 보이게하려면 어떻게해야합니까?

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

그러나 "트윈"이 존재하지 않음을 데모에서 확인할 수 있습니다. 내가 제안하는 트위닝의 예를 보려면 here을 참조하십시오!

어디로 잘못 갔습니까? ticked() 함수는 노드가 어디에 있는지 알고 있습니까? 노드 대신 시뮬레이션 위치를 지정해야합니까? (데모 위의 링크에 포함)

키 코드 :

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); 
} 

내가 D3 v4를위한 해답을 선호하지만, 어떤 아이디어가 매우 환영받을 것입니다! 이 d3 놈 덕분에.

답변

0

트위닝이 보이지 않는 이유는 솔루션이 매우 빠르게 수렴된다는 것입니다. 즉, "틱"함수의 첫 번째 반복은 x와 y를 최종 솔루션에 매우 가깝게 계산합니다. 최종 위치를 찾으면 시뮬레이션이 끝날 때 점들이 조금 더 반짝임을 볼 수 있습니다.

노드가 어디에 있는지 (d.x와 d.y를 통해) 알 수 있으므로 시뮬레이션 위치를 지정하지 않아도됩니다.

노드가 초기 위치에서 최종 솔루션으로 움직이는 것을 보려면, 시뮬레이션 설정을 비효율적 인 것으로 조정하는 것이 좋습니다.

나는 여기에 d3.transition를 사용하여 청소기 솔루션() 아마이있는 updated codepen

있어 velocityDecay을 추가 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)); 

에 forceCollide 반복을 변경했습니다.