Giter Club home page Giter Club logo

glue-map's People

Contributors

jfoster17 avatar

Watchers

 avatar  avatar

glue-map's Issues

Layer hide/unhide with native controls is broken

Layer hide/unhide is not directly exposed in ipyleaflet, only through the native layer UI tool. If ipyleaflet is updated to include .show attributes on all layers we can keep these in sync with native and glue controls. Otherwise we can probably just remove the glue controls to hide/show layers and rely on the native UI tool.

Expose Z-order

Z order is very important for mapping applications. Right now, fiddling with hide/unhide layers sometimes moves layers around. We should look to other glue widgets for examples of how to control this.

Record more state

Currently, much of the state of things is not captured, which means that we can't restore settings upon changing modes

Fix color-scale option for regions type data

The color/size drop-down menus in the GUI are really slow to appear if there are a large number of regions, to the point where they look as if they do not appear and the user is confused. They should either appear quickly (before we do anything to the layer) or... block somehow.

Remove initial color hack

In layer_artist.py, we hack things to make the initial color white. We should be able to set this initial color when setting up the state object and have it respected here. Since default colors are sort of grey, the defaults aren't going to work very well.

Figure out scroll-bar issues

We have many extraneous scrollbars in the UI.

Do we see the same thing in bqplot-based widgets?

Is this alleviated by switching over MapViewerStateWidget to a simple VBox thing? Manually settings sizes is sort of a whack-a-mole process.

Fix subset cloropleth crash

When we have a subset, we can choose to apply a linear colorscale but it does not work.

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:676, in Widget._handle_msg(self, msg)
    674         if 'buffer_paths' in data:
    675             _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 676         self.set_state(state)
    678 # Handle a state request.
    679 elif method == 'request_state':

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:540, in Widget.set_state(self, sync_data)
    536 """Called when a state is received from the front-end."""
    537 # The order of these context managers is important. Properties must
    538 # be locked when the hold_trait_notification context manager is
    539 # released and notifications are fired.
--> 540 with self._lock_property(**sync_data), self.hold_trait_notifications():
    541     for name in sync_data:
    542         if name in self.keys:

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/contextlib.py:142, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
    140 if typ is None:
    141     try:
--> 142         next(self.gen)
    143     except StopIteration:
    144         return False

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1216, in HasTraits.hold_trait_notifications(self)
   1214 for changes in cache.values():
   1215     for change in changes:
-> 1216         self.notify_change(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:606, in Widget.notify_change(self, change)
    603     if name in self.keys and self._should_send_property(name, getattr(self, name)):
    604         # Send new state to front-end
    605         self.send_state(key=name)
--> 606 super(Widget, self).notify_change(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1229, in HasTraits.notify_change(self, change)
   1227 def notify_change(self, change):
   1228     """Notify observers of a change event"""
-> 1229     return self._notify_observers(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1266, in HasTraits._notify_observers(self, event)
   1263 elif isinstance(c, EventHandler) and c.name is not None:
   1264     c = getattr(self, c.name)
-> 1266 c(event)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/ipywidgets/widgets/widget_selection.py:235, in _Selection._propagate_index(self, change)
    233     self.label = label
    234 if self.value is not value:
--> 235     self.value = value

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:606, in TraitType.__set__(self, obj, value)
    604     raise TraitError('The "%s" trait is read-only.' % self.name)
    605 else:
--> 606     self.set(obj, value)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:595, in TraitType.set(self, obj, value)
    591     silent = False
    592 if silent is not True:
    593     # we explicitly compare silent to True just in case the equality
    594     # comparison above returns something other than True/False
--> 595     obj._notify_trait(self.name, old_value, new_value)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1219, in HasTraits._notify_trait(self, name, old_value, new_value)
   1218 def _notify_trait(self, name, old_value, new_value):
-> 1219     self.notify_change(Bunch(
   1220         name=name,
   1221         old=old_value,
   1222         new=new_value,
   1223         owner=self,
   1224         type='change',
   1225     ))

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:606, in Widget.notify_change(self, change)
    603     if name in self.keys and self._should_send_property(name, getattr(self, name)):
    604         # Send new state to front-end
    605         self.send_state(key=name)
--> 606 super(Widget, self).notify_change(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1229, in HasTraits.notify_change(self, change)
   1227 def notify_change(self, change):
   1228     """Notify observers of a change event"""
-> 1229     return self._notify_observers(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1266, in HasTraits._notify_observers(self, event)
   1263 elif isinstance(c, EventHandler) and c.name is not None:
   1264     c = getattr(self, c.name)
-> 1266 c(event)

File ~/Desktop/glue-jupyter-registry-dev/glue-jupyter/glue_jupyter/link.py:26, in link._link.<locals>.sync(*ignore)
     24 new_value = f(getattr(source[0], source[1]))
     25 if new_value != old_value:
---> 26     setattr(target[0], target[1], new_value)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/core.py:263, in HasCallbackProperties.__setattr__(self, attribute, value)
    261 super(HasCallbackProperties, self).__setattr__(attribute, value)
    262 if self.is_callback_property(attribute):
--> 263     self._notify_global(**{attribute: value})

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/core.py:258, in HasCallbackProperties._notify_global(self, **kwargs)
    256 if len(kwargs) > 0:
    257     for callback in self._global_callbacks:
--> 258         callback(**kwargs)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/containers.py:45, in CallbackList.notify_all(self, *args, **kwargs)
     43 def notify_all(self, *args, **kwargs):
     44     for callback in self.callbacks:
---> 45         callback(*args, **kwargs)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/containers.py:166, in dynamic_callback.__call__(self, *args, **kwargs)
    165 def __call__(self, *args, **kwargs):
--> 166     self.function(*args, **kwargs)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/containers.py:189, in ListCallbackProperty._default_setter.<locals>.callback(*args, **kwargs)
    188 def callback(*args, **kwargs):
--> 189     self.notify(instance, wrapped_list, wrapped_list)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/core.py:125, in CallbackProperty.notify(self, instance, old, new)
    123     return
    124 for cback in self._callbacks.get(instance, []):
--> 125     cback(new)
    126 for cback in self._2arg_callbacks.get(instance, []):
    127     cback(old, new)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/core.py:250, in HasCallbackProperties._notify_global_listordict(self, *args)
    248             properties[prop_name] = callback_listordict
    249             break
--> 250 self._notify_global(**properties)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/echo/core.py:258, in HasCallbackProperties._notify_global(self, **kwargs)
    256 if len(kwargs) > 0:
    257     for callback in self._global_callbacks:
--> 258         callback(**kwargs)

File ~/python-repos/glue-map/glue_map/map/layer_artist.py:399, in MapRegionLayerArtist._update_presentation(self, force, **kwargs)
    396         del old_style['fillColor']
    398     self.map_layer.style = old_style #We need to blank these https://github.com/jupyter-widgets/ipyleaflet/issues/675#issuecomment-710970550
--> 399     self.map_layer.style_callback = feature_color
    401 elif self.state.color_mode == 'Fixed':
    402     self.map_layer.style = {'color':self.state.color, 'fillColor':self.state.color}

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:606, in TraitType.__set__(self, obj, value)
    604     raise TraitError('The "%s" trait is read-only.' % self.name)
    605 else:
--> 606     self.set(obj, value)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:595, in TraitType.set(self, obj, value)
    591     silent = False
    592 if silent is not True:
    593     # we explicitly compare silent to True just in case the equality
    594     # comparison above returns something other than True/False
--> 595     obj._notify_trait(self.name, old_value, new_value)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1219, in HasTraits._notify_trait(self, name, old_value, new_value)
   1218 def _notify_trait(self, name, old_value, new_value):
-> 1219     self.notify_change(Bunch(
   1220         name=name,
   1221         old=old_value,
   1222         new=new_value,
   1223         owner=self,
   1224         type='change',
   1225     ))

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:606, in Widget.notify_change(self, change)
    603     if name in self.keys and self._should_send_property(name, getattr(self, name)):
    604         # Send new state to front-end
    605         self.send_state(key=name)
--> 606 super(Widget, self).notify_change(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1229, in HasTraits.notify_change(self, change)
   1227 def notify_change(self, change):
   1228     """Notify observers of a change event"""
-> 1229     return self._notify_observers(change)

File ~/opt/anaconda3/envs/geo_env/lib/python3.10/site-packages/traitlets/traitlets.py:1266, in HasTraits._notify_observers(self, event)
   1263 elif isinstance(c, EventHandler) and c.name is not None:
   1264     c = getattr(self, c.name)
-> 1266 c(event)

File ~/python-repos/ipyleaflet/ipyleaflet/leaflet.py:1185, in GeoJSON._update_data(self, change)
   1182     return
   1184 self.updating = True
-> 1185 self.data = self._get_data()
   1186 self.updating = False

File ~/python-repos/ipyleaflet/ipyleaflet/leaflet.py:1211, in GeoJSON._get_data(self)
   1209 elif datatype == 'FeatureCollection':
   1210     for feature in data['features']:
-> 1211         self._apply_style(feature, style_callback)
   1213 return data

File ~/python-repos/ipyleaflet/ipyleaflet/leaflet.py:1232, in GeoJSON._apply_style(self, feature, style_callback)
   1230 if 'style' in properties:
   1231     style = properties['style'].copy()
-> 1232     style.update(style_callback(feature))
   1233     properties['style'] = style
   1234 else:

File ~/python-repos/glue-map/glue_map/map/layer_artist.py:390, in MapRegionLayerArtist._update_presentation.<locals>.feature_color(feature)
    388 def feature_color(feature):
    389     feature_name = feature["id"]
--> 390     return {'fillColor': color2hex(self.state.cmap(mapping[feature_name]))}

KeyError: '0'

Crashes with some geometries

Clicking around the MA towns + watershed dataset will sometimes produce a crash, I think because one of the regions is somehow not a valid polygon? We need to be robust to this kind of error.

Allow better control over color

In general we need more options for controlling the color of overlays.

    # Color from ScatterLayerState. We probably want all? or some of this
    
    #cmap_mode = DDSCProperty(docstring="Whether to use color to encode an attribute")
    #cmap_att = DDSCProperty(docstring="The attribute to use for the color")
    #cmap_vmin = DDCProperty(docstring="The lower level for the colormap")
    #cmap_vmax = DDCProperty(docstring="The upper level for the colormap")
    #cmap = DDCProperty(docstring="The colormap to use (when in colormap mode)")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.