Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Good read from JMP Help Construct Display Boxes for New Windows (jmp.com). I did at the end mention that I would post quick template I tend to use (my complete template does have a bit more bells and whistles DEPENDING on what type of add-in it is going to be).
/*""" One sentence function description.
Author: jthi
Creation Date: 2023-11-16
Creation JMP Version: JMP Pro 17.2.0
Description (generally this part is longer explanation about the app): This is part of the template I generally use. I do have different utility
functions which I add through version control as needed and I store my configuration files
separated from this script.
Basic structure for my add-ins/larger tools is:
/my_app
/config
ma_config.jsl
/bin
/externals
ma_utilies.jsl
/doc
my_app.jsl
my_app -> ma prefix. I use this type of prefixes for some of my script names
because JMPs Recent Files shows only the file name, nothing more. This way I can at least
have an idea which config file I'm going to open as I develop many different tools.
/config contains all sorts of configuration files, it could be sql query templates, images,
settings files, specification tables...
/bin contains the scripts which are included to make my_app work
/bin/externals are common scripts/files which I copy as externals (I'm using svn for version control)
as needed (for example generic utility functions, version control functions)
/doc would contain documentation but it is usually empty. User instructions and such
I write to content management system and my code documents itself (mostly). Sometimes
this folder does contain flowcharts or some sort of readme if I feel like those are needed.
Some examples which might (or might not) follow this type of template can be found from community:
- https://community.jmp.com/t5/Discovery-Summit-Europe-2023/Pythonless-Python-Integration-for-JMP-2023-EU-30MP-1265/ta-p/572674
- https://community.jmp.com/t5/JMP-Add-Ins/Analyse-Columns/ta-p/460329
- https://community.jmp.com/t5/JMP-Add-Ins/Enhanced-Sankey-Plot-ESP/ta-p/549745 (different layout)
Todo:
*
*
"""*/
Names Default To Here(1);
app_name = "My App Template";
version_str = "1.0.0";
window_name = app_name || " - version: " || version_str;
help_url = "https://community.jmp.com/";
window_icon = "Distrib"; // Built-in JMP Icons is very helpful for icons
// I either keep the logo in my config folder or store the expression created by
// JMP when I open that (usually I store the expression), for example:
// company_logo = Open("$SAMPLE_IMAGES/tile.jpg", "jpg");
company_logo = Icon Box("JMPLogo") << get picture;
run_app = Expr(
nw = New Window(window_name, Show Menu(0), Show Toolbars(0),
V List Box(align("center"),
H List Box(
Try(Picture Box(company_logo)),
Spacer Box(Size(5,0)),
H List Box(Align(top),
Text Box(app_name, << Set Font Size(22), << Font Color("Red"), << Set Font Style("Bold"), << Set Wrap(500)),
Text Box(version_str, << Set Font Size(11), << Font Color("Black"), << Set Font Style("Plain"))
)
),
Tab Box(
Tab Page Box("Inputs",
// Usually I don't force my tab page box sizes, but if I do, I use Spacer Boxes like this
V List Box(Spacer Box(Size(600, 0)), // Force width using V List Box + Spacer Box
H List Box(Spacer Box(Size(0, 300)), // H List Box + Spacer Box for height
Lineup Box(N Col(1),
Text Box("Some inputs here"), // And content inside this H List Box + Spacer Box
)
)
),
, << Set Base Font("Title")
),
Tab Page Box("Actions",
Lineup Box(N Col(1),
Button Box("OK",
<< Set Icon("RunTableScript")
),
Button Box("Cancel",
<< Set Function(function({this}, (this << top parent) << close window)
)
, << Set Icon("DebuggerAddBreakpoint")
),
Spacer Box(Size(0, 10)),
Button Box("Help", Web(help_url), << Set Icon("WinHelpAbout")),
), << Set Base Font("Title")
), << Set Style("Horizontal Spread")
)
), << Set Window Icon(window_icon)
);
);
run_app;
Write(); // I use Write(); to avoid "returning" the last run line mostly to keep log cleaner
Great overview and invaluable information for understanding visual elements in JSL. If you’re building a graphical interface (e.g., dialog box and report) consider using Application Builder. AB lets you more quickly and efficiently build the visual parts of applications using drag-and-drop to create, organize, and reorganize elements. It will save you a ton of time by generating the code for all visual elements and letting you change most properties interactively through the integrated Property window. You can still make changes programmatically, if needed. The layout can be built and changed interactively. In the end, you end up with an application that’s more compact and easier to maintain. I recently did a Discovery session on AB and added a recipe to the JSL Cookbook (I’m still working on the second recipe I used in the live Discovery session).
There are some differences between from-scratch JSL and AB, particularly when it comes to work with objects (e.g., how they are referenced and how scripts are associated with them) and passing values between windows (modules). I talk about this in the Discovery materials and the second recipe will act as an example.
Regardless of the approach you use to build your applications, what Troy talked about is still important. You can still message objects to change their properties. This comes in handy when you need to set a value at run time or when the property doesn’t appear in the Property panel (e.g., White Box Style for Text Edit Box). The Scripting Index is the best place to find information about the messages an object will take and examples of their use. It’s also good to understand what objects do and how to use them.
'
var data = div.getElementsByClassName("video-js");
var script = document.createElement('script');
script.src = "https://players.brightcove.net/" + data_account + "/" + data_palyer + "_default/index.min.js";
for(var i=0;i< data.length;i++){
videodata.push(data[i]);
}
}
}
for(var i=0;i< videodata.length;i++){
document.getElementsByClassName('lia-vid-container')[i].innerHTML = videodata[i].outerHTML;
document.body.appendChild(script);
}
}
catch(e){
}
/* Re compile html */
$compile(rootElement.querySelectorAll('div.lia-message-body-content')[0])($scope);
}
if (code_l.toLowerCase() != newBody.getAttribute("slang").toLowerCase()) {
/* Adding Translation flag */
var tr_obj = $filter('filter')($scope.sourceLangList, function (obj_l) {
return obj_l.code.toLowerCase() === newBody.getAttribute("slang").toLowerCase()
});
if (tr_obj.length > 0) {
tr_text = "This post originally written in lilicon-trans-text has been computer translated for you. When you reply, it will also be translated back to lilicon-trans-text.".replace(/lilicon-trans-text/g, tr_obj[0].title);
try {
if ($scope.wootMessages[$rootScope.profLang] != undefined) {
tr_text = $scope.wootMessages[$rootScope.profLang].replace(/lilicon-trans-text/g, tr_obj[0].title);
}
} catch (e) {
}
} else {
//tr_text = "This message was translated for your convenience!";
tr_text = "This message was translated for your convenience!";
}
try {
if (!document.getElementById("tr-msz-" + value)) {
var tr_para = document.createElement("P");
tr_para.setAttribute("id", "tr-msz-" + value);
tr_para.setAttribute("class", "tr-msz");
tr_para.style.textAlign = 'justify';
var tr_fTag = document.createElement("IMG");
tr_fTag.setAttribute("class", "tFlag");
tr_fTag.setAttribute("src", "/html/assets/lingoTrFlag.PNG");
tr_fTag.style.marginRight = "5px";
tr_fTag.style.height = "14px";
tr_para.appendChild(tr_fTag);
var tr_textNode = document.createTextNode(tr_text);
tr_para.appendChild(tr_textNode);
/* Woot message only for multi source */
if(rootElement.querySelector(".lia-quilt-forum-message")){
rootElement.querySelector(".lia-quilt-forum-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-message-view-blog-topic-message")) {
rootElement.querySelector(".lia-message-view-blog-topic-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-quilt-blog-reply-message")){
rootElement.querySelector(".lia-quilt-blog-reply-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-quilt-tkb-message")){
rootElement.querySelector(".lia-quilt-tkb-message").appendChild(tr_para);
} else if(rootElement.querySelector(".lia-quilt-tkb-reply-message")){
rootElement.querySelector(".lia-quilt-tkb-reply-message").insertBefore(tr_para,rootElement.querySelector(".lia-quilt-row.lia-quilt-row-footer"));
} else if(rootElement.querySelector(".lia-quilt-idea-message")){
rootElement.querySelector(".lia-quilt-idea-message").appendChild(tr_para);
}else if(rootElement.querySelector(".lia-quilt-column-alley-left")){
rootElement.querySelector(".lia-quilt-column-alley-left").appendChild(tr_para);
}
else {
if (rootElement.querySelectorAll('div.lia-quilt-row-footer').length > 0) {
rootElement.querySelectorAll('div.lia-quilt-row-footer')[0].appendChild(tr_para);
} else {
rootElement.querySelectorAll('div.lia-quilt-column-message-footer')[0].appendChild(tr_para);
}
}
}
} catch (e) {
}
}
} else {
/* Do not display button for same language */
// syncList.remove(value);
var index = $scope.syncList.indexOf(value);
if (index > -1) {
$scope.syncList.splice(index, 1);
}
}
}
}
}
}
angular.forEach(mszList_l, function (value) {
if (document.querySelectorAll('div.lia-js-data-messageUid-' + value).length > 0) {
var rootElements = document.querySelectorAll('div.lia-js-data-messageUid-' + value);
}else if(document.querySelectorAll('.lia-occasion-message-view .lia-component-occasion-message-view').length >0){
var rootElements = document.querySelectorAll('.lia-occasion-message-view .lia-component-occasion-message-view')[0].querySelectorAll('.lia-occasion-description')[0];
}else {
var rootElements = document.querySelectorAll('div.message-uid-' + value);
}
angular.forEach(rootElements, function (rootElement) {
if (value == '699256' && "ForumTopicPage" == "TkbArticlePage") {
rootElement = document.querySelector('.lia-thread-topic');
}
/* V1.1 Remove from UI */
if (document.getElementById("tr-msz-" + value)) {
document.getElementById("tr-msz-" + value).remove();
}
if (document.getElementById("tr-sync-" + value)) {
document.getElementById("tr-sync-" + value).remove();
}
/* XPath expression for subject and Body */
var lingoRBExp = "//lingo-body[@id = " + "'lingo-body-" + value + "'" + "]";
lingoRSExp = "//lingo-sub[@id = " + "'lingo-sub-" + value + "'" + "]";
/* Get translated subject of the message */
lingoRSXML = doc.evaluate(lingoRSExp, doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < lingoRSXML.snapshotLength; i++) {
/* Replace Reply/Comment subject with transalted subject */
var newSub = lingoRSXML.snapshotItem(i);
/*** START : extracting subject from source if selected language and source language is same **/
var sub_L = "";
if (newSub.getAttribute("slang").toLowerCase() == code_l.toLowerCase()) {
if (value == '699256') {
sub_L = decodeURIComponent($scope.sourceContent[value].subject);
}
else{
sub_L = decodeURIComponent($scope.sourceContent[value].subject);
}
} else {
sub_L = newSub.innerHTML;
}
/*** End : extracting subject from source if selected language and source language is same **/
/* This code is placed to remove the extra meta tag adding in the UI*/
try{
sub_L = sub_L.replace('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />','');
}
catch(e){
}
// if($scope.viewTrContentOnly || (newSub.getAttribute("slang").toLowerCase() != code_l.toLowerCase())) {
if ($scope.viewTrContentOnly) {
if ("ForumTopicPage" == "IdeaPage") {
if (value == '699256') {
if( (sub_L != "") && (sub_L != undefined) && (sub_L != "undefined") ){
document.querySelector('.MessageSubject .lia-message-subject').innerHTML = sub_L;
}
}
}
if ("ForumTopicPage" == "TkbArticlePage") {
if (value == '699256') {
if( (sub_L != "") && (sub_L != undefined) && (sub_L != "undefined") ){
var subTkbElement = document.querySelector('.lia-thread-subject');
if(subTkbElement){
document.querySelector('.lia-thread-subject').innerHTML = sub_L;
}
}
}
}
else if ("ForumTopicPage" == "BlogArticlePage") {
if (value == '699256') {
try {
if((sub_L != "") && (sub_L!= undefined) && (sub_L != "undefined")){
var subElement = rootElement.querySelector('.lia-blog-article-page-article-subject');
if(subElement) {
subElement.innerText = sub_L;
}
}
} catch (e) {
}
/* var subElement = rootElement.querySelectorAll('.lia-blog-article-page-article-subject');
for (var subI = 0; subI < subElement.length; subI++) {
if((sub_L != "") && (sub_L!= undefined) && (sub_L != "undefined")){
subElement[subI].innerHTML = sub_L;
}
} */
}
else {
try {
// rootElement.querySelectorAll('.lia-blog-article-page-article-subject').innerHTML= sub_L;
/** var subElement = rootElement.querySelectorAll('.lia-blog-article-page-article-subject');
for (var j = 0; j < subElement.length; j++) {
if( (sub_L != "") && (sub_L != undefined) && (sub_L != "undefined") ){
subElement[j].innerHTML = sub_L;
}
} **/
} catch (e) {
}
}
}
else {
if (value == '699256') {
try{
/* Start: This code is written by iTalent as part of iTrack LILICON - 98 */
if( (sub_L != "") && (sub_L != undefined) && (sub_L != "undefined") ){
if(document.querySelectorAll('.lia-quilt-forum-topic-page').length > 0){
if(rootElement.querySelector('div.lia-message-subject').querySelector('h5')){
rootElement.querySelector('div.lia-message-subject').querySelector('h5').innerText = decodeURIComponent(sub_L);
} else {
rootElement.querySelector('.MessageSubject .lia-message-subject').innerText = sub_L;
}
} else {
rootElement.querySelector('.MessageSubject .lia-message-subject').innerText = sub_L;
}
}
/* End: This code is written by iTalent as part of iTrack LILICON - 98 */
}
catch(e){
console.log("subject not available for second time. error details: " + e);
}
} else {
try {
/* Start: This code is written by iTalent as part of LILICON - 98 reported by Ian */
if ("ForumTopicPage" == "IdeaPage") {
if( (sub_L != "") && (sub_L != undefined) && (sub_L != "undefined") ){
document.querySelector('.lia-js-data-messageUid-'+ value).querySelector('.MessageSubject .lia-message-subject').innerText = sub_L;
}
}
else{
if( (sub_L != "") && (sub_L != undefined) && (sub_L != "undefined") ){
rootElement.querySelector('.MessageSubject .lia-message-subject').innerText = sub_L;
/* End: This code is written as part of LILICON - 98 reported by Ian */
}
}
} catch (e) {
console.log("Reply subject not available. error details: " + e);
}
}
}
// Label translation
var labelEle = document.querySelector("#labelsForMessage");
if (!labelEle) {
labelEle = document.querySelector(".LabelsList");
}
if (labelEle) {
var listContains = labelEle.querySelector('.label');
if (listContains) {
/* Commenting this code as bussiness want to point search with source language label */
// var tagHLink = labelEle.querySelectorAll(".label")[0].querySelector(".label-link").href.split("label-name")[0];
var lingoLabelExp = "//lingo-label/text()";
trLabels = [];
trLabelsHtml = "";
/* Get translated labels of the message */
lingoLXML = doc.evaluate(lingoLabelExp, doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
/* try{
for(var j=0;j,';
}
trLabelsHtml = trLabelsHtml+'