Aztec-3x5
Aztec-3x5

Reputation: 155

Interrupting D3 transition: How to interrupt an ongoing transition upon drag?

Following is the small piece of code.

timeline_svg.append("line")
.attr("class", "track")
.attr("x1", x.range()[0] + 135 - marginTimeAxis) //
.attr("x2", x.range()[1] + marginTimeAxis)
.attr('y1', 10)
.attr('y2', 10)
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "track-inset")
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "track-overlay") //axis tAxis
.call(d3.drag()
    .on("start.interrupt", function() { timeline_svg.interrupt();})
    .on("start drag", function() {
    currentValue = d3.event.x;
    console.log("current value:-> ", currentValue);
    update(t.invert(currentValue)); 
    })
);    

In the above code, whenever I am trying to start a drag action timeline_svg.interrupt() should get called but that is not happening. The transition doesn't getting interrupted. I want the transition of the svg to get interrupted upon drag.

F.Y.I I am using d3v5 for my project.

Tried Approaches: #1.

.call(d3.drag()
.on("interrupt", function() { timeline_svg.interrupt();})
.call(d3.drag()
.on("start.interrupt", function() { timeline_svg.transition.duration(0);})

Thank you for reading my post I appreciate your time and effort you put into this.

Upvotes: 2

Views: 762

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38161

You'll want to use selection.interrupt() when dragging:

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

var circle = svg.append("circle")
  .attr("r", 20)
  .attr("cx",100)
  .attr("cy",100)
  .attr("fill","crimson")
  
circle.transition()
  .attr("cx", 300)
  .attr("fill","steelblue")
  .duration(5000)
  
var drag = d3.drag()
  .on("start", function() {
    d3.select(this).interrupt()
  })
  .on("drag", function() {
    d3.select(this)
      .attr("cx", d3.event.x)
      .attr("cy", d3.event.y)
  })

circle.call(drag);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width = 500 height=300></svg>

You almost had it between the two approaches.

Your first approach doesn't work for a number of reasons: transition.on() has an event type "interrupt", but d3-drag does not; but no interrupt event will be triggered until you use selection.interrupt(), listening for the interrupt to trigger the interrupt is putting the horse before the cart.

Your second approach doesn't work because you aren't setting a new transition: selection.transition.duration(0) should be selection.transition().duration(0);

var svg = d3.select("body").append("svg");
var circle = svg.append("circle")
  .attr("cx",50)
  .attr("cy",50)
  .attr("r", 10)
  
circle.transition()
  .attr("cx", 200)
  
circle.transition
  .duration(0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Upvotes: 3

Related Questions