Introduction
Welcome to RDKit.js for React. If you didn't do it already, we first recommend to go through the JavaScript examples for a low-level overview of the RDKit.js API.
Overview
You can draw any molecule from SMILES dynamically with RDKit.js .
import React from "react";
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
import { SMILES_LIST } from "../utils/smiles";
class ExampleList extends React.Component {
render() {
return (
<div id="component-example-list" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">Overview</p>
<p className="subtitle">
You can draw any molecule from SMILES dynamically with RDKit.js .
</p>
</div>
</section>
<div
id="structure-list"
className="columns is-desktop"
style={{ margin: "12px", overflowX: "scroll" }}
>
{SMILES_LIST.map((smiles) => (
<div className="column" key={smiles}>
<MoleculeStructure
id={smiles}
structure={smiles}
height={200}
width={200}
svgMode
/>
</div>
))}
</div>
</div>
);
}
}
export default ExampleList;
MoleculeStructure
The examples below will mostly use the React component MoleculeStructure
to render the examples. You can see the React implementation in the code below.
import React, { Component } from "react";
import _ from "lodash";
import PropTypes from "prop-types";
import "./MoleculeStructure.css";
import initRDKit from "../../utils/initRDKit";
class MoleculeStructure extends Component {
static propTypes = {
/**
* Generic properties
*/
id: PropTypes.string.isRequired,
className: PropTypes.string,
svgMode: PropTypes.bool,
width: PropTypes.number,
height: PropTypes.number,
/**
* RDKit-specific properties
*/
structure: PropTypes.string.isRequired,
subStructure: PropTypes.string,
extraDetails: PropTypes.object,
drawingDelay: PropTypes.number
};
static defaultProps = {
subStructure: "",
className: "",
width: 250,
height: 200,
svgMode: false,
extraDetails: {},
drawingDelay: undefined
};
constructor(props) {
super(props);
this.MOL_DETAILS = {
width: this.props.width,
height: this.props.height,
bondLineWidth: 1,
addStereoAnnotation: true,
...this.props.extraDetails
};
this.state = {
svg: undefined,
rdKitLoaded: false,
rdKitError: false
};
}
drawOnce = (() => {
let wasCalled = false;
return () => {
if (!wasCalled) {
wasCalled = true;
this.draw();
}
};
})();
draw() {
if (this.props.drawingDelay) {
setTimeout(() => {
this.drawSVGorCanvas();
}, this.props.drawingDelay);
} else {
this.drawSVGorCanvas();
}
}
drawSVGorCanvas() {
const mol = window.RDKit.get_mol(this.props.structure || "invalid");
const qmol = window.RDKit.get_qmol(this.props.subStructure || "invalid");
const isValidMol = this.isValidMol(mol);
if (this.props.svgMode && isValidMol) {
const svg = mol.get_svg_with_highlights(this.getMolDetails(mol, qmol));
this.setState({ svg });
} else if (isValidMol) {
const canvas = document.getElementById(this.props.id);
mol.draw_to_canvas_with_highlights(canvas, this.getMolDetails(mol, qmol));
}
/**
* Delete C++ mol objects manually
* https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management
*/
mol?.delete();
qmol?.delete();
}
isValidMol(mol) {
return !!mol;
}
getMolDetails(mol, qmol) {
if (this.isValidMol(mol) && this.isValidMol(qmol)) {
const subStructHighlightDetails = JSON.parse(
mol.get_substruct_matches(qmol)
);
const subStructHighlightDetailsMerged = !_.isEmpty(
subStructHighlightDetails
)
? subStructHighlightDetails.reduce(
(acc, { atoms, bonds }) => ({
atoms: [...acc.atoms, ...atoms],
bonds: [...acc.bonds, ...bonds]
}),
{ bonds: [], atoms: [] }
)
: subStructHighlightDetails;
return JSON.stringify({
...this.MOL_DETAILS,
...(this.props.extraDetails || {}),
...subStructHighlightDetailsMerged
});
} else {
return JSON.stringify({
...this.MOL_DETAILS,
...(this.props.extraDetails || {})
});
}
}
componentDidMount() {
initRDKit()
.then(() => {
this.setState({ rdKitLoaded: true });
try {
this.draw();
} catch (err) {
console.log(err);
}
})
.catch((err) => {
console.log(err);
this.setState({ rdKitError: true });
});
}
componentDidUpdate(prevProps) {
if (
!this.state.rdKitError &&
this.state.rdKitLoaded &&
!this.props.svgMode
) {
this.drawOnce();
}
if (this.state.rdKitLoaded) {
const shouldUpdateDrawing =
prevProps.structure !== this.props.structure ||
prevProps.svgMode !== this.props.svgMode ||
prevProps.subStructure !== this.props.subStructure ||
prevProps.width !== this.props.width ||
prevProps.height !== this.props.height ||
!_.isEqual(prevProps.extraDetails, this.props.extraDetails);
if (shouldUpdateDrawing) {
this.draw();
}
}
}
render() {
if (this.state.rdKitError) {
return "Error loading renderer.";
}
if (!this.state.rdKitLoaded) {
return "Loading renderer...";
}
const mol = window.RDKit.get_mol(this.props.structure || "invalid");
const isValidMol = this.isValidMol(mol);
mol?.delete();
if (!isValidMol) {
return (
<span title={`Cannot render structure: ${this.props.structure}`}>
Render Error.
</span>
);
} else if (this.props.svgMode) {
return (
<div
title={this.props.structure}
className={"molecule-structure-svg " + (this.props.className || "")}
style={{ width: this.props.width, height: this.props.height }}
dangerouslySetInnerHTML={{ __html: this.state.svg }}
></div>
);
} else {
return (
<div
className={
"molecule-canvas-container " + (this.props.className || "")
}
>
<canvas
title={this.props.structure}
id={this.props.id}
width={this.props.width}
height={this.props.height}
></canvas>
</div>
);
}
}
}
export default MoleculeStructure;
SVG Rendering
You can render molecules using svg.
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
function ExampleSVG() {
const caffeine = "CN1C=NC2=C1C(=O)N(C(=O)N2C)";
const aspirin = "CC(=O)Oc1ccccc1C(=O)O";
return (
<div id="component-example-svg" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">SVG Rendering</p>
<p className="subtitle">You can render molecules using svg.</p>
</div>
</section>
<div className="columns is-desktop">
<div className="column">
<MoleculeStructure
id="structure-example-svg-caffeine"
structure={caffeine}
width={350}
height={300}
svgMode
/>
</div>
<div className="column">
<MoleculeStructure
id="structure-example-svg-aspirin"
structure={aspirin}
width={350}
height={300}
svgMode
/>
</div>
</div>
</div>
);
}
export default ExampleSVG;
Canvas rendering
You can also render molecules using the HTML Canvas API.
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
function ExampleCanvas() {
const caffeine = "CN1C=NC2=C1C(=O)N(C(=O)N2C)";
const aspirin = "CC(=O)Oc1ccccc1C(=O)O";
return (
<div id="component-example-canvas" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">Canvas rendering</p>
<p className="subtitle">
You can also render molecules using the HTML Canvas API.
</p>
</div>
</section>
<div className="columns is-desktop">
<div className="column">
<MoleculeStructure
id="structure-example-canvas-caffeine"
structure={caffeine}
width={350}
height={300}
/>
</div>
<div className="column">
<MoleculeStructure
id="structure-example-canvas-aspirin"
structure={aspirin}
width={350}
height={300}
/>
</div>
</div>
</div>
);
}
export default ExampleCanvas;
Substructure Highlight
You can also highlight substructure of molecules with both the SVG and Canvas APIs.
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
function ExampleSubstructure() {
const caffeine = "CN1C=NC2=C1C(=O)N(C(=O)N2C)";
const caffeineSubStruct = "[N,n,O;!H0]";
const aspirin = "CC(=O)Oc1ccccc1C(=O)O";
const aspirinSubStruct = "CC(=O)Oc1ccccc1C";
return (
<div id="component-example-substruct" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">Substructure Highlight</p>
<p className="subtitle">
You can also highlight substructure of molecules with both the SVG
and Canvas APIs.
</p>
</div>
</section>
<div className="columns is-desktop">
<div className="column">
<MoleculeStructure
id="structure-example-substruct-svg-caffeine"
structure={caffeine}
subStructure={caffeineSubStruct}
width={350}
height={300}
svgMode
/>
</div>
<div className="column">
<MoleculeStructure
id="structure-example-subsctruct-canvas-aspirin"
structure={aspirin}
subStructure={aspirinSubStruct}
width={350}
height={300}
/>
</div>
</div>
</div>
);
}
export default ExampleSubstructure;
Multi-substructure Highlight
You can also highlight multiple substructures of molecules with SMILES, SMARTS and a combination of the two with dot notation.
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
function ExampleMultiSubstructure() {
const caffeine = "CN1C=NC2=C1C(=O)N(C(=O)N2C)";
const caffeineSubStruct = "[N,n,o,O]";
const aspirin = "CC(=O)Oc1ccccc1C(=O)O";
const aspirinSubStruct = "[O,o].c1ccccc1";
return (
<div id="component-example-multi-substruct" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">Multi-substructure Highlight</p>
<p className="subtitle">
You can also highlight multiple substructures of molecules with
SMILES, SMARTS and a combination of the two with dot notation.
</p>
</div>
</section>
<div className="columns is-desktop">
<div className="column">
<MoleculeStructure
id="structure-example-multisubstruct-svg-caffeine"
structure={caffeine}
subStructure={caffeineSubStruct}
width={350}
height={300}
svgMode
/>
</div>
<div className="column">
<MoleculeStructure
id="structure-example-multisubsctruct-canvas-aspirin"
structure={aspirin}
subStructure={aspirinSubStruct}
width={350}
height={300}
/>
</div>
</div>
</div>
);
}
export default ExampleMultiSubstructure;
Substructure match
You can perform client-side substructure match.
import React from "react";
import _ from "lodash";
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
import { SMILES_LIST } from "../utils/smiles";
class ExampleList extends React.Component {
state = {
matches: SMILES_LIST,
searchValue: "",
searching: false
};
render() {
const matches = this.state.matches.slice(0, 50);
return (
<div id="component-example-substruct-search" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">Substructure match</p>
<p className="subtitle">
You can perform client-side substructure match.
</p>
</div>
</section>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<div className="control has-icons-left">
<input
className="input"
type="email"
onChange={(e) => this.handleSearchChange(e)}
placeholder="Enter a SMARTS or SMILES string here..."
/>
{this.renderInputIcon()}
</div>
</div>
</div>
</div>
<div className="columns is-multiline" style={{ margin: "12px" }}>
{matches.length > 0
? matches.slice(0, 40).map((smiles) => (
<div className="column" key={smiles}>
<MoleculeStructure
id={smiles}
structure={smiles}
subStructure={this.state.searchValue}
height={200}
width={200}
svgMode
/>
</div>
))
: "Input is either invalid or no matches were found."}
</div>
</div>
);
}
handleSearchChange = _.debounce((e) => {
this.setState({ searching: true });
setTimeout(() => {
const noMatchLength = 2;
const currentVal = e.target.value;
this.setState({ searchValue: currentVal });
if (!currentVal) {
this.setState({ matches: SMILES_LIST.slice(), searching: false });
} else {
const qmol = window.RDKit.get_qmol(currentVal);
if (!this.isValidMol(qmol)) {
this.setState({ matches: [], searching: false });
} else {
const matches = SMILES_LIST.filter((smiles) => {
const mol = window.RDKit.get_mol(smiles);
const hasMatch = mol.get_substruct_match(qmol).length > noMatchLength;
mol?.delete();
return hasMatch;
});
this.setState({ matches, searching: false });
qmol?.delete();
}
}
}, 100);
}, 300);
renderInputIcon() {
if (this.state.searching) {
return (
<span key="searching-input-icon" className="icon is-small is-left">
<i className="fas fa-circle-notch fa-spin" />
</span>
);
} else {
return (
<span key="search-input-icon" className="icon is-small is-left">
<i className="fas fa-search" />
</span>
);
}
}
isValidMol(qmolOrMol) {
return !!qmolOrMol;
}
}
export default ExampleList;
Additional Drawing Options
RDKit.js provides you a lot of options for drawing molecules. Checkout the JavaScript examples for the full list of available options.
import React from "react";
import _ from "lodash";
import hexRgb from "hex-rgb";
import MoleculeStructure from "../components/MoleculeStructure/MoleculeStructure";
class ExampleDrawingOptions extends React.Component {
static initialState = {
computing: false,
mainStructureInput:
"CSCC[C@H](NC(=O)[C@H](CC1=CNC2=C1C=CC=C2)NC(=O)CCNC(=O)OC(C)(C)C)C(=O)N[C@@H](CC(O)=O)C(=O)N[C@@H](CC1=CC=CC=C1)C(N)=O",
subStructureInput: "[n,O]",
legend: "Legend Text",
legendFontSize: 16,
width: 500,
height: 450,
bondLineWidth: 1,
scaleBondWidth: false,
addStereoAnnotation: true,
addAtomIndices: true,
addBondIndices: false,
explicitMethyl: true,
centreMoleculesBeforeDrawing: false,
highlightColour: "#fd5c63",
legendColour: "#000000",
symbolColour: "#000000",
backgroundColour: "#ffffff",
rotate: 0.0,
annotationFontScale: 0.5,
comicMode: false,
svgMode: true
};
constructor(props) {
super(props);
this.state = {
...ExampleDrawingOptions.initialState
};
}
render() {
return (
<div id="component-example-drawing-options" className="container">
<section className="hero">
<div className="hero-body">
<p className="title">Additional Drawing Options</p>
<p className="subtitle column is-two-thirds pl-0">
RDKit.js provides you a lot of options for drawing molecules.
Checkout the{" "}
<a href="https://rdkitjs.com#drawing-molecules-all-options">
JavaScript examples
</a>{" "}
for the full list of available options.
</p>
</div>
</section>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">Main Structure</label>
<div className="control">
<input
className="input"
defaultValue={this.state.mainStructureInput}
onChange={(e) =>
this.handleStateChange(e, "mainStructureInput")
}
placeholder="Enter a SMILES string here..."
/>
</div>
</div>
</div>
</div>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">Substructure</label>
<div className="control">
<input
className="input"
defaultValue={this.state.subStructureInput}
onChange={(e) =>
this.handleStateChange(e, "subStructureInput")
}
placeholder="Enter a SMILES or SMARTS string here..."
/>
</div>
</div>
</div>
</div>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">Legend</label>
<div className="control">
<input
className="input"
defaultValue={this.state.legend}
onChange={(e) => this.handleStateChange(e, "legend")}
placeholder="Add a legend here..."
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Legend font size</label>
<div className="control">
<input
className="input"
type="number"
defaultValue={this.state.legendFontSize}
onChange={(e) => this.handleStateChange(e, "legendFontSize")}
placeholder="Add a font size..."
/>
</div>
</div>
</div>
</div>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">Width</label>
<div className="control">
<input
className="input"
type="number"
defaultValue={this.state.width}
onChange={(e) => this.handleStateChange(e, "width")}
placeholder="Width"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Height</label>
<div className="control">
<input
className="input"
type="number"
defaultValue={this.state.height}
onChange={(e) => this.handleStateChange(e, "height")}
placeholder="Height"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Bond line width</label>
<div className="control">
<input
className="input"
type="number"
defaultValue={this.state.bondLineWidth}
onChange={(e) => this.handleStateChange(e, "bondLineWidth")}
placeholder="Bond line width"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Annotation font scale</label>
<div className="control">
<input
className="input"
type="number"
step="0.1"
defaultValue={this.state.annotationFontScale}
onChange={(e) =>
this.handleStateChange(e, "annotationFontScale ")
}
placeholder="Annotation font scale"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Rotate</label>
<div className="control">
<input
className="input"
type="number"
step="0.5"
defaultValue={this.state.rotate}
onChange={(e) => this.handleStateChange(e, "rotate")}
placeholder="Rotate"
/>
</div>
</div>
</div>
</div>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">Stereo-Annotation</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.addStereoAnnotation}
onChange={(e) =>
this.handleStateChange(e, "addStereoAnnotation")
}
placeholder="Stereo-Annotation"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Atom Indices</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.addAtomIndices}
onChange={(e) => this.handleStateChange(e, "addAtomIndices")}
placeholder="Atom Indices"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Bond Indices</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.addBondIndices}
onChange={(e) => this.handleStateChange(e, "addBondIndices")}
placeholder="Bond Indices"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Explicit Methyl</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.explicitMethyl}
onChange={(e) => this.handleStateChange(e, "explicitMethyl")}
placeholder="Explicit Methyl"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Scale bond width</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.scaleBondWidth}
onChange={(e) => this.handleStateChange(e, "scaleBondWidth")}
placeholder="Scale bond width"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Center molecule</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.centreMoleculesBeforeDrawing}
onChange={(e) =>
this.handleStateChange(e, "centreMoleculesBeforeDrawing")
}
placeholder="Center molecule"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Comic mode</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.comicMode}
onChange={(e) => this.handleStateChange(e, "comicMode")}
placeholder="Comic mode"
/>
</div>
</div>
</div>
</div>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">Highlight Colour</label>
<div className="control">
<input
type="color"
className="input"
defaultValue={this.state.highlightColour}
onChange={(e) => this.handleStateChange(e, "highlightColour")}
placeholder="Highlight Colour"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Background Colour (canvas only)</label>
<div className="control">
<input
type="color"
className="input"
defaultValue={this.state.backgroundColour}
onChange={(e) =>
this.handleStateChange(e, "backgroundColour")
}
placeholder="Background Colour"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Legend Colour</label>
<div className="control">
<input
type="color"
className="input"
defaultValue={this.state.legendColour}
onChange={(e) => this.handleStateChange(e, "legendColour")}
placeholder="Legend Colour"
/>
</div>
</div>
</div>
<div className="column">
<div className="field">
<label className="label">Symbol Colour</label>
<div className="control">
<input
type="color"
className="input"
defaultValue={this.state.symbolColour}
onChange={(e) => this.handleStateChange(e, "symbolColour")}
placeholder="Symbol Colour"
/>
</div>
</div>
</div>
</div>
<div className="columns" style={{ margin: "12px 0" }}>
<div className="column">
<div className="field">
<label className="label">
SVG/Canvas Rendering (Uncheck for canvas rendering)
</label>
<div className="control">
<input
className="checkbox"
type="checkbox"
defaultChecked={this.state.svgMode}
onChange={(e) => this.handleStateChange(e, "svgMode")}
placeholder="Svg mode"
/>
</div>
</div>
</div>
</div>
{this.renderContent()}
</div>
);
}
renderContent() {
const width = this.state.width || 250;
const height = this.state.width || 250;
const bondLineWidth = this.state.bondLineWidth || 1;
const rotate = this.state.rotate || 0.0;
const annotationFontScale = this.state.annotationFontScale || 0.5;
const addStereoAnnotation = this.state.addStereoAnnotation || false;
const addAtomIndices = this.state.addAtomIndices || false;
const addBondIndices = this.state.addBondIndices || false;
const explicitMethyl = this.state.explicitMethyl || false;
const scaleBondWidth = this.state.scaleBondWidth || false;
const comicMode = this.state.comicMode || false;
const centreMoleculesBeforeDrawing =
this.state.centreMoleculesBeforeDrawing || false;
const highlightColour = this.getColourProportionsFromHex(
this.state.highlightColour
);
const legendColour = this.getColourProportionsFromHex(
this.state.legendColour
);
const backgroundColour = this.getColourProportionsFromHex(
this.state.backgroundColour
);
const symbolColour = this.getColourProportionsFromHex(
this.state.symbolColour
);
const svgMode = this.state.svgMode || false;
if (this.state.computing) {
return (
<div className="columns">
<div className="column">
<span
style={{ width: width, height: height }}
key="computing-input-icon"
className="icon is-small is-left"
>
<i className="fas fa-circle-notch fa-spin" />
</span>
</div>
</div>
);
}
return (
<div className="columns">
<div className="column" style={{ margin: "12px 12px" }}>
<div
style={{
width: width + 12,
height: height + 12,
border: "1px solid rgba(0,0,0,.1)",
borderRadius: "2px"
}}
>
<MoleculeStructure
id="structure-example-drawing-options"
structure={this.state.mainStructureInput}
subStructure={this.state.subStructureInput}
drawingDelay={200}
width={width}
height={height}
svgMode={svgMode}
extraDetails={{
legend: this.state.legend || "",
legendFontSize: this.state.legendFontSize || 16,
bondLineWidth,
rotate,
clearBackground: true,
addStereoAnnotation,
addAtomIndices,
addBondIndices,
explicitMethyl,
scaleBondWidth,
highlightColour,
legendColour,
backgroundColour,
symbolColour,
centreMoleculesBeforeDrawing,
annotationFontScale,
comicMode
}}
/>
</div>
</div>
</div>
);
}
renderInputIcon() {
if (this.state.computing) {
return (
<span key="computing-input-icon" className="icon is-small is-left">
<i className="fas fa-circle-notch fa-spin" />
</span>
);
} else {
return (
<span key="search-input-icon" className="icon is-small is-left">
<i className="fas fa-search" />
</span>
);
}
}
handleStateChange = _.debounce((e, stateProp) => {
this.setState({ computing: true });
setTimeout(() => {
let value;
if (e.target.type === "number") {
value = parseFloat(e.target.value, 10);
} else if (e.target.type === "checkbox") {
value = !!e.target.checked;
} else {
value = e.target.value;
}
this.setState({ [stateProp]: value });
this.setState({ computing: false });
}, 100);
}, 300);
getColourProportionsFromHex(hex) {
return _.take(
hexRgb(hex, { format: "array" }).map((v) =>
parseFloat((v / 255).toFixed(2), 10)
),
3
);
}
}
export default ExampleDrawingOptions;
Where to go next?
You can visit the JavaScript examples here, which presents the low-level API of RDKit.js.
You can visit the Vue examples here, which include more advanced and interactive examples.
You can visit the Angular examples here, which include more advanced and interactive examples.
You can also checkout the legacy getting started and demo.