Jonathan
Jonathan

Reputation: 3644

Why dont the axis tick marks get removed?

I have recently started getting into d3 and graph plotting.

Now I have constructed a very simple graph that should get animated with new data. The animation works however if I animate the axis change all tick marks stay inside the svg. Their opacity drops to something very low but never reaches 0. After a long running time my svg contains every tick mark ever created.

I have seperated my code in a plunker (see below code)

////////////////////////// LINE ////////////////////////////////////////////////////////////////////////////
function createLine() {
  var random = d3.random.normal(0, 20),
    data = d3.range(22).map(random),
    svg = d3.select('#line').append('svg')
      .attr('width', 1000)
      .attr('height', 500);

  var scaleX = d3.scale.linear()
    .domain([0, 20])
    .range([0, 800]);

  var axisX = d3.svg.axis()
    .scale(scaleX).orient('bottom')
    .ticks(5);

  var scaleY = d3.scale.linear()
    .domain([-40, 40])
    .range([0, 400])
    .nice();

  var axisY = d3.svg.axis()
    .scale(scaleY).orient('right')
    .ticks(5);

  var increment = 0;

  var line = d3.svg.line()
    .interpolate('basis')
    .x(function(d, i) {
      return scaleX(i + increment);
    })
    .y(function(d, i) {
      return scaleY(d);
    });

  var area = d3.svg.area()
    .interpolate("basis")
    .x(function(d, i) {
      return scaleX(i + increment);
    })
    .y0(400)
    .y1(function(d, i) {
      return scaleY(d);
    });


  svg.append('defs').append('clipPath')
    .attr('id', 'clip')
    .append('rect')
    .attr('width', 800)
    .attr('height', 400);

  var path = svg.append('g')
    .attr('transform', 'translate(10, 50)')
    .attr("clip-path", "url(#clip)")
    .append('path').datum(data).attr('d', line);

  var xAxis = svg.append('g').attr('class', 'axis-x')
    .attr('transform', 'translate(10,250)').call(axisX);
  var yAxis = svg.append('g').attr('class', 'axis-y')
    .attr('transform', 'translate(820,50)').call(axisY);

  function tick() {
    data.push(random());

    path.attr('d', line)
      .attr('transform', null)
      .transition().duration(500).ease('linear')
      .attr('transform', 'translate(' + scaleX(increment - 1) + ')')
      .each('end', tick);

    ++increment;
    scaleX.domain([increment, increment + 20]);

    xAxis.transition().duration(500).ease('linear')
      .call(axisX);


    data.shift();
  }

  tick();
}
////////////////////////// LINE ////////////////////////////////////////////////////////////////////////////

http://plnkr.co/k4B1OxFBPwD3z9ARVrjg

Upvotes: 1

Views: 150

Answers (2)

Jonathan
Jonathan

Reputation: 3644

The end event is invoked during the last asynchronous callback (tick) after the transition duration and delay expires, after all tweens are invoked with t=1. Note that if the transition is superseded by a later-scheduled transition on a given element, no end event will be dispatched for that element; interrupted transitions do not trigger end events. For example, transition.remove schedules each element to be removed when the transition ends, but if the transition is interrupted, the element will not be removed.

https://github.com/mbostock/d3/wiki/Transitions#each

Upvotes: 1

Henry S
Henry S

Reputation: 3112

This seems to fix it: http://plnkr.co/KgdBVTmac1QLAxjgACDD

I ended up looking at the code used to generate the final example in Mike Bostock's 'Path Transitions' tutorial. The only difference I could see between that and your code was that the axis update\transition was happening before the path transition in Mike's.

So I reordered your code in function tick() to put:

path.attr('d', line)
    .attr('transform', null)
    .transition().duration(500).ease('linear')
    .attr('transform', 'translate(' + scaleX(increment - 1) + ')')
    .each('end', tick);

at the end of the function block, after:

xAxis.transition().duration(1000).ease('linear')
    .call(axisX);

and it seems to work fine. Instead of 'old' x-axis ticks hanging around in the DOM with opacity: 0.000001, they are removed. Frustratingly, I can't understand why this works at the moment!

Upvotes: 0

Related Questions