Как я могу сгенерировать текст описания Dynami c для боке за пределами холста? - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть боке-график с несколькими глифами и функция обратного вызова javascript, которая смешивается с дополнительными глифами в зависимости от того, где мышь находится на графике.

Теперь я хочу добавить описание с дополнительной информацией о с правой стороны за пределами этого графика в зависимости от того, где мышь (или, возможно, щелчки) на левой стороне графика.

Как создать динамически изменяющийся текст описания для графика боке вне холста?

Моя идея заключалась в том, чтобы написать функцию обратного вызова сценария java, которая изменяет текст div вне графика, но я не уверен, возможно ли это или как это сделать sh.

Использование инструмента наведения курсора было бы возможно, но описания, которые у меня есть, слишком длинные, чтобы отображаться как наложение.

Вот пример кода с div, который я хотел бы динамически изменить:

from bokeh.models import ColumnDataSource, CustomJS, HoverTool, Div, Spacer
from bokeh.plotting import figure, output_file, show
from bokeh.layouts import row

output_file("hover_callback.html")

# define some points and a little graph between them
x = [2, 3, 5, 6, 8, 7]
y = [6, 4, 3, 8, 7, 5]
links = {
    0: [1, 2],
    1: [0, 3, 4],
    2: [0, 5],
    3: [1, 4],
    4: [1, 3],
    5: [2, 3, 4]
}

p = figure(plot_width=400, plot_height=400, tools="", toolbar_location=None, title='Hover over points')

source = ColumnDataSource({'x0': [], 'y0': [], 'x1': [], 'y1': []})
sr = p.segment(x0='x0', y0='y0', x1='x1', y1='y1', color='olive', alpha=0.6, line_width=3, source=source, )
cr = p.circle(x, y, color='olive', size=30, alpha=0.4, hover_color='olive', hover_alpha=1.0)

# Add a hover tool, that sets the link data for a hovered circle
code = """
const links = %s
const data = {'x0': [], 'y0': [], 'x1': [], 'y1': []}
const indices = cb_data.index.indices

console.log(cb_data.index.indices)

for (var i = 0; i < indices.length; i++) {
    const start = indices[i]
    for (var j = 0; j < links[start].length; j++) {
        const end = links[start][j]
        data['x0'].push(circle.data.x[start])
        data['y0'].push(circle.data.y[start])
        data['x1'].push(circle.data.x[end])
        data['y1'].push(circle.data.y[end])
    }
}
segment.data = data
""" % links

callback = CustomJS(args={'circle': cr.data_source, 'segment': sr.data_source}, code=code)
p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[cr]))


div = Div(text="""<br>
Here is were I want to display some additional information about the point that is currently hovered over.""",
width=200, height=100)

show(row(p,Spacer(width=20), div))

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Я понял это:

from bokeh.models import ColumnDataSource, CustomJS, HoverTool, Div, Spacer
from bokeh.plotting import figure, output_file, show
from bokeh.layouts import row

output_file("hover_callback.html")

# define some points and a little graph between them
x = [2, 3, 5, 6, 8, 7]
y = [6, 4, 3, 8, 7, 5]
links = {
    0: [1, 2],
    1: [0, 3, 4],
    2: [0, 5],
    3: [1, 4],
    4: [1, 3],
    5: [2, 3, 4]
}

p = figure(plot_width=400, plot_height=400, tools="", toolbar_location=None, title='Hover over points')

source = ColumnDataSource({'x0': [], 'y0': [], 'x1': [], 'y1': []})
sr = p.segment(x0='x0', y0='y0', x1='x1', y1='y1', color='olive', alpha=0.6, line_width=3, source=source, )
cr = p.circle(x, y, color='olive', size=30, alpha=0.4, hover_color='olive', hover_alpha=1.0)

# Add a hover tool, that sets the link data for a hovered circle
code = """
const links = %s
const data = {'x0': [], 'y0': [], 'x1': [], 'y1': []}
const indices = cb_data.index.indices

console.log(cb_data.index.indices)

for (var i = 0; i < indices.length; i++) {
    const start = indices[i]
    for (var j = 0; j < links[start].length; j++) {
        const end = links[start][j]
        data['x0'].push(circle.data.x[start])
        data['y0'].push(circle.data.y[start])
        data['x1'].push(circle.data.x[end])
        data['y1'].push(circle.data.y[end])
    }
}
segment.data = data
""" % links

callback = CustomJS(args={'circle': cr.data_source, 'segment': sr.data_source}, code=code)
p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[cr]))


div = Div(text="""<br>
Here is were I want to display some additional information about the point that is currently hovered over.""",
width=200, height=100)

new_code = """
console.log(div_object.text)

const indices = cb_data.index.indices

console.log(indices)

if (indices == undefined || indices.length == 0){{
    div_object.text = ""
}}
else {{
    div_object.text = " currently point with index <b>" + indices.toString(10) + "</b> is selected. Here follows a very long description... <br> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ornare metus at justo semper finibus. Donec malesuada ut nisl ac convallis. Nulla laoreet in metus non dictum. In odio libero, elementum sit amet mi vitae, iaculis tincidunt sem. Quisque eget auctor massa. Nunc pulvinar cursus eros vitae bibendum. Integer vitae pharetra nulla. Integer vitae iaculis ligula. Cras elementum neque magna, posuere semper leo iaculis nec. Curabitur vel neque ut massa efficitur luctus. In at enim sed est pulvinar rhoncus. Aliquam dictum venenatis interdum. Pellentesque accumsan imperdiet varius."
}}

"""

callback = CustomJS(args={'div_object': div}, code=new_code)

p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[cr]))


show(row(p,Spacer(width=20), div))
0 голосов
/ 11 апреля 2020

Посмотрите на этот пример, он делает именно то, что вам нужно: https://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html?highlight=event#customjs -for-user-взаимодействия-events

Короче говоря, вы можете использовать модель Div и измените его атрибут text на любой другой.

...