{"spec_id":"subplot-grid","library":"muix","language":"javascript","code":"// anyplot.ai\n// subplot-grid: Subplot Grid Layout\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 85/100 | Created: 2026-09-09\n//# anyplot-orientation: landscape\n// anyplot.ai\n// subplot-grid: Subplot Grid Layout\n// Library: MUI X Charts | React | Node 22\n// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope.\n// Quality: pending | Created: 2026-09-09\nimport { LineChart } from \"@mui/x-charts/LineChart\";\nimport { BarChart } from \"@mui/x-charts/BarChart\";\nimport { ScatterChart } from \"@mui/x-charts/ScatterChart\";\nimport { PieChart } from \"@mui/x-charts/PieChart\";\nimport { ChartsReferenceLine } from \"@mui/x-charts/ChartsReferenceLine\";\nimport { Box, Typography } from \"@mui/material\";\n\nconst t = window.ANYPLOT_TOKENS;\nconst W = window.ANYPLOT_SIZE.width;\nconst H = window.ANYPLOT_SIZE.height;\n\n// --- Layout (2x2 grid: figure title + 4 independent panels) ----------------\nconst FIGURE_TITLE_H = 48;\nconst OUTER_GAP = 16;\nconst CELL_GAP = 20;\nconst CELL_TITLE_H = 26;\nconst GRID_W = W - OUTER_GAP * 2;\nconst GRID_H = H - FIGURE_TITLE_H - OUTER_GAP * 2;\nconst CELL_W = (GRID_W - CELL_GAP) / 2;\nconst CELL_H = (GRID_H - CELL_GAP) / 2;\nconst CHART_H = CELL_H - CELL_TITLE_H;\n\n// --- Data (in-memory, deterministic LCG) ------------------------------------\nfunction makeRng(seed: number) {\n  let state = seed >>> 0;\n  return () => {\n    state = (state * 1664525 + 1013904223) >>> 0;\n    return state / 4294967296;\n  };\n}\nconst rng = makeRng(42);\n\nconst dayLabels = Array.from({ length: 18 }, (_, i) => `D${i + 1}`);\n\nlet price = 128;\nconst closingPrices = dayLabels.map(() => {\n  price += (rng() - 0.47) * 2.4;\n  return Math.round(price * 100) / 100;\n});\n\nconst peakPrice = Math.max(...closingPrices);\n\nconst tradingVolume = dayLabels.map(() => Math.round(420_000 + rng() * 380_000));\n\nconst priceVolumePoints = closingPrices.map((p, i) => ({\n  id: i,\n  x: tradingVolume[i],\n  y: p,\n}));\n\nconst sectorAllocation = [\n  { id: 0, value: 34, label: \"Technology\" },\n  { id: 1, value: 24, label: \"Healthcare\" },\n  { id: 2, value: 22, label: \"Financials\" },\n  { id: 3, value: 20, label: \"Energy\" },\n];\n\n// --- Chart (default-exported component — the harness mounts it) -----------\nexport default function Chart() {\n  return (\n    <Box\n      sx={{\n        width: W,\n        height: H,\n        bgcolor: \"transparent\",\n        display: \"flex\",\n        flexDirection: \"column\",\n        alignItems: \"center\",\n      }}\n    >\n      <Typography\n        sx={{\n          height: FIGURE_TITLE_H,\n          lineHeight: `${FIGURE_TITLE_H}px`,\n          fontSize: 22,\n          fontWeight: 600,\n          color: t.ink,\n        }}\n      >\n        subplot-grid · javascript · muix · anyplot.ai\n      </Typography>\n\n      <Box\n        sx={{\n          display: \"grid\",\n          gridTemplateColumns: `repeat(2, ${CELL_W}px)`,\n          gridTemplateRows: `repeat(2, ${CELL_H}px)`,\n          gap: `${CELL_GAP}px`,\n        }}\n      >\n        {/* Top-left: line chart — price trend, shares the day-index axis with volume */}\n        <Box>\n          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>\n            Closing Price (18 trading days)\n          </Typography>\n          <LineChart\n            width={CELL_W}\n            height={CHART_H}\n            colors={[t.palette[0]]}\n            skipAnimation\n            grid={{ horizontal: true }}\n            slotProps={{ legend: { hidden: true } }}\n            margin={{ left: 56, right: 16, top: 8, bottom: 40 }}\n            xAxis={[{ scaleType: \"point\", data: dayLabels, label: \"Trading Day\" }]}\n            yAxis={[{ label: \"Price ($)\" }]}\n            series={[{ data: closingPrices, label: \"Close\", showMark: false, curve: \"monotoneX\" }]}\n          >\n            <ChartsReferenceLine\n              y={peakPrice}\n              label={`Peak $${peakPrice.toFixed(2)}`}\n              labelAlign=\"end\"\n              lineStyle={{ stroke: t.amber, strokeDasharray: \"4 4\" }}\n              labelStyle={{ fill: t.amber, fontSize: 12, fontWeight: 600 }}\n            />\n          </LineChart>\n        </Box>\n\n        {/* Top-right: bar chart — volume, shares the day-index axis with price */}\n        <Box>\n          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>\n            Trading Volume, shares (18 trading days)\n          </Typography>\n          <BarChart\n            width={CELL_W}\n            height={CHART_H}\n            colors={[t.palette[0]]}\n            skipAnimation\n            grid={{ horizontal: true }}\n            slotProps={{ legend: { hidden: true } }}\n            margin={{ left: 56, right: 16, top: 8, bottom: 40 }}\n            xAxis={[{ scaleType: \"band\", data: dayLabels, label: \"Trading Day\" }]}\n            yAxis={[{ label: \"Volume (K)\", valueFormatter: (v: number) => `${Math.round(v / 1000)}` }]}\n            series={[{ data: tradingVolume, label: \"Volume\" }]}\n          />\n        </Box>\n\n        {/* Bottom-left: scatter chart — price vs. volume, fully independent axes */}\n        <Box>\n          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>\n            Price vs. Volume Correlation\n          </Typography>\n          <ScatterChart\n            width={CELL_W}\n            height={CHART_H}\n            colors={[t.palette[0]]}\n            skipAnimation\n            grid={{ horizontal: true, vertical: true }}\n            slotProps={{ legend: { hidden: true } }}\n            margin={{ left: 64, right: 20, top: 8, bottom: 40 }}\n            xAxis={[{ label: \"Volume (shares)\", valueFormatter: (v: number) => `${Math.round(v / 1000)}K` }]}\n            yAxis={[{ label: \"Price ($)\" }]}\n            series={[{ data: priceVolumePoints, markerSize: 9 }]}\n          />\n        </Box>\n\n        {/* Bottom-right: pie chart — sector allocation, independent, no cartesian axes */}\n        <Box>\n          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>\n            Portfolio Sector Allocation\n          </Typography>\n          <Box sx={{ display: \"flex\", alignItems: \"center\", height: CHART_H, gap: \"24px\" }}>\n            <PieChart\n              width={CHART_H}\n              height={CHART_H}\n              colors={t.palette}\n              skipAnimation\n              slotProps={{ legend: { hidden: true } }}\n              sx={{ \"& .MuiPieArcLabel-root\": { fill: \"#FFFFFF\", fontSize: 14, fontWeight: 600 } }}\n              series={[\n                {\n                  data: sectorAllocation,\n                  innerRadius: CHART_H * 0.17,\n                  outerRadius: CHART_H * 0.47,\n                  paddingAngle: 2,\n                  cx: CHART_H / 2,\n                  cy: CHART_H / 2,\n                  arcLabel: (item) => `${item.value}%`,\n                  arcLabelMinAngle: 15,\n                },\n              ]}\n            />\n            <Box sx={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n              {sectorAllocation.map((sector, i) => (\n                <Box key={sector.id} sx={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n                  <Box sx={{ width: 14, height: 14, borderRadius: \"3px\", bgcolor: t.palette[i] }} />\n                  <Typography sx={{ fontSize: 15, color: t.ink }}>{sector.label}</Typography>\n                </Box>\n              ))}\n            </Box>\n          </Box>\n        </Box>\n      </Box>\n    </Box>\n  );\n}\n"}