{"spec_id":"bar-stacked","library":"chartjs","language":"javascript","code":"// anyplot.ai\n// bar-stacked: Stacked Bar Chart\n// Library: chartjs 4.4.7 | JavaScript 22.23.2\n// Quality: 88/100 | Created: 2026-09-02\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Monthly energy consumption by source (GWh) — renewables rising, gas falling.\nconst months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"];\nconst solar = [18, 22, 30, 38, 45, 50];\nconst wind = [35, 32, 28, 25, 20, 18];\nconst hydro = [40, 38, 36, 34, 32, 30];\nconst naturalGas = [52, 48, 44, 38, 30, 22];\nconst totals = months.map(\n  (_, i) => solar[i] + wind[i] + hydro[i] + naturalGas[i]\n);\n\n// --- Mount -------------------------------------------------------------------\nconst canvas = document.createElement(\"canvas\");\ndocument.getElementById(\"container\").appendChild(canvas);\n\n// --- Total-above-stack labels (own plugin, no external dependency) ----------\nconst totalLabelsPlugin = {\n  id: \"totalLabels\",\n  afterDatasetsDraw(chart) {\n    const {\n      ctx,\n      data,\n      scales: { x: xScale, y: yScale },\n    } = chart;\n    ctx.save();\n    ctx.fillStyle = t.ink;\n    ctx.font = \"600 15px sans-serif\";\n    ctx.textAlign = \"center\";\n    ctx.textBaseline = \"bottom\";\n    data.labels.forEach((_, i) => {\n      const total = data.datasets.reduce((sum, ds) => sum + ds.data[i], 0);\n      const xPixel = xScale.getPixelForValue(i);\n      const yPixel = yScale.getPixelForValue(total);\n      ctx.fillText(`${total} GWh`, xPixel, yPixel - 8);\n    });\n    ctx.restore();\n  },\n};\n\n// --- Chart --------------------------------------------------------------------\nnew Chart(canvas, {\n  type: \"bar\",\n  data: {\n    labels: months,\n    datasets: [\n      {\n        label: \"Solar\",\n        data: solar,\n        backgroundColor: t.palette[0],\n        stack: \"energy\",\n        borderColor: t.pageBg,\n        borderWidth: 1,\n      },\n      {\n        label: \"Wind\",\n        data: wind,\n        backgroundColor: t.palette[1],\n        stack: \"energy\",\n        borderColor: t.pageBg,\n        borderWidth: 1,\n      },\n      {\n        label: \"Hydro\",\n        data: hydro,\n        backgroundColor: t.palette[2],\n        stack: \"energy\",\n        borderColor: t.pageBg,\n        borderWidth: 1,\n      },\n      {\n        label: \"Natural Gas\",\n        data: naturalGas,\n        backgroundColor: t.palette[3],\n        stack: \"energy\",\n        borderColor: t.pageBg,\n        borderWidth: 1,\n      },\n    ],\n  },\n  plugins: [totalLabelsPlugin],\n  options: {\n    responsive: true,\n    maintainAspectRatio: false,\n    animation: false,\n    layout: { padding: { top: 30 } },\n    plugins: {\n      title: {\n        display: true,\n        text: \"bar-stacked · javascript · chartjs · anyplot.ai\",\n        color: t.ink,\n        font: { size: 27 },\n      },\n      legend: {\n        position: \"top\",\n        labels: { color: t.ink, font: { size: 16 } },\n      },\n    },\n    scales: {\n      x: {\n        stacked: true,\n        categoryPercentage: 0.8,\n        barPercentage: 0.6,\n        ticks: { color: t.inkSoft, font: { size: 14 } },\n        grid: { display: false },\n        title: {\n          display: true,\n          text: \"Month\",\n          color: t.ink,\n          font: { size: 16 },\n        },\n      },\n      y: {\n        stacked: true,\n        beginAtZero: true,\n        suggestedMax: Math.max(...totals) * 1.15,\n        ticks: { color: t.inkSoft, font: { size: 14 } },\n        grid: { color: t.grid },\n        title: {\n          display: true,\n          text: \"Energy Consumption (GWh)\",\n          color: t.ink,\n          font: { size: 16 },\n        },\n      },\n    },\n  },\n});\n"}