Skip to content

ImageGraphic no longer has tooltips when the buffer is replaced #998

@kushalkolar

Description

@kushalkolar

I figured this out already, fix in #971

The issue is that when the buffer needs to be replaced in an ImageGraphic, we actually have to replace the ImageTile WorldObjects since the number and positions etc. of such tiles may change. This also requires updating the global WORLDOBJECT_TO_GRAPHIC map so that when a tooltip is requested, we can map the new WorldObject in the picking info to the same Graphic.

I'm pretty sure events are still fine though, that's what would be more complicated to detach and re-add, events are added directly to the pygfx.Group and not the individual ImageTiles

These are the specific changes I implemented in the NDWidget branch w.r.t. main.

Index: fastplotlib/graphics/_base.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/fastplotlib/graphics/_base.py b/fastplotlib/graphics/_base.py
--- a/fastplotlib/graphics/_base.py	(revision 78878b1b072d37d4e87695d24c17546a91f9225a)
+++ b/fastplotlib/graphics/_base.py	(date 1771397588617)
@@ -291,15 +291,8 @@
 
         # add to world object -> graphic mapping
         if isinstance(wo, pygfx.Group):
-            for child in wo.children:
-                if isinstance(
-                    child, (pygfx.Image, pygfx.Volume, pygfx.Points, pygfx.Line)
-                ):
-                    # unique 32 bit integer id for each world object
-                    global_id = child.id
-                    WORLD_OBJECT_TO_GRAPHIC[global_id] = self
-                    # store id to pop from dict when graphic is deleted
-                    self._world_object_ids.append(global_id)
+            # for Graphics which use a pygfx.Group, ImageGraphic and graphic collections
+            self._add_group_graphic_map(wo)
         else:
             global_id = wo.id
             WORLD_OBJECT_TO_GRAPHIC[global_id] = self
@@ -324,6 +317,31 @@
         if not all(wo.world.rotation == self.rotation):
             self.rotation = self.rotation
 
+    def _add_group_graphic_map(self, wo: pygfx.Group):
+        # add the children of the group to the WorldObject -> Graphic map
+        # used by images since they create new WorldObject ImageTiles when a different buffer size is required
+        # also used by GraphicCollections inititally, but not used for reseting like images
+        for child in wo.children:
+            if isinstance(
+                    child, (pygfx.Image, pygfx.Volume, pygfx.Points, pygfx.Line)
+            ):
+                # unique 32 bit integer id for each world object
+                global_id = child.id
+                WORLD_OBJECT_TO_GRAPHIC[global_id] = self
+                # store id to pop from dict when graphic is deleted
+                self._world_object_ids.append(global_id)
+
+    def _remove_group_graphic_map(self, wo: pygfx.Group):
+        # remove the children of the group to the WorldObject -> Graphic map
+        for child in wo.children:
+            if isinstance(
+                    child, (pygfx.Image, pygfx.Volume, pygfx.Points, pygfx.Line)
+            ):
+                # unique 32 bit integer id for each world object
+                global_id = child.id
+                WORLD_OBJECT_TO_GRAPHIC.pop(global_id)
+                self._world_object_ids.remove(global_id)
+
     @property
     def tooltip_format(self) -> Callable[[dict], str] | None:
         """
Index: fastplotlib/graphics/image.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/fastplotlib/graphics/image.py b/fastplotlib/graphics/image.py
--- a/fastplotlib/graphics/image.py	(revision 78878b1b072d37d4e87695d24c17546a91f9225a)
+++ b/fastplotlib/graphics/image.py	(date 1771397550096)
@@ -261,6 +261,9 @@
 
                 self._material.clim = quick_min_max(self.data.value)
 
+                # remove tiles from the WorldObject -> Graphic map
+                self._remove_group_graphic_map(self.world_object)
+
                 # clear image tiles
                 self.world_object.clear()
 
@@ -268,6 +271,9 @@
                 for tile in self._create_tiles():
                     self.world_object.add(tile)
 
+                # add new tiles to WorldObject -> Graphic map
+                self._add_group_graphic_map(self.world_object)
+
                 return
 
         self._data[:] = data

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions