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.
const OESVGGroup *svg_group_circ = image.NewSVGGroup("circle");
image.PushGroup(svg_group_circ);
image.DrawCircle(OEGetCenter(image), 30.0, OERedBoxPen);
image.PopGroup(svg_group_circ);
OEWriteImage("CreateSVGGroup.svg", image);
Download code
First an OESVGGroup object is created on the image by calling the
OEImageBase::NewSVGGroup
method.The OESVGGroup object is the can be utilized by invoking the
OEImageBase::PushGroup
method. This result in writing the<g id='circle'>
line into thesvg
image.Each push has to be coupled with a corresponding pop. When the
OEImageBase::PopGroup
method is invoked the</g>
closing line will be written into the image file.
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
Group SVG element section in MDN
Grouping section in W3C
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.
OESVGGroup* svg_group_circ = image.NewSVGGroup("circle");
OESVGGroup* svg_group_rect = image.NewSVGGroup("rectangle");
const OESVGClass* 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(OEGetCenter(image), 30.0, OERedBoxPen);
image.PopGroup(svg_group_circ);
image.PushGroup(svg_group_rect);
image.DrawRectangle(OE2DPoint(10, 10), OE2DPoint(90, 90), OELightGreyPen);
image.PopGroup(svg_group_rect);
OEWriteImage("CreateSVGClass.svg", image);
Download code
First two OESVGGroup objects are created on the image, followed by creating a OESVGClass object by calling the
OEImageBase::NewSVGClass
method.The OESVGClass object then can be added to any groups by calling
OESVGGroup::AddSVGClass
method.When a OESVGGroup object is pushed classes associated with it will be written into the
svg
file:<g id='circle' class='object'>
and<g id='rectangle' class='object'>
.
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
MDN Class attribute section in MDN
WSC Class attribute section in WSC
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
andOEAddSVGToggle
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.
Hover the mouse over any atom |
Click on any atom |
|
|
Hover the mouse over any bond |
Click on the middle on any bond |
|
|
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
OEDrawIridiumData
functionOEDrawPeptide
functionOERenderRamachandranPlot
functionOERenderBFactorMap
function
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.
Download code
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.
const auto width = 400u;
const auto height = 200u;
OEImage image(width, height);
OEGraphMol mol;
OESmilesToMol(mol, "Cc1cccnc1/C=C/[C@H](C(=O)O)O");
OEPrepareDepiction(mol);
OE2DMolDisplayOptions opts(width, height, OEScale::AutoScale);
OE2DMolDisplay disp(mol, opts);
for (OEIter<OE2DAtomDisplay> ai = disp.GetAtomDisplays(); ai; ++ai)
{
OE2DAtomDisplay* adisp = ai;
const OEAtomBase* atom = adisp->GetAtom();
const string message = "atom idx=" + OENumberToString(atom->GetIdx());
OEAddSVGClickEvent(disp, adisp, message);
}
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:
Generate a directory (such as
test
) that contains both theAddAtomClickEvent.svg
and theindex.html
file (click on them to download).Start up a HTTP server inside
test
directoryprompt> python -m http.server
Open http://0.0.0.0:8000 in your browser (see image below)
Click on any atom on the image and the message specified by the
OEAddSVGClickEvent
function will be displayed below the image.