{"spec_id":"line-reaction-coordinate","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// line-reaction-coordinate: Reaction Coordinate Energy Diagram\n// Library: highcharts 12.6.0 | JavaScript 22.22.3\n// Quality: 91/100 | Created: 2026-06-24\n\n//# anyplot-orientation: landscape\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (deterministic smooth energy profile via smoothstep) ---\n// Single-step exothermic: reactants=50 kJ/mol, TS=120 kJ/mol, products=20 kJ/mol\nconst energyData = [];\nfor (let i = 0; i <= 100; i++) {\n    let energy;\n    if (i <= 40) {\n        const s = i / 40;\n        energy = 50 + 70 * (3 * s * s - 2 * s * s * s);\n    } else {\n        const s = (i - 40) / 60;\n        energy = 120 - 100 * (3 * s * s - 2 * s * s * s);\n    }\n    energyData.push([i, parseFloat(energy.toFixed(3))]);\n}\n\n// --- Chart ---\nHighcharts.chart(\"container\", {\n    chart: {\n        type: \"spline\",\n        backgroundColor: \"transparent\",\n        animation: false,\n        style: { fontFamily: \"inherit\" },\n        margin: [70, 60, 80, 80],\n        plotBorderWidth: 0,\n        events: {\n            load: function () {\n                const chart = this;\n                const renderer = chart.renderer;\n                const xA = chart.xAxis[0];\n                const yA = chart.yAxis[0];\n\n                // Pixel positions for key energy levels\n                const y50  = yA.toPixels(50);\n                const y120 = yA.toPixels(120);\n                const y20  = yA.toPixels(20);\n\n                // Pixel positions for key x locations\n                const xLeft    = xA.toPixels(2);\n                const xPeak    = xA.toPixels(40);\n                const xRight   = xA.toPixels(88);\n                const eaX      = xA.toPixels(13);\n                const dhX      = xA.toPixels(74);\n\n                const ink = t.ink;\n                const soft = t.inkSoft;\n                const lw = 1.5;\n                const arrowSize = 6;\n\n                // --- Ea double-headed arrow (reactant level → TS peak) ---\n                renderer.path([\"M\", eaX, y50, \"L\", eaX, y120])\n                    .attr({ stroke: ink, \"stroke-width\": lw })\n                    .add();\n                // top arrowhead (pointing up toward TS)\n                renderer.path([\"M\", eaX - arrowSize, y120 + arrowSize * 1.5,\n                                \"L\", eaX, y120,\n                                \"L\", eaX + arrowSize, y120 + arrowSize * 1.5])\n                    .attr({ stroke: ink, \"stroke-width\": lw, fill: \"none\" })\n                    .add();\n                // bottom arrowhead (pointing down toward reactant)\n                renderer.path([\"M\", eaX - arrowSize, y50 - arrowSize * 1.5,\n                                \"L\", eaX, y50,\n                                \"L\", eaX + arrowSize, y50 - arrowSize * 1.5])\n                    .attr({ stroke: ink, \"stroke-width\": lw, fill: \"none\" })\n                    .add();\n                renderer.text(\"Ea = 70 kJ/mol\", eaX + 9, (y50 + y120) / 2 + 5)\n                    .css({ color: ink, fontSize: \"13px\", fontFamily: \"inherit\" })\n                    .add();\n\n                // --- ΔH double-headed arrow (reactant level → product level) ---\n                renderer.path([\"M\", dhX, y50, \"L\", dhX, y20])\n                    .attr({ stroke: ink, \"stroke-width\": lw })\n                    .add();\n                // top arrowhead (pointing up toward reactant)\n                renderer.path([\"M\", dhX - arrowSize, y50 + arrowSize * 1.5,\n                                \"L\", dhX, y50,\n                                \"L\", dhX + arrowSize, y50 + arrowSize * 1.5])\n                    .attr({ stroke: ink, \"stroke-width\": lw, fill: \"none\" })\n                    .add();\n                // bottom arrowhead (pointing down toward products)\n                renderer.path([\"M\", dhX - arrowSize, y20 - arrowSize * 1.5,\n                                \"L\", dhX, y20,\n                                \"L\", dhX + arrowSize, y20 - arrowSize * 1.5])\n                    .attr({ stroke: ink, \"stroke-width\": lw, fill: \"none\" })\n                    .add();\n                renderer.text(\"ΔH = −30 kJ/mol\", dhX + 9, (y50 + y20) / 2 + 5)\n                    .css({ color: ink, fontSize: \"13px\", fontFamily: \"inherit\" })\n                    .add();\n\n                // --- Direct labels ---\n                renderer.text(\"Reactants\", xLeft, y50 - 30)\n                    .css({ color: ink, fontSize: \"14px\", fontWeight: \"600\", fontFamily: \"inherit\" })\n                    .add();\n                renderer.text(\"50 kJ/mol\", xLeft, y50 - 17)\n                    .css({ color: soft, fontSize: \"12px\", fontFamily: \"inherit\" })\n                    .add();\n\n                renderer.text(\"Transition State\", xPeak + 8, y120 - 14)\n                    .css({ color: ink, fontSize: \"14px\", fontWeight: \"600\", fontFamily: \"inherit\" })\n                    .add();\n                renderer.text(\"120 kJ/mol\", xPeak + 8, y120 - 1)\n                    .css({ color: soft, fontSize: \"12px\", fontFamily: \"inherit\" })\n                    .add();\n\n                renderer.text(\"Products\", xRight + 5, y20 - 30)\n                    .css({ color: ink, fontSize: \"14px\", fontWeight: \"600\", fontFamily: \"inherit\" })\n                    .add();\n                renderer.text(\"20 kJ/mol\", xRight + 5, y20 - 17)\n                    .css({ color: soft, fontSize: \"12px\", fontFamily: \"inherit\" })\n                    .add();\n            }\n        }\n    },\n    credits: { enabled: false },\n    colors: t.palette,\n    title: {\n        text: \"line-reaction-coordinate · javascript · highcharts · anyplot.ai\",\n        style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" }\n    },\n    xAxis: {\n        title: {\n            text: \"Reaction Coordinate\",\n            style: { color: t.inkSoft, fontSize: \"16px\" }\n        },\n        lineColor: t.inkSoft,\n        tickLength: 0,\n        tickPositions: [],\n        min: 0,\n        max: 100,\n        labels: { enabled: false }\n    },\n    yAxis: {\n        title: {\n            text: \"Potential Energy (kJ/mol)\",\n            style: { color: t.inkSoft, fontSize: \"16px\" }\n        },\n        gridLineColor: t.grid,\n        lineColor: t.inkSoft,\n        labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n        min: 0,\n        max: 145,\n        tickInterval: 20,\n        plotLines: [\n            {\n                value: 50,\n                color: t.inkSoft,\n                dashStyle: \"ShortDash\",\n                width: 1.5,\n                zIndex: 3\n            },\n            {\n                value: 20,\n                color: t.inkSoft,\n                dashStyle: \"ShortDash\",\n                width: 1.5,\n                zIndex: 3\n            }\n        ]\n    },\n    legend: { enabled: false },\n    tooltip: { enabled: false },\n    plotOptions: {\n        series: {\n            animation: false,\n            lineWidth: 3,\n            marker: { enabled: false }\n        }\n    },\n    series: [{\n        type: \"areaspline\",\n        name: \"Potential Energy\",\n        data: energyData,\n        color: t.palette[0],\n        fillColor: \"rgba(0,158,115,0.10)\",\n        threshold: null\n    }]\n});\n"}