diff --git a/src/aiidalab_qe/app/result/components/viewer/structure/structure.py b/src/aiidalab_qe/app/result/components/viewer/structure/structure.py index 3ddd7f55e..b83550c27 100644 --- a/src/aiidalab_qe/app/result/components/viewer/structure/structure.py +++ b/src/aiidalab_qe/app/result/components/viewer/structure/structure.py @@ -10,45 +10,49 @@ class StructureResultsPanel(ResultsPanel[StructureResultsModel]): def _render(self): - if not hasattr(self, "widget"): - structure = self._model.get_structure() - self.widget = StructureDataViewer(structure=structure) - # Select the Cell tab by default - self.widget.configuration_box.selected_index = 2 - self.table_description = ipw.HTML(""" -

- Structure table information: Atom coordinates in Å -

-

- You can click on a row to select an atom. Multiple atoms - can be selected by clicking on additional rows. To unselect - an atom, click on the selected row again. -

- """) - self.atom_coordinates_table = TableWidget() - self._generate_table(structure.get_ase()) + if hasattr(self, "widget"): + # HACK to resize the NGL viewer in cases where it auto-rendered when its + # container was not displayed, which leads to a null width. This hack restores + # the original dimensions. + ngl = self.widget._viewer + ngl._set_size("100%", "300px") + ngl.control.zoom(0.0) + return - structure_info = self._get_structure_info(structure) + structure = self._model.get_structure() + self.widget = StructureDataViewer(structure=structure) - self.results_container.children = [ - structure_info, - self.widget, - self.table_description, - self.atom_coordinates_table, - ] + self.widget.configuration_box.selected_index = 2 # select the Cell tab + + self.atom_coordinates_table = TableWidget() + self._generate_table(structure.get_ase()) - self.atom_coordinates_table.observe(self._change_selection, "selected_rows") - # Listen for changes in self.widget.displayed_selection and update the table - self.widget.observe(self._update_table_selection, "displayed_selection") + structure_info = self._get_structure_info(structure) + + ipw.link( + (self.widget, "displayed_selection"), + (self.atom_coordinates_table, "selected_rows"), + ) - # HACK to resize the NGL viewer in cases where it auto-rendered when its - # container was not displayed, which leads to a null width. This hack restores - # the original dimensions. - ngl = self.widget._viewer - ngl._set_size("100%", "300px") - ngl.control.zoom(0.0) + self.results_container.children = [ + structure_info, + self.widget, + ipw.HTML(""" +

+ Structure information: Atom coordinates in Å +

+

+ You can click on a row to select an atom. Multiple atoms can be + selected by clicking on additional rows. To unselect an atom, click + on the selected row again. +

+ """), + self.atom_coordinates_table, + ] def _get_structure_info(self, structure): + formatted = format_time(structure.ctime) + relative = relative_time(structure.ctime) return ipw.HTML( f"""
@@ -56,7 +60,7 @@ def _get_structure_info(self, structure): Label: {structure.label}
Description: {structure.description}
Number of atoms: {len(structure.sites)}
- Creation time: {format_time(structure.ctime)} ({relative_time(structure.ctime)})
+ Creation time: {formatted} ({relative})
""" ) @@ -79,15 +83,7 @@ def _generate_table(self, structure): for index, (symbol, tag, position) in enumerate( zip(chemical_symbols, tags, positions), start=1 ): - # Format position values to two decimal places formatted_position = [f"{coord:.2f}" for coord in position] data.append([index, symbol, tag, *formatted_position]) - self.atom_coordinates_table.data = data - def _change_selection(self, _): - selected_indices = self.atom_coordinates_table.selected_rows - self.widget.displayed_selection = selected_indices - - def _update_table_selection(self, change): - selected_indices = change.new - self.atom_coordinates_table.selected_rows = selected_indices + self.atom_coordinates_table.data = data