From b5f9033a59b2d07df00fdd504d55529e9a255fa1 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Mon, 10 Apr 2017 00:08:49 +0100 Subject: [PATCH] Defined Dimension.step and used it for dynamic widgets --- holoviews/core/dimension.py | 5 +++++ holoviews/plotting/bokeh/widgets.py | 2 ++ holoviews/plotting/widgets/__init__.py | 2 ++ tests/testbokehwidgets.py | 13 +++++++++++++ 4 files changed, 22 insertions(+) diff --git a/holoviews/core/dimension.py b/holoviews/core/dimension.py index 29a629b5f9..ece24a9ad6 100644 --- a/holoviews/core/dimension.py +++ b/holoviews/core/dimension.py @@ -149,6 +149,11 @@ class Dimension(param.Parameterized): may be an inbuilt constructor (such as int, str, float) or a custom class object.""") + step = param.Number(default=None, doc=""" + Optional floating point step specifying how frequently the + underlying space should be sampled. May be used to define a + discrete sampling of over the range.""") + unit = param.String(default=None, allow_None=True, doc=""" Optional unit string associated with the Dimension. For instance, the string 'm' may be used represent units of meters diff --git a/holoviews/plotting/bokeh/widgets.py b/holoviews/plotting/bokeh/widgets.py index 39b51658d1..28c94fa18e 100644 --- a/holoviews/plotting/bokeh/widgets.py +++ b/holoviews/plotting/bokeh/widgets.py @@ -114,6 +114,8 @@ def create_widget(self, dim, holomap=None, editable=False): int_type = isinstance(dim.type, type) and issubclass(dim.type, int) if isinstance(dim_range, int) or int_type: step = 1 + elif dim.step is not None: + step = dim.step else: step = 10**((round(math.log10(dim_range))-3)) if editable: diff --git a/holoviews/plotting/widgets/__init__.py b/holoviews/plotting/widgets/__init__.py index f095015f94..9f5ac123b7 100644 --- a/holoviews/plotting/widgets/__init__.py +++ b/holoviews/plotting/widgets/__init__.py @@ -302,6 +302,8 @@ def get_widgets(self): int_type = isinstance(dim.type, type) and issubclass(dim.type, int) if isinstance(dim_range, int) or int_type: step = 1 + elif dim.step is not None: + step = dim.step else: step = 10**(round(math.log10(dim_range))-3) init_dim_vals.append(dim_vals[0]) diff --git a/tests/testbokehwidgets.py b/tests/testbokehwidgets.py index 391c83185b..bc4d993f2a 100644 --- a/tests/testbokehwidgets.py +++ b/tests/testbokehwidgets.py @@ -47,6 +47,19 @@ def test_bokeh_server_dynamic_range_float(self): self.assertEqual(label.value, '3.1') self.assertIs(mapping, None) + def test_bokeh_server_dynamic_range_float_step(self): + dim = Dimension('x', range=(3.1, 11.2), step=0.1) + widget, label, mapping = BokehServerWidgets.create_widget(dim, editable=True) + self.assertIsInstance(widget, Slider) + self.assertEqual(widget.value, 3.1) + self.assertEqual(widget.start, 3.1) + self.assertEqual(widget.end, 11.2) + self.assertEqual(widget.step, 0.1) + self.assertIsInstance(label, TextInput) + self.assertEqual(label.title, dim.pprint_label) + self.assertEqual(label.value, '3.1') + self.assertIs(mapping, None) + def test_bokeh_server_dynamic_range_not_editable(self): dim = Dimension('x', range=(3.1, 11.2)) widget, label, mapping = BokehServerWidgets.create_widget(dim, editable=False)