Hi, I’m trying to build an app that lets my users inspect timeseries of data points in a table. For this, I would like to use the row_content
, because it makes it easy to compare rows that are not neighbors. The plots are usually more involved than in the minimal example below, and take data from the row in question into account.
import datetime as dt
import numpy as np
import pandas as pd
import panel as pn
import param
import hvplot.pandas # noqa
datetime_range_slider = pn.widgets.DatetimeRangeSlider(
name="Select timerange:",
start=dt.datetime(2021, 1, 1),
end=dt.datetime(2021, 1, 10),
value=(dt.datetime(2021, 1, 1), dt.datetime(2021, 1, 3)),
step=3600000,
)
class MyTable(param.Parameterized):
states = param.DataFrame(doc="Plant state")
def __init__(self, timerange_widget=None, **kwargs):
super().__init__(**kwargs)
self.timerange_widget = timerange_widget
# this will normally be triggered by some widget:
self.states = pd.DataFrame([[1, 3], [2, 4]], columns=["foo", "bar"])
def get_tabulator(self):
table_ = pn.widgets.Tabulator.from_param(
self.param.states,
sizing_mode="stretch_width",
row_content=pn.bind( # doesn't work
self.myplot,
timerange=self.timerange_widget.value_throttled,
watch=True,
),
height=700,
embed_content=True, # makes no difference?
layout="fit_columns",
)
return table_
def get_timeseries(self, name):
dates = pd.date_range(
self.timerange_widget.value[0], self.timerange_widget.value[1], freq="h"
)
ts = pd.DataFrame(
np.random.normal(size=len(dates)), index=dates, columns=["state"]
)
return ts
def myplot(self, state_row, timerange=None):
state_condition_ts = self.get_timeseries(state_row.foo)
return pn.pane.HoloViews(
state_condition_ts.hvplot(),
sizing_mode="stretch_width",
)
mytab = MyTable(timerange_widget=datetime_range_slider)
tab_states = mytab.get_tabulator()
template = pn.template.VanillaTemplate(
title="Test",
)
template.main.append(
pn.Column(
datetime_range_slider,
pn.pane.Markdown("### Plant states"),
pn.Row(tab_states, sizing_mode="stretch_width"),
width=1000,
)
)
template.servable(target="main", title="Plant manager")
So far, so good. If anyone could show me how to integrate the extra widgets into my parameterized class, all the better!
But my main issue is that the row_content
is not dynamically updating if I move the slider. It only updates when I collapse and reopen a row. What am I doing wrong?
Any hints would be greatly appreciated. Thank you in advance!