<script src="https://d3js.org/d3.v7.min.js"></script>
const ages = ["<10", "10-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70-79", "≥80"];

const width = 940;

const stateages = [{"state":"AL","age":"<10","population":598478},{"state":"AK","age":"<10","population":106741},{"state":"AZ","age":"<10","population":892083},{"state":"AR","age":"<10","population":392177},{"state":"CA","age":"<10","population":5038433},{"state":"CO","age":"<10","population":690830},{"state":"CT","age":"<10","population":399369},{"state":"DE","age":"<10","population":112177},{"state":"DC","age":"<10","population":74377},{"state":"FL","age":"<10","population":2211012},{"state":"GA","age":"<10","population":1363631},{"state":"HI","age":"<10","population":176484},{"state":"ID","age":"<10","population":236658},{"state":"IL","age":"<10","population":1619682},{"state":"IN","age":"<10","population":863029},{"state":"IA","age":"<10","population":401712},{"state":"KS","age":"<10","population":401751},{"state":"KY","age":"<10","population":555615},{"state":"LA","age":"<10","population":622061},{"state":"ME","age":"<10","population":137954},{"state":"MD","age":"<10","population":741952},{"state":"MA","age":"<10","population":737748},{"state":"MI","age":"<10","population":1181424},{"state":"MN","age":"<10","population":711604},{"state":"MS","age":"<10","population":400288},{"state":"MO","age":"<10","population":763948},{"state":"MT","age":"<10","population":126020},{"state":"NE","age":"<10","population":263518},{"state":"NV","age":"<10","population":369362},{"state":"NH","age":"<10","population":138762},{"state":"NJ","age":"<10","population":1079136},{"state":"NM","age":"<10","population":276468},{"state":"NY","age":"<10","population":2319945},{"state":"NC","age":"<10","population":1250298},{"state":"ND","age":"<10","population":99477},{"state":"OH","age":"<10","population":1422838},{"state":"OK","age":"<10","population":534481},{"state":"OR","age":"<10","population":474456},{"state":"PA","age":"<10","population":1458931},{"state":"RI","age":"<10","population":111377},{"state":"SC","age":"<10","population":599591},{"state":"SD","age":"<10","population":120366},{"state":"TN","age":"<10","population":818404},{"state":"TX","age":"<10","population":3983091},{"state":"UT","age":"<10","population":513515},{"state":"VT","age":"<10","population":63768},{"state":"VA","age":"<10","population":1033629},{"state":"WA","age":"<10","population":895790},{"state":"WV","age":"<10","population":207017},{"state":"WI","age":"<10","population":705648},{"state":"WY","age":"<10","population":78217},{"state":"PR","age":"<10","population":389428},{"state":"AL","age":"10-19","population":638789},{"state":"AK","age":"10-19","population":99926},{"state":"AZ","age":"10-19","population":912735},{"state":"AR","age":"10-19","population":397185},{"state":"CA","age":"10-19","population":5170341},{"state":"CO","age":"10-19","population":697447},{"state":"CT","age":"10-19","population":481065},{"state":"DE","age":"10-19","population":117854},{"state":"DC","age":"10-19","population":62783},{"state":"FL","age":"10-19","population":2331102},{"state":"GA","age":"10-19","population":1421557},{"state":"HI","age":"10-19","population":163559},{"state":"ID","age":"10-19","population":239509},{"state":"IL","age":"10-19","population":1715984},{"state":"IN","age":"10-19","population":905594},{"state":"IA","age":"10-19","population":418667},{"state":"KS","age":"10-19","population":402092},{"state":"KY","age":"10-19","population":575866},{"state":"LA","age":"10-19","population":613633},{"state":"ME","age":"10-19","population":155774},{"state":"MD","age":"10-19","population":764730},{"state":"MA","age":"10-19","population":862371},{"state":"MI","age":"10-19","population":1324071},{"state":"MN","age":"10-19","population":714399},{"state":"MS","age":"10-19","population":421329},{"state":"MO","age":"10-19","population":792935},{"state":"MT","age":"10-19","population":126294},{"state":"NE","age":"10-19","population":257610},{"state":"NV","age":"10-19","population":360263},{"state":"NH","age":"10-19","population":167495},{"state":"NJ","age":"10-19","population":1153625},{"state":"NM","age":"10-19","population":282662},{"state":"NY","age":"10-19","population":2445591},{"state":"NC","age":"10-19","population":1310398},{"state":"ND","age":"10-19","population":91069},{"state":"OH","age":"10-19","population":1530264},{"state":"OK","age":"10-19","population":522282},{"state":"OR","age":"10-19","population":485345},{"state":"PA","age":"10-19","population":1608018},{"state":"RI","age":"10-19","population":136885},{"state":"SC","age":"10-19","population":619144},{"state":"SD","age":"10-19","population":113383},{"state":"TN","age":"10-19","population":842873},{"state":"TX","age":"10-19","population":3910528},{"state":"UT","age":"10-19","population":479126},{"state":"VT","age":"10-19","population":79351},{"state":"VA","age":"10-19","population":1065461},{"state":"WA","age":"10-19","population":882812},{"state":"WV","age":"10-19","population":218547},{"state":"WI","age":"10-19","population":755224},{"state":"WY","age":"10-19","population":75535},{"state":"PR","age":"10-19","population":479749},{"state":"AL","age":"20-29","population":661666},{"state":"AK","age":"20-29","population":120674},{"state":"AZ","age":"20-29","population":939804},{"state":"AR","age":"20-29","population":399698},{"state":"CA","age":"20-29","population":5809455},{"state":"CO","age":"20-29","population":780508},{"state":"CT","age":"20-29","population":462323},{"state":"DE","age":"20-29","population":127554},{"state":"DC","age":"20-29","population":136976},{"state":"FL","age":"20-29","population":2597830},{"state":"GA","age":"20-29","population":1418696},{"state":"HI","age":"20-29","population":204336},{"state":"ID","age":"20-29","population":218684},{"state":"IL","age":"20-29","population":1789739},{"state":"IN","age":"20-29","population":905590},{"state":"IA","age":"20-29","population":419456},{"state":"KS","age":"20-29","population":406956},{"state":"KY","age":"20-29","population":593819},{"state":"LA","age":"20-29","population":683606},{"state":"ME","age":"20-29","population":156359},{"state":"MD","age":"20-29","population":815346},{"state":"MA","age":"20-29","population":971340},{"state":"MI","age":"20-29","population":1338179},{"state":"MN","age":"20-29","population":728222},{"state":"MS","age":"20-29","population":414195},{"state":"MO","age":"20-29","population":831725},{"state":"MT","age":"20-29","population":136346},{"state":"NE","age":"20-29","population":260646},{"state":"NV","age":"20-29","population":392834},{"state":"NH","age":"20-29","population":167554},{"state":"NJ","age":"20-29","population":1139927},{"state":"NM","age":"20-29","population":289801},{"state":"NY","age":"20-29","population":2894266},{"state":"NC","age":"20-29","population":1350242},{"state":"ND","age":"20-29","population":124509},{"state":"OH","age":"20-29","population":1535538},{"state":"OK","age":"20-29","population":552528},{"state":"OR","age":"20-29","population":538596},{"state":"PA","age":"20-29","population":1712448},{"state":"RI","age":"20-29","population":153674},{"state":"SC","age":"20-29","population":667523},{"state":"SD","age":"20-29","population":116748},{"state":"TN","age":"20-29","population":895337},{"state":"TX","age":"20-29","population":3946447},{"state":"UT","age":"20-29","population":465219},{"state":"VT","age":"20-29","population":81765},{"state":"VA","age":"20-29","population":1170634},{"state":"WA","age":"20-29","population":1004428},{"state":"WV","age":"20-29","population":232027},{"state":"WI","age":"20-29","population":760961},{"state":"WY","age":"20-29","population":82898},{"state":"PR","age":"20-29","population":480184},{"state":"AL","age":"30-39","population":603013},{"state":"AK","age":"30-39","population":102008},{"state":"AZ","age":"30-39","population":857054},{"state":"AR","age":"30-39","population":372998},{"state":"CA","age":"30-39","population":5354112},{"state":"CO","age":"30-39","population":766382},{"state":"CT","age":"30-39","population":424890},{"state":"DE","age":"30-39","population":114063},{"state":"DC","age":"30-39","population":121520},{"state":"FL","age":"30-39","population":2416176},{"state":"GA","age":"30-39","population":1357210},{"state":"HI","age":"30-39","population":187590},{"state":"ID","age":"30-39","population":209500},{"state":"IL","age":"30-39","population":1721954},{"state":"IN","age":"30-39","population":827086},{"state":"IA","age":"30-39","population":383638},{"state":"KS","age":"30-39","population":368732},{"state":"KY","age":"30-39","population":558201},{"state":"LA","age":"30-39","population":615411},{"state":"ME","age":"30-39","population":147695},{"state":"MD","age":"30-39","population":784097},{"state":"MA","age":"30-39","population":847306},{"state":"MI","age":"30-39","population":1162186},{"state":"MN","age":"30-39","population":715583},{"state":"MS","age":"30-39","population":374724},{"state":"MO","age":"30-39","population":763002},{"state":"MT","age":"30-39","population":125004},{"state":"NE","age":"30-39","population":244236},{"state":"NV","age":"30-39","population":390261},{"state":"NH","age":"30-39","population":151409},{"state":"NJ","age":"30-39","population":1143452},{"state":"NM","age":"30-39","population":260579},{"state":"NY","age":"30-39","population":2605355},{"state":"NC","age":"30-39","population":1268976},{"state":"ND","age":"30-39","population":94713},{"state":"OH","age":"30-39","population":1398724},{"state":"OK","age":"30-39","population":501392},{"state":"OR","age":"30-39","population":537767},{"state":"PA","age":"30-39","population":1520409},{"state":"RI","age":"30-39","population":126503},{"state":"SC","age":"30-39","population":596491},{"state":"SD","age":"30-39","population":105499},{"state":"TN","age":"30-39","population":837313},{"state":"TX","age":"30-39","population":3770534},{"state":"UT","age":"30-39","population":436010},{"state":"VT","age":"30-39","population":70092},{"state":"VA","age":"30-39","population":1112111},{"state":"WA","age":"30-39","population":970613},{"state":"WV","age":"30-39","population":220494},{"state":"WI","age":"30-39","population":714479},{"state":"WY","age":"30-39","population":76912},{"state":"PR","age":"30-39","population":441842},{"state":"AL","age":"40-49","population":625599},{"state":"AK","age":"40-49","population":91539},{"state":"AZ","age":"40-49","population":833290},{"state":"AR","age":"40-49","population":370157},{"state":"CA","age":"40-49","population":5179258},{"state":"CO","age":"40-49","population":705450},{"state":"CT","age":"40-49","population":496265},{"state":"DE","age":"40-49","population":117588},{"state":"DC","age":"40-49","population":80570},{"state":"FL","age":"40-49","population":2575576},{"state":"GA","age":"40-49","population":1404698},{"state":"HI","age":"40-49","population":176904},{"state":"ID","age":"40-49","population":194678},{"state":"IL","age":"40-49","population":1697069},{"state":"IN","age":"40-49","population":844059},{"state":"IA","age":"40-49","population":370719},{"state":"KS","age":"40-49","population":344427},{"state":"KY","age":"40-49","population":580553},{"state":"LA","age":"40-49","population":571991},{"state":"ME","age":"40-49","population":176908},{"state":"MD","age":"40-49","population":815875},{"state":"MA","age":"40-49","population":916106},{"state":"MI","age":"40-49","population":1283122},{"state":"MN","age":"40-49","population":692201},{"state":"MS","age":"40-49","population":377165},{"state":"MO","age":"40-49","population":750989},{"state":"MT","age":"40-49","population":116502},{"state":"NE","age":"40-49","population":222479},{"state":"NV","age":"40-49","population":387272},{"state":"NH","age":"40-49","population":182703},{"state":"NJ","age":"40-49","population":1254602},{"state":"NM","age":"40-49","population":244346},{"state":"NY","age":"40-49","population":2617327},{"state":"NC","age":"40-49","population":1357746},{"state":"ND","age":"40-49","population":80327},{"state":"OH","age":"40-49","population":1490959},{"state":"OK","age":"40-49","population":469410},{"state":"OR","age":"40-49","population":507826},{"state":"PA","age":"40-49","population":1645291},{"state":"RI","age":"40-49","population":137892},{"state":"SC","age":"40-49","population":619792},{"state":"SD","age":"40-49","population":96288},{"state":"TN","age":"40-49","population":866343},{"state":"TX","age":"40-49","population":3545746},{"state":"UT","age":"40-49","population":328569},{"state":"VT","age":"40-49","population":79982},{"state":"VA","age":"40-49","population":1134928},{"state":"WA","age":"40-49","population":921205},{"state":"WV","age":"40-49","population":238218},{"state":"WI","age":"40-49","population":732280},{"state":"WY","age":"40-49","population":68464},{"state":"PR","age":"40-49","population":456009},{"state":"AL","age":"50-59","population":673864},{"state":"AK","age":"50-59","population":104569},{"state":"AZ","age":"50-59","population":834858},{"state":"AR","age":"50-59","population":395070},{"state":"CA","age":"50-59","population":5042094},{"state":"CO","age":"50-59","population":725661},{"state":"CT","age":"50-59","population":546361},{"state":"DE","age":"50-59","population":133331},{"state":"DC","age":"50-59","population":74779},{"state":"FL","age":"50-59","population":2762983},{"state":"GA","age":"50-59","population":1337985},{"state":"HI","age":"50-59","population":188438},{"state":"ID","age":"50-59","population":205170},{"state":"IL","age":"50-59","population":1773366},{"state":"IN","age":"50-59","population":911778},{"state":"IA","age":"50-59","population":427554},{"state":"KS","age":"50-59","population":389834},{"state":"KY","age":"50-59","population":623164},{"state":"LA","age":"50-59","population":631936},{"state":"ME","age":"50-59","population":215787},{"state":"MD","age":"50-59","population":862778},{"state":"MA","age":"50-59","population":979128},{"state":"MI","age":"50-59","population":1454462},{"state":"MN","age":"50-59","population":782655},{"state":"MS","age":"50-59","population":400164},{"state":"MO","age":"50-59","population":857534},{"state":"MT","age":"50-59","population":149800},{"state":"NE","age":"50-59","population":250911},{"state":"NV","age":"50-59","population":373757},{"state":"NH","age":"50-59","population":217950},{"state":"NJ","age":"50-59","population":1307263},{"state":"NM","age":"50-59","population":280363},{"state":"NY","age":"50-59","population":2755620},{"state":"NC","age":"50-59","population":1356117},{"state":"ND","age":"50-59","population":98688},{"state":"OH","age":"50-59","population":1677794},{"state":"OK","age":"50-59","population":512850},{"state":"OR","age":"50-59","population":534421},{"state":"PA","age":"50-59","population":1881378},{"state":"RI","age":"50-59","population":156127},{"state":"SC","age":"50-59","population":663408},{"state":"SD","age":"50-59","population":117012},{"state":"TN","age":"50-59","population":904272},{"state":"TX","age":"50-59","population":3344930},{"state":"UT","age":"50-59","population":301596},{"state":"VT","age":"50-59","population":99521},{"state":"VA","age":"50-59","population":1162028},{"state":"WA","age":"50-59","population":970407},{"state":"WV","age":"50-59","population":269346},{"state":"WI","age":"50-59","population":848672},{"state":"WY","age":"50-59","population":81018},{"state":"PR","age":"50-59","population":452503},{"state":"AL","age":"60-69","population":548376},{"state":"AK","age":"60-69","population":70473},{"state":"AZ","age":"60-69","population":737884},{"state":"AR","age":"60-69","population":329734},{"state":"CA","age":"60-69","population":3737461},{"state":"CO","age":"60-69","population":563376},{"state":"CT","age":"60-69","population":400995},{"state":"DE","age":"60-69","population":110822},{"state":"DC","age":"60-69","population":56984},{"state":"FL","age":"60-69","population":2404659},{"state":"GA","age":"60-69","population":998253},{"state":"HI","age":"60-69","population":164957},{"state":"ID","age":"60-69","population":179429},{"state":"IL","age":"60-69","population":1326121},{"state":"IN","age":"60-69","population":704523},{"state":"IA","age":"60-69","population":344037},{"state":"KS","age":"60-69","population":300759},{"state":"KY","age":"60-69","population":495736},{"state":"LA","age":"60-69","population":488846},{"state":"ME","age":"60-69","population":179540},{"state":"MD","age":"60-69","population":636309},{"state":"MA","age":"60-69","population":737805},{"state":"MI","age":"60-69","population":1148131},{"state":"MN","age":"60-69","population":577313},{"state":"MS","age":"60-69","population":319443},{"state":"MO","age":"60-69","population":668878},{"state":"MT","age":"60-69","population":130977},{"state":"NE","age":"60-69","population":195705},{"state":"NV","age":"60-69","population":309651},{"state":"NH","age":"60-69","population":164287},{"state":"NJ","age":"60-69","population":946399},{"state":"NM","age":"60-69","population":239044},{"state":"NY","age":"60-69","population":2095207},{"state":"NC","age":"60-69","population":1095320},{"state":"ND","age":"60-69","population":73825},{"state":"OH","age":"60-69","population":1320776},{"state":"OK","age":"60-69","population":404704},{"state":"OR","age":"60-69","population":490894},{"state":"PA","age":"60-69","population":1491536},{"state":"RI","age":"60-69","population":117653},{"state":"SC","age":"60-69","population":579856},{"state":"SD","age":"60-69","population":92824},{"state":"TN","age":"60-69","population":741045},{"state":"TX","age":"60-69","population":2431494},{"state":"UT","age":"60-69","population":230007},{"state":"VT","age":"60-69","population":82136},{"state":"VA","age":"60-69","population":881763},{"state":"WA","age":"60-69","population":784208},{"state":"WV","age":"60-69","population":243108},{"state":"WI","age":"60-69","population":645015},{"state":"WY","age":"60-69","population":67484},{"state":"PR","age":"60-69","population":411924},{"state":"AL","age":"70-79","population":316598},{"state":"AK","age":"70-79","population":28422},{"state":"AZ","age":"70-79","population":466153},{"state":"AR","age":"70-79","population":197985},{"state":"CA","age":"70-79","population":2011678},{"state":"CO","age":"70-79","population":274466},{"state":"CT","age":"70-79","population":217827},{"state":"DE","age":"70-79","population":65369},{"state":"DC","age":"70-79","population":31362},{"state":"FL","age":"70-79","population":1615547},{"state":"GA","age":"70-79","population":528108},{"state":"HI","age":"70-79","population":85345},{"state":"ID","age":"70-79","population":97621},{"state":"IL","age":"70-79","population":728821},{"state":"IN","age":"70-79","population":384788},{"state":"IA","age":"70-79","population":197223},{"state":"KS","age":"70-79","population":166104},{"state":"KY","age":"70-79","population":273961},{"state":"LA","age":"70-79","population":266123},{"state":"ME","age":"70-79","population":97899},{"state":"MD","age":"70-79","population":330736},{"state":"MA","age":"70-79","population":401931},{"state":"MI","age":"70-79","population":619722},{"state":"MN","age":"70-79","population":312906},{"state":"MS","age":"70-79","population":181195},{"state":"MO","age":"70-79","population":388086},{"state":"MT","age":"70-79","population":70528},{"state":"NE","age":"70-79","population":107650},{"state":"NV","age":"70-79","population":173499},{"state":"NH","age":"70-79","population":84791},{"state":"NJ","age":"70-79","population":523620},{"state":"NM","age":"70-79","population":135013},{"state":"NY","age":"70-79","population":1160055},{"state":"NC","age":"70-79","population":609234},{"state":"ND","age":"70-79","population":41348},{"state":"OH","age":"70-79","population":728158},{"state":"OK","age":"70-79","population":239887},{"state":"OR","age":"70-79","population":255809},{"state":"PA","age":"70-79","population":850897},{"state":"RI","age":"70-79","population":63359},{"state":"SC","age":"70-79","population":322073},{"state":"SD","age":"70-79","population":50398},{"state":"TN","age":"70-79","population":414939},{"state":"TX","age":"70-79","population":1291486},{"state":"UT","age":"70-79","population":123674},{"state":"VT","age":"70-79","population":42978},{"state":"VA","age":"70-79","population":475141},{"state":"WA","age":"70-79","population":401094},{"state":"WV","age":"70-79","population":138134},{"state":"WI","age":"70-79","population":350772},{"state":"WY","age":"70-79","population":32819},{"state":"PR","age":"70-79","population":268783},{"state":"AL","age":"≥80","population":174781},{"state":"AK","age":"≥80","population":12503},{"state":"AZ","age":"≥80","population":254716},{"state":"AR","age":"≥80","population":113468},{"state":"CA","age":"≥80","population":1311374},{"state":"CO","age":"≥80","population":155175},{"state":"CT","age":"≥80","population":159475},{"state":"DE","age":"≥80","population":35937},{"state":"DC","age":"≥80","population":19658},{"state":"FL","age":"≥80","population":1019566},{"state":"GA","age":"≥80","population":269182},{"state":"HI","age":"≥80","population":66060},{"state":"ID","age":"≥80","population":54234},{"state":"IL","age":"≥80","population":478948},{"state":"IN","age":"≥80","population":243131},{"state":"IA","age":"≥80","population":143583},{"state":"KS","age":"≥80","population":117637},{"state":"KY","age":"≥80","population":155074},{"state":"LA","age":"≥80","population":152063},{"state":"ME","age":"≥80","population":62007},{"state":"MD","age":"≥80","population":208079},{"state":"MA","age":"≥80","population":288408},{"state":"MI","age":"≥80","population":398303},{"state":"MN","age":"≥80","population":215985},{"state":"MS","age":"≥80","population":100689},{"state":"MO","age":"≥80","population":242554},{"state":"MT","age":"≥80","population":41920},{"state":"NE","age":"≥80","population":78504},{"state":"NV","age":"≥80","population":82273},{"state":"NH","age":"≥80","population":52552},{"state":"NJ","age":"≥80","population":367432},{"state":"NM","age":"≥80","population":74393},{"state":"NY","age":"≥80","population":804091},{"state":"NC","age":"≥80","population":342497},{"state":"ND","age":"≥80","population":32206},{"state":"OH","age":"≥80","population":481890},{"state":"OK","age":"≥80","population":138055},{"state":"OR","age":"≥80","population":157153},{"state":"PA","age":"≥80","population":615069},{"state":"RI","age":"≥80","population":51021},{"state":"SC","age":"≥80","population":166727},{"state":"SD","age":"≥80","population":38540},{"state":"TN","age":"≥80","population":227483},{"state":"TX","age":"≥80","population":732179},{"state":"UT","age":"≥80","population":70711},{"state":"VT","age":"≥80","population":26656},{"state":"VA","age":"≥80","population":274606},{"state":"WA","age":"≥80","population":242589},{"state":"WV","age":"≥80","population":79201},{"state":"WI","age":"≥80","population":241747},{"state":"WY","age":"≥80","population":19682},{"state":"PR","age":"≥80","population":148963}];

const chart = StackedBarChart(stateages, {
  x: d => d.state,
  y: d => d.population / 1e6,
  z: d => d.age,
  xDomain: d3.groupSort(stateages, D => d3.sum(D, d => -d.population), d => d.state),
  yLabel: "↑ Population (millions)",
  zDomain: ages,
  colors: d3.schemeSpectral[ages.length],
  width,
  height: 500
});

document.body.appendChild(chart);

// Copyright 2021 Observable, Inc.
// Released under the ISC license.
// https://observablehq.com/@d3/stacked-bar-chart
function StackedBarChart(data, {
  x = (d, i) => i, // given d in data, returns the (ordinal) x-value
  y = d => d, // given d in data, returns the (quantitative) y-value
  z = () => 1, // given d in data, returns the (categorical) z-value
  title, // given d in data, returns the title text
  marginTop = 30, // top margin, in pixels
  marginRight = 0, // right margin, in pixels
  marginBottom = 30, // bottom margin, in pixels
  marginLeft = 40, // left margin, in pixels
  width = 640, // outer width, in pixels
  height = 400, // outer height, in pixels
  xDomain, // array of x-values
  xRange = [marginLeft, width - marginRight], // [left, right]
  xPadding = 0.1, // amount of x-range to reserve to separate bars
  yType = d3.scaleLinear, // type of y-scale
  yDomain, // [ymin, ymax]
  yRange = [height - marginBottom, marginTop], // [bottom, top]
  zDomain, // array of z-values
  offset = d3.stackOffsetDiverging, // stack offset method
  order = d3.stackOrderNone, // stack order method
  yFormat, // a format specifier string for the y-axis
  yLabel, // a label for the y-axis
  colors = d3.schemeTableau10, // array of colors
} = {}) {
  // Compute values.
  const X = d3.map(data, x);
  const Y = d3.map(data, y);
  const Z = d3.map(data, z);

  // Compute default x- and z-domains, and unique them.
  if (xDomain === undefined) xDomain = X;
  if (zDomain === undefined) zDomain = Z;
  xDomain = new d3.InternSet(xDomain);
  zDomain = new d3.InternSet(zDomain);

  // Omit any data not present in the x- and z-domains.
  const I = d3.range(X.length).filter(i => xDomain.has(X[i]) && zDomain.has(Z[i]));

  // Compute a nested array of series where each series is [[y1, y2], [y1, y2],
  // [y1, y2], …] representing the y-extent of each stacked rect. In addition,
  // each tuple has an i (index) property so that we can refer back to the
  // original data point (data[i]). This code assumes that there is only one
  // data point for a given unique x- and z-value.
  const series = d3.stack()
      .keys(zDomain)
      .value(([x, I], z) => Y[I.get(z)])
      .order(order)
      .offset(offset)
    (d3.rollup(I, ([i]) => i, i => X[i], i => Z[i]))
    .map(s => s.map(d => Object.assign(d, {i: d.data[1].get(s.key)})));

  // Compute the default y-domain. Note: diverging stacks can be negative.
  if (yDomain === undefined) yDomain = d3.extent(series.flat(2));

  // Construct scales, axes, and formats.
  const xScale = d3.scaleBand(xDomain, xRange).paddingInner(xPadding);
  const yScale = yType(yDomain, yRange);
  const color = d3.scaleOrdinal(zDomain, colors);
  const xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
  const yAxis = d3.axisLeft(yScale).ticks(height / 60, yFormat);

  // Compute titles.
  if (title === undefined) {
    const formatValue = yScale.tickFormat(100, yFormat);
    title = i => `${X[i]}\n${Z[i]}\n${formatValue(Y[i])}`;
  } else {
    const O = d3.map(data, d => d);
    const T = title;
    title = i => T(O[i], i, data);
  }

  const svg = d3.create("svg")
      .attr("width", width)
      .attr("height", height)
      .attr("viewBox", [0, 0, width, height])
      .attr("style", "max-width: 100%; height: auto; height: intrinsic;");

  svg.append("g")
      .attr("transform", `translate(${marginLeft},0)`)
      .call(yAxis)
      .call(g => g.select(".domain").remove())
      .call(g => g.selectAll(".tick line").clone()
          .attr("x2", width - marginLeft - marginRight)
          .attr("stroke-opacity", 0.1))
      .call(g => g.append("text")
          .attr("x", -marginLeft)
          .attr("y", 10)
          .attr("fill", "currentColor")
          .attr("text-anchor", "start")
          .text(yLabel));

  const bar = svg.append("g")
    .selectAll("g")
    .data(series)
    .join("g")
      .attr("fill", ([{i}]) => color(Z[i]))
    .selectAll("rect")
    .data(d => d)
    .join("rect")
      .attr("x", ({i}) => xScale(X[i]))
      .attr("y", ([y1, y2]) => Math.min(yScale(y1), yScale(y2)))
      .attr("height", ([y1, y2]) => Math.abs(yScale(y1) - yScale(y2)))
      .attr("width", xScale.bandwidth());

  if (title) bar.append("title")
      .text(({i}) => title(i));

  svg.append("g")
      .attr("transform", `translate(0,${yScale(0)})`)
      .call(xAxis);

  return Object.assign(svg.node(), {scales: {color}});
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.