Generating Interactive SVG Images

SVG group

SVG group is a container for grouping and naming collections of SVG drawing elements. In OEDepict TK, the OESVGGroup class is to used for grouping drawing instructions together.

The code snippet below shows how to create and use an OESVGGroup object.

svg_group_circ = image.NewSVGGroup("circle")

image.PushGroup(svg_group_circ)
image.DrawCircle(oedepict.OEGetCenter(image), 30, oedepict.OERedBoxPen)
image.PopGroup(svg_group_circ)

oedepict.OEWriteImage("CreateSVGGroup.svg", image)

Download code

CreateSVGGroup.py

The above snippet will generate the following svg image:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"   viewBox="0.00 0.00 100.00 100.00">
<!-- Created by OpenEye Scientific Software -->
<!-- Creation Date Fri Mar  3 16:37:06 2017 -->
<rect width="100.00" height="100.00" fill="white" />
<g id='circle'>
<circle cx="50.00" cy="50.00" r="30.00" fill="red" stroke="red" stroke-linejoin="round" stroke-linecap="round" />
</g>
</svg>

The guideline below should be followed when using SVG groups in OEDepict TK:

  • The name of the OESVGGroup has to be unique for the given image and it can only contain alphanumeric, _ or - characters.

  • An OESVGGroup object can be used (pushed / popped) only once.

  • OESVGGroup objects can be nested. They should be used in LIFO (for last in, first out) i.e. the group that has been pushed last should be popped first.

See also

SVG class

In OEDepict TK, the OESVGClass class can be used to add class attributes to group containers.

The code snippet below shows how to create and use an OESVGClass object.

svg_group_circ = image.NewSVGGroup("circle")
svg_group_rect = image.NewSVGGroup("rectangle")
svg_class_objs = image.NewSVGClass("object")

svg_group_circ.AddSVGClass(svg_class_objs)
svg_group_rect.AddSVGClass(svg_class_objs)

image.PushGroup(svg_group_circ)
image.DrawCircle(oedepict.OEGetCenter(image), 30, oedepict.OERedBoxPen)
image.PopGroup(svg_group_circ)

image.PushGroup(svg_group_rect)
image.DrawRectangle(oedepict.OE2DPoint(10, 10), oedepict.OE2DPoint(90, 90), oedepict.OELightGreyPen)
image.PopGroup(svg_group_rect)

oedepict.OEWriteImage("CreateSVGClass.svg", image)

Download code

CreateSVGClass.py

The above snippet will generate the following svg image:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"   viewBox="0.00 0.00 100.00 100.00">
<!-- Created by OpenEye Scientific Software -->
<!-- Creation Date Fri Mar  3 17:22:19 2017 -->
<rect width="100.00" height="100.00" fill="white" />
<g id='circle' class='object'>
<circle cx="50.00" cy="50.00" r="30.00" fill="red" stroke="red" stroke-linejoin="round" stroke-linecap="round" />
</g>
<g id='rectangle' class='object'>
<rect x="10" y="10" width="80" height="80" fill="none" stroke="#bfbfbf" stroke-linejoin="round" stroke-linecap="round" />
</g>
</svg>

The guideline below should be followed when using SVG classes in OEDepict TK:

  • The name of the OESVGClass has to be unique for the given image and it can only contain alphanumeric, _ or - characters.

  • An OESVGClass object can be associated with multiple OESVGGroup objects.

  • An OESVGGroup object can be associated with multiple OESVGClass objects.

See also

Examples of Generating Interactive SVG Images

OEDepict TK also provides high-level APIs that are not only group SVG elements together but also adds styles and events to them to generate interactive images.

See the following OEDepict TK API:

  • OEAddSVGHover and OEAddSVGToggle low-level functions that allow to add effects to any objects.

  • OEAddSVGClickEvent low-level functions that allows to add click event to any objects.

  • OEDrawSVGHoverText function that displays a text associated with an atom or bond when the mouse is hovering over their position on the image.

  • OEDrawSVGToggleText function that displays a text associated with an atom or bond when clicking at their position on the image.

Gallery of OEDepict TK examples of interactive SVG images

Hover the mouse over any atom

Click on any atom

Hover the mouse over any bond

Click on the middle on any bond

../_images/HoverAtomText.svg ../_images/ToggleAtomText.svg ../_images/HoverBondText.svg ../_images/ToggleBondText.svg

See also the following OEGrapheme TK APIs that generate interactive SVG images:

  • OERenderContactMap function that generated an interactive protein-ligand contact map image. Clicking on any residue will highlight those ligand atoms that are interacting with the residue.

click on any residue circles

../_images/RenderContactMap.svg

Inserting SVG Images into HTML

The interactive svg image generated by OEDepict TK and Grapheme TK can inserted into HTML files with the SVG MIME type:

<object data="<imagename>.svg" type="image/svg+xml"></object>

The following example inserts two svg images into an HTML table:

<!DOCTYPE html>
<html>
<head>
  <title>test</title>
</head>
<body>

<h2>Examples of interactive SVG images inserted into HTML</h2>

<table style="width:100%">
  <tr>
    <th>hover atom text</th>
    <th>toggle atom text</th> 
  </tr>
  <tr>
   <td><object data="hover-atom-text.svg" type="image/svg+xml"  width = "400" ></object></td>
   <td><object data="toggle-atom-text.svg" type="image/svg+xml"  width = "400" ></object></td>
  </tr>

</table>
</body>
</html>

Download the following three files and open the insert-index.html file in a browser.

How to Catch SVG Events

The example in this section illustrates how to throw a mouse event in an .svg image and how to catch it in a html file.

The code below shows how to create an .svg image where each atom is associated with an SVG event. When clicking on an atom in the image, a click event is fired with the message specified in the OEAddSVGClickEvent function.

width, height = 400, 200
image = oedepict.OEImage(width, height)

mol = oechem.OEGraphMol()
smiles = "Cc1cccnc1/C=C/[C@H](C(=O)O)O"
oechem.OESmilesToMol(mol, smiles)
oedepict.OEPrepareDepiction(mol)

opts = oedepict.OE2DMolDisplayOptions(width, height, oedepict.OEScale_AutoScale)
opts.SetMargins(10)
disp = oedepict.OE2DMolDisplay(mol, opts)

for adisp in disp.GetAtomDisplays():
    atom = adisp.GetAtom()
    message = "atom idx=%s" % atom.GetIdx()
    oedepict.OEAddSVGClickEvent(disp, adisp, message)

oedepict.OERenderMolecule("AddAtomClickEvent.svg", disp)

The events thrown by the AddAtomClickEvent.svg image can be caught in the html file that contains the image. The following html file illustrates how to catch the events and display the messages that were associated with the atoms using the OEAddSVGClickEvent function.

<!DOCTYPE html>
<html>
<head>
  <title>test</title>

  <script type="text/javascript">
    window.addEventListener("load", init);

    function init() {
      var svg = document.getElementById('depictsvg');
      svg.contentDocument.addEventListener('OEDepictSVGEvent', function(evt) {
        var logarea = document.querySelector('.svg-event-log');
        logarea.innerHTML = evt.detail.message;
      });
    }
  </script>

</head>
<body>

<h2> Image </h2>
<object data="AddAtomClickEvent.svg" type="image/svg+xml" id="depictsvg" width = "400" ></object>

<h2>Event log message:</h2>
<h4 class="svg-event-log">

</h4>

</body>
</html>

To try it out follow the instructions below:

  1. Generate a directory (such as test) that contains both the AddAtomClickEvent.svg and the index.html file (click on them to download).

  2. Start up a HTTP server inside test directory

    prompt> python -m http.server
    
  3. Open http://0.0.0.0:8000 in your browser (see image below)

  4. Click on any atom on the image and the message specified by the OEAddSVGClickEvent function will be displayed below the image.

../_images/ScreenShot-AddAtomClickEven.png

Screenshot of the OEAddSVGClickEvent example in the browser