chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
svg
.append("g")
.attr("fill", "steelblue")
.selectAll("rect")
.data(m_users)
.join("rect")
.attr("x", x_m(0))
.attr("y", d => y(d.age))
.attr("width", d => x_m(d.average_playcount) - x_m(0))
.attr("height", y.bandwidth());
svg
.append("g")
.attr("fill", "white")
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.selectAll("text")
.data(m_users)
.join("text")
.attr("x", d => x_m(d.average_playcount))
.attr("y", d => y(d.age) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.attr("dx", -4)
.text(d => d.average_playcount)
.call(text =>
text
.filter(d => x_m(d.average_playcount) - x_m(0) < 20)
.attr("dx", +4)
.attr("fill", "black")
.attr("text-anchor", "start")
);
// Female bars
svg
.append("g")
.attr("fill", "firebrick")
.selectAll("rect")
.data(f_users)
.join("rect")
.attr("x", d => x_f(0) - (x_m(d.average_playcount) - x_m(0)))
.attr("y", d => y(d.age))
.attr("width", d => x_m(d.average_playcount) - x_m(0))
.attr("height", y.bandwidth());
// Female labels
svg
.append("g")
.attr("fill", "white")
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.selectAll("text")
.data(f_users)
.join("text")
.attr("x", d => x_f(0) - x_m(d.average_playcount) + x_m(0))
.attr("y", d => y(d.age) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.attr("dx", 4)
.attr("text-anchor", "start")
.text(d => d.average_playcount)
.call(text =>
text
.filter(d => x_m(d.average_playcount) - x_m(0) < 20) // short bars
.attr("dx", 4)
.attr("fill", "white")
.attr("text-anchor", "end")
);
svg.append("g").call(xmAxis);
svg.append("g").call(xfAxis);
svg.append("g").call(yAxis);
svg.append("g").call(y2Axis);
svg
.append("text")
.attr("transform", `translate(${middle}, ${margin.top - 10})`)
.style("text-anchor", "middle")
.style("font-size", "18px")
.text("Age");
svg
.append("text")
.attr("transform", `translate(${middle}, ${height - margin.bottom + 40})`)
.style("text-anchor", "middle")
.style("font-size", "18px")
.text("Average # of Listens Per Day");
const tooltip = d3
.select("body")
.append("div")
.attr("class", "svg-tooltip")
.style("position", "absolute")
.style("visibility", "hidden");
svg
.selectAll("rect")
.on("mouseover", d => {
tooltip.text(
"Age: " +
d.age +
" years old\nAverage Playcount: " +
d.average_playcount +
" plays/day\nNumber of Records: " +
d.n
);
return tooltip.style("visibility", "visible");
})
.on("mousemove", function() {
return tooltip
.style("top", d3.event.pageY - 10 + "px")
.style("left", d3.event.pageX + 10 + "px");
})
.on("mouseout", function() {
return tooltip.style("visibility", "hidden");
});
return svg.node();
}