{"spec_id":"dot-matrix-proportional","library":"chartjs","language":"javascript","code":"// anyplot.ai\n// dot-matrix-proportional: Dot Matrix Chart for Proportional Counts\n// Library: chartjs 4.4.7 | JavaScript 22.23.2\n// Quality: 91/100 | Created: 2026-09-05\n\n//# anyplot-orientation: square\nconst t = window.ANYPLOT_TOKENS;\n// Theme-adaptive \"muted\" semantic anchor (default-style-guide.md) — the\n// browser harness token set does not expose it, so it is derived here.\nconst MUTED = t.theme === \"light\" ? \"#6B6A63\" : \"#A8A79F\";\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Survey: \"Should the city expand the downtown bike-lane network?\"\nconst total = 100;\nconst cols = 10;\nconst rows = 10;\nconst categories = [\n  { label: \"Agreed\", count: 47, color: t.palette[0] }, // positive sentiment -> brand green\n  { label: \"Disagreed\", count: 34, color: t.palette[4] }, // negative sentiment -> semantic red\n  { label: \"No opinion\", count: 19, color: MUTED }, // neutral sentiment -> muted anchor\n];\n\n// Assign each of the `total` grid cells to a category, filled in category\n// order, left-to-right then top-to-bottom.\nconst dotIndexToCategory = new Array(total);\nlet cursor = 0;\ncategories.forEach((cat, catIndex) => {\n  for (let i = 0; i < cat.count; i += 1) {\n    dotIndexToCategory[cursor] = catIndex;\n    cursor += 1;\n  }\n});\n\nconst datasets = categories.map((cat, catIndex) => {\n  const points = [];\n  for (let i = 0; i < total; i += 1) {\n    if (dotIndexToCategory[i] !== catIndex) continue;\n    const row = Math.floor(i / cols);\n    const col = i % cols;\n    points.push({ x: col, y: rows - 1 - row });\n  }\n  return {\n    label: `${cat.label} (${cat.count})`,\n    data: points,\n    backgroundColor: cat.color,\n    borderColor: t.pageBg,\n    borderWidth: 1.5,\n    pointStyle: \"circle\",\n    pointRadius: 30,\n    pointHoverRadius: 30,\n  };\n});\n\n// --- Mount -------------------------------------------------------------------\nconst canvas = document.createElement(\"canvas\");\ndocument.getElementById(\"container\").appendChild(canvas);\n\n// --- Chart ---------------------------------------------------------------\nnew Chart(canvas, {\n  type: \"scatter\",\n  data: { datasets },\n  options: {\n    responsive: true,\n    maintainAspectRatio: false,\n    animation: false,\n    layout: { padding: { top: 8, bottom: 8, left: 8, right: 8 } },\n    plugins: {\n      title: {\n        display: true,\n        text: \"dot-matrix-proportional · javascript · chartjs · anyplot.ai\",\n        color: t.ink,\n        font: { size: 22 },\n        padding: { bottom: 20 },\n      },\n      legend: {\n        display: true,\n        position: \"bottom\",\n        labels: {\n          color: t.ink,\n          font: { size: 16 },\n          usePointStyle: true,\n          padding: 24,\n        },\n      },\n      tooltip: { enabled: false },\n    },\n    scales: {\n      x: {\n        type: \"linear\",\n        min: -0.7,\n        max: cols - 0.3,\n        display: false,\n      },\n      y: {\n        type: \"linear\",\n        min: -0.7,\n        max: rows - 0.3,\n        display: false,\n      },\n    },\n  },\n});\n"}