Skip to content

Commit

Permalink
Merge pull request #42 from Hoxbro/feature/support-panel-1.0-hoxbro
Browse files Browse the repository at this point in the history
Updating JSMEEditor to work with Panel 1 / Bokeh 3
  • Loading branch information
MarcSkovMadsen authored Nov 12, 2023
2 parents 2d28641 + 63b1ffe commit 4121842
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 55 deletions.
7 changes: 4 additions & 3 deletions examples/reference/JSMEEditor.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:root] *",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "conda-root-py"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -174,7 +174,8 @@
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ exclude = []
[[tool.mypy.overrides]]
module = [
"bokeh.*",
"comm.*",
"holoviews.*",
"hvplot.*",
"param",
"pyviz_comms",
"py3Dmol",
"pyviz_comms",
]
ignore_missing_imports = true

Expand Down
30 changes: 19 additions & 11 deletions src/panel_chemistry/bokeh_extensions/jsme_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,25 @@
class JSMEEditor(HTMLBox): # pylint: disable=too-few-public-methods,too-many-ancestors
"""JSMEEditor Bokeh Model"""

__javascript__ = ["https://unpkg.com/jsme-editor@0.8.2/jsme.nocache.js"]
__javascript__ = [
"https://cdn.jsdelivr.net/npm/jsme-editor@2023.7.31/jsme.nocache.js",
]

value = String()
format = String()
subscriptions = List(String())
options = List(String())
__css__ = [
"https://cdn.jsdelivr.net/npm/jsme-editor@2023.7.31/gwt/chrome/mosaic.css",
"https://cdn.jsdelivr.net/npm/jsme-editor@2023.7.31/jsa.css",
"https://cdn.jsdelivr.net/npm/jsme-editor@2023.7.31/gwt/chrome/chrome.css",
]

jme = String()
smiles = String()
mol = String()
mol3000 = String()
sdf = String()
value = String(default="")
format = String(default="smiles")
subscriptions = List(String, default=[]) # type: ignore
options = List(String, default=[]) # type: ignore

guicolor = String()
jme = String(default="")
smiles = String(default="")
mol = String(default="")
mol3000 = String(default="")
sdf = String(default="")

guicolor = String(default="#c0c0c0")
63 changes: 38 additions & 25 deletions src/panel_chemistry/bokeh_extensions/jsme_editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ function readSDFValue(jsmeElement: any) {
}

function setModelValue(model: JSMEEditor, jsmeElement: any){
console.log("setValue - start", model.value)
var value = model.value
if (model.format==="smiles"){
console.log("getting smiles")
value = jsmeElement.smiles()
console.log("got smiles")
} else if (model.format==="mol"){
value = jsmeElement.molFile(false)
} else if (model.format==="mol3000"){
Expand All @@ -40,17 +37,13 @@ function setModelValue(model: JSMEEditor, jsmeElement: any){
value = jsmeElement.jmeFile()
}
if (model.value!==value && value!==null){
console.log("setting value", value)
model.value = value
}
console.log("setValue - end", model.value)
}

function setModelValues(model: JSMEEditor, jsmeElement: any){
console.log("setValues - start")
setModelValue(model, jsmeElement)
setOtherModelValues(model, jsmeElement)
console.log("setValues - end")
setOtherModelValues(model, jsmeElement)
}

function resetOtherModelValues(model: JSMEEditor, jsmeElement: any){
Expand All @@ -72,13 +65,11 @@ function cleanValue(value: any){
}

function setOtherModelValues(model: JSMEEditor, jsmeElement: any){
console.log("setOtherValues - start")
if (model.subscriptions.includes("jme")){model.jme = cleanValue(jsmeElement.jmeFile())}
if (model.subscriptions.includes("smiles")){model.smiles = cleanValue(jsmeElement.smiles())}
if (model.subscriptions.includes("mol")){model.mol = cleanValue(jsmeElement.molFile(false))}
if (model.subscriptions.includes("mol3000")){model.mol3000 = cleanValue(jsmeElement.molFile(true))}
if (model.subscriptions.includes("sdf")){model.sdf = cleanValue(readSDFValue(jsmeElement))}
console.log("setOtherValues - end")
}

// The view of the Bokeh extension/ HTML element
Expand All @@ -89,12 +80,20 @@ export class JSMEEditorView extends HTMLBoxView {
JSME = (window as any).JSApplet.JSME
valueFunc: any
valueChanging: boolean = true
container: HTMLDivElement
_intialized: boolean = false

initialize(): void {
super.initialize()
this.container = div({
style: {display: "contents"}
})
}

connect_signals(): void {
super.connect_signals()

this.connect(this.model.properties.value.change, () => {
console.log("value change", this.model.value)
if (!this.valueChanging){
if (this.model.value===""){
this.jsmeElement.reset()
Expand All @@ -104,29 +103,40 @@ export class JSMEEditorView extends HTMLBoxView {
}
})
this.connect(this.model.properties.format.change, () => {
console.log("format change", this.model.format)
setModelValue(this.model, this.jsmeElement);
})
this.connect(this.model.properties.subscriptions.change, () => {
console.log("subscriptions change", this.model.subscriptions)
resetOtherModelValues(this.model, this.jsmeElement);
})
this.connect(this.model.properties.options.change, () => {
console.log("options change", this.model.options)
this.setJSMEOptions()
})
this.connect(this.model.properties.guicolor.change, () => {
console.log("options change", this.model.options)
this.setGUIColor()
})
}

render(): void {
console.log("render - start")
super.render()
const id = "jsme-" + uuidv4()
const container = div({class: "jsme-editor", id: id});
this.el.appendChild(container)
const el = div({
class: "jsme-editor",
id: id,
style: {width: "100%", height: "100%"}
})
this.container.appendChild(el)
this._intialized = false
}

createJSMEElement() {
if (this._intialized)
return

const id = this.container.children[0].id

// Need to add it to document body for JSME to be able to find the id
document.body.appendChild(this.container)

this.jsmeElement = new this.JSME(id, this.getHeight(), this.getWidth(), {
"options": this.model.options.join(","),
"guicolor": this.model.guicolor
Expand All @@ -136,25 +146,26 @@ export class JSMEEditorView extends HTMLBoxView {
setModelValues(this.model, this.jsmeElement)

const this_ = this;
function showEvent(event: any){
console.log("event", event)
function showEvent(_: any){
this_.valueChanging = true
setModelValues(this_.model, this_.jsmeElement)
this_.valueChanging = false
}
this.jsmeElement.setAfterStructureModifiedCallback(showEvent);

console.log("render - end")
// Remove from document body and add to shadow DOM
document.body.removeChild(this.container)
this.shadow_el.appendChild(this.container)

this._intialized = true
}

setGUIColor(){
console.log("setGUIColor", this.model.guicolor)
this.jsmeElement.setUserInterfaceBackgroundColor(this.model.guicolor)
}

setJSMEOptions(){
const options = this.model.options.join(",")
console.log("setJSMEOptions", options)
this.jsmeElement.options(options)
}

Expand Down Expand Up @@ -185,6 +196,7 @@ export class JSMEEditorView extends HTMLBoxView {

after_layout(): void{
super.after_layout()
this.createJSMEElement()
this.resizeJSMEElement()
}
}
Expand Down Expand Up @@ -213,14 +225,15 @@ export interface JSMEEditor extends JSMEEditor.Attrs { }
// The Bokeh .ts model corresponding to the Bokeh .py model
export class JSMEEditor extends HTMLBox {
properties: JSMEEditor.Props
__view_type__: JSMEEditorView

constructor(attrs?: Partial<JSMEEditor.Attrs>) {
super(attrs)
}

static __module__ = "panel_chemistry.bokeh_extensions.jsme_editor"

static init_JSMEEditor(): void {
static {
this.prototype.default_view = JSMEEditorView;

this.define<JSMEEditor.Props>(({String, Array}) => ({
Expand All @@ -236,4 +249,4 @@ export class JSMEEditor extends HTMLBox {
guicolor: [String, "#c0c0c0"],
}))
}
}
}
17 changes: 5 additions & 12 deletions src/panel_chemistry/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/panel_chemistry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"license": "Apache 2.0",
"keywords": [],
"dependencies": {
"@bokeh/bokehjs": "~3.1.1"
"@bokeh/bokehjs": "~3.3.1"
}
}
2 changes: 1 addition & 1 deletion src/panel_chemistry/pane/py3dmol_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
try:
import py3Dmol
except ModuleNotFoundError:
# pylint: disable=invalid-name
# pylint: disable=invalid-name, too-few-public-methods
class py3Dmol(param.Parameterized): # type: ignore
"""Dummy py3Dmol class"""

Expand Down
2 changes: 1 addition & 1 deletion src/panel_chemistry/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
}
},
"include": ["./**/*.ts"]
}
}

0 comments on commit 4121842

Please sign in to comment.