{"spec_id":"line-reaction-coordinate","library":"echarts","language":"javascript","code":"// anyplot.ai\n// line-reaction-coordinate: Reaction Coordinate Energy Diagram\n// Library: echarts 5.5.1 | JavaScript 22.22.3\n// Quality: 92/100 | Created: 2026-06-24\n\nconst t = window.ANYPLOT_TOKENS;\n\n// Data: single-step exothermic reaction\n// Reactants 50 kJ/mol → Transition State ~120 kJ/mol → Products 20 kJ/mol\nconst N = 300;\nconst curveData = [];\nfor (let i = 0; i < N; i++) {\n  const x = i / (N - 1);\n  const sig = 1 / (1 + Math.exp(-15 * (x - 0.55)));\n  const baseline = 50 * (1 - sig) + 20 * sig;\n  const bump = 80 * Math.exp(-((x - 0.5) / 0.13) * ((x - 0.5) / 0.13));\n  curveData.push([x, baseline + bump]);\n}\n\nconst chart = echarts.init(document.getElementById(\"container\"));\n\nchart.setOption({\n  animation: false,\n  color: t.palette,\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"line-reaction-coordinate · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    top: 18,\n    textStyle: { color: t.ink, fontSize: 22, fontWeight: \"500\" },\n  },\n  grid: { left: 120, right: 80, top: 88, bottom: 80 },\n  xAxis: {\n    type: \"value\",\n    name: \"Reaction Coordinate (arbitrary units)\",\n    nameLocation: \"middle\",\n    nameGap: 38,\n    nameTextStyle: { color: t.inkSoft, fontSize: 15 },\n    min: 0,\n    max: 1,\n    axisLabel: { show: false },\n    axisTick: { show: false },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    splitLine: { show: false },\n  },\n  yAxis: {\n    type: \"value\",\n    name: \"Potential Energy (kJ/mol)\",\n    nameLocation: \"middle\",\n    nameGap: 60,\n    nameTextStyle: { color: t.inkSoft, fontSize: 15 },\n    min: 0,\n    max: 140,\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    splitLine: { show: false },\n  },\n  series: [\n    {\n      type: \"line\",\n      data: curveData,\n      smooth: false,\n      symbol: \"none\",\n      lineStyle: { color: t.palette[0], width: 4 },\n      markLine: {\n        silent: true,\n        symbol: [\"none\", \"none\"],\n        label: { show: false },\n        data: [\n          [\n            { coord: [0.0, 50], lineStyle: { type: \"dashed\", color: t.inkSoft, width: 1.5, opacity: 0.7 } },\n            { coord: [0.30, 50] },\n          ],\n          [\n            { coord: [0.68, 20], lineStyle: { type: \"dashed\", color: t.inkSoft, width: 1.5, opacity: 0.7 } },\n            { coord: [1.0, 20] },\n          ],\n        ],\n      },\n    },\n  ],\n});\n\n// Pixel positions for annotation elements (CSS px on the 1600×900 mount)\nconst toP = (xy) => chart.convertToPixel({ gridIndex: 0 }, xy);\n\nconst [, yTs]    = toP([0, 120]);\nconst [, yReact] = toP([0, 50]);\nconst [, yProd]  = toP([0, 20]);\nconst [eaX]      = toP([0.28, 0]);\nconst [dhX]      = toP([0.80, 0]);\nconst [tsX]      = toP([0.50, 0]);\nconst [rX]       = toP([0.12, 0]);\nconst [pX]       = toP([0.88, 0]);\n\nconst AH = 9;  // arrowhead height in CSS px\n\nchart.setOption({\n  graphic: {\n    elements: [\n      // --- Species labels ---\n      {\n        type: \"text\",\n        x: rX,\n        y: yReact - 36,\n        style: { text: \"Reactants\", fill: t.ink, fontSize: 15, fontWeight: \"bold\", align: \"center\" },\n      },\n      {\n        type: \"text\",\n        x: tsX,\n        y: yTs - 44,\n        style: { text: \"Transition State\", fill: t.ink, fontSize: 15, fontWeight: \"bold\", align: \"center\" },\n      },\n      {\n        type: \"text\",\n        x: pX,\n        y: yProd - 36,\n        style: { text: \"Products\", fill: t.ink, fontSize: 15, fontWeight: \"bold\", align: \"center\" },\n      },\n\n      // --- Eₐ double-headed arrow (reactant level → TS peak) ---\n      {\n        type: \"line\",\n        shape: { x1: eaX, y1: yReact, x2: eaX, y2: yTs },\n        style: { stroke: t.inkSoft, lineWidth: 1.5 },\n      },\n      // top arrowhead pointing up (toward TS)\n      {\n        type: \"polygon\",\n        shape: { points: [[eaX, yTs], [eaX - 5, yTs + AH], [eaX + 5, yTs + AH]] },\n        style: { fill: t.inkSoft },\n      },\n      // bottom arrowhead pointing down (toward reactants)\n      {\n        type: \"polygon\",\n        shape: { points: [[eaX, yReact], [eaX - 5, yReact - AH], [eaX + 5, yReact - AH]] },\n        style: { fill: t.inkSoft },\n      },\n      {\n        type: \"text\",\n        x: eaX + 10,\n        y: (yReact + yTs) / 2 - 10,\n        style: { text: \"Eₐ\", fill: t.inkSoft, fontSize: 15 },\n      },\n\n      // --- ΔH double-headed arrow (product level → reactant level) ---\n      {\n        type: \"line\",\n        shape: { x1: dhX, y1: yProd, x2: dhX, y2: yReact },\n        style: { stroke: t.inkSoft, lineWidth: 1.5 },\n      },\n      // top arrowhead pointing up (toward reactant level)\n      {\n        type: \"polygon\",\n        shape: { points: [[dhX, yReact], [dhX - 5, yReact + AH], [dhX + 5, yReact + AH]] },\n        style: { fill: t.inkSoft },\n      },\n      // bottom arrowhead pointing down (toward product level)\n      {\n        type: \"polygon\",\n        shape: { points: [[dhX, yProd], [dhX - 5, yProd - AH], [dhX + 5, yProd - AH]] },\n        style: { fill: t.inkSoft },\n      },\n      {\n        type: \"text\",\n        x: dhX + 10,\n        y: (yProd + yReact) / 2 - 10,\n        style: { text: \"ΔH = −30 kJ/mol\", fill: t.inkSoft, fontSize: 14 },\n      },\n    ],\n  },\n});\n"}