d3 / d3-axis

Human-readable reference marks for scales.

Home Page:https://d3js.org/d3-axis

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Updating scale domain does not remove old tick marks

enjoylife opened this issue · comments

First time using an axis results in correct ticks, but upon modifying the underlying scale, selecting the same axis, and calling it again, what happens is new ticks are created, but the old ones are not removed.

EX:

// Create svg, etc... 
var svg = d3.select("body").append("svg")/* margin conventions, etc */ .append("g")



var y = d3.scaleLinear().rangeRound([height, 0]).domain([0,1]);
var yAxis = d3.axisRight(y).tickFormat(d3.format(".2s"))

// Works
svg.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + width + ",0)")
  .call(yAxis)

// updating the scales domain
var max = 16000;
y.domain([0, max]);

// issues occur
 svg.select(".y.axis").call(yAxis);

Gist pulled out from a larger app which reproduces the issue

Seems like the key for data binding is a possible culprit.

If I use the identity function it updates correctly.

// this works instead of using the scale for the key accessor
 tick = selection.selectAll(".tick").data(values, identity).order(),

I think the problem lies in how the exit selection is being computed. In this case the key function is returning the same key for all of the old ticks because you’ve enabled rounding. The old ticks values are [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], and the new scale maps them all to the same values: [450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450].

So, this is probably a bug in d3-selection, where if there are multiple elements with the same key, the later ones are should be put into the exit selection and not ignored.

Fixed in d3-selection 0.7.3. I will push a new alpha build of D3 4.0 shortly.

This fix is now included in alpha 41.