bookTidesViz = {
const selectedAgeGroup = "35-44";
const filteredData = readingDataMod.filter(d => d.ageGroup === selectedAgeGroup);
const genreCounts = d3.rollups(
filteredData.flatMap(d => d.genres),
v => v.length,
d => d
).map(([key, value]) => ({ genre: key, value }));
const root = d3
.hierarchy({ children: genreCounts })
.sum(d => d.value)
.sort((a, b) => b.value - a.value);
const width = 800;
const height = 400;
d3.treemap()
.size([width, height])
.padding(1)(root);
const svg = d3
.select(DOM.svg(width, height))
.attr("viewBox", `0 0 ${width} ${height}`)
.style("font-family", "helvetica neue");
const tooltip = d3
.select("body")
.append("div")
.style("position", "absolute")
.style("background", "white")
.style("border", "1px solid #ccc")
.style("border-radius", "5px")
.style("padding", "5px")
.style("box-shadow", "0px 0px 5px rgba(0,0,0,0.3)")
.style("pointer-events", "none")
.style("opacity", 0)
.style("font-family", "helvetica neue")
.style("font-size", "12px")
.style("font-weight", "normal")
const node = svg
.selectAll("g")
.data(root.leaves())
.join("g")
.attr("transform", d => `translate(${d.x0},${d.y0})`);
node
.append("rect")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0)
.attr("fill", (d, i) => d3.schemeObservable10[i % 7])
.on("mouseover", function (event, d) {
d3.select(this).attr("fill-opacity", 0.7);
const total = d.parent.value;
const percentage = ((d.value / total) * 100).toFixed(1);
tooltip
.style("opacity", 1)
.html(
`<strong>${d.data.genre}</strong><br>${percentage}% of people reading this genre`
)
.style("left", `${event.pageX + 5}px`)
.style("top", `${event.pageY - 55}px`);
})
.on("mousemove", function (event) {
tooltip
.style("left", `${event.pageX + 5}px`)
.style("top", `${event.pageY - 55}px`);
})
.on("mouseout", function () {
d3.select(this).attr("fill-opacity", 1);
tooltip.style("opacity", 0);
});
node
.append("text")
.selectAll("tspan")
.data(d => d.data.genre.split(" "))
.join("tspan")
.attr("x", 4)
.attr("y", (d, i) => 13 + i * 12)
.text(d => d)
.attr("fill", "white")
.attr("font-size", "11px")
.attr("font-weight", "bold");
node
.append("title")
.text(d => `${d.data.genre}: ${d.value}`);
return svg.node();
}