, void>;
export default examplePlugin;
diff --git a/src/widget.ts b/src/widget.ts
index 42e0ea4..80c2785 100644
--- a/src/widget.ts
+++ b/src/widget.ts
@@ -22,29 +22,29 @@ import '../css/ptable.css';
// These assumptions are used both in the generation of the elementList
// and in the template.
var elementTable: string[][] = [
- ["H", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "He"],
- ["Li", "Be", "", "", "", "", "", "", "","", "", "", "B", "C", "N", "O", "F", "Ne"],
- ["Na", "Mg", "", "", "", "", "", "", "","", "", "", "Al", "Si", "P", "S", "Cl", "Ar"],
- ["K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co","Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr"],
- ["Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh","Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe"],
- ["Cs", "Ba", "*", "Hf", "Ta", "W", "Re", "Os", "Ir","Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn"],
- ["Fr", "Ra", "*", "Rf", "Db", "Sg", "Bh", "Hs", "Mt","Ds", "Rg", "Cn", "Nh", "Fi", "Mc", "Lv", "Ts", "Og"],
- ["", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", ""],
- ["", "", "*", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu","Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu"],
- ["", "", "*", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am","Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr"]
+ ["H", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", "He"],
+ ["Li", "Be", "", "", "", "", "", "", "","", "", "", "B", "C", "N", "O", "F", "Ne"],
+ ["Na", "Mg", "", "", "", "", "", "", "","", "", "", "Al", "Si", "P", "S", "Cl", "Ar"],
+ ["K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co","Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr"],
+ ["Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh","Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe"],
+ ["Cs", "Ba", "*", "Hf", "Ta", "W", "Re", "Os", "Ir","Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn"],
+ ["Fr", "Ra", "*", "Rf", "Db", "Sg", "Bh", "Hs", "Mt","Ds", "Rg", "Cn", "Nh", "Fi", "Mc", "Lv", "Ts", "Og"],
+ ["", "", "", "", "", "", "", "", "","", "", "", "", "", "", "", "", ""],
+ ["", "", "*", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu","Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu"],
+ ["", "", "*", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am","Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr"]
];
// Flat list of elements, used for validation and cleaning up of the
// selectedElements list.
let elementList: string[] = [];
for (let elementRow of elementTable) {
- for (let elementName of elementRow) {
- if ( (elementName === "") || (elementName == "*" ) ) {
- }
- else {
- elementList.push(elementName);
- }
+ for (let elementName of elementRow) {
+ if ( (elementName === "") || (elementName == "*" ) ) {
}
+ else {
+ elementList.push(elementName);
+ }
+ }
}
export
@@ -62,9 +62,9 @@ class MCPTableModel extends DOMWidgetModel {
}
static serializers: ISerializers = {
- ...DOMWidgetModel.serializers,
- // Add any extra serializers here
- }
+ ...DOMWidgetModel.serializers,
+ // Add any extra serializers here
+ }
static model_name = 'MCPTableModel';
static model_module = MODULE_NAME;
@@ -77,109 +77,138 @@ class MCPTableModel extends DOMWidgetModel {
export
class MCPTableView extends DOMWidgetView {
- // TODO: move template to external file to make it more readable, see
- // http://codebeerstartups.com/2012/12/how-to-improve-templates-in-backbone-js-learning-backbone-js/
- tableTemplate = _.template( '<% for (let elementRow of elementTable) { print(""); for (let elementName of elementRow) { if ( (elementName === "") || (elementName == "*" ) ) { %>' + ' <%= elementName %>' + '<% } else { %>' + ' noselect element-<%= elementName %><% if (selectedElements.includes(elementName) && (! disabledElements.includes(elementName)) ) { print(" elementOn"); } %>"><% print(displayNamesReplacements[elementName] || elementName); %>' + '<% } }; print("
"); } %>');
-
- render() {
- // I render the widget
- this.rerenderScratch();
- // I bind on_change events
- this.model.on('change:selected_elements', this.rerenderScratch, this);
- this.model.on('change:disabled_elements', this.rerenderScratch, this);
- this.model.on('change:display_names_replacements', this.rerenderScratch, this);
- }
+ // TODO: move template to external file to make it more readable, see
+ // http://codebeerstartups.com/2012/12/how-to-improve-templates-in-backbone-js-learning-backbone-js/
+ tableTemplate = _.template( '<% for (let elementRow of elementTable)'+
+ ' { print(""); for (let elementName of elementRow)'+
+ ' { if ( (elementName === "") || (elementName == "*" ) ) { %>' +
+ ' <%= elementName %>' + '<% } else { %>' +
+ ' '+
+ ' noselect element-<%= elementName %><% if (selectedElements.includes(elementName) && ' +
+ '(! disabledElements.includes(elementName)) ) { print(" elementOn"); } %>" '+
+ 'style="background-color: <% if (disabledElements.includes(elementName)) {print(disabledColor)}' +
+ 'else if (selectedElements.includes(elementName)) { i = selectedElements.indexOf(elementName); print(selectedColors[selectedStates[i]]);} else{print(noselectColor)} %>" '+
+ 'title="state: <% if (selectedElements.includes(elementName)) { i = selectedElements.indexOf(elementName); print(selectedStates[i]);} '+
+ 'else if (disabledElements.includes(elementName)){print("disabled");} else {print("noselcted");} %>" ><% '+
+ 'print(displayNamesReplacements[elementName] || elementName); %>' +
+ '<% } }; print("
"); } %>');
+
+ render() {
+ // I render the widget
+ this.rerenderScratch();
+ // I bind on_change events
+ this.model.on('change:selected_elements', this.rerenderScratch, this);
+ this.model.on('change:selected_states', this.rerenderScratch, this);
+ this.model.on('change:disabled_elements', this.rerenderScratch, this);
+ this.model.on('change:display_names_replacements', this.rerenderScratch, this);
+ }
- events(): {[e: string]: string} {
- return {"click .periodic-table-entry": "toggleElement", "click .periodic-table-disabled": "toggleElement"};
-}
+ events(): {[e: string]: string} {
+ return {"click .periodic-table-entry": "toggleElement", "click .periodic-table-disabled": "toggleElement"};
+ }
- toggleElement(event: any) {
- let classNames: string[] = _.map(event.target.classList, function(a: string){return a});
- let elementName: string = _.chain(classNames)
- .filter(function(a: any){return a.startsWith('element-')})
- .map(function(a: any){return a.slice("element-".length);})
- .first()
- .value();
-
- var isOn = _.includes(classNames, 'elementOn');
- var isDisabled = _.includes(classNames, "periodic-table-disabled");
- // If this button is disabled, do not do anything
- // (Actually, this function should not be triggered if the button
- // is disabled, this is just a safety measure)
- // if (isDisabled) return;
-
- // Check if we understood which element we are
- if (typeof elementName !== 'undefined') {
- var currentList = this.model.get('selected_elements');
- var currentDisabledList = this.model.get('disabled_elements');
- // NOTE! it is essential to duplicate the list,
- // otherwise the value will not be updated.
- var newList = currentList.slice();
- var newDisabledList = currentDisabledList.slice();
-
- if (isOn) {
- // remove the element from the selected_elements
- newList = _.without(newList, elementName);
- newDisabledList.push(elementName);
- // Swap CSS state
- event.target.classList.remove('elementOn');
- }
- else if (isDisabled) {
- newDisabledList = _.without(newDisabledList, elementName);
- event.target.classList.remove('periodic-table-disabled');
- }
- else {
- // add the element from the selected_elements
- newList.push(elementName);
- // Swap CSS state
- event.target.classList.add('elementOn');
- }
-
- // Update the model (send back data to python)
- this.model.set('selected_elements', newList);
- this.model.set('disabled_elements', newDisabledList);
- this.touch();
+ toggleElement(event: any) {
+ let classNames: string[] = _.map(event.target.classList, function(a: string){return a});
+ let elementName: string = _.chain(classNames)
+ .filter(function(a: any){return a.startsWith('element-')})
+ .map(function(a: any){return a.slice("element-".length);})
+ .first()
+ .value();
+
+ var isOn = _.includes(classNames, 'elementOn');
+ // If this button is disabled, do not do anything
+ // (Actually, this function should not be triggered if the button
+ // is disabled, this is just a safety measure)
+ // if (isDisabled) return;
+
+ let states = this.model.get("states");
+
+ // Check if we understood which element we are
+ if (typeof elementName !== 'undefined') {
+ var currentList = this.model.get('selected_elements');
+ var currentStatesList = this.model.get('selected_states');
+ // NOTE! it is essential to duplicate the list,
+ // otherwise the value will not be updated.
+ var newList = currentList.slice();
+ var newStatesList = currentStatesList.slice();
+ var num = newList.indexOf(elementName);
+
+ if (isOn) {
+ // remove the element from the selected_elements
+
+ if (newStatesList[num] < states -1){
+ newStatesList[num]++;
}
- }
-
- rerenderScratch() {
-// Re-render full widget when the list of selected elements
-// changed from python
- var selectedElements = this.model.get('selected_elements');
- var disabledElements = this.model.get('disabled_elements');
- var newSelectedElements = selectedElements.slice();
-
-// Here I want to clean up the two elements lists, to avoid
-// to have unknown elements in the selectedElements, and
-// to remove disabledElements from the selectedElements list.
-// I use s variable to check if anything changed, so I send
-// back the data to python only if needed
-
- var selectedElementsLength = newSelectedElements.length;
-// Remove disabled elements from the selectedElements list
-// newSelectedElements = _.difference(newSelectedElements, disabledElements);
-// Remove unknown elements from the selectedElements list
-// newSelectedElements = _.intersection(newSelectedElements, elementList);
- var changed = newSelectedElements.length != selectedElementsLength;
-
-// call the update (to python) only if I actually removed/changed
-// something
- if (changed) {
-// Make a copy before setting
- this.model.set('selected_elements', newSelectedElements);
- this.touch();
+ else{
+ newList = _.without(newList, elementName);
+ newStatesList.splice(num, 1);
+ // Swap CSS state
+ event.target.classList.remove('elementOn');
}
+ }
+ else {
+ // add the element from the selected_elements
+ newList.push(elementName);
+ newStatesList.push(0);
+ // Swap CSS state
+ event.target.classList.add('elementOn');
+ }
+
+ // Update the model (send back data to python)
+ this.model.set('selected_elements', newList);
+ this.model.set('selected_states', newStatesList);
+ this.touch();
+ }
+ }
-// Render the full widget using the template
- this.el.innerHTML = '' +
- this.tableTemplate({
- elementTable: elementTable,
- displayNamesReplacements: this.model.get('display_names_replacements'),
- selectedElements: newSelectedElements,
- disabledElements: disabledElements
- }) +
- '
';
+ rerenderScratch() {
+ // Re-render full widget when the list of selected elements
+ // changed from python
+ var selectedElements = this.model.get('selected_elements');
+ var disabledElements = this.model.get('disabled_elements');
+ var disabledColor = this.model.get('disabled_color');
+ var noselectColor = this.model.get('noselect_color');
+ var selectedColors = this.model.get('selected_colors');
+ var selectedStates = this.model.get('selected_states');
+ var newSelectedElements = selectedElements.slice();
+ var newSelectedColors = selectedColors.slice();
+ var newSelectedStates = selectedStates.slice();
+
+ // Here I want to clean up the two elements lists, to avoid
+ // to have unknown elements in the selectedElements, and
+ // to remove disabledElements from the selectedElements list.
+ // I use s variable to check if anything changed, so I send
+ // back the data to python only if needed
+
+ var selectedElementsLength = newSelectedElements.length;
+ // Remove disabled elements from the selectedElements list
+ // newSelectedElements = _.difference(newSelectedElements, disabledElements);
+ // Remove unknown elements from the selectedElements list
+ // newSelectedElements = _.intersection(newSelectedElements, elementList);
+ var changed = newSelectedElements.length != selectedElementsLength;
+
+ // call the update (to python) only if I actually removed/changed
+ // something
+ if (changed) {
+ // Make a copy before setting
+ this.model.set('selected_elements', newSelectedElements);
+ this.touch();
}
+ // Render the full widget using the template
+ this.el.innerHTML = '' +
+ this.tableTemplate({
+ elementTable: elementTable,
+ displayNamesReplacements: this.model.get('display_names_replacements'),
+ selectedElements: newSelectedElements,
+ disabledElements: disabledElements,
+ disabledColor: disabledColor,
+ noselectColor: noselectColor,
+ selectedColors: newSelectedColors,
+ selectedStates: newSelectedStates
+ }) +
+ '
';
+ }
+
}
diff --git a/version_check.py b/version_check.py
index 447e6bb..9c22aac 100644
--- a/version_check.py
+++ b/version_check.py
@@ -1,9 +1,11 @@
from setupbase import get_version
from os.path import join as pjoin
-import json
+import json
+from widget_periodictable._frontend import module_version
name = 'widget_periodictable'
+module_version = module_version[1:]
version_py = get_version(pjoin(name, '_version.py'))
with open('package.json') as json_file:
@@ -11,9 +13,8 @@
version_npm = data['version']
-if version_py != version_npm :
+if version_py != version_npm or module_version != version_npm:
raise ValueError('The version number are NOT equal')
else:
print(version_py)
- print('Check fine for the version number')
diff --git a/widget_periodictable/_frontend.py b/widget_periodictable/_frontend.py
index 1a3cf2c..b4b66d5 100644
--- a/widget_periodictable/_frontend.py
+++ b/widget_periodictable/_frontend.py
@@ -9,4 +9,4 @@
"""
module_name = "widget-periodictable"
-module_version = "^0.1.0"
+module_version = "^1.1.0"
diff --git a/widget_periodictable/_version.py b/widget_periodictable/_version.py
index f44ab0e..347eabc 100644
--- a/widget_periodictable/_version.py
+++ b/widget_periodictable/_version.py
@@ -4,5 +4,5 @@
# Copyright (c) Giovanni Pizzi and Dou Du.
# Distributed under the terms of the Modified BSD License.
-version_info = (0, 3, 0)
+version_info = (1, 1, 0)
__version__ = ".".join(map(str, version_info))
diff --git a/widget_periodictable/periodic_table.py b/widget_periodictable/periodic_table.py
index 116ca8d..1248d91 100644
--- a/widget_periodictable/periodic_table.py
+++ b/widget_periodictable/periodic_table.py
@@ -9,10 +9,9 @@
"""
from ipywidgets import DOMWidget
-from traitlets import Unicode, Int, List, Dict
+from traitlets import Unicode, Int, List, Dict
from ._frontend import module_name, module_version
-
class PTableWidget(DOMWidget):
"""TODO: Add docstring here
"""
@@ -25,4 +24,26 @@ class PTableWidget(DOMWidget):
selected_elements = List([]).tag(sync=True)
disabled_elements = List([]).tag(sync=True)
display_names_replacements = Dict({}).tag(sync=True)
+ disabled_color = Unicode('gray').tag(sync=True)
+ noselect_color = Unicode('pink').tag(sync=True)
+ states = Int(1).tag(sync=True)
+ selected_states = List([]).tag(sync=True)
+ selected_colors = List([]).tag(sync=True)
+
+
+ def __init__(self, states = 1, disabled_color = 'gray', noselect_color = 'pink', selected_colors = ["#a6cee3", "#b2df8a", "#fdbf6f", "#6a3d9a", "#b15928", "#e31a1c", "#1f78b4", "#33a02c", "#ff7f00", "#cab2d6", "#ffff99"]):
+ super(PTableWidget, self).__init__()
+ self.states = states
+ self.disabled_color = disabled_color
+ self.noselect_color = noselect_color
+ self.selected_colors = selected_colors
+
+ if len(selected_colors) < states:
+ self.selected_colors = selected_colors + ["#a6cee3", "#b2df8a", "#fdbf6f", "#6a3d9a", "#b15928", "#e31a1c", "#1f78b4", "#33a02c", "#ff7f00", "#cab2d6", "#ffff99"]
+ def get_elements_by_state(self, state):
+ x = [];
+ for i, j in enumerate(self.selected_states):
+ if j == state:
+ x.append(self.selected_elements[i])
+ return x