Bokeh项目中的JavaScript回调机制详解

Bokeh项目中的JavaScript回调机制详解

bokeh bokeh/bokeh: 是一个用于创建交互式图形和数据的 Python 库。适合用于数据可视化、数据分析和呈现,以及创建动态的 Web 应用。特点是提供了一种简洁、直观的 API 来描述和处理数据,并生成交互式的可视化效果。 bokeh 项目地址: https://gitcode.com/gh_mirrors/bo/bokeh

概述

Bokeh作为一个强大的Python可视化库,其核心目标是通过纯Python代码在浏览器中创建丰富的交互式可视化效果。然而,在某些情况下,预定义的核心库功能可能无法满足所有需求。为此,Bokeh提供了多种方式让用户能够在必要时注入自定义JavaScript代码,实现更灵活的交互行为。

JavaScript回调的三种实现方式

1. js_link方法

js_link是一个Python便捷方法,用于将不同模型的属性链接在一起。这种方法会自动生成所需的JavaScript代码,无需手动编写。

2. SetValue对象

SetValue模型允许在浏览器中发生特定事件时,动态设置另一个对象的属性。它包含三个关键属性:

  • obj: 要设置值的对象
  • attr: 要修改的对象属性
  • value: 要为属性设置的值

3. CustomJS对象

CustomJS模型允许直接提供自定义JavaScript代码片段,在浏览器中发生事件时执行。这是最灵活的方式,可以完全自定义交互逻辑。

回调触发机制

1. js_on_change

大多数Bokeh对象都有.js_on_change属性,当对象状态发生变化时,会调用分配给此属性的回调函数。

2. js_on_event

某些小部件还有.js_on_event属性,当浏览器中发生特定事件时,会调用分配给此属性的回调函数。

SetValue回调详解

SetValue是一种声明式方法,让开发者无需直接编写JavaScript代码就能实现属性间的动态关联。例如:

from bokeh.models import SetValue

# 当滑块值变化时,设置绘图范围的开始值
callback = SetValue(obj=plot.x_range, attr="start", value=slider.value)
slider.js_on_change("value", callback)

这种方式简洁明了,适合简单的属性关联场景。

CustomJS回调详解

CustomJS提供了完整的JavaScript编程能力,支持两种写法:

现代写法(推荐)

from bokeh.models.callbacks import CustomJS

callback = CustomJS(args=dict(x_range=plot.x_range), code="""
// 可以导入外部模块
import {some_function} from "https://cdn.example.com/module"

// 定义常量、函数和类
const FACTOR = 2.5

function transform(value) {
    return FACTOR * value
}

// 默认导出的回调函数
export default ({x_range}, obj, data, context) => {
    x_range.start = transform(obj.value)
    x_range.end = x_range.start + 10
}
""")

特点:

  • 支持ES模块语法
  • 明确的函数参数:args, obj, data, context
  • 可以定义复杂逻辑和状态
  • 代码只编译一次,函数可多次执行

传统写法

callback = CustomJS(args=dict(x_range=plot.x_range), code="""
// 通过cb_obj访问触发回调的对象
x_range.start = cb_obj.value
x_range.end = x_range.start + 10
""")

特点:

  • 隐式参数:cb_obj, cb_data, cb_context
  • 更简洁但功能有限
  • 适合简单场景

从文件加载

对于复杂逻辑,可以将代码保存在文件中:

# 加载.mjs文件(现代写法)
callback = CustomJS.from_file("callback.mjs", x_range=plot.x_range)

# 加载.js文件(传统写法) 
callback = CustomJS.from_file("callback.js", x_range=plot.x_range)

回调触发场景示例

1. 属性变化回调

# 当绘图x范围起始值变化时触发回调
plot.x_range.js_on_change('start', callback)

2. 事件回调

from bokeh.events import Tap

# 当点击绘图区域时触发回调
callback = CustomJS(code="""
console.log('点击位置: x=' + cb_obj.x + ', y=' + cb_obj.y)
""")
plot.js_on_event(Tap, callback)

3. 文档事件回调

from bokeh.io import curdoc

# 当文档完全渲染后触发回调
callback = CustomJS(code="console.log('文档已就绪')")
curdoc().js_on_event("document_ready", callback)

实用案例

小部件交互

# 滑块控制绘图数据
slider.js_on_change('value', CustomJS(args=dict(source=source), code="""
const f = cb_obj.value
const data = source.data
// 更新数据逻辑...
source.change.emit()
""")

选择交互

# 响应选择变化
source.selected.js_on_change('indices', CustomJS(code="""
// 处理选中点的索引
const indices = cb_obj.indices
// ...
"""))

悬停工具

hover = HoverTool(callback=CustomJS(args=dict(div=div), code="""
// index包含悬停点索引
div.text = "悬停点索引: " + cb_data.index
"""))

点击打开URL

from bokeh.models import OpenURL, TapTool

# 点击点打开对应URL
tap = TapTool(callback=OpenURL(url="/details/@id"))

安全注意事项

由于CustomJS会直接在浏览器中执行原始JavaScript代码,如果代码的任何部分来自不受信任的用户输入,必须在传递给Bokeh之前进行适当的清理和验证,以防止潜在的安全问题。

总结

Bokeh的JavaScript回调机制为开发者提供了强大的扩展能力,从简单的属性关联到复杂的自定义交互逻辑都能支持。通过合理选择js_linkSetValueCustomJS,可以构建出丰富多样的交互式可视化应用。

bokeh bokeh/bokeh: 是一个用于创建交互式图形和数据的 Python 库。适合用于数据可视化、数据分析和呈现,以及创建动态的 Web 应用。特点是提供了一种简洁、直观的 API 来描述和处理数据,并生成交互式的可视化效果。 bokeh 项目地址: https://gitcode.com/gh_mirrors/bo/bokeh

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

左唯妃Stan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值