使用前端访问绑定到散景字形的数据 javascript
Access data bound to Bokeh glyphs using front end javascript
我正在尝试将我的每个字形与一个 ID 相关联,然后在单击按钮时获取所选字形 ID 的列表。我需要将 ID 列表与页面上的一些其他用户输入相结合,因此使用 python 回调效果不佳。
到目前为止,我已经成功地通过 ColumnDataSource 传递了我的 ID(我没有找到仅使用 patches 方法的方法),但我不确定如何获取关联的 ID使用已选择的字形。
注意 ColumnDataSource 的 glyph_id 字段
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource
from bokeh.models.glpyhs import Patches
output_file("patch.html")
plot = figure(tools="tap", plot_width=400, plot_height=400)
source = ColumnDataSource(dict(
xs = [[1, 3, 2], [3, 4, 6, 6]],
ys = [[2, 1, 4], [4, 7 , 8, 5]],
glyph_id = [1, 2]
))
patches = Patches(xs="xs", ys="ys")
plot.add_glyph(source, patches)
show(plot)
编辑:
这是一个使用回调的解决方案,但有很多问题,主要问题是它会在每次点击事件时更新列表,而不是在我需要时简单地获取列表。
source.callback = CustomJS(code="""
var selected_glyphs = cb_obj['selected']['1d']['indices'];
var glyph_ids = cb_obj['data']['glyph_id']
window.selected_glyphs = [];
selected_glyphs.forEach(function(idx) {
window.selected_glyphs.push(glyph_ids[idx]);
});
""")
下面的示例仅在按下按钮时从数据源中检索当前选择,这似乎是您所要求的(仍然不是 100% 确定)。它还展示了如何将 patches
与明确提供的数据源一起使用。
from bokeh.layouts import column
from bokeh.models import Button, ColumnDataSource, CustomJS
from bokeh.plotting import figure, output_file, show
output_file("patch.html")
source = ColumnDataSource(dict(
xs = [[1, 3, 2], [3, 4, 6, 6]],
ys = [[2, 1, 4], [4, 7 , 8, 5]],
id = [1, 2]
))
plot = figure(tools="tap", plot_width=400, plot_height=400)
plot.patches('xs', 'ys', source=source)
callback=CustomJS(args=dict(source=source), code="""
var result = [];
var selected = source.selected['1d'].indices;
selected.forEach(function(idx) {
result.push(source.data.id[idx]);
});
alert(result);
""")
button = Button(label='Make Selection and Press Me', callback=callback)
show(column(button, plot))
这是一个函数,用于获取使用 selected
的模型的句柄。使用 ColumnDataSource
获取任何模型句柄的更通用的方法可能是用 "column_names"
替换 "selected"
,但我还没有测试过。
var models = [];
for (var idx in Bokeh.index)
{
if (Bokeh.index.hasOwnProperty(idx))
{
var idx_models = Bokeh.index[idx].model.document._all_models
for (var model in idx_models)
{
if (idx_models.hasOwnProperty(model) && idx_models[model].attributes.hasOwnProperty("selected"))
models.push(idx_models[model]);
}
}
}
以下是我实际完成特定事件的方式:
<button id="get-glyph-ids">Get Glyph Ids</button>
<script>
document.getElementById("get-glyph-ids").addEventListener("click", function() {
var selectedGlyphIds = [];
for (var idx in Bokeh.index)
{
if (Bokeh.index.hasOwnProperty(idx))
{
var idxModels = Bokeh.index[idx].model.document._all_models;
for (var modelId in idxModels)
{
if (idxModels.hasOwnProperty(modelId) && idxModels[modelId].attributes.hasOwnProperty("selected"))
{
var modelGlyphIds = idxModels[modelId].data.glyph_id;
idxModels[modelId].selected["1d"]["indices"].forEach(function(glyphIdx){
selectedGlyphIds.push(modelGlyphIds[glyphIdx]);
});
}
}
}
}
console.log(selectedGlyphIds);
});
</script>
我正在尝试将我的每个字形与一个 ID 相关联,然后在单击按钮时获取所选字形 ID 的列表。我需要将 ID 列表与页面上的一些其他用户输入相结合,因此使用 python 回调效果不佳。
到目前为止,我已经成功地通过 ColumnDataSource 传递了我的 ID(我没有找到仅使用 patches 方法的方法),但我不确定如何获取关联的 ID使用已选择的字形。
注意 ColumnDataSource 的 glyph_id 字段
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource
from bokeh.models.glpyhs import Patches
output_file("patch.html")
plot = figure(tools="tap", plot_width=400, plot_height=400)
source = ColumnDataSource(dict(
xs = [[1, 3, 2], [3, 4, 6, 6]],
ys = [[2, 1, 4], [4, 7 , 8, 5]],
glyph_id = [1, 2]
))
patches = Patches(xs="xs", ys="ys")
plot.add_glyph(source, patches)
show(plot)
编辑:
这是一个使用回调的解决方案,但有很多问题,主要问题是它会在每次点击事件时更新列表,而不是在我需要时简单地获取列表。
source.callback = CustomJS(code="""
var selected_glyphs = cb_obj['selected']['1d']['indices'];
var glyph_ids = cb_obj['data']['glyph_id']
window.selected_glyphs = [];
selected_glyphs.forEach(function(idx) {
window.selected_glyphs.push(glyph_ids[idx]);
});
""")
下面的示例仅在按下按钮时从数据源中检索当前选择,这似乎是您所要求的(仍然不是 100% 确定)。它还展示了如何将 patches
与明确提供的数据源一起使用。
from bokeh.layouts import column
from bokeh.models import Button, ColumnDataSource, CustomJS
from bokeh.plotting import figure, output_file, show
output_file("patch.html")
source = ColumnDataSource(dict(
xs = [[1, 3, 2], [3, 4, 6, 6]],
ys = [[2, 1, 4], [4, 7 , 8, 5]],
id = [1, 2]
))
plot = figure(tools="tap", plot_width=400, plot_height=400)
plot.patches('xs', 'ys', source=source)
callback=CustomJS(args=dict(source=source), code="""
var result = [];
var selected = source.selected['1d'].indices;
selected.forEach(function(idx) {
result.push(source.data.id[idx]);
});
alert(result);
""")
button = Button(label='Make Selection and Press Me', callback=callback)
show(column(button, plot))
这是一个函数,用于获取使用 selected
的模型的句柄。使用 ColumnDataSource
获取任何模型句柄的更通用的方法可能是用 "column_names"
替换 "selected"
,但我还没有测试过。
var models = [];
for (var idx in Bokeh.index)
{
if (Bokeh.index.hasOwnProperty(idx))
{
var idx_models = Bokeh.index[idx].model.document._all_models
for (var model in idx_models)
{
if (idx_models.hasOwnProperty(model) && idx_models[model].attributes.hasOwnProperty("selected"))
models.push(idx_models[model]);
}
}
}
以下是我实际完成特定事件的方式:
<button id="get-glyph-ids">Get Glyph Ids</button>
<script>
document.getElementById("get-glyph-ids").addEventListener("click", function() {
var selectedGlyphIds = [];
for (var idx in Bokeh.index)
{
if (Bokeh.index.hasOwnProperty(idx))
{
var idxModels = Bokeh.index[idx].model.document._all_models;
for (var modelId in idxModels)
{
if (idxModels.hasOwnProperty(modelId) && idxModels[modelId].attributes.hasOwnProperty("selected"))
{
var modelGlyphIds = idxModels[modelId].data.glyph_id;
idxModels[modelId].selected["1d"]["indices"].forEach(function(glyphIdx){
selectedGlyphIds.push(modelGlyphIds[glyphIdx]);
});
}
}
}
}
console.log(selectedGlyphIds);
});
</script>