Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

169
Visualizações
Panel - JSCallback function - Linking stream data to a JSObject in Echarts within a Panel dashboard

The goal is to stream data into panel and show the current temperature in a Gauge. Panel EChart Gauge

Therefore I am using the callback function for the panel to retrieve a new temperature value and like to update the Gauge as well with the JSCallback function.

Panel JSCallback Function

I also looked into the following questions on stackoverflow:

  • CustomJSCallback
  • Updating existing plot
  • Dynamically updating a Holoviz Panel layout

Here is the current code:

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)

May be someone from the panel developers / community has some hints or some example. I mainly like to understand how I can access the JS Objects to be updated in the panel. So maybe JSLink is the right way to do it? If yes how would that work with my little example? - Thank you! :-)

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

There is no easy way to call a jscallback from python, I think, but I am not sure. Bokeh callbacks with CustomJS: is there a way to trigger a callback with CustomJS from inside another callback with custom JS?

I think your problem is related there is no pn.state.jscallback (or maybe I am not aware of that).

I added a dummy slider, which is not visible, to use the callback attached to this slider. When you change the slider value, the callback is triggered internally by panel. This is good because the js_callback always has a cb_obj object in the javascript code, which you can use to pass the temperature generated with the random.randint function. I think you do not need to define the temperature global in that case either.

A gif of the solution working is here 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")
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda