Skip to content

Instantly share code, notes, and snippets.

@yanhann10
Last active March 26, 2018 01:22
Show Gist options
  • Save yanhann10/5f6cf68b781fe992608355780d4e01e3 to your computer and use it in GitHub Desktop.
Save yanhann10/5f6cf68b781fe992608355780d4e01e3 to your computer and use it in GitHub Desktop.
barchart_enter_exit
license: mit
Food Deliciousness
Apples 9
Green Beans 5
Egg Salad Sandwich 4
Cookies 10
Liver 2
Burrito 7
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta charset="utf-8">
<title>D3: Loading data from a CSV file</title>
</head>
<body>
<p>Click on this text to update the chart with new data values (once).</p>
<script type="text/javascript">
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
w = 600 - margin.left - margin.right,
h = 300 - margin.top - margin.bottom;
var padding = 40;
var data = [{
"Food": "Apples",
"Deliciousness": 9,
"new": 4
}, {
"Food": "Green Beans",
"Deliciousness": 5,
"new": 4
}, {
"Food": "Egg Salad Sandwich",
"Deliciousness": 4,
"new": 4
}, {
"Food": "Cookies",
"Deliciousness": 10,
"new": 4
}, {
"Food": "Liver",
"Deliciousness": 2,
"new": 4
}, ];
data.forEach(function(d) {
d.Deliciousness = +d.Deliciousness;
});
//define key
var key = function(d) {
return d.Food;
}
var svg = d3.select("body")
.append("svg")
.attr("width", w + margin.left + margin.right + padding)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," +
margin.top + ")");
//initial state
//scale and axis
var xScale = d3.scaleBand()
.domain(d => d.Food)
.range([0, w])
.paddingInner(0.2);
xScale.domain(data.map(function(d) {
return d.Food;
}));
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.Deliciousness)])
.rangeRound([h, 0]);
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
//draw rect
svg.selectAll('rect')
.data(data, key)
.enter()
.append('rect')
.attr('x', (d, i) => margin.left + i * ((w + 20) / data.length))
.attr('y', d => yScale(d.Deliciousness))
.attr('width', xScale.bandwidth())
.attr('height', d => h - yScale(d.Deliciousness))
.attr('fill', function(d) {
if (d === 30) return "red";
return "rgb(0,0," + d.Deliciousness * 10 + ")";
});
//text label
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(d => d.Deliciousness)
.attr('x', (d, i) => margin.left + i * ((w + 20) / data.length) + 0.4 * w / data.length)
.attr("y", d => yScale(d.Deliciousness) + 15)
.attr("fill", "white")
.attr("text-anchor", "middle");
//draw axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
svg.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(" + margin.left + "," + h + ")")
.call(xAxis);
//transition
d3.select("p")
.on("click", function() {
//New values for dataset
data = [{
"Food": "Green Beans",
"Deliciousness": 5,
"new": 4
}, {
"Food": "Egg Salad Sandwich",
"Deliciousness": 4,
"new": 4
}, {
"Food": "Cookies",
"Deliciousness": 10,
"new": 4
}, {
"Food": "Liver",
"Deliciousness": 2,
"new": 4
}, {
"Food": "Burrito",
"Deliciousness": 7,
"new": 4
}];
xScale.domain(data.map(function(d) {
return d.Food;
}));
svg.select('.xaxis')
.call(xAxis);
//Update all rects
var bars = svg.selectAll("rect")
.data(data, key);
bars.exit().remove();
bars.enter()
.append("rect")
// <-- This makes it a smooth transition!
.attr("x", w)
.attr('y', d => yScale(d.Deliciousness))
.attr("width", xScale.bandwidth())
.attr('height', d => h - yScale(d.Deliciousness))
.merge(bars) //Merges the enter selection with the update selection
.transition() //Initiate a transition on all elements in the update selection (all rects)
.duration(500)
.attr('x', (d, i) => margin.left + i * ((w + 20) / data.length))
.attr('y', d => yScale(d.Deliciousness))
.attr('width', xScale.bandwidth())
.attr('height', d => h - yScale(d.Deliciousness));
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment