{"spec_id":"bullet-basic","library":"muix","language":"javascript","code":"// anyplot.ai\n// bullet-basic: Basic Bullet Chart\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 91/100 | Created: 2026-08-24\nimport { BarChart } from \"@mui/x-charts/BarChart\";\nimport { ChartsReferenceLine } from \"@mui/x-charts/ChartsReferenceLine\";\n\nconst t = window.ANYPLOT_TOKENS;\nconst SIZE = window.ANYPLOT_SIZE;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Quarterly KPI dashboard: actual performance vs. target, banded by\n// poor / satisfactory / good qualitative ranges (Stephen Few's design).\nconst kpis = [\n  { label: \"Quarterly Revenue ($M)\", actual: 82, target: 90, ranges: [50, 75, 100] },\n  { label: \"New Customers Acquired\", actual: 145, target: 130, ranges: [80, 120, 160] },\n  { label: \"Support SLA Compliance (%)\", actual: 96, target: 95, ranges: [85, 95, 100] },\n  { label: \"Project Milestones (%)\", actual: 68, target: 80, ranges: [40, 70, 100] },\n];\n\nconst hexToRgba = (hex, alpha) => {\n  const int = parseInt(hex.slice(1), 16);\n  const r = (int >> 16) & 255;\n  const g = (int >> 8) & 255;\n  const b = int & 255;\n  return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n};\n\n// Grayscale range-band shading (darkest = poor, lightest = good) per spec notes.\nconst BAND_COLORS = [hexToRgba(t.ink, 0.26), hexToRgba(t.ink, 0.15), hexToRgba(t.ink, 0.08)];\nconst BAR_COLOR = t.palette[0]; // brand green — the measure, identical across every bullet\n\n// --- Layout constants (CSS px within the mount's coordinate space) ---------\n// BAND_HEIGHT occupies most of each row (denser, space-efficient dashboard\n// block per the spec's own framing) instead of a thin band lost in tall rows.\nconst PADDING = 40;\nconst TITLE_HEIGHT = 40;\nconst KEY_HEIGHT = 24;\nconst ROW_GAP = 14;\nconst LABEL_WIDTH = 300;\nconst VALUE_WIDTH = 150;\nconst BAND_HEIGHT = 110;\n\nconst rowAreaHeight =\n  SIZE.height - PADDING * 2 - TITLE_HEIGHT - KEY_HEIGHT - ROW_GAP * (kpis.length + 1);\nconst rowHeight = rowAreaHeight / kpis.length;\nconst chartWidth = SIZE.width - PADDING * 2 - LABEL_WIDTH - VALUE_WIDTH;\n\nfunction Bullet({ kpi }) {\n  const maxRange = kpi.ranges[2];\n  const bands = [kpi.ranges[0], kpi.ranges[1] - kpi.ranges[0], kpi.ranges[2] - kpi.ranges[1]];\n\n  return (\n    <div style={{ display: \"flex\", alignItems: \"center\", height: rowHeight, gap: 20 }}>\n      <div\n        style={{\n          width: LABEL_WIDTH,\n          textAlign: \"right\",\n          color: t.ink,\n          fontSize: 16,\n          fontWeight: 500,\n          paddingRight: 8,\n        }}\n      >\n        {kpi.label}\n      </div>\n      <div style={{ position: \"relative\", width: chartWidth, height: BAND_HEIGHT }}>\n        {/* Background: stacked qualitative range bands, grayscale, full band height */}\n        <BarChart\n          width={chartWidth}\n          height={BAND_HEIGHT}\n          layout=\"horizontal\"\n          series={bands.map((value, i) => ({ data: [value], stack: \"range\", color: BAND_COLORS[i] }))}\n          xAxis={[{ scaleType: \"linear\", min: 0, max: maxRange }]}\n          yAxis={[{ scaleType: \"band\", data: [\"\"], categoryGapRatio: 0.08 }]}\n          margin={{ top: 0, bottom: 0, left: 0, right: 0 }}\n          bottomAxis={null}\n          leftAxis={null}\n          slotProps={{ legend: { hidden: true } }}\n          tooltip={{ trigger: \"none\" }}\n          skipAnimation\n        />\n        {/* Foreground: thin actual-value bar plus the target reference line */}\n        <div style={{ position: \"absolute\", top: 0, left: 0 }}>\n          <BarChart\n            width={chartWidth}\n            height={BAND_HEIGHT}\n            layout=\"horizontal\"\n            series={[{ data: [kpi.actual], color: BAR_COLOR }]}\n            xAxis={[{ scaleType: \"linear\", min: 0, max: maxRange }]}\n            yAxis={[{ scaleType: \"band\", data: [\"\"], categoryGapRatio: 0.6 }]}\n            margin={{ top: 0, bottom: 0, left: 0, right: 0 }}\n            bottomAxis={null}\n            leftAxis={null}\n            slotProps={{ legend: { hidden: true } }}\n            tooltip={{ trigger: \"none\" }}\n            skipAnimation\n          >\n            <ChartsReferenceLine\n              x={kpi.target}\n              lineStyle={{ stroke: t.ink, strokeWidth: 3 }}\n              label={`${kpi.target}`}\n              labelStyle={{ fill: t.ink, fontSize: 11, fontWeight: 600 }}\n              labelAlign=\"end\"\n            />\n          </BarChart>\n        </div>\n      </div>\n      <div style={{ width: VALUE_WIDTH, color: t.inkSoft, fontSize: 15 }}>\n        {kpi.actual} / {kpi.target}\n      </div>\n    </div>\n  );\n}\n\n// --- Chart (default-exported component — the harness mounts it) ------------\nexport default function Chart() {\n  return (\n    <div\n      style={{\n        width: SIZE.width,\n        height: SIZE.height,\n        padding: PADDING,\n        boxSizing: \"border-box\",\n        display: \"flex\",\n        flexDirection: \"column\",\n      }}\n    >\n      <div style={{ height: TITLE_HEIGHT, color: t.ink, fontSize: 22, fontWeight: 500 }}>\n        bullet-basic · javascript · muix · anyplot.ai\n      </div>\n      <div\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          height: KEY_HEIGHT,\n          marginTop: ROW_GAP,\n          marginLeft: LABEL_WIDTH + 20,\n          gap: 20,\n          fontSize: 13,\n          color: t.inkSoft,\n        }}\n      >\n        {[\"Poor\", \"Satisfactory\", \"Good\"].map((name, i) => (\n          <div key={name} style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n            <span style={{ width: 12, height: 12, background: BAND_COLORS[i], borderRadius: 2 }} />\n            {name}\n          </div>\n        ))}\n        <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n          <span style={{ width: 2, height: 12, background: t.ink }} />\n          Target\n        </div>\n      </div>\n      <div style={{ display: \"flex\", flexDirection: \"column\", gap: ROW_GAP, marginTop: ROW_GAP }}>\n        {kpis.map((kpi) => (\n          <Bullet key={kpi.label} kpi={kpi} />\n        ))}\n      </div>\n    </div>\n  );\n}\n"}