{"spec_id":"line-arrhenius","library":"chartjs","language":"javascript","code":"// anyplot.ai\n// line-arrhenius: Arrhenius Plot for Reaction Kinetics\n// Library: chartjs 4.4.7 | JavaScript 22.22.3\n// Quality: 91/100 | Created: 2026-06-24\n\nconst t = window.ANYPLOT_TOKENS;\n\n// H₂O₂ decomposition over MnO₂ catalyst — experimental ln(k) vs 1/T\nconst temperatures = [300, 320, 340, 360, 380, 400, 425, 450, 475, 500, 525, 550];\nconst lnK = [0.01, 1.62, 3.59, 4.79, 6.41, 7.28, 8.85, 9.73, 11.13, 11.78, 12.88, 13.36];\nconst invT = temperatures.map(T => 1 / T);\n\n// Linear regression: slope = -Ea/R, intercept = ln(A)\nconst nn = invT.length;\nconst xm = invT.reduce((a, b) => a + b, 0) / nn;\nconst ym = lnK.reduce((a, b) => a + b, 0) / nn;\nconst slope = invT.reduce((s, x, i) => s + (x - xm) * (lnK[i] - ym), 0) /\n              invT.reduce((s, x) => s + (x - xm) ** 2, 0);\nconst intercept = ym - slope * xm;\n\n// R² and activation energy\nconst ssTot = lnK.reduce((s, y) => s + (y - ym) ** 2, 0);\nconst ssRes = invT.reduce((s, x, i) => s + (lnK[i] - (slope * x + intercept)) ** 2, 0);\nconst r2 = 1 - ssRes / ssTot;\nconst Ea_kJ = (-slope * 8.314 / 1000).toFixed(1);\n\n// x-axis bounds (slightly wider than data range)\nconst X_MIN = 1 / 565;\nconst X_MAX = 1 / 290;\n\nconst scatterData = invT.map((x, i) => ({ x, y: lnK[i] }));\nconst regLineData = [\n    { x: X_MIN, y: slope * X_MIN + intercept },\n    { x: X_MAX, y: slope * X_MAX + intercept },\n];\n\nconst canvas = document.createElement(\"canvas\");\ndocument.getElementById(\"container\").appendChild(canvas);\n\n// Inline annotation plugin: Ea/R and R² in bottom-left (away from data cluster)\nconst annotPlugin = {\n    id: \"annot\",\n    afterDraw(chart) {\n        const { ctx, chartArea: ca } = chart;\n        const line1 = `Eₐ/R = ${(-slope).toFixed(0)} K   →   Eₐ = ${Ea_kJ} kJ/mol`;\n        const line2 = `R² = ${r2.toFixed(4)}`;\n        const x = ca.left + 14;\n        const y1 = ca.bottom - 74;\n        const y2 = ca.bottom - 48;\n        ctx.save();\n        ctx.font = \"bold 14px sans-serif\";\n        const boxW = Math.max(ctx.measureText(line1).width, ctx.measureText(line2).width) + 18;\n        ctx.globalAlpha = 0.82;\n        ctx.fillStyle = t.elevatedBg;\n        ctx.fillRect(x - 6, y1 - 18, boxW, 62);\n        ctx.globalAlpha = 1;\n        ctx.fillStyle = t.ink;\n        ctx.textAlign = \"left\";\n        ctx.fillText(line1, x, y1);\n        ctx.fillText(line2, x, y2);\n        ctx.restore();\n    },\n};\n\nconst titleStr = \"line-arrhenius · javascript · chartjs · anyplot.ai\";\n\nnew Chart(canvas, {\n    data: {\n        datasets: [\n            {\n                type: \"line\",\n                label: \"Arrhenius fit\",\n                data: regLineData,\n                borderColor: t.palette[2],\n                borderWidth: 3.0,\n                backgroundColor: \"transparent\",\n                pointRadius: 0,\n                tension: 0,\n                fill: false,\n            },\n            {\n                type: \"scatter\",\n                label: \"Experimental ln(k)\",\n                data: scatterData,\n                backgroundColor: t.palette[0],\n                borderColor: t.pageBg,\n                borderWidth: 2,\n                pointRadius: 9,\n                pointHoverRadius: 11,\n            },\n        ],\n    },\n    options: {\n        responsive: true,\n        maintainAspectRatio: false,\n        animation: false,\n        layout: { padding: { top: 6, right: 24, bottom: 6, left: 8 } },\n        plugins: {\n            title: {\n                display: true,\n                text: titleStr,\n                color: t.ink,\n                font: { size: 22, weight: \"500\" },\n                padding: { top: 8, bottom: 12 },\n            },\n            legend: {\n                labels: {\n                    color: t.ink,\n                    font: { size: 14 },\n                    padding: 20,\n                    boxWidth: 30,\n                },\n            },\n        },\n        scales: {\n            x: {\n                type: \"linear\",\n                min: X_MIN,\n                max: X_MAX,\n                title: {\n                    display: true,\n                    text: \"1/T  (K⁻¹)\",\n                    color: t.ink,\n                    font: { size: 15 },\n                    padding: { top: 8 },\n                },\n                ticks: {\n                    color: t.inkSoft,\n                    font: { size: 13 },\n                    maxTicksLimit: 8,\n                    callback: (v) => v.toExponential(2),\n                },\n                grid: { color: t.grid },\n            },\n            y: {\n                title: {\n                    display: true,\n                    text: \"ln(k)\",\n                    color: t.ink,\n                    font: { size: 15 },\n                },\n                ticks: {\n                    color: t.inkSoft,\n                    font: { size: 13 },\n                },\n                grid: { color: t.grid },\n            },\n            x2: {\n                type: \"linear\",\n                position: \"top\",\n                min: X_MIN,\n                max: X_MAX,\n                title: {\n                    display: true,\n                    text: \"Temperature (K)\",\n                    color: t.ink,\n                    font: { size: 15 },\n                    padding: { bottom: 8 },\n                },\n                afterBuildTicks(scale) {\n                    scale.ticks = [550, 500, 450, 400, 360, 320, 300].map(T => ({ value: 1 / T }));\n                },\n                ticks: {\n                    color: t.inkSoft,\n                    font: { size: 13 },\n                    callback: (v) => `${Math.round(1 / v)}`,\n                },\n                grid: { display: false },\n                border: { display: false },\n            },\n        },\n    },\n    plugins: [annotPlugin],\n});\n"}