cdk / cdk

The Chemistry Development Kit
https://cdk.github.io/
GNU Lesser General Public License v2.1
487 stars 157 forks source link

Atom number depiction in the reaction svg #1101

Closed parit closed 1 week ago

parit commented 1 month ago

Hello, I am working on a new version of Rhea reaction visualizer, where I can show the atom mapping along with the transformation that happens in the reaction. I am using an atom mapped smile generated via RXNMapper and then generating svg with CDKKit. Here is the code snippet.

public static void main( String[] args )
        throws CDKException, IOException
    {
        String aam = "[NH2:1][c:2]1[n:3][c:4]2[c:5]([c:6](=[O:7])[nH:8]1)[N:9]([CH:34]=[O:33])[C@@H:10]([CH2:11][NH:12][c:13]1[cH:14][cH:15][c:16]([C:17](=[O:18])[NH:19][C@@H:20]([CH2:21][CH2:22][C:23](=[O:24])[O-:25])[C:26](=[O:27])[O-:28])[cH:29][cH:30]1)[CH2:31][NH:32]2.[NH3+:35][C@@H:36]([CH2:37][CH2:38][C:39](=[O:40])[O-:41])[C:42](=[O:43])[O-:44]>>[NH2:1][c:2]1[n:3][c:4]2[c:5]([c:6](=[O:7])[nH:8]1)[NH:9][C@@H:10]([CH2:11][NH:12][c:13]1[cH:14][cH:15][c:16]([C:17](=[O:18])[NH:19][C@@H:20]([CH2:21][CH2:22][C:23](=[O:24])[O-:25])[C:26](=[O:27])[O-:28])[cH:29][cH:30]1)[CH2:31][NH:32]2.[O:33]=[CH:34][NH:35][C@@H:36]([CH2:37][CH2:38][C:39](=[O:40])[O-:41])[C:42](=[O:43])[O-:44].[H+:45]";
        final SmilesParser smilesParser = new SmilesParser(DefaultChemObjectBuilder.getInstance());
        IReaction rxn = smilesParser.parseReactionSmiles(aam);
        DepictionGenerator myGenerator = new DepictionGenerator()
            .withAtomColors(new CDK2DAtomColors())
            .withBackgroundColor(Color.WHITE)
            .withAtomMapNumbers()
            .withAnnotationColor(Color.RED);
        String svg = myGenerator.depict(rxn).toSvgStr("px");
        Files.writeString(Paths.get("rxn.svg"), svg);
    }

This gives me the required svg correctly (See attached). rxn

Now I wanted to manipulate this via javascript in the browser. So basically, I want to turn on/off atom mapping. To test this, I opened the svg file in browser (Chrome/ff) and ran the following javascript in console:

Array.from(document.querySelectorAll('.annotation')).forEach(el => el.setAttribute("stroke", "#000000"))

As you will see, some atom numbers turn black and others remain red. It means not all the atom numbers are marked with class "annotation". I am not sure why it is so? Shouldn't all the atom numbers (represented by path element) be marked with class annotation?

I hope someone could clarify this. Big thanks for developing this toolkit.

johnmay commented 1 month ago

In my experience generally loading an SVG in the dom is a bit wonky and they are better treated as <img> tags and just have multiple of them. Particularly because there are likely more options you want to tweak, For follow is all generated on the fly with CDK depict from SMILES:

https://github.com/user-attachments/assets/2ed887eb-1731-4d52-ac5e-81d3753866b7

Having said that I think it is the fill you want to tweak since we embed the fonts glyphs. It could be that something has gone out of sync.

BTW here was an old demo page when I was playing with the idea of doing this.

https://cdk.github.io/cdk/1.5/docs/svg/examples.html

It turns out once you have more than one <object> on a page (e.g. a page of results) performance is pretty poor.

johnmay commented 1 week ago

OK to close?

parit commented 1 week ago

Hello @johnmay For now I have a hacky way to make it work to select specific svg path elements and it works fine. Using "fill" as you suggested as well as "fill-opacity". I can see it's easier to generate all the images on the fly but don't want to pack the cdkit in our webapp, instead have svg prepared as a batch job. Seems to work fine for now so yes happy to close the issue.