{"spec_id":"parallel-basic","library":"muix","language":"javascript","code":"// anyplot.ai\n// parallel-basic: Basic Parallel Coordinates Plot\n// Library: muix 7.29.1 | JavaScript 22.23.1\n// Quality: 92/100 | Created: 2026-07-24\nimport { ChartContainer } from \"@mui/x-charts/ChartContainer\";\nimport { useXScale, useDrawingArea } from \"@mui/x-charts/hooks\";\n\nconst t = window.ANYPLOT_TOKENS;\nconst FONT = \"Inter, system-ui, -apple-system, sans-serif\";\n\n// --- Data: 30 model-training runs across 3 architectures, compared on 5 -----\n// hyperparameter/performance dimensions. Each dimension keeps its own native\n// scale (batch size, layer count, dropout %, accuracy %, minutes) — that is\n// the whole point of a parallel-coordinates plot: it lets very differently\n// scaled variables sit side by side without forcing a shared axis.\nfunction makeLcg(seed) {\n  let state = seed >>> 0;\n  return () => {\n    state = (state * 1664525 + 1013904223) >>> 0;\n    return state / 4294967296;\n  };\n}\nconst rand = makeLcg(20260724);\n\nconst DIMENSIONS = [\n  { key: \"batch\", label: \"Batch Size\", min: 16, max: 256, format: (v) => `${Math.round(v)}` },\n  { key: \"layers\", label: \"Hidden Layers\", min: 1, max: 8, format: (v) => `${Math.round(v)}` },\n  { key: \"dropout\", label: \"Dropout (%)\", min: 0, max: 50, format: (v) => `${v.toFixed(0)}%` },\n  { key: \"accuracy\", label: \"Val Accuracy (%)\", min: 60, max: 99, format: (v) => `${v.toFixed(0)}%` },\n  { key: \"time\", label: \"Train Time (min)\", min: 5, max: 180, format: (v) => `${Math.round(v)}` },\n];\n\n// Fractional (0–1) centers per dimension, per architecture — the source of\n// the clustering pattern the plot is meant to reveal.\nconst ARCHITECTURES = [\n  { name: \"CNN\", color: t.palette[0], count: 10, centers: [0.35, 0.5, 0.25, 0.65, 0.4] },\n  { name: \"RNN\", color: t.palette[1], count: 10, centers: [0.25, 0.35, 0.55, 0.35, 0.7] },\n  { name: \"Transformer\", color: t.palette[2], count: 10, centers: [0.75, 0.8, 0.35, 0.85, 0.85] },\n];\n\nfunction withAlpha(hex, alpha) {\n  const r = parseInt(hex.slice(1, 3), 16);\n  const g = parseInt(hex.slice(3, 5), 16);\n  const b = parseInt(hex.slice(5, 7), 16);\n  return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nconst RUNS = [];\nARCHITECTURES.forEach((arch) => {\n  for (let i = 0; i < arch.count; i += 1) {\n    const values = DIMENSIONS.map((dim, d) => {\n      const jitter = (rand() - 0.5) * 0.36;\n      const fraction = Math.min(1, Math.max(0, arch.centers[d] + jitter));\n      return dim.min + fraction * (dim.max - dim.min);\n    });\n    RUNS.push({ architecture: arch.name, color: arch.color, values });\n  }\n});\n\n// --- Custom marks — drawn on the MUI X coordinate system --------------------\n// @mui/x-charts has no native parallel-coordinates chart, so the axes and\n// connecting lines are drawn directly with useXScale/useDrawingArea, the same\n// low-level building blocks ChartsAxis/ChartsGrid use internally. The x-axis\n// (dimension index → pixel) comes from a genuine x-charts linear scale; the\n// y position per dimension is computed by hand since each axis has its own\n// independent value domain, which no single x-charts y-axis can express.\n\nfunction ParallelAxes() {\n  const xScale = useXScale();\n  const { top, height } = useDrawingArea();\n  return (\n    <g fontFamily={FONT}>\n      {DIMENSIONS.map((dim, i) => {\n        const x = xScale(i);\n        return (\n          <g key={dim.key}>\n            <line x1={x} y1={top} x2={x} y2={top + height} stroke={t.inkSoft} strokeWidth={1.5} />\n            {[0, 0.5, 1].map((f) => {\n              const y = top + height * (1 - f);\n              const value = dim.min + f * (dim.max - dim.min);\n              return (\n                <g key={f}>\n                  <line x1={x - 6} y1={y} x2={x + 6} y2={y} stroke={t.inkSoft} strokeWidth={1.5} />\n                  <text x={x + 10} y={y} fontSize={13} fill={t.inkSoft} dominantBaseline=\"middle\">\n                    {dim.format(value)}\n                  </text>\n                </g>\n              );\n            })}\n            <text x={x} y={top - 18} fontSize={15} fontWeight={600} fill={t.ink} textAnchor=\"middle\">\n              {dim.label}\n            </text>\n          </g>\n        );\n      })}\n    </g>\n  );\n}\n\nfunction ParallelLines() {\n  const xScale = useXScale();\n  const { top, height } = useDrawingArea();\n  const yFor = (dimIndex, value) => {\n    const dim = DIMENSIONS[dimIndex];\n    const fraction = (value - dim.min) / (dim.max - dim.min);\n    return top + height * (1 - fraction);\n  };\n  return (\n    <g fill=\"none\" strokeWidth={1.6}>\n      {RUNS.map((run, i) => {\n        const points = run.values.map((v, d) => `${xScale(d)},${yFor(d, v)}`).join(\" \");\n        return <polyline key={i} points={points} stroke={withAlpha(run.color, 0.55)} />;\n      })}\n    </g>\n  );\n}\n\nfunction Legend() {\n  return (\n    <g fontFamily={FONT}>\n      {ARCHITECTURES.map((arch, i) => (\n        <g key={arch.name} transform={`translate(${i * 170}, 0)`}>\n          <circle cx={7} cy={7} r={7} fill={arch.color} />\n          <text x={20} y={12} fontSize={15} fill={t.ink}>\n            {arch.name}\n          </text>\n        </g>\n      ))}\n    </g>\n  );\n}\n\nconst TITLE_H = 64;\n\nexport default function Chart() {\n  const W = window.ANYPLOT_SIZE.width;\n  const H = window.ANYPLOT_SIZE.height;\n  const N = DIMENSIONS.length;\n\n  return (\n    <div\n      style={{\n        width: W,\n        height: H,\n        background: t.pageBg,\n        fontFamily: FONT,\n        display: \"flex\",\n        flexDirection: \"column\",\n      }}\n    >\n      <div\n        style={{\n          height: TITLE_H,\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"space-between\",\n          padding: \"0 90px\",\n        }}\n      >\n        <span style={{ fontSize: 22, fontWeight: 600, color: t.ink }}>\n          parallel-basic · javascript · muix · anyplot.ai\n        </span>\n        <svg width={ARCHITECTURES.length * 170} height={20}>\n          <Legend />\n        </svg>\n      </div>\n      <ChartContainer\n        width={W}\n        height={H - TITLE_H}\n        skipAnimation\n        series={[]}\n        margin={{ top: 70, right: 90, bottom: 40, left: 90 }}\n        xAxis={[{ scaleType: \"linear\", min: 0, max: N - 1 }]}\n        yAxis={[{ scaleType: \"linear\", min: 0, max: 1 }]}\n      >\n        <ParallelAxes />\n        <ParallelLines />\n      </ChartContainer>\n    </div>\n  );\n}\n"}