Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: PNG drawer does work in version 2.1.7 as a React component #167

Open
biostu24 opened this issue Mar 27, 2023 · 5 comments
Open

Bug: PNG drawer does work in version 2.1.7 as a React component #167

biostu24 opened this issue Mar 27, 2023 · 5 comments

Comments

@biostu24
Copy link

biostu24 commented Mar 27, 2023

I am using React in Next.js.

I created a React component to render a chemical structure and I found when using SmilesDrawer.Drawer, the canvas is not updated and no structure is drawn. Using SmilesDrawer.SvgDrawer does work. After a bit of experimentation I found this appears to be a bug with version 2.1.7. Rolling back to earlier 2.1.x versions resulted in an import error. Rolling back to version 2.0.3 the SmilesDrawer.Drawer class does work.

Also, it would be very helpful if the documentation showed how to use smiles-drawer with React as it is not immediately obvious.

Summary of issues:

  • SmilesDrawer.Drawer does not render PNG image in version 2.1.7.
  • SmilesDrawer.SvgDrawer works correctly in 2.1.7.
  • Versions 2.1.1 to 2.1.6 throw SyntaxError: Cannot use import statement outside a module when importing.
  • SmilesDrawer.Drawer works correctly in version 2.0.3.

Example code

This code is for a component to render a structure either as PNG or SVG.

import React, { useRef, useEffect } from "react";
import SmilesDrawer from "smiles-drawer";

const USE_SVG = false;

const SETTINGS = {
  width: 800,
  height: 400,
};

const SmileDrawerContainer = ({ smilesStr }: { smilesStr: string }) => {
  if (USE_SVG) {
    // SVG version (versions: <=2.0.3 and 2.1.7)
    const svgRef = useRef<SVGElement>(null);

    let drawer = new SmilesDrawer.SvgDrawer(SETTINGS);

    useEffect(() => {
      SmilesDrawer.parse(smilesStr, function (tree: any) {
        drawer.draw(tree, "structure-svg", "light");
      });
    }, []);

    return (
      <div>
        <svg id="structure-svg"></svg>
      </div>
    );
  } else {
    // Canvas version (versions: <=2.0.3 only)
    const canvasRef = useRef<HTMLCanvasElement>(null);

    let drawer = new SmilesDrawer.Drawer(SETTINGS);

    useEffect(() => {
      SmilesDrawer.parse(smilesStr, function (tree: any) {
        drawer.draw(tree, "structure-canvas", "light");
      });
    }, []);

    return (
      <div>
        <canvas
          className="relative"
          id="structure-canvas"
          ref={canvasRef}
          width={"800px"}
          height={"400px"}
        />
      </div>
    );
  }
};

export default SmileDrawerContainer;
@whitead
Copy link
Contributor

whitead commented Apr 2, 2023

Thanks for writing this out - I've been so confused.

@Acylation
Copy link

Acylation commented Apr 26, 2023

const source = 'CC(=O)Nc1ccccc1C(=O)O'
const targetImg = container.createEl('img') as HTMLImageElement // container is a HTMLDivElement, decleared previously
const theme = 'dark'

let drawer = new SmilesDrawer.SmiDrawer();
drawer.draw(source, targetImg, theme)

These lines are able to generate a PNG file in v2.1.7.

@biostu24
Copy link
Author

If that is the case, the documentation really needs to be updated to reflect that a canvas element no longer works

@Acylation
Copy link

Acylation commented Jun 1, 2023

Here's a React example that yields png

const imgRef = useRef<HTMLImageElement>(null);
const drawer = new SmilesDrawer.SmiDrawer(options); // options is a param

useEffect(() => {
  drawer.draw(smilesStr, imgRef.current, 'light');
});

return (
  <div>
    <img ref={imgRef} width={300}></img>
  </div>
);

@Sinkler521
Copy link

Sinkler521 commented Jun 8, 2024

If that is the case, the documentation really needs to be updated to reflect that a canvas element no longer works

2.1.7 smiles-drawer still works with canvas.
Look at example/next.html file in lib repository and go this way. In case you'll draw a lot of different molecules, create a function which generates unique classname for each of those canvas element

Example: codesandbox link look at the files SmilesDrawer.tsx and App.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants