El objetivo es transmitir datos al panel y mostrar la temperatura actual en un indicador. Medidor de gráfico de panel
Por lo tanto, estoy usando la función de devolución de llamada para que el panel recupere un nuevo valor de temperatura y me gustaría actualizar el medidor también con la función JSCallback.
Panel JS Función de devolución de llamada
También analicé las siguientes preguntas sobre stackoverflow:
Aquí está el código actual:
import time import panel as pn import random random.seed() def read_temp(): return random.randint(15, 30) global temperature temperature = read_temp() # Stream function def stream(): temperature = read_temp() print(temperature) #how to access the js object? pn.state.jscallback(args={'gauge': gauge_pane}, value=""" gauge.data.series[0].data[0].value = """+str(temperature)) gauge = { 'tooltip': { 'formatter': '{a} <br/>{b} : {c}°C' }, 'series': [ { 'name': 'Gauge', 'type': 'gauge', 'detail': {'formatter': '{value}°C'}, 'data': [{'value': [temperature], 'name': 'Temperature'}] } ] }; #Panel pn.extension('echarts',sizing_mode="stretch_width",template="fast") ACCENT = "orange" pn.state.template.param.update(site="Test", title="Introduction to data apps with Panel", sidebar_width=200, accent_base_color=ACCENT, header_background=ACCENT, font="Montserrat") gauge_pane = pn.pane.ECharts(gauge,width=400, height=400).servable() pn.pane.JPG("logo.jpg", sizing_mode="scale_width", embed=False).servable(area="sidebar") pn.panel("# Settings").servable(area="sidebar") # Set up callback with streaming data pn.state.add_periodic_callback(stream, 500)Puede ser que alguien de los desarrolladores/comunidad del panel tenga algunos consejos o algún ejemplo. Principalmente me gusta entender cómo puedo acceder a los Objetos JS para actualizarlos en el panel. Entonces, ¿tal vez JSLink es la forma correcta de hacerlo? En caso afirmativo, ¿cómo funcionaría eso con mi pequeño ejemplo? - ¡Gracias! :-)
Creo que no hay una manera fácil de llamar a un jscallback desde python, pero no estoy seguro. Devoluciones de llamada de Bokeh con CustomJS: ¿hay alguna forma de activar una devolución de llamada con CustomJS desde dentro de otra devolución de llamada con JS personalizado?
Creo que su problema está relacionado, no hay pn.state.jscallback (o tal vez no estoy al tanto de eso).
Agregué un control deslizante ficticio, que no está visible, para usar la devolución de llamada adjunta a este control deslizante. Cuando cambia el valor del control deslizante, el panel activa internamente la devolución de llamada. Esto es bueno porque js_callback siempre tiene un objeto cb_obj en el código javascript, que puede usar para pasar la temperatura generada con la función random.randint. Creo que tampoco es necesario definir la temperatura global en ese caso.
Un gif de la solución funcionando está aquí https://discourse.holoviz.org/uploads/default/original/2X/f/f65a8da7b3224b1a6a86b57e4ddd20dc0aa11bb1.gif
import time import panel as pn import random random.seed() def read_temp(): return random.randint(15, 30) global temperature temperature = read_temp() slider = pn.widgets.FloatSlider(visible=False) # Stream function def stream(): temperature = read_temp() print('in python', temperature) #how to access the js object? slider.value = random.randint(0, 30) # this step triggers internally the js_callback attached to the slider gauge = { 'tooltip': { 'formatter': '{a} <br/>{b} : {c}°C' }, 'series': [ { 'name': 'Gauge', 'type': 'gauge', 'detail': {'formatter': '{value}°C'}, 'data': [{'value': [temperature], 'name': 'Temperature'}] } ] }; # Set up callback with streaming data pn.state.add_periodic_callback(stream, 500) #Panel pn.extension('echarts',sizing_mode="stretch_width",template="fast") ACCENT = "orange" pn.state.template.param.update(site="Test", title="Introduction to data apps with Panel", sidebar_width=200, accent_base_color=ACCENT, header_background=ACCENT, font="Montserrat") gauge_pane = pn.pane.ECharts(gauge,width=400, height=400) row = pn.Row(gauge_pane,slider).servable() slider.jscallback(args={'gauge': gauge_pane}, value=""" console.log( 'dummy slider:', cb_obj.value, 'gauge value',gauge.data.series[0].data[0].value); gauge.data.series[0].data[0].value = cb_obj.value; gauge.properties.data.change.emit()""" ) # pn.pane.JPG("logo.jpg", sizing_mode="scale_width", embed=False).servable(area="sidebar") pn.panel("# Settings").servable(area="sidebar")