简体   繁体   中英

D3 axis label rotate transition not smooth

In my transition, an axis rotates 90 degree and then the labels rotate in the opposition direction in order to remain upright. Below is a minimal example of what I want, except the transition is not as smooth as it could be. If you watch closely, you can see the labels shift (translate) up before rotating into place. How can I get rid of this shift? I've fiddled with rotate and translate to no avail.

(If you think this isn't too bad, I agree, but the shift is actually significantly more noticeable in my actual plot for some reason.)

Update. The culprit is the text-anchor property's getting switched back and forth between middle and start . Since these are discrete values, I can't think of a simple way to transition between them.

 var width = 170; var scale = d3.scaleLinear().domain([0, 5]) .range([0, width]); var axis = d3.axisBottom() .scale(scale) .ticks(6); var graph = d3.select('svg').append('g') .attr('transform', 'translate(10,10)'); graph.append('g') .attr('transform', 'translate(0,' + width + ')') .call(axis); var tickLabels = d3.selectAll('text'); var toggle = false; d3.select('button').on('click', function() { toggle = !toggle; if (toggle) { graph.transition().duration(1000) // .attr('transform','rotate(-90)'); .attr('transform', 'rotate(-90 ' + (width / 2 + 10) + ' ' + (width / 2 + 10) + ')'); tickLabels.transition().duration(1500).delay(1000) .attr("y", 0) .attr("x", 9) .attr("dy", ".3em") .attr("transform", "rotate(90)") .style("text-anchor", "start"); } else { graph.transition().duration(1000) .attr('transform', 'rotate(0) translate(10,10)'); tickLabels.transition().duration(1500).delay(1000) .attr('y', 9) .attr('x', 0.5) .attr('dy', '0.71em') .attr('transform', 'rotate(0)') .style('text-anchor', null); } });
 <script src="https://d3js.org/d3.v4.min.js"></script> <svg width='200' height='200'> </svg> <div> <button>Rotate</button> </div>

Found the solution, which is actually fairly simple. The key is to alter the x attribute to offset the text-anchor shift before rotating the labels. The result is actually quite nice.

 var width = 170; var scale = d3.scaleLinear().domain([0, 5]) .range([0, width]); var axis = d3.axisBottom() .scale(scale) .ticks(6); var graph = d3.select('svg').append('g') .attr('transform', 'translate(10,10)'); graph.append('g') .attr('transform', 'translate(0,' + width + ')') .call(axis); var tickLabels = d3.selectAll('text'); var toggle = false; d3.select('button').on('click', function() { toggle = !toggle; if (toggle) { graph.transition().duration(1000) // .attr('transform','rotate(-90)'); .attr('transform', 'rotate(-90 ' + (width / 2 + 10) + ' ' + (width / 2 + 10) + ')'); tickLabels.transition().duration(0).delay(1000) .attr('x', -3) .style("text-anchor", "start") .transition().duration(1000) .attr("y", 0) .attr("x", 9) .attr("dy", ".3em") .attr("transform", "rotate(90)"); } else { graph.transition().duration(1000) .attr('transform', 'rotate(0) translate(10,10)'); tickLabels.transition().duration(0).delay(1000) .attr('x', 12) .style('text-anchor', null) .transition().duration(1000) .attr('y', 9) .attr('x', 0.5) .attr('dy', '0.71em') .attr('transform', 'rotate(0)'); } });
 <script src="https://d3js.org/d3.v4.min.js"></script> <svg width='200' height='200'> </svg> <div> <button>Rotate</button> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM