使用前端javascript

时间:2016-12-27 20:54:46

标签: javascript python bokeh

我正在尝试将每个字形与id相关联,然后在单击按钮时获取所选字形ID的列表。我需要将id列表与页面上的其他用户输入结合起来,因此使用python回调不能很好地工作。

到目前为止,我已成功通过ColumnDataSource传递我的ID(我没有找到一种方法只使用补丁方法),但我不知道如何获取与此关联的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]);
    });
""")

2 个答案:

答案 0 :(得分:1)

以下示例仅在按下按钮时从数据源检索当前选择,这似乎是您要求的(仍然不是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))

答案 1 :(得分:0)

这是一个获取使用selected的模型句柄的函数。使用ColumnDataSource获取任何模型句柄的更通用方法可能是将"selected"替换为"column_names",但我还没有对其进行测试。

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>