{"spec_id":"line-filled","library":"chartjs","language":"javascript","code":"// anyplot.ai\n// line-filled: Filled Line Plot\n// Library: chartjs 4.4.7 | JavaScript 22.23.2\n// Quality: 92/100 | Created: 2026-09-05\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Daily active users over a 30-day product launch window.\nlet seed = 42;\nfunction lcg() {\n  seed = (seed * 1664525 + 1013904223) % 4294967296;\n  return seed / 4294967296;\n}\n\nconst days = Array.from({ length: 30 }, (_, i) => i + 1);\nconst dailyActiveUsers = [];\nlet level = 2400;\nfor (let i = 0; i < days.length; i++) {\n  level += 180 + (lcg() - 0.35) * 260;\n  level = Math.max(level, 1800);\n  let value = Math.round(level);\n  // Weekend-style lull around day 20 breaks the otherwise steady climb.\n  if (days[i] === 20) value = Math.round(value * 0.9);\n  dailyActiveUsers.push(value);\n}\nconst peakIndex = dailyActiveUsers.length - 1;\n\n// --- Mount -------------------------------------------------------------------\nconst canvas = document.createElement(\"canvas\");\ndocument.getElementById(\"container\").appendChild(canvas);\n\n// --- Chart ---------------------------------------------------------------------\nconst title = \"line-filled · javascript · chartjs · anyplot.ai\";\n\n// Vertical gradient: brand green at the line fading to transparent at the baseline.\nfunction fillGradient(context) {\n  const { chart } = context;\n  const { ctx, chartArea } = chart;\n  if (!chartArea) return t.palette[0] + \"4D\";\n  const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);\n  gradient.addColorStop(0, t.palette[0] + \"80\");\n  gradient.addColorStop(1, t.palette[0] + \"00\");\n  return gradient;\n}\n\nnew Chart(canvas, {\n  type: \"line\",\n  data: {\n    labels: days,\n    datasets: [\n      {\n        label: \"Daily active users\",\n        data: dailyActiveUsers,\n        borderColor: t.palette[0],\n        backgroundColor: fillGradient,\n        borderWidth: 3.5,\n        borderCapStyle: \"round\",\n        borderJoinStyle: \"round\",\n        fill: \"origin\",\n        pointRadius: (context) => (context.dataIndex === peakIndex ? 6 : 0),\n        pointHoverRadius: 0,\n        pointBackgroundColor: t.palette[0],\n        pointBorderColor: t.pageBg,\n        pointBorderWidth: 2,\n        tension: 0.25,\n      },\n    ],\n  },\n  options: {\n    responsive: true,\n    maintainAspectRatio: false,\n    animation: false,\n    layout: { padding: { top: 8, right: 28, bottom: 4, left: 4 } },\n    plugins: {\n      title: { display: true, text: title, color: t.ink, font: { size: 22, weight: \"500\" } },\n      legend: { display: false },\n    },\n    scales: {\n      x: {\n        title: { display: true, text: \"Day since launch\", color: t.ink, font: { size: 16 } },\n        ticks: { color: t.inkSoft, font: { size: 14 }, maxTicksLimit: 10 },\n        grid: { display: false },\n      },\n      y: {\n        title: { display: true, text: \"Daily active users\", color: t.ink, font: { size: 16 } },\n        ticks: { color: t.inkSoft, font: { size: 14 } },\n        grid: { color: t.grid },\n        beginAtZero: true,\n      },\n    },\n  },\n});\n"}