一、库概述
OpenChemLib JS(简称 OCL)是Java OpenChemLib 的 GWT 编译 JavaScript 移植版,前端 / Node.js 通用化学信息学工具库,支持分子解析、结构转换、2D 绘图、子结构搜索、理化性质计算、结构式编辑器、反应处理等全流程化学计算。
三大构建包(按需引入,控制体积)
| 构建入口 | 体积 | 包含能力 | 适用场景 |
|---|---|---|---|
openchemlib/minimal | 最小 | Molecule、SMILES、MolFile、子结构搜索、基础分子操作 | 轻量后端、仅分子计算无绘图 |
openchemlib(core 默认) | 中等 | minimal 全部 + 类药性 / 毒性预测、分子性质、力场构象生成 | Node 服务、轻前端 |
openchemlib/full | 完整 | core 全部 + Canvas 结构式编辑器、SVG/Canvas 绘图 Depictor | 网页绘图、结构式编辑器 |
官方资源
- 完整 API 文档(TypeDoc):https://cheminfo.github.io/openchemlib-js/
- 在线示例集:https://www.cheminfo.org/Chemistry/Cheminformatics/OpenChemLib_js/index.html
- Github 仓库:https://github.com/cheminfo/openchemlib-js
- 扩展工具:
openchemlib-utils(路径分析、HOSE 编码、同位素拆分等)
二、安装引入
1. NPM 安装(推荐 Node/Vue/React)
npm install openchemlib # 扩展工具(可选) npm install openchemlib-utilsES Module 导入
// 完整包(含绘图编辑器,浏览器) import OCL from 'openchemlib/full'; // core包(Node后端,无绘图) import OCL from 'openchemlib'; // minimal极小包 import OCL from 'openchemlib/minimal'; // 扩展工具 import { initOCL, getPathsInfo } from 'openchemlib-utils'; initOCL(OCL); // 绑定OCL实例CommonJS(Node.js)
const OCL = require('openchemlib/full');2. CDN 直接引入(原生 HTML 页面)
<!-- full完整版,含绘图编辑器 --> <script src="https://unpkg.com/openchemlib@latest/dist/full.js"></script> <script> const OCL = window.OCL; </script>三、核心类总览
- Molecule:核心分子操作类(90% 业务使用)
- Reaction:化学反应,反应物 / 产物 / 催化剂
- SmilesParser/SmilesGenerator:SMILES 解析 / 生成
- SDFileParser:SDF 批量分子文件读写
- SSSearcher:SMARTS 子结构匹配搜索
- CanvasEditor:网页交互式结构式编辑器(full 包专属)
- Depictor:分子 2D 渲染 SVG/Canvas
- MoleculeProperties:分子量、logP、可旋转键等理化计算
- ForceFieldMMFF94:MMFF94 力场 3D 构象优化
- Canonizer:标准 SMILES、分子去重 IDCode
四、Molecule 核心 API(最常用)
4.1 分子创建(从各类格式导入)
1)从 SMILES 创建
const smi = "c1ccccc1O"; // 苯酚 // 基础创建 const mol = OCL.Molecule.fromSmiles(smi); // 带解析参数(手性、芳香处理) const mol2 = OCL.Molecule.fromSmiles(smi, { ignoreStereo: false, // 是否忽略立体化学 kekulize: false });2)从 MolFile V2000 字符串创建
const molfileStr = ` Ketcher 05231617272D 6 6 0 0 0 0 0 0 0 0999 V2000 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.5000 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 1.0000 1.7320 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 1.7320 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 -0.5000 0.8660 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 1 2 4 0 0 0 0 2 3 4 0 0 0 0 3 4 4 0 0 0 0 4 5 4 0 0 0 0 5 6 1 0 0 0 0 6 1 1 0 0 0 0 M END `; const mol = OCL.Molecule.fromMolfile(molfileStr);3)空白分子手动构建(增原子、键)
const mol = new OCL.Molecule(); // 添加C原子,坐标x,y mol.addAtom(6, 0, 0); mol.addAtom(6, 1, 0); mol.addAtom(8, 1, 1); // 添加单键:原子索引0-1,键级1 mol.addBond(0, 1, 1); mol.addBond(1, 2, 2); // 双键 mol.organize(); // 标准化结构4.2 分子导出格式
1)导出标准 SMILES(Canonical 去重)
// 普通SMILES const smi = mol.toSmiles(); // 标准Canonical SMILES(相同分子固定字符串,用于查重) const canSmi = mol.toSmiles({ canonical: true });2)导出 MolFile V2000
const molfile = mol.toMolfile({ title: "苯酚", dimensionality: "2D" });3)分子唯一 IDCode(分子指纹,快速比对)
const idcode = mol.getIDCode(); // 从IDCode还原分子 const molRestore = OCL.Molecule.fromIDCode(idcode);4.3 分子基础信息读取
// 分子式 const mf = mol.getMolecularFormula(); console.log(mf.formula, mf.molecularWeight); // 原子总数、重原子数 const atomCount = mol.getAtomCount(); const heavyAtoms = mol.getHeavyAtomCount(); // 遍历所有原子 for (let i = 0; i < mol.getAtomCount(); i++) { const elem = mol.getAtomicNumber(i); // 原子序数 6=C,8=O const x = mol.getX(i); const y = mol.getY(i); } // 不饱和度 const unsat = mol.getUnsaturation(); // 复制分子(避免原对象被修改) const molCopy = mol.clone();4.4 子结构搜索 SMARTS(SSSearcher)
const mol = OCL.Molecule.fromSmiles("CC(=O)Oc1ccccc1C(=O)O"); // 阿司匹林 const searcher = new OCL.SSSearcher(); // 匹配羰基 C=O const pattern = OCL.Molecule.fromSmarts("[C]=O"); const matches = searcher.findMatches(mol, pattern); // matches 数组:[[原子索引1,原子索引2], ...] console.log("羰基匹配数量:", matches.length);4.5 立体化学处理
// 判断分子是否含手性中心 const hasStereo = mol.hasStereo(); // 标准化立体结构 mol.canonizeStereo(); // 生成无立体SMILES const smiNoStereo = mol.toSmiles({ ignoreStereo: true });五、网页绘图(full 包专属 Depictor)
5.1 生成 SVG 字符串(无 DOM 依赖,可保存图片)
const mol = OCL.Molecule.fromSmiles("c1ccccc1"); const depictor = new OCL.Depictor(); // 配置绘图参数 depictor.setWidth(400); depictor.setHeight(300); depictor.setBondThickness(1.2); depictor.setShowAromaticCircles(true); // 苯环画圆圈 depictor.setAtomLabelFontSize(14); const svg = depictor.drawMolecule(mol); // 直接插入页面 document.body.innerHTML += svg;5.2 Canvas 画布渲染
<canvas id="chemCanvas" width="400" height="300"></canvas> <script src="https://unpkg.com/openchemlib/full.js"></script> <script> const OCL = window.OCL; const mol = OCL.Molecule.fromSmiles("CCO"); const canvas = document.getElementById("chemCanvas"); const ctx = canvas.getContext("2d"); const depictor = new OCL.Depictor(); depictor.drawMoleculeToCanvas(mol, ctx, 0, 0, 400, 300); </script>六、交互式结构式编辑器 CanvasEditor(full 包)
网页端可拖拽、增删原子 / 键、编辑手性的绘图编辑器
<div id="editorContainer" style="width:600px;height:400px;border:1px solid #ccc;"></div> <script src="https://unpkg.com/openchemlib/full.js"></script> <script> const OCL = window.OCL; const container = document.getElementById("editorContainer"); // 创建编辑器 const editor = new OCL.CanvasEditor(container, { backgroundColor: "#ffffff", allowReaction: false // 关闭反应模式,仅分子 }); // 初始化分子 const initMol = OCL.Molecule.fromSmiles("c1ccccc1"); editor.setMolecule(initMol); // 监听编辑变化 editor.setOnChangeListener((evt) => { const currentMol = editor.getMolecule(); console.log("当前SMILES:", currentMol.toSmiles()); }); // 外部赋值改写编辑器结构 function setMolBySmi(smi) { const mol = OCL.Molecule.fromSmiles(smi); editor.setMolecule(mol); editor.moleculeChanged(); // 通知重绘 } </script>七、反应处理 Reaction 类
// 创建反应:A + B >> C const rxn = new OCL.Reaction(); // 反应物 rxn.addReactant(OCL.Molecule.fromSmiles("C=C")); rxn.addReactant(OCL.Molecule.fromSmiles("BrBr")); // 产物 rxn.addProduct(OCL.Molecule.fromSmiles("BrCCBr")); // 导出反应SMILES const rxnSmi = rxn.toSmiles(); // 导出RXN文件 const rxnFile = rxn.toRxnFile(); // 从反应SMILES解析 const rxn2 = OCL.Reaction.fromSmiles("C=C.BrBr>>BrCCBr");八、理化性质计算 MoleculeProperties
const mol = OCL.Molecule.fromSmiles("C1CCCCC1O"); const props = new OCL.MoleculeProperties(mol); console.log({ logP: props.calcLogP(), molarRefractivity: props.calcMR(), rotatableBonds: props.getRotatableBondCount(), hDonor: props.getHDonorCount(), hAcceptor: props.getHAcceptorCount(), tpsa: props.calcTPSA() // 极性表面积 });九、3D 构象生成与力场优化
const mol = OCL.Molecule.fromSmiles("CC(=O)O"); // 生成3D初始坐标 mol.generate3DCoordinates(); // MMFF94力场能量最小化 const ff = new OCL.ForceFieldMMFF94(mol); ff.minimize(500); // 迭代500步优化十、SDF 批量文件读写
// 解析SDF字符串 const sdfParser = new OCL.SDFileParser(); const molecules = sdfParser.parse(sdfText); // molecules 为Molecule数组,每个分子携带属性字段 molecules.forEach(mol => { const props = mol.getSDFProperties(); console.log(props.ID, mol.toSmiles()); }); // 批量分子导出SDF let sdfOut = ""; molecules.forEach(mol => { sdfOut += mol.toMolfile() + "\n$$$$\n"; });十一、Node.js 后端纯计算示例(无浏览器)
const OCL = require('openchemlib'); // 1. SMILES转标准SMILES const smi = "OC1=CC=CC=C1"; const mol = OCL.Molecule.fromSmiles(smi); const canSmi = mol.toSmiles({ canonical: true }); console.log("标准SMILES:", canSmi); // 2. 分子量计算 const mf = mol.getMolecularFormula(); console.log("分子量:", mf.molecularWeight); // 3. 子结构匹配 const searcher = new OCL.SSSearcher(); const ohPattern = OCL.Molecule.fromSmarts("[OH]"); const ohCount = searcher.findMatches(mol, ohPattern).length; console.log("羟基数量:", ohCount);十二、常见配置与性能优化
- 打包体积优化
- 后端 Node:使用
openchemlib/minimal,剔除预测、绘图模块 - 前端仅展示不编辑:core 包 + 手动引入 Depictor,不加载 CanvasEditor
- 后端 Node:使用
- 分子克隆OCL 的 Molecule 为可变对象,跨函数传递必须
mol.clone()防止篡改 - 批量分子处理大量 SDF 循环时复用
SSSearcher、MoleculeProperties实例,减少重复创建开销 - 芳香环渲染Depictor 默认双键交替,
setShowAromaticCircles(true)显示圆圈更美观
十三、常见报错与解决方案
fromSmiles is not a function导入包错误:绘图编辑器必须引入/full,Node 后端用默认 core- 绘图空白 / 无渲染
- canvas 容器必须设置宽高;Depictor 宽高不能为 0
- 分子无 2D 坐标:
mol.generate2DCoordinates()自动生成布局
- SMILES 解析失败 校验 SMILES 合法性,开启
ignoreErrors捕获:try { OCL.Molecule.fromSmiles(smi); } catch(e) { console.error("SMILES非法", e); } - 打包时报 GWT/wasm 相关错误 vite/webpack 配置排除二进制资源,或使用 CDN 引入 full.js 避开打包
十四、官方手册直达链接
- 完整 API 索引(所有类 / 方法):https://cheminfo.github.io/openchemlib-js/modules.html
- Molecule 类完整方法文档:https://cheminfo.github.io/openchemlib-js/classes/Molecule.html
- CanvasEditor 编辑器文档:https://cheminfo.github.io/openchemlib-js/classes/CanvasEditor.html
- 在线可运行 Demo:https://www.cheminfo.org/Chemistry/Cheminformatics/OpenChemLib_js/index.html