{"spec_id":"bar-feature-importance","library":"muix","language":"javascript","code":"// anyplot.ai\n// bar-feature-importance: Feature Importance Bar Chart\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 93/100 | Created: 2026-09-02\nimport { BarChart } from \"@mui/x-charts/BarChart\";\nimport { useDrawingArea, useXScale, useYScale } from \"@mui/x-charts/hooks\";\nimport { Box, Typography } from \"@mui/material\";\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Feature importances from a random forest regressor predicting wine quality\n// (UCI Wine Quality dataset), sorted descending so the most influential\n// feature renders first.\nconst features = [\n  \"Alcohol\",\n  \"Sulphates\",\n  \"Volatile Acidity\",\n  \"Total Sulfur Dioxide\",\n  \"Density\",\n  \"Chlorides\",\n  \"Citric Acid\",\n  \"Fixed Acidity\",\n  \"pH\",\n  \"Free Sulfur Dioxide\",\n  \"Residual Sugar\",\n];\nconst importance = [0.192, 0.134, 0.121, 0.095, 0.084, 0.069, 0.063, 0.058, 0.054, 0.049, 0.041];\n\nconst TITLE = \"bar-feature-importance · javascript · muix · anyplot.ai\";\nconst LEAD_RATIO = (importance[0] / importance[1]).toFixed(1);\nconst CALLOUT = `${features[0]} leads the ranking at ${importance[0].toFixed(3)} — ${LEAD_RATIO}× the next-highest driver.`;\n\n// Right-aligns the value just past each bar's tip (reading the real x/y\n// scales rather than the animated bar geometry, which still reports its\n// pre-mount \"from\" position during this synchronous render pass), falling\n// back to an inside-end placement when the bar runs close to the axis max\n// so the label never clips the canvas edge (spec asks for \"text\n// annotations at the end of bars\").\nfunction EndBarLabel({ dataIndex, className, children }) {\n  const xScale = useXScale();\n  const yScale = useYScale();\n  const drawingArea = useDrawingArea();\n  const value = importance[dataIndex];\n  if (value == null || !children) {\n    return null;\n  }\n  const barEnd = xScale(value);\n  const rowCenter = yScale(features[dataIndex]) + yScale.bandwidth() / 2;\n  const canvasRight = drawingArea.left + drawingArea.width + drawingArea.right;\n  const pad = 8;\n  const estimatedTextWidth = String(children).length * 9;\n  const fitsOutside = barEnd + pad + estimatedTextWidth <= canvasRight - 6;\n  return (\n    <text\n      x={fitsOutside ? barEnd + pad : barEnd - pad}\n      y={rowCenter}\n      textAnchor={fitsOutside ? \"start\" : \"end\"}\n      dominantBaseline=\"central\"\n      className={className}\n      style={{ fontSize: 13, fontWeight: 700, fill: t.ink }}\n    >\n      {children}\n    </text>\n  );\n}\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 = 76;\n  const chartWidth = size.width - padding.left - padding.right;\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: \"4px\", lineHeight: 1 }}>\n        {TITLE}\n      </Typography>\n      <Typography sx={{ fontSize: 14, color: t.inkSoft, mb: \"20px\", lineHeight: 1.3 }}>{CALLOUT}</Typography>\n      <BarChart\n        width={chartWidth}\n        height={chartHeight}\n        layout=\"horizontal\"\n        skipAnimation\n        borderRadius={5}\n        series={[\n          {\n            data: importance,\n            label: \"Feature importance\",\n            valueFormatter: (v) => (v === null ? \"\" : `${v.toFixed(3)} importance`),\n          },\n        ]}\n        xAxis={[\n          {\n            min: 0,\n            label: \"Importance Score\",\n            colorMap: {\n              type: \"continuous\",\n              min: Math.min(...importance),\n              max: Math.max(...importance),\n              color: [t.seq[0], t.seq[1]],\n            },\n            tickLabelStyle: { fontSize: 14 },\n            labelStyle: { fontSize: 16 },\n          },\n        ]}\n        yAxis={[\n          {\n            scaleType: \"band\",\n            data: features,\n            tickLabelStyle: { fontSize: 14 },\n          },\n        ]}\n        barLabel={(item) => (item.value === null ? \"\" : item.value.toFixed(3))}\n        slots={{ barLabel: EndBarLabel }}\n        grid={{ vertical: true }}\n        margin={{ left: 190, right: 64, top: 16, bottom: 56 }}\n        slotProps={{ legend: { hidden: true } }}\n        sx={{\n          \"& .MuiChartsAxis-line\": { stroke: t.grid },\n          \"& .MuiChartsGrid-line\": { strokeDasharray: \"4 3\" },\n        }}\n      />\n    </Box>\n  );\n}\n"}