{"spec_id":"qq-basic","library":"muix","language":"javascript","code":"// anyplot.ai\n// qq-basic: Basic Q-Q Plot\n// Library: muix 7.29.1 | JavaScript 22.23.1\n// Quality: 90/100 | Created: 2026-07-24\n\nimport { ChartContainer } from \"@mui/x-charts/ChartContainer\";\nimport { ScatterPlot } from \"@mui/x-charts/ScatterChart\";\nimport { ChartsXAxis } from \"@mui/x-charts/ChartsXAxis\";\nimport { ChartsYAxis } from \"@mui/x-charts/ChartsYAxis\";\nimport { ChartsGrid } from \"@mui/x-charts/ChartsGrid\";\nimport { useXScale, useYScale } from \"@mui/x-charts/hooks\";\n\nconst t = window.ANYPLOT_TOKENS;\nconst { width, height } = window.ANYPLOT_SIZE;\n\n// Deterministic LCG (seed 42) — no Math.random() in browser harness\nlet _seed = 42;\nfunction lcg() {\n  _seed = (1664525 * _seed + 1013904223) >>> 0;\n  return _seed / 4294967296;\n}\nfunction randn() {\n  const u = lcg(), v = lcg();\n  return Math.sqrt(-2 * Math.log(u + 1e-15)) * Math.cos(2 * Math.PI * v);\n}\n\n// Inverse standard-normal CDF (Acklam's rational approximation, |err| < 1.15e-9)\nfunction invNorm(p) {\n  const a = [-3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00];\n  const b = [-5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01];\n  const c = [-7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00];\n  const d = [7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00];\n  const pLow = 0.02425;\n  if (p < pLow) {\n    const q = Math.sqrt(-2 * Math.log(p));\n    return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) /\n      ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n  }\n  if (p <= 1 - pLow) {\n    const q = p - 0.5, r = q * q;\n    return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q /\n      (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);\n  }\n  const q = Math.sqrt(-2 * Math.log(1 - p));\n  return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) /\n    ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}\n\n// Order-fulfillment time (hours), right-skewed lognormal process — a classic\n// \"does this follow a Normal distribution\" QC question. Deliberately non-normal\n// so the plot demonstrates a real curvature away from the diagonal.\nconst N = 60;\nconst MU = 3.4, SIGMA = 0.35;\nconst rawSample = Array.from({ length: N }, () => Math.exp(MU + SIGMA * randn()));\nconst sorted = [...rawSample].sort((x, y) => x - y);\n\nconst mean = sorted.reduce((s, v) => s + v, 0) / N;\nconst variance = sorted.reduce((s, v) => s + (v - mean) ** 2, 0) / (N - 1);\nconst std = Math.sqrt(variance);\n\n// Blom plotting positions, standardized sample quantiles so a perfectly Normal\n// sample lands exactly on y = x.\nconst points = sorted.map((v, i) => {\n  const p = (i + 1 - 0.375) / (N + 0.25);\n  const x = invNorm(p);\n  const y = (v - mean) / std;\n  return { x, y, id: i };\n});\n\nconst allValues = points.flatMap((pt) => [pt.x, pt.y]);\nconst rangeMin = Math.min(...allValues);\nconst rangeMax = Math.max(...allValues);\nconst pad = (rangeMax - rangeMin) * 0.08;\nconst axMin = rangeMin - pad;\nconst axMax = rangeMax + pad;\n\n// Diagonal y = x reference line — rendered via MUI X axis scale hooks\nfunction ReferenceLine() {\n  const xScale = useXScale();\n  const yScale = useYScale();\n  if (!xScale || !yScale) return null;\n  return (\n    <line\n      x1={xScale(axMin)} y1={yScale(axMin)}\n      x2={xScale(axMax)} y2={yScale(axMax)}\n      stroke={t.ink}\n      strokeWidth={2.5}\n      strokeDasharray=\"10,8\"\n      opacity={0.5}\n    />\n  );\n}\n\nconst series = [\n  {\n    type: \"scatter\",\n    id: \"sample\",\n    label: \"Sample vs. Normal\",\n    color: t.palette[0],\n    markerSize: 9,\n    data: points,\n  },\n];\n\nconst TITLE = \"qq-basic · javascript · muix · anyplot.ai\";\nconst MARGIN = { top: 80, right: 60, bottom: 96, left: 110 };\n\nexport default function Chart() {\n  return (\n    <ChartContainer\n      width={width}\n      height={height}\n      margin={MARGIN}\n      series={series}\n      xAxis={[{\n        scaleType: \"linear\",\n        min: axMin,\n        max: axMax,\n        label: \"Theoretical Quantiles\",\n        tickLabelStyle: { fontSize: 14, fill: t.inkSoft },\n        labelStyle: { fontSize: 16, fill: t.ink },\n      }]}\n      yAxis={[{\n        scaleType: \"linear\",\n        min: axMin,\n        max: axMax,\n        label: \"Sample Quantiles\",\n        tickLabelStyle: { fontSize: 14, fill: t.inkSoft },\n        labelStyle: { fontSize: 16, fill: t.ink },\n      }]}\n    >\n      <ChartsGrid horizontal vertical />\n      <ReferenceLine />\n      <ScatterPlot skipAnimation />\n      <ChartsXAxis />\n      <ChartsYAxis />\n      {/* L-frame: mask top and right spines with background color */}\n      <line\n        x1={MARGIN.left - 1} y1={MARGIN.top}\n        x2={width - MARGIN.right + 1} y2={MARGIN.top}\n        stroke={t.pageBg}\n        strokeWidth={3}\n      />\n      <line\n        x1={width - MARGIN.right} y1={MARGIN.top - 1}\n        x2={width - MARGIN.right} y2={height - MARGIN.bottom + 1}\n        stroke={t.pageBg}\n        strokeWidth={3}\n      />\n      {/* Title */}\n      <text\n        x={width / 2}\n        y={36}\n        textAnchor=\"middle\"\n        fontSize={22}\n        fontWeight={600}\n        fill={t.ink}\n      >\n        {TITLE}\n      </text>\n      {/* Subtitle */}\n      <text\n        x={width / 2}\n        y={58}\n        textAnchor=\"middle\"\n        fontSize={14}\n        fill={t.inkSoft}\n      >\n        Order fulfillment time (n = 60, standardized) vs. Normal — upper-tail curvature reveals right skew\n      </text>\n      {/* Reference-line caption */}\n      <text\n        x={width - MARGIN.right - 14}\n        y={MARGIN.top + 28}\n        textAnchor=\"end\"\n        fontSize={14}\n        fill={t.inkSoft}\n      >\n        {\"– – –  y = x  (perfect Normal fit)\"}\n      </text>\n    </ChartContainer>\n  );\n}\n"}