{"spec_id":"bump-basic","library":"muix","language":"javascript","code":"// anyplot.ai\n// bump-basic: Basic Bump Chart\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 90/100 | Created: 2026-08-24\n\nimport { LineChart } from \"@mui/x-charts/LineChart\";\nimport { useXScale, useYScale } from \"@mui/x-charts/hooks\";\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data: programming-language popularity rank by year, 2018-2025 ----------\n// Each year column is a permutation of 1..6 (one rank per language).\nconst YEARS = [\"2018\", \"2019\", \"2020\", \"2021\", \"2022\", \"2023\", \"2024\", \"2025\"];\n\nconst LANGUAGES = [\n  { name: \"JavaScript\", ranks: [1, 1, 1, 2, 2, 2, 2, 2] },\n  { name: \"Python\", ranks: [3, 2, 2, 1, 1, 1, 1, 1] },\n  { name: \"Java\", ranks: [2, 3, 4, 4, 5, 5, 6, 6] },\n  { name: \"TypeScript\", ranks: [6, 6, 5, 5, 4, 3, 3, 3] },\n  { name: \"Go\", ranks: [5, 5, 6, 6, 6, 6, 5, 4] },\n  { name: \"Rust\", ranks: [4, 4, 3, 3, 3, 4, 4, 5] },\n];\n\n// Slugified id (no spaces) so per-series CSS selectors stay valid.\nconst slug = (name) => name.replace(/\\s+/g, \"-\");\n\nconst series = LANGUAGES.map((lang, i) => ({\n  id: slug(lang.name),\n  data: lang.ranks,\n  label: lang.name,\n  color: t.palette[i],\n  showMark: true,\n  curve: \"monotoneX\",\n}));\n\n// Direct end-of-line labels replace the legend — with 6 close hues, naming\n// each line right where it finishes is a clearer identity cue than a\n// color-matching exercise against a corner legend.\nfunction EndLabels() {\n  const xScale = useXScale();\n  const yScale = useYScale();\n  const xEnd = xScale(YEARS[YEARS.length - 1]);\n\n  return (\n    <g fontFamily=\"'Roboto','Helvetica Neue',Arial,sans-serif\" fontSize={14}>\n      {LANGUAGES.map((lang, i) => (\n        <text\n          key={lang.name}\n          x={xEnd + 14}\n          y={yScale(lang.ranks[lang.ranks.length - 1])}\n          textAnchor=\"start\"\n          dominantBaseline=\"middle\"\n          fill={t.palette[i]}\n          fontWeight={500}\n        >\n          {lang.name}\n        </text>\n      ))}\n    </g>\n  );\n}\n\nconst TITLE = \"Language Popularity Rankings · bump-basic · javascript · muix · anyplot.ai\";\nconst TITLE_FONT_SIZE = Math.round(22 * Math.min(1, 67 / TITLE.length));\nconst TITLE_H = 70;\n\nexport default function Chart() {\n  const { width, height } = window.ANYPLOT_SIZE;\n\n  return (\n    <div style={{ width, height, background: t.pageBg, boxSizing: \"border-box\" }}>\n      <div style={{ height: TITLE_H, display: \"flex\", alignItems: \"center\", paddingLeft: 28 }}>\n        <span\n          style={{\n            color: t.ink,\n            fontSize: TITLE_FONT_SIZE,\n            fontWeight: 500,\n            fontFamily: \"'Roboto','Helvetica Neue',Arial,sans-serif\",\n            letterSpacing: 0.3,\n          }}\n        >\n          {TITLE}\n        </span>\n      </div>\n\n      <LineChart\n        width={width}\n        height={height - TITLE_H}\n        skipAnimation\n        margin={{ top: 30, bottom: 70, left: 90, right: 140 }}\n        xAxis={[\n          {\n            scaleType: \"point\",\n            data: YEARS,\n            label: \"Year\",\n            labelStyle: { fontSize: 16, fill: t.ink },\n            tickLabelStyle: { fontSize: 14, fill: t.inkSoft },\n          },\n        ]}\n        yAxis={[\n          {\n            min: 1,\n            max: 6,\n            reverse: true,\n            tickNumber: 6,\n            valueFormatter: (v) => `#${Math.round(v)}`,\n            label: \"Rank\",\n            labelStyle: { fontSize: 16, fill: t.ink },\n            tickLabelStyle: { fontSize: 14, fill: t.inkSoft },\n          },\n        ]}\n        series={series}\n        grid={{ horizontal: true, vertical: false }}\n        slotProps={{ legend: { hidden: true } }}\n        sx={{\n          \"& .MuiLineElement-root\": { strokeWidth: 3 },\n          \"& .MuiMarkElement-root\": { r: 5, stroke: t.pageBg, strokeWidth: 2 },\n          \"& .MuiChartsAxis-line\": { stroke: t.inkSoft },\n          \"& .MuiChartsAxis-tick\": { stroke: t.inkSoft },\n          \"& .MuiChartsGrid-line\": { stroke: t.grid },\n        }}\n      >\n        <EndLabels />\n      </LineChart>\n    </div>\n  );\n}\n"}