{"spec_id":"area-stacked-percent","library":"chartjs","language":"javascript","code":"// anyplot.ai\n// area-stacked-percent: 100% Stacked Area Chart\n// Library: chartjs 4.4.7 | JavaScript 22.23.2\n// Quality: 92/100 | Created: 2026-09-02\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Smartphone OS market share, 2015-2024 — raw unit counts normalized to a\n// percentage of the yearly total so every stack sums to exactly 100%.\nconst years = [2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024];\nconst rawByCategory = {\n  Android: [713, 780, 850, 917, 965, 1001, 1027, 1041, 1057, 1072],\n  iOS: [161, 192, 231, 273, 315, 342, 362, 381, 400, 417],\n  \"Windows Phone\": [161, 120, 81, 39, 13, 3, 0, 0, 0, 0],\n  BlackBerry: [81, 66, 38, 20, 7, 0, 0, 0, 0, 0],\n  Other: [34, 42, 50, 51, 40, 34, 31, 28, 23, 21],\n};\n\nconst categories = Object.keys(rawByCategory);\nconst yearlyTotals = years.map((_, i) =>\n  categories.reduce((sum, cat) => sum + rawByCategory[cat][i], 0),\n);\nconst shareByCategory = {};\ncategories.forEach((cat) => {\n  shareByCategory[cat] = rawByCategory[cat].map(\n    (v, i) => (v / yearlyTotals[i]) * 100,\n  );\n});\n\nconst hexToRgba = (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 datasets = categories.map((cat, i) => ({\n  label: cat,\n  data: shareByCategory[cat],\n  backgroundColor: hexToRgba(t.palette[i % t.palette.length], 0.75),\n  borderColor: t.palette[i % t.palette.length],\n  // Dominant series (Android) gets a heavier stroke as the focal emphasis.\n  borderWidth: i === 0 ? 3 : 1.5,\n  pointRadius: 0,\n  // Straight segments guarantee the 100%-stacked bands never overshoot\n  // between the 10 sampled years (a spline could dip below 0 or over 100).\n  tension: 0,\n  fill: i === 0 ? \"origin\" : \"-1\",\n}));\n\n// --- Mount -------------------------------------------------------------------\nconst canvas = document.createElement(\"canvas\");\ndocument.getElementById(\"container\").appendChild(canvas);\n\n// --- Chart ---------------------------------------------------------------\nconst title =\n  \"Smartphone OS Market Share · area-stacked-percent · javascript · chartjs · anyplot.ai\";\n\nnew Chart(canvas, {\n  type: \"line\",\n  data: { labels: years, datasets },\n  options: {\n    responsive: true,\n    maintainAspectRatio: false,\n    animation: false,\n    interaction: { intersect: false, mode: \"index\" },\n    plugins: {\n      title: {\n        display: true,\n        text: title,\n        color: t.ink,\n        font: { size: 17, weight: \"500\" },\n        padding: { bottom: 6 },\n      },\n      subtitle: {\n        display: true,\n        text: \"Annual global shipment share across five platforms, 2015-2024\",\n        color: t.inkSoft,\n        font: { size: 13, weight: \"400\", style: \"italic\" },\n        padding: { bottom: 18 },\n      },\n      legend: {\n        position: \"bottom\",\n        labels: { color: t.ink, font: { size: 16 }, boxWidth: 20, padding: 16 },\n      },\n      filler: { propagate: false },\n    },\n    scales: {\n      x: {\n        title: { display: true, text: \"Year\", color: t.ink, font: { size: 16 } },\n        ticks: { color: t.inkSoft, font: { size: 14 } },\n        grid: { display: false },\n      },\n      y: {\n        stacked: true,\n        min: 0,\n        max: 100,\n        title: {\n          display: true,\n          text: \"Market Share (%)\",\n          color: t.ink,\n          font: { size: 16 },\n        },\n        ticks: {\n          color: t.inkSoft,\n          font: { size: 14 },\n          stepSize: 20,\n          callback: (value) => `${value}%`,\n        },\n        grid: { color: t.grid, borderDash: [3, 4] },\n      },\n    },\n  },\n});\n"}