width = 500 - 120 - 20
height = 1000 - 20 - 30
const nestedData = d3.nest()
.key(function(d) {
return d.state;
})
.rollup(function(leaves) {
return d3.mean(leaves, function(d) {
return +d.Age;
});
})
.entries(data)
.map(function(d) {
return {
state: d.key,
Age: d.value
};
});
const y = d3.scaleBand()
.range([0, height])
.padding(0.1)
.domain(nestedData.map(function(d) { return d.state; }));
const x = d3.scaleLinear()
.range([0, width])
.domain([0, d3.max(nestedData, function(d) { return +d.Age; })]);
const yAxis = d3.axisLeft(y);
const xAxis = d3.axisBottom(x);
const svg = select("svg");
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 + ")");
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
g.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
g.selectAll(".bar")
.data(nestedData)
.enter().append("rect")
.attr("class", "bar")
.attr("y", function(d) { return y(d.state); })
.attr("x", 0)
.attr("height", y.bandwidth())
.attr("width", function(d) { return x(d.Age); })
.on("mouseover", function(d) {
tooltip.html("Average age: " + d.Age.toFixed(2) + "<br>State: " + d.state)
.style("opacity", 1)
.style("left", (d3.event.pageX + 10) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mousemove", function(d, event) {
tooltip.style("left", `${event.pageX}px`)
.style("top", `${event.pageY}px`);
})
.on("mouseout", function(d, event) {
tooltip.attr("class", "tooltip")
.style("opacity", 0);
});
const tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);