diff --git a/panel/models/reactive_html.py b/panel/models/reactive_html.py index 416943db21..185406e27b 100644 --- a/panel/models/reactive_html.py +++ b/panel/models/reactive_html.py @@ -7,7 +7,7 @@ import bokeh.core.properties as bp import param as pm -from bokeh.models import HTMLBox, LayoutDOM +from bokeh.models import ColumnDataSource, HTMLBox, LayoutDOM from bokeh.model import DataModel from bokeh.events import ModelEvent @@ -141,10 +141,15 @@ def find_attrs(html): PARAM_MAPPING = { + pm.Array: lambda p, kwargs: bp.Array(**kwargs), pm.Boolean: lambda p, kwargs: bp.Bool(**kwargs), pm.CalendarDate: lambda p, kwargs: bp.Date(**kwargs), pm.CalendarDateRange: lambda p, kwargs: bp.Tuple(bp.Date, bp.Date, **kwargs), pm.Color: lambda p, kwargs: bp.Color(**kwargs), + pm.DataFrame: lambda p, kwargs: ( + bp.ColumnData(bp.Any, bp.Seq(bp.Any), **kwargs), + [(bp.PandasDataFrame, lambda x: ColumnDataSource._data_from_df(x))] + ), pm.DateRange: lambda p, kwargs: bp.Tuple(bp.Datetime, bp.Datetime, **kwargs), pm.Date: lambda p, kwargs: bp.Datetime(**kwargs), pm.Dict: lambda p, kwargs: bp.Dict(bp.String, bp.Any, **kwargs), @@ -175,11 +180,15 @@ def construct_data_model(parameterized, name=None, ignore=[], types={}): nullable = getattr(p, 'allow_None', False) kwargs = {'default': p.default, 'help': p.doc} if prop is None: - properties[pname] = bp.Any(**kwargs) - elif nullable: - properties[pname] = bp.Nullable(prop(p, {}), **kwargs) + bk_prop, accepts = bp.Any(**kwargs), [] else: - properties[pname] = prop(p, kwargs) + bkp = prop(p, {} if nullable else kwargs) + bk_prop, accepts = bkp if isinstance(bkp, tuple) else (bkp, []) + if nullable: + bk_prop = bp.Nullable(bk_prop, **kwargs) + for bkp, convert in accepts: + bk_prop = bk_prop.accepts(bkp, convert) + properties[pname] = bk_prop name = name or parameterized.name return type(name, (DataModel,), properties)