{"spec_id":"recurrence-basic","library":"muix","language":"javascript","code":"// anyplot.ai\n// recurrence-basic: Recurrence Plot for Nonlinear Time Series\n// Library: muix 7.29.1 | JavaScript 22.22.3\n// Quality: 87/100 | Created: 2026-06-10\n//# anyplot-orientation: square\n// anyplot.ai\n// recurrence-basic: Recurrence Plot for Nonlinear Time Series\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-06-10\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 { useDrawingArea } from \"@mui/x-charts/hooks\";\n\nconst t = window.ANYPLOT_TOKENS;\n\n// Logistic map — chaotic regime (r = 3.95), deterministic seed via fixed start\nconst N = 300;\nconst r = 3.95;\nconst ts: number[] = [0.4];\nfor (let i = 1; i < N; i++) {\n  ts.push(r * ts[i - 1] * (1 - ts[i - 1]));\n}\n\n// Time-delay embedding: state[i] = [ts[i], ts[i + tau]] (Takens' theorem)\nconst tau = 5;\nconst M = N - tau;\nconst states = Array.from({ length: M }, (_, i) => [ts[i], ts[i + tau]]);\n\n// Binary recurrence: pairs (i, j) where Euclidean distance < epsilon\nconst epsilon = 0.15;\nconst recPts: { x: number; y: number; id: number }[] = [];\nlet ptId = 0;\nfor (let i = 0; i < M; i++) {\n  for (let j = 0; j < M; j++) {\n    const dx = states[i][0] - states[j][0];\n    const dy = states[i][1] - states[j][1];\n    if (dx * dx + dy * dy < epsilon * epsilon) {\n      recPts.push({ x: i, y: j, id: ptId++ });\n    }\n  }\n}\n\nconst TITLE_H = 56;\n\n// Annotated identity line (i = j) — drawn via useDrawingArea hook in SVG space.\n// In MUI X linear scatter axes, data (0,0) maps to SVG (left, top+height) and\n// data (M-1, M-1) maps to SVG (left+width, top), so this diagonal is exact.\nfunction IdentityLine() {\n  const { left, top, width, height } = useDrawingArea();\n  const labelX = left + width * 0.87;\n  const labelY = top + height * 0.07;\n  return (\n    <g>\n      <line\n        x1={left}\n        y1={top + height}\n        x2={left + width}\n        y2={top}\n        stroke={t.amber}\n        strokeWidth={2}\n        strokeDasharray=\"9 5\"\n        opacity={0.8}\n      />\n      <text\n        x={labelX}\n        y={labelY}\n        fill={t.amber}\n        textAnchor=\"middle\"\n        opacity={0.9}\n        style={{ fontSize: 12, fontFamily: \"Inter, system-ui, sans-serif\", fontWeight: 500 }}\n      >\n        i = j\n      </text>\n    </g>\n  );\n}\n\nexport default function Chart() {\n  const W = window.ANYPLOT_SIZE.width;\n  const H = window.ANYPLOT_SIZE.height;\n  const side = H - TITLE_H;\n\n  return (\n    <div\n      style={{\n        width: W,\n        height: H,\n        background: t.pageBg,\n        fontFamily: \"Inter, system-ui, sans-serif\",\n        display: \"flex\",\n        flexDirection: \"column\",\n        alignItems: \"center\",\n      }}\n    >\n      <div\n        style={{\n          height: TITLE_H,\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"center\",\n        }}\n      >\n        <span style={{ fontSize: 22, fontWeight: 600, color: t.ink }}>\n          recurrence-basic · javascript · muix · anyplot.ai\n        </span>\n      </div>\n      <ChartContainer\n        width={side}\n        height={side}\n        skipAnimation\n        colors={[t.palette[0]]}\n        margin={{ top: 15, bottom: 72, left: 80, right: 25 }}\n        series={[\n          {\n            type: \"scatter\",\n            data: recPts,\n            markerSize: 2,\n            label: \"Recurrent\",\n          },\n        ]}\n        xAxis={[\n          {\n            min: 0,\n            max: M - 1,\n            label: \"Time Index i\",\n            tickLabelStyle: { fontSize: 11 },\n            labelStyle: { fontSize: 13 },\n          },\n        ]}\n        yAxis={[\n          {\n            min: 0,\n            max: M - 1,\n            label: \"Time Index j\",\n            tickLabelStyle: { fontSize: 11 },\n            labelStyle: { fontSize: 13 },\n          },\n        ]}\n        sx={{\n          \"& .MuiChartsLegend-root\": { display: \"none\" },\n          \"& .MuiChartsAxis-line\": { display: \"none\" },\n          \"& .MuiChartsGrid-line\": { stroke: t.grid, strokeWidth: 1 },\n        }}\n      >\n        <ChartsGrid vertical horizontal />\n        <ScatterPlot />\n        <ChartsXAxis />\n        <ChartsYAxis />\n        <IdentityLine />\n      </ChartContainer>\n    </div>\n  );\n}\n"}