обновить данные при нажатии на гистограмму боке - PullRequest
0 голосов
/ 07 мая 2020

Я сделал гистограмму боке и таблицу данных из pandas отображения фрейма данных рядом друг с другом на веб-странице, используя django. Я хочу щелкнуть гистограмму и изменить отображаемые строки таблицы данных в зависимости от заголовка гистограммы.

Я привел пример ниже. Основываясь на примере, я хочу щелкнуть полосу на гистограмме и получить имя полосы (одна из этикеток с фруктами). Затем я хочу отфильтровать фрейм данных (просто список в примере), если имя столбчатой ​​диаграммы совпадает со строкой в ​​столбце. Например: если я нажму на полосу гистограммы под названием «яблоко», должны отобразиться строки фрейма данных, в которых значение столбца «слово» равно яблоку.

Я пытался сделать это с помощью js_on_event и js_on_change но не смог ничего прочитать. Есть какой-либо способ сделать это? Или даже просто прочитать название столбца при нажатии?

def indexPage(request):
fruits = ["apple", "banana","carrot","daikon","eggplant","fig","grape"]
count = [1,2,3,4,5,6,7]

data = {'fruits' : fruits,
        'count'   : count}

source = ColumnDataSource(data=data)

p = figure(y_range=fruits, sizing_mode='scale_width',toolbar_location='right',tools=['tap', 'reset'])

p.hbar(y='fruits', right="count",height=0.9,selection_color='deepskyblue', nonselection_color='lightgray',nonselection_alpha=0.3,source=source)
hover = HoverTool(tooltips=[("word","@fruits"),("count","@count")])
p.add_tools(hover)

script, div = components(p)
########################################################################################################
text = ["apples r red", "banana is yelo","carrt is loong","daikon is long","eggplants r","figs are the food","grape is red"]
word = ["apple", "banana","carrot","daikon","eggplant","fig","grape"]

data1 = {'text' : text}

source = ColumnDataSource(data=data1)

dt = DataTable(columns=[TableColumn(field='text', title='text')],source=source)

script1, div1 = components(dt)
return render(request, "index.html", {'script':script, 'div':div, "script1":script1,"div1":div1})

1 Ответ

0 голосов
/ 07 мая 2020

Вот рабочий пример, основанный на вашем коде, который демонстрирует описанное поведение:

from bokeh.io import show
from bokeh.layouts import row
from bokeh.models import ColumnDataSource, HoverTool, DataTable, TableColumn, CDSView, CustomJS, IndexFilter
from bokeh.plotting import figure

p_ds = ColumnDataSource(dict(fruits=["apple", "banana", "carrot", "daikon", "eggplant", "fig", "grape"],
                             count=[1, 2, 3, 4, 5, 6, 7]))

p = figure(y_range=sorted(set(p_ds.data['fruits'])), sizing_mode='scale_width',
           toolbar_location='right', tools=['tap', 'reset'])

p.hbar(y='fruits', right="count", height=0.9, selection_color='deepskyblue', nonselection_color='lightgray',
       nonselection_alpha=0.3, source=p_ds)
p.add_tools(HoverTool(tooltips=[("word", "@fruits"), ("count", "@count")]))

dt_ds = ColumnDataSource(data=dict(text=["apples r red", "banana is yelo", "carrt is loong", "daikon is long",
                                         "eggplants r", "figs are the food", "grape is red"],
                                   word=["apple", "banana", "carrot", "daikon", "eggplant", "fig", "grape"]))


dt = DataTable(columns=[TableColumn(field='text', title='text')], source=dt_ds,
               # Since none of the bars are selected at the start,
               # the filters are set to show an empty table.
               view=CDSView(source=dt_ds, filters=[IndexFilter(indices=[])]))

p_ds.selected.js_on_change('indices',
                           CustomJS(args=dict(view=dt.view, p_ds=p_ds),
                                    code="""\
                                        const {indices} = cb_obj;
                                        if (indices.length > 0) {
                                            const idx = indices[0];
                                            const word = p_ds.data.fruits[idx];
                                            const GroupFilter = Bokeh.Models('GroupFilter');
                                            view.filters = [new GroupFilter({column_name: 'word', group: word})];
                                        } else {
                                            const IndexFilter = Bokeh.Models('IndexFilter');
                                            view.filters = [new IndexFilter({indices: []})];
                                        }
                                        // Needed to work around https://github.com/bokeh/bokeh/issues/7273.
                                        view.source.change.emit();
                                    """))

show(row(p, dt))
...