{"spec_id":"datamatrix-basic","library":"muix","language":"javascript","code":"// anyplot.ai\n// datamatrix-basic: Basic Data Matrix 2D Barcode\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 87/100 | Created: 2026-09-02\n//# anyplot-orientation: square\n// anyplot.ai\n// datamatrix-basic: Basic Data Matrix 2D Barcode\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-02\nimport { ChartContainer } from \"@mui/x-charts/ChartContainer\";\nimport { useDrawingArea } from \"@mui/x-charts/hooks\";\n\nconst t = window.ANYPLOT_TOKENS;\nconst TITLE = \"datamatrix-basic · javascript · muix · anyplot.ai\";\n\n// --- Data (in-memory, deterministic): part serial number for a small item ---\nconst CONTENT = \"PCB-SN:48291X7A\";\nconst MODULE_COUNT = 24; // ISO/IEC 16022 valid square symbol size\nconst QUIET_ZONE = 2; // modules of blank margin (spec requires >= 1)\nconst CAPTION = `Encodes \"${CONTENT}\" · ${MODULE_COUNT}×${MODULE_COUNT} modules · ECC 200`;\nconst TITLE_HEIGHT = 64;\nconst CAPTION_HEIGHT = 48;\nconst OUTER_MARGIN = 40; // page-level breathing room above/below the card, balancing the horizontal margin from centering it in the full-width canvas\nconst CARD_PADDING = 32; // uniform inset on all four sides between the card edge and the matrix's own quiet zone\n\n// FNV-1a hash — used only to seed the deterministic filler LCG below.\nfunction hashString(text) {\n  let hash = 2166136261;\n  for (let i = 0; i < text.length; i++) {\n    hash ^= text.charCodeAt(i);\n    hash = Math.imul(hash, 16777619);\n  }\n  return hash >>> 0;\n}\n\n// Packs the content's bits first, then fills remaining capacity with a\n// fixed-seed LCG so the pattern is fully reproducible across renders.\nfunction encodeBits(text, capacity) {\n  const bits = [];\n  for (let i = 0; i < text.length && bits.length < capacity; i++) {\n    const code = text.charCodeAt(i);\n    for (let shift = 7; shift >= 0 && bits.length < capacity; shift--) {\n      bits.push((code >> shift) & 1);\n    }\n  }\n  let state = hashString(text) || 1;\n  while (bits.length < capacity) {\n    state = (Math.imul(state, 1103515245) + 12345) >>> 0;\n    bits.push((state >>> 16) & 1);\n  }\n  return bits;\n}\n\n// Builds the module grid: a solid L-shaped finder (left column + bottom row),\n// an alternating clock track (top row + right column) for timing reference,\n// and a data region carrying the encoded content.\nfunction buildMatrix(text, size) {\n  const grid = Array.from({ length: size }, () => new Array(size).fill(0));\n\n  for (let r = 0; r < size; r++) grid[r][0] = 1;\n  for (let c = 0; c < size; c++) grid[size - 1][c] = 1;\n  for (let c = 1; c < size; c++) grid[0][c] = c % 2 === 1 ? 1 : 0;\n  for (let r = 1; r < size - 1; r++) grid[r][size - 1] = r % 2 === 1 ? 1 : 0;\n\n  const dataBits = encodeBits(text, (size - 2) * (size - 2));\n  let bitIndex = 0;\n  for (let r = 1; r < size - 1; r++) {\n    for (let c = 1; c < size - 1; c++) {\n      grid[r][c] = dataBits[bitIndex++];\n    }\n  }\n  return grid;\n}\n\nconst GRID = buildMatrix(CONTENT, MODULE_COUNT);\n\n// --- Module squares, drawn directly in pixel space from the drawing area ---\n// ScatterChart's marker is a fixed-radius circle, unsuited to gapless square\n// modules — plain rects sized to the drawing area's own pitch tile exactly.\nfunction DataMatrixModules() {\n  const { left, top, width } = useDrawingArea();\n  const totalUnits = MODULE_COUNT + QUIET_ZONE * 2;\n  const cellSize = width / totalUnits;\n\n  const modules = [];\n  for (let r = 0; r < MODULE_COUNT; r++) {\n    for (let c = 0; c < MODULE_COUNT; c++) {\n      if (!GRID[r][c]) continue;\n      modules.push(\n        <rect\n          key={`${r}-${c}`}\n          x={left + (QUIET_ZONE + c) * cellSize}\n          y={top + (QUIET_ZONE + r) * cellSize}\n          width={cellSize + 0.6}\n          height={cellSize + 0.6}\n          fill={t.palette[0]}\n        />,\n      );\n    }\n  }\n  return <g>{modules}</g>;\n}\n\nexport default function Chart() {\n  const size = window.ANYPLOT_SIZE;\n  const cardSide = Math.min(\n    size.width,\n    size.height - TITLE_HEIGHT - CAPTION_HEIGHT - OUTER_MARGIN * 2,\n  );\n  const matrixSide = cardSide - CARD_PADDING * 2;\n\n  return (\n    <div\n      style={{\n        width: size.width,\n        height: size.height,\n        display: \"flex\",\n        flexDirection: \"column\",\n      }}\n    >\n      <div\n        style={{\n          height: TITLE_HEIGHT,\n          lineHeight: `${TITLE_HEIGHT}px`,\n          paddingLeft: 24,\n          fontSize: 22,\n          fontWeight: 500,\n          color: t.ink,\n        }}\n      >\n        {TITLE}\n      </div>\n      <div\n        style={{\n          flex: 1,\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"center\",\n        }}\n      >\n        <div\n          style={{\n            width: cardSide,\n            height: cardSide,\n            boxSizing: \"border-box\",\n            padding: CARD_PADDING,\n            backgroundColor: t.elevatedBg,\n            border: `1px solid ${t.grid}`,\n            borderRadius: 20,\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n          }}\n        >\n          <ChartContainer\n            width={matrixSide}\n            height={matrixSide}\n            series={[]}\n            margin={{ top: 0, right: 0, bottom: 0, left: 0 }}\n            skipAnimation\n          >\n            <DataMatrixModules />\n          </ChartContainer>\n        </div>\n      </div>\n      <div\n        style={{\n          height: CAPTION_HEIGHT,\n          lineHeight: `${CAPTION_HEIGHT}px`,\n          textAlign: \"center\",\n          fontSize: 16,\n          color: t.inkSoft,\n        }}\n      >\n        {CAPTION}\n      </div>\n    </div>\n  );\n}\n"}