Another updating joyplot, this one with labels and an axis and some more reasonable design decisions. See also Joyplot Update Pattern.
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
}
.area {
fill: steelblue;
stroke: #fff;
}
.area:nth-child(odd){
fill: lightskyblue;
}
.line {
fill: #fff;
}
.baseline {
stroke: #000;
shape-rendering: crispEdges;
}
.baseline:last-of-type {
display: none;
}
.line-label {
text-anchor: end;
font-size: .8em;
}
.line-label:nth-child(odd){
fill: #888;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/jeezy@1.11.0/lib/jeezy.min.js"></script>
<script>
var alpha = "Annie,Bob,Christina,Dylan,Elizabeth,Fred,Gertrude,Isaiah,Jennifer".split(",");
var margin = {top: 50, left: 75, bottom: 50, right: 10}, width = window.innerWidth - margin.right - margin.left, height = window.innerHeight - margin.top - margin.bottom;
var svg = d3.select("body").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 y_wrapper = d3.scaleBand()
.rangeRound([0, height])
.domain(alpha);
var y = d3.scaleLinear()
.range([y_wrapper.bandwidth(), 0])
.domain([0, 100]);
var x = d3.scaleLinear()
.range([0, width])
.domain([0, 100]);
var area = d3.area()
.x(function(d){ return x(d.day); })
.y1(function(d) { return y(d.value * 2); })
.y0(y(0))
.curve(d3.curveBasis);
svg.append("g")
.attr("class", "axis x")
.attr("transform", "translate(0, " + (height - 2) + ")")
.call(d3.axisBottom(x))
drawChart(makeData());
d3.interval(function(){drawChart(makeData())}, 1000);
function drawChart(data){
// labels
svg.selectAll(".line-label")
.data(data, function(d){ return d.id; })
.enter().append("text")
.attr("class", "line-label")
.attr("x", -5)
.attr("y", function(d) { return y_wrapper(d.id) + y_wrapper.bandwidth() - 3; })
.text(function(d){ return d.id; });
// baselines
svg.selectAll(".baseline")
.data(data, function(d){ return d.id; })
.enter().append("line")
.attr("class", "baseline")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", function(d) { return y_wrapper(d.id) + y_wrapper.bandwidth(); })
.attr("y2", function(d) { return y_wrapper(d.id) + y_wrapper.bandwidth(); });
// JOIN
var area_path = svg.selectAll(".area")
.data(data, function(d){ return d.id; });
// UDATE
area_path
.transition()
.attr("d", function(d){ return area(d.data); });
// ENTER
area_path.enter().append("path")
.attr("class", "area")
.attr("transform", function(d) { return "translate(0, " + (y_wrapper(d.id) - 1.5) + ")"; })
.attr("d", function(d){ return area(d.data); });
}
function makeData(){
return alpha.map(function(letter){
var arr = [];
for (var i = 0; i <= 100; i++){
arr.push({day: i, value: jz.num.randBetween(10, 90)})
}
return {
id: letter,
data: arr
}
});
}
</script>
</body>
</html>