{"spec_id":"area-stacked-percent","library":"muix","language":"javascript","code":"// anyplot.ai\n// area-stacked-percent: 100% Stacked Area Chart\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 93/100 | Created: 2026-09-02\nimport { LineChart } from \"@mui/x-charts/LineChart\";\nimport { ChartsReferenceLine } from \"@mui/x-charts/ChartsReferenceLine\";\nimport { Box, Typography } from \"@mui/material\";\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Illustrative global electricity generation mix, 2010-2024 (TWh per source).\n// Solar and wind grow quadratically (falling technology cost curve), hydro and\n// nuclear stay roughly flat, fossil declines linearly — the energy-transition\n// story the 100% stacking is meant to surface.\nconst YEARS = Array.from({ length: 15 }, (_, i) => 2010 + i);\n\nconst solarTWh = YEARS.map((_, i) => 4 + Math.round(i * i * 1.6));\nconst windTWh = YEARS.map((_, i) => 15 + Math.round(i * i * 0.9));\nconst hydroTWh = YEARS.map((_, i) => 150 + i * 3);\nconst nuclearTWh = YEARS.map((_, i) => 260 - i * 2);\nconst fossilTWh = YEARS.map((_, i) => 680 - i * 18);\n\nconst totalByYear = YEARS.map(\n  (_, i) => solarTWh[i] + windTWh[i] + hydroTWh[i] + nuclearTWh[i] + fossilTWh[i],\n);\n\nconst shareValueFormatter = (value, { dataIndex }) =>\n  `${Math.round((value / totalByYear[dataIndex]) * 100)}% · ${value.toLocaleString()} TWh`;\n\n// Milestone year where fossil drops below half the generation mix — the\n// clearest single moment in the energy-transition story to call out.\nconst milestoneIndex = fossilTWh.findIndex((v, i) => v / totalByYear[i] < 0.5);\nconst milestoneYear = YEARS[milestoneIndex];\n\nconst TITLE = \"area-stacked-percent · javascript · muix · anyplot.ai\";\n\n// --- Chart (default-exported component — the harness mounts it) ------------\nexport default function Chart() {\n  const size = window.ANYPLOT_SIZE;\n  const padding = { top: 28, right: 40, bottom: 24, left: 40 };\n  const titleBlockHeight = 56;\n  // Hand-rotated axis label in its own flex column avoids MUI X's y-axis\n  // `label` offset (tuned for a fixed guessed tick width) colliding with the\n  // 3-character percent tick labels.\n  const yLabelWidth = 32;\n  const chartWidth = size.width - padding.left - padding.right - yLabelWidth;\n  const chartHeight = size.height - padding.top - padding.bottom - titleBlockHeight;\n\n  return (\n    <Box\n      sx={{\n        width: size.width,\n        height: size.height,\n        boxSizing: \"border-box\",\n        padding: `${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px`,\n        display: \"flex\",\n        flexDirection: \"column\",\n      }}\n    >\n      <Typography sx={{ fontSize: 22, fontWeight: 600, color: \"text.primary\", mb: \"20px\", lineHeight: 1 }}>\n        {TITLE}\n      </Typography>\n      <Box sx={{ display: \"flex\", flexDirection: \"row\", height: chartHeight }}>\n        <Box sx={{ width: yLabelWidth, display: \"flex\", alignItems: \"center\", justifyContent: \"center\" }}>\n          <Typography\n            sx={{\n              fontSize: 16,\n              color: \"text.secondary\",\n              whiteSpace: \"nowrap\",\n              transform: \"rotate(-90deg)\",\n            }}\n          >\n            Share of generation\n          </Typography>\n        </Box>\n        <LineChart\n          width={chartWidth}\n          height={chartHeight}\n          skipAnimation\n          margin={{ bottom: 112 }}\n          series={[\n            {\n              id: \"solar\",\n              label: \"Solar\",\n              data: solarTWh,\n              stack: \"mix\",\n              stackOffset: \"expand\",\n              area: true,\n              showMark: false,\n              color: t.palette[0],\n              valueFormatter: shareValueFormatter,\n            },\n            {\n              id: \"wind\",\n              label: \"Wind\",\n              data: windTWh,\n              stack: \"mix\",\n              stackOffset: \"expand\",\n              area: true,\n              showMark: false,\n              color: t.palette[1],\n              valueFormatter: shareValueFormatter,\n            },\n            {\n              id: \"hydro\",\n              label: \"Hydro\",\n              data: hydroTWh,\n              stack: \"mix\",\n              stackOffset: \"expand\",\n              area: true,\n              showMark: false,\n              color: t.palette[2],\n              valueFormatter: shareValueFormatter,\n            },\n            {\n              id: \"nuclear\",\n              label: \"Nuclear\",\n              data: nuclearTWh,\n              stack: \"mix\",\n              stackOffset: \"expand\",\n              area: true,\n              showMark: false,\n              color: t.palette[3],\n              valueFormatter: shareValueFormatter,\n            },\n            {\n              id: \"fossil\",\n              label: \"Fossil\",\n              data: fossilTWh,\n              stack: \"mix\",\n              stackOffset: \"expand\",\n              area: true,\n              showMark: false,\n              color: t.palette[4],\n              valueFormatter: shareValueFormatter,\n            },\n          ]}\n          xAxis={[\n            {\n              data: YEARS,\n              scaleType: \"point\",\n              label: \"Year\",\n              valueFormatter: (year) => `${year}`,\n              tickLabelStyle: { fontSize: 14 },\n              labelStyle: { fontSize: 14 },\n            },\n          ]}\n          yAxis={[\n            {\n              min: 0,\n              max: 1,\n              valueFormatter: (value) => `${Math.round(value * 100)}%`,\n              tickLabelStyle: { fontSize: 14 },\n            },\n          ]}\n          grid={{ horizontal: true }}\n          slotProps={{\n            legend: {\n              direction: \"row\",\n              position: { vertical: \"bottom\", horizontal: \"center\" },\n              labelStyle: { fontSize: 14 },\n              itemMarkWidth: 18,\n              itemMarkHeight: 10,\n              markGap: 8,\n            },\n          }}\n          sx={{\n            \"& .MuiLineElement-root\": { strokeWidth: 2.25 },\n            \"& .MuiAreaElement-root\": { fillOpacity: 0.9 },\n            \"& .MuiChartsGrid-line\": { strokeDasharray: \"4 3\" },\n          }}\n        >\n          <ChartsReferenceLine\n            x={milestoneYear}\n            label={`${milestoneYear}: fossil share drops below 50%`}\n            labelAlign=\"start\"\n            lineStyle={{ stroke: t.inkSoft, strokeWidth: 1.5, strokeDasharray: \"6 4\" }}\n            labelStyle={{ fontSize: 13, fontWeight: 600, fill: t.ink }}\n          />\n        </LineChart>\n      </Box>\n    </Box>\n  );\n}\n"}