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 .

Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
Loading renderer...
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.

Loading renderer...
Loading renderer...
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.

Loading renderer...
Loading renderer...
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.

Loading renderer...
Loading renderer...
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.

Loading renderer...
Loading renderer...
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;

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.

Loading renderer...
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.