1

I'm trying to use Cytoscape.js to create a diagram of chemical reactions generated from student input, but I can't seem to get the images of the molecules to display on each of the nodes.

The images I need are automatically generated with RDKit.js.

These images can be displayed outside of cytoscape just fine (when embedded in a plain HTML document, for example), but I can't get the images to display properly on the cytoscape diagram nodes. Specifically, when I try to use the RDKit svg as the node's background-image, it won't display it.

Here's a live example of what I've tried so far, modified from some other guides about using svg images with cytoscape. Here's what it looks like:

Example diagram image

And here's the code for the node data:

[
  {
    "data": {
      "id": "id0"
    },
    "position": {
      "x": 44,
      "y": 93
    },
    "style": {
      "background-image": "data:image/svg+xml;utf-8,%3Csvg%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20version=%221.1%22%20xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cpath%20d=%22M12,11.5A2.5,2.5%200%200,1%209.5,9A2.5,2.5%200%200,1%2012,6.5A2.5,2.5%200%200,1%2014.5,9A2.5,2.5%200%200,1%2012,11.5M12,2A7,7%200%200,0%205,9C5,14.25%2012,22%2012,22C12,22%2019,14.25%2019,9A7,7%200%200,0%2012,2Z%22%20fill=%22yellow%22%3E%3C/path%3E%3C/svg%3E",
      "background-fit": "cover cover",
      "background-image-opacity": 1
    }
  },
  {
    "data": {
      "id": "id1"
    },
    "position": {
      "x": 77,
      "y": 93
    },
    "style": {
      "background-image": "benzene.svg",
      "background-fit": "cover cover",
      "background-image-opacity": 1
    }
  },
  {
    "data": {
      "id": "id2"
    },
    "position": {
      "x": 77,
      "y": 150
    },
    "style": {
      "background-image": "data:image/svg+xml;utf-8,data:image/svg+xml;utf-8,%3C%3Fxml version='1.0' encoding='iso-8859-1'%3F%3E%3Csvg version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg' xmlns:rdkit='http://www.rdkit.org/xml' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve' width='250px' height='200px' viewBox='0 0 250 200'%3E%3C!-- END OF HEADER --%3E%3Crect style='opacity:1.0;fill:%23FFFFFF;stroke:none' width='250.0' height='200.0' x='0.0' y='0.0'%3E%3C/rect%3E%3Cpath class='bond-0 atom-0 atom-1' d='M 230.0,100.0 L 177.5,190.9' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-0 atom-0 atom-1' d='M 211.8,100.0 L 168.4,175.2' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-1 atom-1 atom-2' d='M 177.5,190.9 L 72.5,190.9' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-2 atom-2 atom-3' d='M 72.5,190.9 L 20.0,100.0' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-2 atom-2 atom-3' d='M 81.6,175.2 L 38.2,100.0' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-3 atom-3 atom-4' d='M 20.0,100.0 L 72.5,9.1' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-4 atom-4 atom-5' d='M 72.5,9.1 L 177.5,9.1' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-4 atom-4 atom-5' d='M 81.6,24.8 L 168.4,24.8' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath class='bond-5 atom-5 atom-0' d='M 177.5,9.1 L 230.0,100.0' style='fill:none;fill-rule:evenodd;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1' /%3E%3Cpath d='M 227.3,104.5 L 230.0,100.0 L 227.3,95.5' style='fill:none;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;' /%3E%3Cpath d='M 180.1,186.4 L 177.5,190.9 L 172.2,190.9' style='fill:none;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;' /%3E%3Cpath d='M 77.8,190.9 L 72.5,190.9 L 69.9,186.4' style='fill:none;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;' /%3E%3Cpath d='M 22.7,104.5 L 20.0,100.0 L 22.7,95.5' style='fill:none;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;' /%3E%3Cpath d='M 69.9,13.6 L 72.5,9.1 L 77.8,9.1' style='fill:none;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;' /%3E%3Cpath d='M 172.2,9.1 L 177.5,9.1 L 180.1,13.6' style='fill:none;stroke:%23000000;stroke-width:2.0px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;' /%3E%3C/svg%3E",
      "background-fit": "cover cover",
      "background-image-opacity": 1
    }
  }
]

There are three nodes in this diagram; the first node ("id0", top left) uses an example SVG from another tutorial, and it displays as expected.

The second node ("id1", top right) displays a chemical structure generated by RDKit. This structure's image was saved as a separate svg file. This works as expected, but I can't use this method for my desired application.

Finally, for the third node ("id2", bottom right), I've tried encoding and embedding the svg and using it directly, as in the first example. The second and third node should be identical! Instead there is no image on the third node at all.

I've tried trimming out the excess header information from the svg (leaving just the width, height, version, and xmlns). I've tried changing the width and height in the header to match the example svg. I've even tried running the svg through various optimizers, all to no avail. How can I fix this?

  • Did you figure this out yet? The [rdkit tag at MMSE](https://mattermodeling.stackexchange.com/questions/tagged/rdkit) has 95.5% of its questions answered. If you want this question migrated there, please ping me by typing @Nike in a comment and letting me know. I'll make a case to the moderators for a migration. – Nike Mar 10 '23 at 20:25
  • @Nike Thanks for the followup! I did just recently get it to work by encoding the svg to base64 and using that - it's not necessarily an ideal solution, but it works! Thanks also for making me aware of the existence of MMSE, I'll go there first in the future. – Jacob Horger Mar 13 '23 at 17:32
  • I'm glad it worked out for you! Why not write a self-answer to help future users? – Nike Mar 13 '23 at 19:15

1 Answers1

0

Just in case this comes up in the future for anyone else: I solved the problem by encoding the svg to base64 and using that. So, if you have something like this:

var svg = "<svg>[svg content here]</svg>";

Encode it like this:

var svgBase64 = btoa(svg);

And then use that as the Cytoscape background-image instead.