Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python-side selection #316

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions python/chemiscope/jupyter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ class ChemiscopeWidgetBase(ipywidgets.DOMWidget, ipywidgets.ValueWidget):
# change what's being displayed by chemiscope, but you need to assign a full
# dictionary (`widget.settings["map"]["x"]["property"] = "foo"` will not
# work, but `widget.settings = updated_settings` will).
settings = Dict().tag(sync=True)
# switch to disable automatic update of settings
settings = Dict().tag(sync=True)
selection = Dict().tag(sync=True)
# switch to disable automatic update of settings (& se;lection)
_settings_sync = Bool().tag(sync=True)

def __init__(self, data, has_metadata):
Expand Down
47 changes: 45 additions & 2 deletions python/jupyter/src/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import './widget.css';

import { DefaultVisualizer, MapVisualizer, StructureVisualizer } from '../../../src/index';
import { Dataset, Settings } from '../../../src/dataset';
import { Indexes } from '../../../src/indexer';

const PlausibleTracker = Plausible({
domain: 'jupyter.chemiscope.org',
Expand Down Expand Up @@ -71,6 +72,43 @@ class ChemiscopeBaseView extends DOMWidgetView {
this.model.save_changes();
}
}

protected _bindPythonSelection(): void {
// update settings on the JS side when they are changed in Python
this.model.on(
'change:selection',
() => {
// only trigger a visualizer update if required.
// this is also used to avoid an infinite loop when settings are changed JS-side
if (!this.model.get('_settings_sync')) {
return;
}

const selection = this.model.get('selection') as Indexes;
console.log("selection update", selection);

(this.visualizer as DefaultVisualizer).select(selection);
// for the moment does nothing
},
this
);
}

protected _updatePythonSelection(): void {
if (this.visualizer !== undefined) {
const selection = this.visualizer.getSelected();
console.log("getting selection ", selection);
// save current settings of settings_sync
const sync_state = this.model.get('_settings_sync') as unknown;

this.model.set('_settings_sync', false);
this.model.save_changes();
this.model.set('selection', selection);
this.model.save_changes();
this.model.set('_settings_sync', sync_state);
this.model.save_changes();
}
}
}

/**
Expand Down Expand Up @@ -135,15 +173,18 @@ export class ChemiscopeView extends ChemiscopeBaseView {
};

this._bindPythonSettings();
this._bindPythonSelection();

const data = JSON.parse(this.model.get('value') as string) as Dataset;
void DefaultVisualizer.load(config, data)
.then((visualizer) => {
.then((visualizer) => {
this.visualizer = visualizer;
// update the Python side settings whenever a setting changes
this.visualizer.onSettingChange(() => this._updatePythonSettings());
this.visualizer.onSettingChange(() => this._updatePythonSettings());
this.visualizer.info.onselection = (() => this._updatePythonSelection());
// and set them to the initial value right now
this._updatePythonSettings();
this._updatePythonSelection();
})
.catch((e: Error) => {
// eslint-disable-next-line no-console
Expand Down Expand Up @@ -216,6 +257,7 @@ export class StructureView extends ChemiscopeBaseView {
};

this._bindPythonSettings();
this._bindPythonSelection();

const data = JSON.parse(this.model.get('value') as string) as Dataset;
void StructureVisualizer.load(config, data)
Expand Down Expand Up @@ -298,6 +340,7 @@ export class MapView extends ChemiscopeBaseView {
};

this._bindPythonSettings();
this._bindPythonSelection();

const data = JSON.parse(this.model.get('value') as string) as Dataset;
void MapVisualizer.load(config, data)
Expand Down
38 changes: 34 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
public map: PropertiesMap;
public info: EnvironmentInfo;
public meta: MetadataPanel;
public structure: ViewersGrid;
public structure: ViewersGrid;

private _indexer: EnvironmentIndexer;
// Stores raw input input so we can give it back later
Expand Down Expand Up @@ -214,7 +214,7 @@

this.structure.onselect = (indexes) => {
this.map.select(indexes);
this.info.show(indexes);
this.info.show(indexes);
};

this.structure.onremove = (guid) => {
Expand All @@ -240,8 +240,9 @@
);

this.map.onselect = (indexes) => {
console.log("map onselect");

Check failure on line 243 in src/index.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
this.info.show(indexes);
this.structure.show(indexes);
this.structure.show(indexes);
};

this.map.activeChanged = (guid, indexes) => {
Expand All @@ -256,9 +257,14 @@
this._indexer,
dataset.parameters
);

this.info.onchange = (indexes) => {
this.map.select(indexes);
this.structure.show(indexes);
if (this.info.onselection !== undefined) {
console.log("info onchange", indexes);

Check failure on line 265 in src/index.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
this.info.onselection();
}
};

this.structure.delayChanged = (delay) => {
Expand Down Expand Up @@ -379,7 +385,7 @@
this.structure.applySettings(settings.structure as Settings[]);
}
}

/**
* Add the given `callback` to be called whenever a setting changes. The
* callback will be given the path to the settings as a list of keys; and
Expand All @@ -403,6 +409,21 @@
});
}

public getSelected(): Indexes {
return this.info.getSelected();
}

public select(indexes: Indexes) {
console.log("selecting");

Check failure on line 417 in src/index.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
this.map.select(indexes);
this.info.show(indexes);
}
/*public onSelectedChange(callback: (keys: string[], value: unknown) => void): void {
this.info.onSelectedChange( (keys, value) ==> {
callback(keys, value);
});
}*/

/**
* Get the dataset used to create the current visualization
*
Expand Down Expand Up @@ -525,6 +546,7 @@
};

let initial: Indexes = { environment: 0, structure: 0, atom: 0 };

// if we have sparse environments, make sure to use the first
// environment actually part of the dataset
if (dataset.environments !== undefined) {
Expand Down Expand Up @@ -595,6 +617,10 @@
callback(keys, value);
});
}

public getSelected(): Indexes {
return this.info.getSelected();
}
}

/**
Expand Down Expand Up @@ -752,6 +778,10 @@
callback(keys, value);
});
}

public getSelected(): Indexes {
return this.info.getSelected();
}
}

declare const CHEMISCOPE_GIT_VERSION: string;
Expand Down
16 changes: 16 additions & 0 deletions src/info/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
export class EnvironmentInfo {
/** Callback used when the user changes one of the sliders value */
public onchange: (indexes: Indexes) => void;

/** Callback used when the selection is changed, no matter the source */
public onselection?: () => void;;

/** delay in ms between "frames" during playback over structures/atoms */
public playbackDelay: number;

Expand Down Expand Up @@ -138,6 +142,7 @@

/** Show properties for the given `indexes`, and update the sliders values */
public show(indexes: Indexes): void {
console.log("info/show");

Check failure on line 145 in src/info/info.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
const previousStructure = this._indexes().structure;

this._structure.number.value = `${indexes.structure + 1}`;
Expand All @@ -163,6 +168,11 @@
this._atom.table.show(indexes);
}
}

if (this.onselection !== undefined) {
console.log("info show trigger onselection");

Check failure on line 173 in src/info/info.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
this.onselection();
}
}

/**
Expand Down Expand Up @@ -220,6 +230,7 @@
};

slider.onchange = () => {
console.log("slider/onchange");

Check failure on line 233 in src/info/info.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
const structure = this._structure.slider.value();

if (this._atom !== undefined) {
Expand Down Expand Up @@ -256,6 +267,7 @@
number.max = this._indexer.structuresCount().toString();

number.onchange = () => {
console.log("number/onchange");

Check failure on line 270 in src/info/info.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Unexpected console statement
const value = parseInt(number.value, 10) - 1;
if (isNaN(value) || value < 0 || value >= parseInt(number.max, 10)) {
// reset to the current slider value if we got an invalid value
Expand Down Expand Up @@ -395,4 +407,8 @@
assert(indexes !== undefined);
return indexes;
}

public getSelected(): Indexes {
return this._indexes()

Check failure on line 412 in src/info/info.ts

View workflow job for this annotation

GitHub Actions / npm-test (20.x)

Missing semicolon
}
}
Loading