#-----------------------------------------------------------------------------# Copyright (c) Anaconda, Inc., and Bokeh Contributors.# All rights reserved.## The full license is in the file LICENSE.txt, distributed with this software.#-----------------------------------------------------------------------------''' Various kinds of slider widgets.'''#-----------------------------------------------------------------------------# Boilerplate#-----------------------------------------------------------------------------from__future__importannotationsimportlogging# isort:skiplog=logging.getLogger(__name__)#-----------------------------------------------------------------------------# Imports#-----------------------------------------------------------------------------# Standard library importsimportnumbersfromdatetimeimportdate,datetime,timezone# Bokeh importsfrom...core.has_propsimportabstractfrom...core.propertiesimport(Bool,Color,Datetime,Either,Enum,Float,Instance,Int,Nullable,Override,Readonly,Required,Seq,String,Tuple,)from...core.property.descriptorsimportUnsetValueErrorfrom...core.property.singletonsimportUndefinedfrom...core.validationimporterrorfrom...core.validation.errorsimportEQUAL_SLIDER_START_ENDfrom..formattersimportTickFormatterfrom.widgetimportWidget#-----------------------------------------------------------------------------# Globals and constants#-----------------------------------------------------------------------------__all__=('AbstractSlider','CategoricalSlider','Slider','RangeSlider','DateSlider','DateRangeSlider','DatetimeRangeSlider',)#-----------------------------------------------------------------------------# Dev API#-----------------------------------------------------------------------------
[docs]@abstractclassAbstractSlider(Widget):""" """def__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)try:# synchronize the value of a readonly property `value_throttled`self.lookup("value_throttled")._set(self,Undefined,self.value)exceptUnsetValueError:passexceptAttributeError:# TODO Remove this when proper support for property overrides is# implemented. For now this is required to make defaults' tests# work, because we depend there on model instances to provide# "default" values.pass# TODO value = Required(GenericType, help="""# Initial or selected range.# """)# TODO value_throttled = Readonly(GenericType, help="""# Initial or selected value, throttled according to report only on mouseup.# """)orientation=Enum("horizontal","vertical",help=""" Orient the slider either horizontally (default) or vertically. """)title=Nullable(String,default="",help=""" The slider's label (supports :ref:`math text <ug_styling_mathtext>`). """)show_value=Bool(default=True,help=""" Whether or not show slider's value. """)direction=Enum("ltr","rtl",help=""" """)tooltips=Bool(default=True,help=""" Display the slider's current value in a tooltip. """)bar_color=Color(default="#e6e6e6",help=""" """)width=Override(default=300)@error(EQUAL_SLIDER_START_END)def_check_missing_dimension(self):ifhasattr(self,'start')andhasattr(self,'end'):ifself.start==self.end:returnf"{self!s} with title {self.title!s}"
@abstractclassNumericalSlider(AbstractSlider):""" Base class for numerical sliders. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)format=Either(String,Instance(TickFormatter),help=""" """)#-----------------------------------------------------------------------------# General API#-----------------------------------------------------------------------------
[docs]classCategoricalSlider(AbstractSlider):""" Discrete slider allowing selection from a collection of values. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)categories=Required(Seq(String),help=""" A collection of categories to choose from. """)value=Required(String,help=""" Initial or selected value. """)value_throttled=Readonly(Required(String),help=""" Initial or throttled selected value. """)
[docs]classSlider(NumericalSlider):""" Slider-based number selection widget. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)start=Required(Float,help=""" The minimum allowable value. """)end=Required(Float,help=""" The maximum allowable value. """)value=Required(Float,help=""" Initial or selected value. """)value_throttled=Readonly(Required(Float),help=""" Initial or selected value, throttled according to report only on mouseup. """)step=Float(default=1,help=""" The step between consecutive values. """)format=Override(default="0[.]00")
[docs]classRangeSlider(NumericalSlider):""" Range-slider based number range selection widget. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)value=Required(Tuple(Float,Float),help=""" Initial or selected range. """)value_throttled=Readonly(Required(Tuple(Float,Float)),help=""" Initial or selected value, throttled according to report only on mouseup. """)start=Required(Float,help=""" The minimum allowable value. """)end=Required(Float,help=""" The maximum allowable value. """)step=Float(default=1,help=""" The step between consecutive values. """)format=Override(default="0[.]00")
[docs]classDateSlider(NumericalSlider):""" Slider-based date selection widget. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)@propertydefvalue_as_datetime(self)->datetime|None:''' Convenience property to retrieve the value as a datetime object. Added in version 2.0 '''ifself.valueisNone:returnNoneifisinstance(self.value,numbers.Number):returndatetime.fromtimestamp(self.value/1000,tz=timezone.utc)returnself.value@propertydefvalue_as_date(self)->date|None:''' Convenience property to retrieve the value as a date object. Added in version 2.0 '''ifself.valueisNone:returnNoneifisinstance(self.value,numbers.Number):dt=datetime.fromtimestamp(self.value/1000,tz=timezone.utc)returndate(*dt.timetuple()[:3])returnself.valuevalue=Required(Datetime,help=""" Initial or selected value. """)value_throttled=Readonly(Required(Datetime),help=""" Initial or selected value, throttled to report only on mouseup. """)start=Required(Datetime,help=""" The minimum allowable value. """)end=Required(Datetime,help=""" The maximum allowable value. """)step=Int(default=1,help=""" The step between consecutive values, in units of days. """)format=Override(default="%d %b %Y")
[docs]classDateRangeSlider(NumericalSlider):""" Slider-based date range selection widget. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)@propertydefvalue_as_datetime(self)->tuple[datetime,datetime]|None:''' Convenience property to retrieve the value tuple as a tuple of datetime objects. Added in version 1.1 '''ifself.valueisNone:returnNonev1,v2=self.valueifisinstance(v1,numbers.Number):d1=datetime.fromtimestamp(v1/1000,tz=timezone.utc)else:d1=v1ifisinstance(v2,numbers.Number):d2=datetime.fromtimestamp(v2/1000,tz=timezone.utc)else:d2=v2returnd1,d2@propertydefvalue_as_date(self)->tuple[date,date]|None:''' Convenience property to retrieve the value tuple as a tuple of date objects. Added in version 1.1 '''ifself.valueisNone:returnNonev1,v2=self.valueifisinstance(v1,numbers.Number):dt=datetime.fromtimestamp(v1/1000,tz=timezone.utc)d1=date(*dt.timetuple()[:3])else:d1=v1ifisinstance(v2,numbers.Number):dt=datetime.fromtimestamp(v2/1000,tz=timezone.utc)d2=date(*dt.timetuple()[:3])else:d2=v2returnd1,d2value=Required(Tuple(Datetime,Datetime),help=""" Initial or selected range. """)value_throttled=Readonly(Required(Tuple(Datetime,Datetime)),help=""" Initial or selected value, throttled to report only on mouseup. """)start=Required(Datetime,help=""" The minimum allowable value. """)end=Required(Datetime,help=""" The maximum allowable value. """)step=Int(default=1,help=""" The step between consecutive values, in units of days. """)format=Override(default="%d %b %Y")
[docs]classDatetimeRangeSlider(NumericalSlider):""" Slider-based datetime range selection widget. """# explicit __init__ to support Init signaturesdef__init__(self,*args,**kwargs)->None:super().__init__(*args,**kwargs)@propertydefvalue_as_datetime(self)->tuple[datetime,datetime]|None:''' Convenience property to retrieve the value tuple as a tuple of datetime objects. '''ifself.valueisNone:returnNonev1,v2=self.valueifisinstance(v1,numbers.Number):d1=datetime.fromtimestamp(v1/1000,tz=timezone.utc)else:d1=v1ifisinstance(v2,numbers.Number):d2=datetime.fromtimestamp(v2/1000,tz=timezone.utc)else:d2=v2returnd1,d2value=Required(Tuple(Datetime,Datetime),help=""" Initial or selected range. """)value_throttled=Readonly(Required(Tuple(Datetime,Datetime)),help=""" Initial or selected value, throttled to report only on mouseup. """)start=Required(Datetime,help=""" The minimum allowable value. """)end=Required(Datetime,help=""" The maximum allowable value. """)step=Int(default=3_600_000,help=""" The step between consecutive values, in units of milliseconds. Default is one hour. """)format=Override(default="%d %b %Y %H:%M:%S")