2014-05-16 3 views
2

줄에 애니메이션을 수행하는 두 가지 기능이 있습니다. 첫 번째 기능 인 one은 입력 선택에 대한 작업을 수행하기 위해 처음에 실행되며 라인의 수평 이동 (x1x2) 만 움직입니다. 두 번째 함수 two은 행의 높이에만 애니메이션을 적용합니다 (y2, y1 만 고정 됨).전환 결합 및 취소

사용자 이벤트를 통해함수로 one 함수를 인터럽트 할 수 없으며 그 반대의 경우도 마찬가지입니다 (two의 애니메이션이 상당히 길기 때문). 즉, two에서 전환이 계속 실행 중일 때 사용자는 one을 트리거 할 수 있습니다. one 어떻게 든 two의 실행 전환의 마지막 상태의 값을 대신 제대로 데이터 기반 값 (즉 .attr('y2', function(d){ ... });)을 할당하기 때문

은 나에게 심각한 두통을 주었다.

http://jsfiddle.net/h39WN/6/ - 다음을 수행하십시오. one을 클릭하십시오. 데이터가 변경되면 수평 이동 만 애니메이션으로 표시됩니다. 또한 실행이 끝나면 줄은 항상 가장 낮은 순서에서 가장 높은 순서로 정렬되어야합니다. two을 한 번 클릭하고 애니메이션이 완료 될 때까지 2 초 정도 기다리십시오. 그런 다음 one을 다시 클릭하십시오. 이것이 바람직한 행동입니다.

지금, two 클릭 몇 밀리 초 기다렸다가 one 클릭 - 당신은 라인들이 올바르게 정렬에도 불구하고, two의 애니메이션의 마지막 상태의 높이를 유지하는 것을 알 수있다. (데이터가 현실적이지 않고이 예제에서 다소 혼란 스럽지만 여전히 문제를 복제 할 수 있음을 알고 있습니다.)

난 다음 다른 일정을 위해 솔루션을 함께했다 "빈", one의 라인 전환 -이 여전히 two에서 실행을 취소해야하는 문서에 따르면이 one가 호출 될 때 :

var one = function() { 

    var svg = d3.select('svg'); 

    vis.mobileTeams = svg 
     .selectAll('.teamGroup') 
     .data(data.values, function (d) { 
      return d.ID; 
     }); 

    // ENTER 
    var teamEnter = vis.mobileTeams 
     .enter() 
     .append('g') 
     .attr('class', 'teamGroup'); 
    // enter line 
    teamEnter 
     .append('line') 
     .attr('class', 'teamWeightedLine'); 


    // UPDATE THE LINE 
    // HEIGHT - SHOULD NOT BE ANIMATED 
    svg 
     .selectAll('.teamGroup line') 
     .attr('y1', paddingY) 

    // I inserted a transition here to cancel 
    // the one triggered by the other function 
    var lineTransition = svg 
     .selectAll('.teamGroup line') 
     .transition() 
     .attr('y2', function(d){ ... }); 

    // I need to use transition chaining so changing 'y2' 
    // with a transition does not get 
    // overwritten by the following transition 

    // HORIZONTAL POSITION - SHOULD BE ANIMATED 
    lineTransition 
     .transition() 
     .duration(500) 
    // 'x1' and 'x2' are the only values that 
    // need to be animated in this function 
     .attr('x1', function (d) { 
      return function(d){ ... }); 
     }) 
     .attr('x2', function (d) { 
      return function(d){ ... }); 
     }); 
}; 

그리고 두 번째 기능이 있습니다.

var lineTransition = svg 
      .selectAll('.teamGroup line') 
      .transition() 
      .attr('y2', function(d){ ... }); 

http://jsfiddle.net/96uN6/8/이 변경을 포함 바이올린 인이 다른 하나가 예약되기 때문에 취소 two의 전이와 "간섭"문제를 해결하더라도

var two = function() { 
    var svg = d3.select('svg'); 

    // this is where the only transition concerning HEIGHT is supposed to take place 
    svg 
     .selectAll('.teamGroup line') 
     .transition() 
     .ease('circle-out') 
     .duration(2000) 
     .attr('y2', vis.mobileCalculateScoreToHeight); 
    console.log('mobile vis updated'); 
}; 

, 그것은 또 다른 문제를 가져온다 . twoone에 의해 중단되는 경우에도, 정확한 높이가 최종 결과 할 -하지만 :

y2 지금은 너무 one에 애니메이션되고있다! 내가 .transition() 그것으로 250 밀리의 기본 지속 시간을 제공합니다 알고, 그래서이 한 :

var lineTransition = svg 
      .selectAll('.teamGroup line') 
      .transition() 
      .duration(0) 
      .attr('y2', function(d){ ... }); 

이를 차례로, 또 다른 문제 제공 : y2는 지금 전혀 설정되어 있지 않은 즉,<line>들도 속성으로 그것을 가지고하지 않습니다

이상하게, 매우 짧은 기간 (그래서 애니메이션은 거의 볼 수 있습니다) 사용할 때 작동하지만, 그것은 단지 때때로 작동하고 아마도 브라우저 의존 :

two에서 애니메이션이 여전히 실행되고있을 때 y2는 설정 - 일반 선택하는 대신는 "간섭"문제를 다시 제공으로 전환 선택 중 하나가 작동하지 않습니다에 y2 설정
var lineTransition = svg 
      .selectAll('.teamGroup line') 
      .transition() 
      .duration(10) 
      .attr('y2', function(d){ ... }); 

. 첫 번째 변화는 바로 두 번째로 취소되고 y2가 설정되어 있지 않습니다 때문에

svg 
    .selectAll('.teamGroup line') 
    .attr('y1', paddingY) 
    .attr('y2', function(d){ ... }); 

var lineTransition = svg 
    .selectAll('.teamGroup line') 
    .transition(); 

전환 체인없는 접근은 물론, 중 하나가 작동하지 않습니다.

svg 
     .selectAll('.teamGroup line') 
     .transition() 
     .duration(10) 
     .attr('y2', function(d){ ... }); 

    svg 
     .selectAll('.teamGroup line') 
     .transition() 
     .duration(TRANSDURATION) 
     .attr('x1', function (d) { 
      return function(d){ ... }; 
     }) 
     .attr('x2', function (d) { 
      return function(d){ ... }; 
     }); 

그래서 나 (짧은 기간 함께 일) 근무 가능한 유일한 해결책은되지해야, 더 나은 솔루션이 있어야합니다, 아주 기발한 것 같다? 불명확 한 것이 있으면 언제든지 물어보십시오.

+0

나는이 주위에 내 머리를 감싸는 몇 가지 문제가 있어요 - 당신은 아마도 문제를 보여줍니다 작은 예제를 만들 수 있습니까? –

+0

@LarsKotthoff 나는 무슨 일이 일어나고 있는지 잘 설명해주는 바이올린을 추가했다. 애플리케이션의 기존 인프라 (즉, 실제 데이터)를 사용할 수 없기 때문에 상당히 어려웠지만 어쨌든 추가 질문을 요청할 수있다. – wnstnsmth

+0

설명해 주셔서 감사합니다. 이 동작은 의도적으로 설계된 것이므로 현재 버전의 D3에서 원하는 작업을 수행 할 수있는 좋은 방법이 없다고 생각합니다. 이상적으로는 "중단 된"전환 이벤트가 필요합니다. 구현은하지만 소스 코드를 수정해야 함). 이 문제를 해결하기 위해 한 가지 기능에서 두 전환을 결합하는 것이 응용 프로그램에서 허용 될 수 있습니까? 예 : http://jsfiddle.net/h39WN/7/ ("one"을 클릭하십시오)? –

답변

1

Mike Bostock (https://github.com/mbostock/d3/issues/1877)을 통해 selection.interrupt()을 사용하여 이전 전환, 즉 이미 전환이 실행 중임을 취소 할 수 있다는 것을 알았습니다.

그래서,

var lineTransition = svg 
      .selectAll('.teamGroup line') 
      .transition() 
      .duration(0) 
      .attr('y2', function(d){ ... }); 

기발한

그것은만큼 쉽게

var lineTransition = svg 
      .selectAll('.teamGroup line') 
      .interrupt() 
      .attr('y2', function(d){ ... }); 

이된다.

은 참조 : http://jsfiddle.net/96uN6/9/

+1

좋은 솔루션이지만 "one"애니메이션이 끝나기 전에 사용자가 "two"를 클릭하면 여전히 엉망인 선을 얻습니다. – cuckovic

+0

물론, 두 가지 유스 케이스 모두 가능할 때와 같은 방식으로 코드를 수정해야합니다. – wnstnsmth