Alex Fallenstedt
Alex Fallenstedt

Reputation: 2093

d3 transitions bar graph

I've been scratching my head for a while, and I'm hoping someone can help clarify how d3 v4 transitions work.

I have a stacked bargraph, and I am attempting to have the bars grow in width.

You can see the current bargraph here Line 36 is where I draw rectangles.

And what I have been trying to do is transition each bar like so:

  layer.selectAll("rect")
    .data(function(d) { return d; })
    .enter().append("rect")
    .attr("y", function(d) { return yScale(parseDate(d.data.date)); })
    .attr("x", function(d) { return xScale(d[0]); })
    .attr("height", yScale.bandwidth())
    .attr("width", function(d) { return xScale(d[1]) - xScale(d[0]) })
    .transition() //start transition here
    .duration(500)
    .delay(function(d,i) { return i * 100 })
    .attr("width", function(d) { return xScale(d[1]) - xScale(d[0]) })

I would expect each rectangle to grow to its full width in 500ms, and have a delay that grows with each rectangle.

How do I properly implement transitions in D3 v4?

Upvotes: 1

Views: 600

Answers (1)

bumbeishvili
bumbeishvili

Reputation: 1460

In your code you are trying to transition from point A to point A . You need to transition from 0 to point A.

So before transition your bars width, needs to be 0

.attr("width", 0)

this will give us such result

enter image description here

you can see, that bars are transitioning , but not as one group

so we can also change x attribute before transition

.attr("x", 0)

and move previous line after transition

.attr("x", function(d) { return xScale(d[0]); })

result:

enter image description here

you can see full working snippet here

<!DOCTYPE html>
<html >

<head>
  <meta charset="UTF-8">
  <link rel="shortcut icon" type="image/x-icon" href="https://production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" />
  <link rel="mask-icon" type="" href="https://production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" />
  <title>CodePen - Stacked Bar Chart D3</title>
  
  
  
  
  
  
  
  
  
</head>

<body translate="no" >

  <div id='stacked-bar'></div>
  
  <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js'></script>

    <script>
    var initStackedBarChart = {
	draw: function(config) {
        let me = this;
        let domEle = config.element;
        let stackKey = config.key;
        let data = config.data;
        let margin = {top: 20, right: 20, bottom: 30, left: 60};
        let parseDate = d3.timeParse("%m/%Y");
        let width = 390 - margin.left - margin.right;
        let height = 500 - margin.top - margin.bottom;
        let xScale = d3.scaleLinear().rangeRound([0, width]);
        let yScale = d3.scaleBand().rangeRound([height, 0]).padding(0.1);
        let color = d3.scaleOrdinal(d3.schemeCategory20);
		svg = d3.select("#"+domEle).append("svg")
				.attr("width", width + margin.left + margin.right)
				.attr("height", height + margin.top + margin.bottom)
				.append("g")
				.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

		var stack = d3.stack()
			.keys(stackKey)
			/*.order(d3.stackOrder)*/
			.offset(d3.stackOffsetNone);
	
		var layers= stack(data);
			data.sort(function(a, b) { return b.total - a.total; });
			yScale.domain(data.map(function(d) { return parseDate(d.date); }));
			xScale.domain([0, d3.max(layers[layers.length - 1], function(d) { return d[0] + d[1]; }) ]).nice();

		var layer = svg.selectAll(".layer")
			.data(layers)
			.enter().append("g")
			.attr("class", "layer")
			.style("fill", function(d, i) { return color(i); });

    //How can I animate the rectangles growing? 
		  layer.selectAll("rect")
			  .data(function(d) { return d; })
			.enter().append("rect")
			  .attr("y", function(d) { return yScale(parseDate(d.data.date)); })
			  .attr("x", function(d) { return 0; return xScale(d[0]); })
			  .attr("height", yScale.bandwidth())
			  .attr("width", function(d) { return 0; return xScale(d[1]) - xScale(d[0]) })
        .transition()
          .duration(500)
          .delay(function(d,i) { return i * 1000 })
          .attr("x", function(d) { return  xScale(d[0]); })
          .attr("width", function(d) { return xScale(d[1]) - xScale(d[0]) })

			svg.append("g")
			.attr("class", "axis axis--x")
			.attr("transform", "translate(0," + (height+5) + ")")
			.call(xAxis);

			svg.append("g")
			.attr("class", "axis axis--y")
			.attr("transform", "translate(0,0)")
			.call(yAxis);							
	}
}
var data = [{"date":"4/1854","total":8571,"disease":1,"wounds":0,"other":5},{"date":"5/1854","total":23333,"disease":12,"wounds":0,"other":9},{"date":"6/1854","total":28333,"disease":11,"wounds":0,"other":6},{"date":"7/1854","total":28772,"disease":359,"wounds":0,"other":23},{"date":"8/1854","total":30246,"disease":828,"wounds":1,"other":30},{"date":"9/1854","total":30290,"disease":788,"wounds":81,"other":70},{"date":"10/1854","total":30643,"disease":503,"wounds":132,"other":128},{"date":"11/1854","total":29736,"disease":844,"wounds":287,"other":106},{"date":"12/1854","total":32779,"disease":1725,"wounds":114,"other":131},{"date":"1/1855","total":32393,"disease":2761,"wounds":83,"other":324},{"date":"2/1855","total":30919,"disease":2120,"wounds":42,"other":361},{"date":"3/1855","total":30107,"disease":1205,"wounds":32,"other":172},{"date":"4/1855","total":32252,"disease":477,"wounds":48,"other":57},{"date":"5/1855","total":35473,"disease":508,"wounds":49,"other":37},{"date":"6/1855","total":38863,"disease":802,"wounds":209,"other":31},{"date":"7/1855","total":42647,"disease":382,"wounds":134,"other":33},{"date":"8/1855","total":44614,"disease":483,"wounds":164,"other":25},{"date":"9/1855","total":47751,"disease":189,"wounds":276,"other":20},{"date":"10/1855","total":46852,"disease":128,"wounds":53,"other":18},{"date":"11/1855","total":37853,"disease":178,"wounds":33,"other":32},{"date":"12/1855","total":43217,"disease":91,"wounds":18,"other":28},{"date":"1/1856","total":44212,"disease":42,"wounds":2,"other":48},{"date":"2/1856","total":43485,"disease":24,"wounds":0,"other":19},{"date":"3/1856","total":46140,"disease":15,"wounds":0,"other":35}];
var key = ["wounds", "other", "disease"];
initStackedBarChart.draw({
	data: data,
	key: key,
	element: 'stacked-bar'
});
  </script>

  
  

</body>
</html>
 

Upvotes: 1

Related Questions