Hello Anvil community !
What I’m trying to do:
I currently use an anvil server side function to create a gantt chart using plotly express, then return the figure when calling for this function, and pass it to plot_component.figure in client side.
However, calling the server function every time i want to access the gantt chart can ruin the UX.
I read it’s always possible to use graph_objects to reproduce exactly the express method.
But i just can’t do it.
Here is the server side snippet (some lines may be obsolete or not optimal, i just didn’t clean the code yet):
@anvil.server.callable
def _plot_planning():
now = datetime.datetime.now(tz=ZoneInfo("UTC")).astimezone(ZoneInfo("Pacific/Tahiti"))
today = datetime.date.today()
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
status_map = {
'ongoing': 'En cours',
'booked': 'Réservé',
'confirmed': 'Confirmé',
"maintenance": "En maintenance",
'finished': 'Terminé'
}
bookings = app_tables.bookings.search(_business_id=anvil.server.session['business_id'])
last_day = max([booking['ending'] for booking in bookings])
df = pd.DataFrame([
{
'id': booking['vehicle_immatriculation'],
'starting': booking['starting'].strftime("%Y-%m-%d %H:%M"),
'ending': booking['ending'].strftime("%Y-%m-%d %H:%M"),
'status': status_map[booking['status']],
}
for booking in bookings])
colors = {
"Réservé": "#FFEE93",
"Confirmé": "#68B6EF",
"En cours": "#90EE90",
"En maintenance": "#D1D1D1",
"Terminé": "#46484F"
}
fig = px.timeline(
df, x_start="starting", x_end="ending", y="id", color="status", color_discrete_map=colors,
custom_data="status"
)
fig.update_traces(
#width= 0.4,
hovertemplate='<b>%{y}</b> <br><b>Status:</b> %{customdata} <br><b>Départ:</b> %{base|%d/%m %Hh%M} <br><b>Retour:</b> %{x|%d/%m %Hh%M}<extra></extra>' # <b>Status:</b> %{customdata} <br>
)
fig.update_layout(
legend=dict(
orientation="h",
yanchor="bottom",
y=1.05,
xanchor="right",
x=1,
),
bargap = 0,
#plot_bgcolor='white',
template='seaborn',
legend_title_text='',
margin=dict(
l=0,
r=10,
b=10,
t=10,
pad=0
),
)
fig.update_yaxes(
autorange="reversed",
automargin=True,
title_text = "",
title_standoff = 0,
showgrid=True,
showline=True,
)
fig.update_xaxes(
ticks="inside",
side='top',
ticklabelstep=1,
tickformat="%d/%m",
type='date',
showgrid=True,
rangeslider_visible=True,
showline=True,
range=[today, last_day]
#linecolor='lightgrey',
#gridcolor='lightgrey'
)
fig.add_vrect(
x0=today,
x1=tomorrow,
fillcolor="#5AC9A1",
opacity=0.35,
line_width=0
)
return fig
I’ve spent a few hours looking for a solution, but only in vain.
Any help will be be largely appreciated !