I’d suggest this:
Plot.textY(
data_sortable,
Plot.stackY(
Plot.groupX(
{ y: "sum", text: "first" },
{
x: "state",
z: "ageGroup",
y: "population",
text: (d) => (d.population < 1000000 ? null : d.ageGroup),
fill: "red" // for debugging
//sort: {x: 'y', reverse: true},
}
)
)
)
Contrary to the bar mark, the text mark isn’t stacked by default, so we have to add Plot.stackY explicitly. Then, we want the sums to be computed for each different ageGroup, so we need to specify z: “ageGroup” (the bar mark gets z from the fill definition). Finally, a filter on population size allows to remove the labels for the smallest segments.