Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active Jul 24, 2017
Embed
What would you like to do?
Staggered Barbells
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: "Helvetica Neue", sans-serif;
margin: 0;
}
.dot {
stroke-width: 1px;
fill-opacity: .6;
}
.dot.a {
stroke: steelblue;
fill: steelblue;
}
.dot.b {
stroke: tomato;
fill: tomato;
}
.connect-line {
stroke: #ccc;
stroke-width: 1px;
}
</style>
</head>
<body>
<div id="viz"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/jeezy/lib/jeezy.min.js"></script>
<script src="https://unpkg.com/d3-marcon/build/d3-marcon.min.js"></script>
<script>
// config
var setup = d3.marcon().top(30).bottom(30).left(30).right(30).width(window.innerWidth).height(window.innerHeight);
setup.render();
var width = setup.innerWidth(),
height = setup.innerHeight(),
svg = setup.svg(),
x_scale = d3.scaleLinear()
.range([0, width])
.domain([0, 100]),
y_scale = d3.scaleLinear()
.range([height, 0])
.domain([0, 1000]),
size_scale = d3.scaleLinear()
.range([1, 30])
.domain([1, 30]),
t = d3.transition()
.duration(750),
stagger_time = 50;
draw_chart(generate_binned_data());
d3.interval(function(){
draw_chart(generate_binned_data());
}, 2000);
function draw_chart(data){
// JOIN
var dot_a = svg.selectAll(".dot.a")
.data(data, function(d){ return d.x; });
var dot_b = svg.selectAll(".dot.b")
.data(data, function(d){ return d.x; });
var connect_line = svg.selectAll(".connect-line")
.data(data, function(d){ return d.x });
// EXIT
// Doesn't get used here but nice to have for copypasta
dot_a.exit()
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.style("r", 1e-6)
.remove();
dot_b.exit()
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.style("r", 1e-6)
.remove();
connect_line.exit()
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.style("opacity", 1e-6)
.remove();
// UPDATE
dot_a
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.attr("cx", function(d){ return x_scale(d.x); })
.attr("cy", function(d){ return y_scale(d.y_a); })
.attr("r", function(d){ return size_scale(d.size_a); });
dot_b
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.attr("cx", function(d){ return x_scale(d.x); })
.attr("cy", function(d){ return y_scale(d.y_b); })
.attr("r", function(d){ return size_scale(d.size_b); });
connect_line
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.attr("y1", function(d){ return y_scale(d.y_a) + (size_scale(d.size_a) * multiplier(d.y_a, d.y_b)); })
.attr("y2", function(d){ return y_scale(d.y_b) - (size_scale(d.size_b) * multiplier(d.y_a, d.y_b)); })
// ENTER
dot_a.enter().append("circle")
.attr("class", "dot a")
.attr("cx", function(d){ return x_scale(d.x); })
.attr("cy", function(d){ return y_scale(d.y_a); })
.attr("r", 1e-6)
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.attr("r", function(d){ return size_scale(d.size_a); });
dot_b.enter().append("circle")
.attr("class", "dot b")
.attr("cx", function(d){ return x_scale(d.x); })
.attr("cy", function(d){ return y_scale(d.y_b); })
.attr("r", 1e-6)
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.attr("r", function(d){ return size_scale(d.size_b); });
connect_line.enter().append("line")
.attr("class", "connect-line")
.attr("x1", function(d){ return x_scale(d.x); })
.attr("x2", function(d){ return x_scale(d.x); })
.attr("y1", height / 2)
.attr("y2", height / 2)
.transition(t).delay(function(d, i){ return stagger(d, i, stagger_time); })
.attr("y1", function(d){ return y_scale(d.y_a) + (size_scale(d.size_a) * multiplier(d.y_a, d.y_b)); })
.attr("y2", function(d){ return y_scale(d.y_b) - (size_scale(d.size_b) * multiplier(d.y_a, d.y_b)); })
}
// a or b on top
function multiplier(a, b){
return a > b ? 1 : -1;
}
// make some data
function generate_binned_data(){
var bin_size = 5,
arr = [];
for (var i = 0; i <= 100; i += bin_size){
arr.push({
x: i,
size_a: jz.num.randBetween(1, 30),
size_b: jz.num.randBetween(1, 30),
y_a: jz.num.randBetween(1, 1000),
y_b: jz.num.randBetween(1, 1000)
});
}
return arr;
}
// a staggered transition
function stagger(d, i, time) {
return i * time;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment