Reaction Coordinate Energy Diagram in Highcharts (JavaScript)

The same plot in 14 other libraries — JavaScript: Chart.js, D3.js, Apache ECharts, MUI X Charts; Python: Altair, Bokeh, lets-plot, Matplotlib, Plotly, plotnine, Pygal, Seaborn; R: ggplot2; Julia: Makie.jl. Compare all 15 side by side: Reaction Coordinate Energy Diagram in Python, R, Julia and JavaScript.

A reaction coordinate diagram plots potential energy against reaction progress, showing the energy landscape of a chemical transformation. The smooth curve traces the path from reactants through the transition state (energy maximum) to products, clearly depicting the activation energy barrier and overall enthalpy change. This fundamental chemistry visualization is essential for understanding reaction kinetics and thermodynamics.

Reaction Coordinate Energy Diagram rendered with Highcharts

Renders

JavaScript source (Highcharts)

// anyplot.ai
// line-reaction-coordinate: Reaction Coordinate Energy Diagram
// Library: highcharts 12.6.0 | JavaScript 22.22.3
// Quality: 91/100 | Created: 2026-06-24

//# anyplot-orientation: landscape
const t = window.ANYPLOT_TOKENS;

// --- Data (deterministic smooth energy profile via smoothstep) ---
// Single-step exothermic: reactants=50 kJ/mol, TS=120 kJ/mol, products=20 kJ/mol
const energyData = [];
for (let i = 0; i <= 100; i++) {
    let energy;
    if (i <= 40) {
        const s = i / 40;
        energy = 50 + 70 * (3 * s * s - 2 * s * s * s);
    } else {
        const s = (i - 40) / 60;
        energy = 120 - 100 * (3 * s * s - 2 * s * s * s);
    }
    energyData.push([i, parseFloat(energy.toFixed(3))]);
}

// --- Chart ---
Highcharts.chart("container", {
    chart: {
        type: "spline",
        backgroundColor: "transparent",
        animation: false,
        style: { fontFamily: "inherit" },
        margin: [70, 60, 80, 80],
        plotBorderWidth: 0,
        events: {
            load: function () {
                const chart = this;
                const renderer = chart.renderer;
                const xA = chart.xAxis[0];
                const yA = chart.yAxis[0];

                // Pixel positions for key energy levels
                const y50  = yA.toPixels(50);
                const y120 = yA.toPixels(120);
                const y20  = yA.toPixels(20);

                // Pixel positions for key x locations
                const xLeft    = xA.toPixels(2);
                const xPeak    = xA.toPixels(40);
                const xRight   = xA.toPixels(88);
                const eaX      = xA.toPixels(13);
                const dhX      = xA.toPixels(74);

                const ink = t.ink;
                const soft = t.inkSoft;
                const lw = 1.5;
                const arrowSize = 6;

                // --- Ea double-headed arrow (reactant level → TS peak) ---
                renderer.path(["M", eaX, y50, "L", eaX, y120])
                    .attr({ stroke: ink, "stroke-width": lw })
                    .add();
                // top arrowhead (pointing up toward TS)
                renderer.path(["M", eaX - arrowSize, y120 + arrowSize * 1.5,
                                "L", eaX, y120,
                                "L", eaX + arrowSize, y120 + arrowSize * 1.5])
                    .attr({ stroke: ink, "stroke-width": lw, fill: "none" })
                    .add();
                // bottom arrowhead (pointing down toward reactant)
                renderer.path(["M", eaX - arrowSize, y50 - arrowSize * 1.5,
                                "L", eaX, y50,
                                "L", eaX + arrowSize, y50 - arrowSize * 1.5])
                    .attr({ stroke: ink, "stroke-width": lw, fill: "none" })
                    .add();
                renderer.text("Ea = 70 kJ/mol", eaX + 9, (y50 + y120) / 2 + 5)
                    .css({ color: ink, fontSize: "13px", fontFamily: "inherit" })
                    .add();

                // --- ΔH double-headed arrow (reactant level → product level) ---
                renderer.path(["M", dhX, y50, "L", dhX, y20])
                    .attr({ stroke: ink, "stroke-width": lw })
                    .add();
                // top arrowhead (pointing up toward reactant)
                renderer.path(["M", dhX - arrowSize, y50 + arrowSize * 1.5,
                                "L", dhX, y50,
                                "L", dhX + arrowSize, y50 + arrowSize * 1.5])
                    .attr({ stroke: ink, "stroke-width": lw, fill: "none" })
                    .add();
                // bottom arrowhead (pointing down toward products)
                renderer.path(["M", dhX - arrowSize, y20 - arrowSize * 1.5,
                                "L", dhX, y20,
                                "L", dhX + arrowSize, y20 - arrowSize * 1.5])
                    .attr({ stroke: ink, "stroke-width": lw, fill: "none" })
                    .add();
                renderer.text("ΔH = −30 kJ/mol", dhX + 9, (y50 + y20) / 2 + 5)
                    .css({ color: ink, fontSize: "13px", fontFamily: "inherit" })
                    .add();

                // --- Direct labels ---
                renderer.text("Reactants", xLeft, y50 - 30)
                    .css({ color: ink, fontSize: "14px", fontWeight: "600", fontFamily: "inherit" })
                    .add();
                renderer.text("50 kJ/mol", xLeft, y50 - 17)
                    .css({ color: soft, fontSize: "12px", fontFamily: "inherit" })
                    .add();

                renderer.text("Transition State", xPeak + 8, y120 - 14)
                    .css({ color: ink, fontSize: "14px", fontWeight: "600", fontFamily: "inherit" })
                    .add();
                renderer.text("120 kJ/mol", xPeak + 8, y120 - 1)
                    .css({ color: soft, fontSize: "12px", fontFamily: "inherit" })
                    .add();

                renderer.text("Products", xRight + 5, y20 - 30)
                    .css({ color: ink, fontSize: "14px", fontWeight: "600", fontFamily: "inherit" })
                    .add();
                renderer.text("20 kJ/mol", xRight + 5, y20 - 17)
                    .css({ color: soft, fontSize: "12px", fontFamily: "inherit" })
                    .add();
            }
        }
    },
    credits: { enabled: false },
    colors: t.palette,
    title: {
        text: "line-reaction-coordinate · javascript · highcharts · anyplot.ai",
        style: { color: t.ink, fontSize: "22px", fontWeight: "600" }
    },
    xAxis: {
        title: {
            text: "Reaction Coordinate",
            style: { color: t.inkSoft, fontSize: "16px" }
        },
        lineColor: t.inkSoft,
        tickLength: 0,
        tickPositions: [],
        min: 0,
        max: 100,
        labels: { enabled: false }
    },
    yAxis: {
        title: {
            text: "Potential Energy (kJ/mol)",
            style: { color: t.inkSoft, fontSize: "16px" }
        },
        gridLineColor: t.grid,
        lineColor: t.inkSoft,
        labels: { style: { color: t.inkSoft, fontSize: "14px" } },
        min: 0,
        max: 145,
        tickInterval: 20,
        plotLines: [
            {
                value: 50,
                color: t.inkSoft,
                dashStyle: "ShortDash",
                width: 1.5,
                zIndex: 3
            },
            {
                value: 20,
                color: t.inkSoft,
                dashStyle: "ShortDash",
                width: 1.5,
                zIndex: 3
            }
        ]
    },
    legend: { enabled: false },
    tooltip: { enabled: false },
    plotOptions: {
        series: {
            animation: false,
            lineWidth: 3,
            marker: { enabled: false }
        }
    },
    series: [{
        type: "areaspline",
        name: "Potential Energy",
        data: energyData,
        color: t.palette[0],
        fillColor: "rgba(0,158,115,0.10)",
        threshold: null
    }]
});

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/line-reaction-coordinate/highcharts/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.

{
  "spec_id": "line-reaction-coordinate",
  "language": "javascript",
  "library": "highcharts",
  "page": "https://anyplot.ai/line-reaction-coordinate/javascript/highcharts",
  "hub": "https://anyplot.ai/line-reaction-coordinate",
  "code_json": "https://api.anyplot.ai/specs/line-reaction-coordinate/highcharts/code",
  "spec_json": "https://api.anyplot.ai/specs/line-reaction-coordinate",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/line-reaction-coordinate/javascript/highcharts/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/line-reaction-coordinate/javascript/highcharts/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/line-reaction-coordinate/javascript/highcharts/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/line-reaction-coordinate/javascript/highcharts/plot-dark.html",
  "quality_score": 91.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Reaction Coordinate Energy Diagram on anyplot.ai.

Other implementations