☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

CustomJS Varriable with Common Scope

Community Supportcustomjsbokehjsbokeh
croots
croots

Hi all,

I suspect this is a duplicate somewhere, but I can’t seem to find an answer that cleanly answers how to do this.

I have a plot that is dynamically generating glyphs and placing them on an X axis. To avoid overlapping glyphs, I’m using CustomJS to track the location of placed glyphs and increment up the Y axis points appropriately when a glyph would overlap on the X axis. These glyphs are generated by a selected table. This works great, since I can calculate each position just by polling the table.

The problem comes when I have multiple tables. I’m having issues sending that persistent variable across multiple CustomJS blocks.

I can create static templates quite easily by passing any arbitrary python dictionary to the CustomJS class. I also saw this way to create a ‘global’ variable, but this seems still seems like it doesn’t create a common javascript object on the back end.

I could probably do this by passing around all the different tables in my code or using a class that manages all the tables and creates some humongous javasctipt block, where I pass all of the relevant tables to the same CustomJS that systematically scans all of them and draws each glyph, but that seems a lot more spagetti than multiple blocks logging the things it placed somewhere.

TLDR How can I track persistent, arbitrary data across diverse CustomJS objects?

Minimal example:

from bokeh.io import curdoc
from bokeh.models import CustomJS
from bokeh.models.widgets import Button
from bokeh.plotting import show
from bokeh.layouts import column

js1 = """
tracker['tracked_item']++
console.log(tracker['tracked_item'])
"""

js2 = """
console.log(tracker['tracked_item'])
"""

curdoc().tracker = {"tracked_item": 0}

# Increments appropriately
increment_button = Button(label="Increment")
increment_button.js_on_click(
    CustomJS(
        args=dict(tracker=curdoc().tracker),
        code=js1,
    )
)

# Does not increment with the increment button
report_button = Button(label="Report")
report_button.js_on_click(
    CustomJS(
        args=dict(tracker=curdoc().tracker),
        code=js2,
    )
)

buttons = column(increment_button, report_button)

show(buttons)

⌁   Link to post

End of archived discussion · Replies are disabled