Hi,
I recently started to work with Vaadin. Actually I work on portlets for a portal used in chemical research. I want to create a UI element that is able to show the 3D structure of a molecule. Therefore I use
ChemDoodle
. ChemDoodle is a Javascript library which enables the 3D representation of molecules. An easy example for the usage of ChemDoodle would be:
<html>
<head>
<title>3D Interactive Model of DDT test 2</title>
<link rel="stylesheet" href="http://hub.chemdoodle.com/cwc/latest/ChemDoodleWeb.css" type="text/css">
<script type="text/javascript" src="http://hub.chemdoodle.com/cwc/latest/ChemDoodleWeb-libs.js"></script>
<script type="text/javascript" src="http://hub.chemdoodle.com/cwc/latest/ChemDoodleWeb.js"></script>
</head>
<body>
<script type="text/javascript">
var mol_DDT = '3036\n CHEMDOOD12280913053D\n\n 28 29 0 0 0 0 0 0 0999 V2000\n 0.0456 1.0544 -1.9374 Cl 0 0 0 0 0 0 0 0 0 0 0 0\n -0.7952 -1.7026 -1.7706 Cl 0 0 0 0 0 0 0 0 0 0 0 0\n 0.6447 -0.8006 -4.1065 Cl 0 0 0 0 0 0 0 0 0 0 0 0\n 1.8316 -0.9435 4.4004 Cl 0 0 0 0 0 0 0 0 0 0 0 0\n 6.9949 1.1239 -3.9007 Cl 0 0 0 0 0 0 0 0 0 0 0 0\n 1.9032 -1.0692 -1.6001 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.8846 -1.0376 -0.1090 C 0 0 0 0 0 0 0 0 0 0 0 0\n 3.2176 -0.5035 -2.1949 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.5585 -0.6223 -2.3126 C 0 0 0 0 0 0 0 0 0 0 0 0\n 2.2670 0.1198 0.5688 C 0 0 0 0 0 0 0 0 0 0 0 0\n 4.3480 -1.2638 -2.0859 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.4856 -2.1660 0.6075 C 0 0 0 0 0 0 0 0 0 0 0 0\n 3.1719 0.7242 -2.7939 C 0 0 0 0 0 0 0 0 0 0 0 0\n 2.2506 0.1490 1.9633 C 0 0 0 0 0 0 0 0 0 0 0 0\n 5.5313 -0.7541 -2.6203 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.4691 -2.1369 2.0020 C 0 0 0 0 0 0 0 0 0 0 0 0\n 4.3552 1.2340 -3.3284 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.8515 -0.9793 2.6800 C 0 0 0 0 0 0 0 0 0 0 0 0\n 5.5350 0.4948 -3.2417 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.9777 -2.1366 -1.8749 H 0 0 0 0 0 0 0 0 0 0 0 0\n 2.5727 1.0177 0.0401 H 0 0 0 0 0 0 0 0 0 0 0 0\n 4.3513 -2.2356 -1.6034 H 0 0 0 0 0 0 0 0 0 0 0 0\n 1.1951 -3.0814 0.0991 H 0 0 0 0 0 0 0 0 0 0 0 0\n 2.3077 1.3562 -2.8879 H 0 0 0 0 0 0 0 0 0 0 0 0\n 2.5491 1.0585 2.4783 H 0 0 0 0 0 0 0 0 0 0 0 0\n 6.4431 -1.3411 -2.5451 H 0 0 0 0 0 0 0 0 0 0 0 0\n 1.1584 -3.0244 2.5473 H 0 0 0 0 0 0 0 0 0 0 0 0\n 4.3449 2.2098 -3.8075 H 0 0 0 0 0 0 0 0 0 0 0 0\n 1 9 1 0 0 0 0\n 2 9 1 0 0 0 0\n 3 9 1 0 0 0 0\n 4 18 1 0 0 0 0\n 5 19 1 0 0 0 0\n 6 7 1 0 0 0 0\n 6 8 1 0 0 0 0\n 6 9 1 0 0 0 0\n 6 20 1 0 0 0 0\n 7 10 2 0 0 0 0\n 7 12 1 0 0 0 0\n 8 11 2 0 0 0 0\n 8 13 1 0 0 0 0\n 10 14 1 0 0 0 0\n 10 21 1 0 0 0 0\n 11 15 1 0 0 0 0\n 11 22 1 0 0 0 0\n 12 16 2 0 0 0 0\n 12 23 1 0 0 0 0\n 13 17 2 0 0 0 0\n 13 24 1 0 0 0 0\n 14 18 2 0 0 0 0\n 14 25 1 0 0 0 0\n 15 19 2 0 0 0 0\n 15 26 1 0 0 0 0\n 16 18 1 0 0 0 0\n 16 27 1 0 0 0 0\n 17 19 1 0 0 0 0\n 17 28 1 0 0 0 0\nM END\n';
</script>
<script type="text/javascript">
var view = new ChemDoodle.TransformCanvas3D('view', 640, 640);
view.specs.set3DRepresentation('Ball and Stick');
view.specs.backgroundColor = 'black';
var molecule = ChemDoodle.readMOL(mol_DDT, 1);
view.loadMolecule(molecule);
</script>
</body>
</html>
The ChemDoodle libraries are loaded in the head element. In the body element, the first script tag defines the molecule, the second creates a canvas in which it is shown. (Just run it by yourself to see how it looks like)
In a first test I added this html document as resource to my portlet and used the Embedded component to show it (Used the resource in Embedded constructor). This works just fine! The problem now is of course that I also want to display other molecules than that defined in the html document i.e. I would like to exchange the first script element during runtime. For this purpose I created my own Widget which is extended from Embedded and VEmbedded respectively (creating own simple widgets worked just fine in some tests). I tried to exchange the script tag in the client side component in the ‘updateFromUIDL’ method like:
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
super.updateFromUIDL(uidl, client);
Element browserElement = DOM.getFirstChild(getElement()); //this is the way VEmbedded gets the browser Element
Element bodyElement = browserElement.getElementsByTagName("body").getItem(0); //get the body of html document
bodyElement.getFirstChildElement().setInnerText(....define new molecule here...); //this should return the first script element. I want to define a new molecule here
}
The new molecule definition shall later be obtained from the uidl of course. By now I just hardcoded the new definition in ‘setInnerText()’ to see if this works in general. However, this does not work and I really don’t know why? Is this dynamic injection not allowed in general? I know the Embedded component creates an IFrame and sets the src attribute to the defined html document. Maybe i can’t change the script element because it would then be a kind of disagreement to the defined src?
By now I worked on three different solutions:
- Create own widget not extended from Embedded. Used a div element and added the corresponding script tags to load the libraries and create the canvas. This did not work at all…
- If the molecule is set once, it will not change in this canvas anymore. So just read in the given html document resource and overwrite first script tag in file (where molecule is defined) with the definition of a new molecule. Then load this new file as resource and use the normal Embedded component. I have not tried this but it should work… nevertheless it’s not a good solution in my opinion.
- Create widget extended from Embedded and replace first script element at runtime (as discussed above)
I would be very happy if some of you would like to discuss this problem with me. I’m stuck at this point
Thanks,
Andi