Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active April 25, 2021 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarryStevens/de1069536e00256d7aa82299fac0f3d5 to your computer and use it in GitHub Desktop.
Save HarryStevens/de1069536e00256d7aa82299fac0f3d5 to your computer and use it in GitHub Desktop.
Bar Update Pattern
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
}
.amount {
text-anchor: middle;
}
.x.axis .domain {
display: none;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v6.min.js"></script>
<script>
const xVar = "name";
const yVar = "value";
const alpha = "abcdefg".split("");
const margin = { left: 10, right: 10, top: 20, bottom: 20 };
const width = innerWidth - margin.left - margin.right;
const height = innerHeight - margin.top - margin.bottom;
const svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
const g = svg.append("g")
.attr("transform", `translate(${[ margin.left, margin.top ]})`);
const x = d3.scaleBand()
.range([0, width])
.domain(alpha)
.padding(.2);
const y = d3.scaleLinear()
.range([height, 0])
.domain([0, 10]);
const xAxis = d3.axisBottom(x);
const yAxis = g => {
g.call(
d3.axisRight(y)
.tickFormat((d, i, e) => `${d}${i == e.length - 1 ? ` ${yVar}s` : ""}`)
.tickSize(width)
);
g.select(".domain").remove();
g.selectAll(".tick:not(:first-of-type) line")
.attr("stroke", "#777")
.attr("stroke-dasharray", "2,2");
g.selectAll(".tick text")
.attr("x", 4)
.attr("dy", -4);
}
g.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${height})`)
.call(xAxis);
g.append("g")
.attr("class", "y axis")
.call(yAxis);
const color = d3.scaleOrdinal(d3.schemeSet2);
redraw(randomData());
d3.interval(() => {
redraw(randomData());
}, 2000);
function redraw(data){
// join
const bar = g.selectAll(".bar")
.data(data, d => d[xVar]);
const amount = g.selectAll(".amount")
.data(data, d => d[xVar]);
// update
bar
.transition()
.attr("y", d => y(d[yVar]))
.attr("height", d => height - y(d[yVar]));
amount
.transition()
.attr("y", d => y(d[yVar]))
.text(d => d[yVar]);
// enter
bar.enter().append("rect")
.attr("class", "bar")
.attr("x", d => x(d[xVar]))
.attr("y", d => y(d[yVar]))
.attr("width", x.bandwidth())
.attr("height", d => height - y(d[yVar]))
.attr("fill", d => color(d[xVar]));
amount.enter().append("text")
.attr("class", "amount")
.attr("x", d => x(d[xVar]) + x.bandwidth() / 2)
.attr("y", d => y(d[yVar]))
.attr("dy", 16)
.attr("fill", d => d3.color(color(d[xVar])).darker(3))
.text(d => d[yVar]);
}
function randomData(){
return alpha.map(name => {
return {
name,
value: Math.round(d3.randomUniform(1, 10)())
}
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment