2017-01-13 1 views
4

ниже код приходит от jupyter notebook:Bokeh - как сделать подсказки HoverTool привязанными к точкам на клике?

from bokeh.io import show, output_notebook 
from bokeh.plotting import ColumnDataSource, figure 
from bokeh.models import HoverTool, Range1d 

output_notebook() 
fig = figure(tools=[HoverTool(tooltips=[("html", '@html{safe}')])]) 

fig.quad(left="left", top="top", bottom="bottom", right="right", 
     source=ColumnDataSource({"left": [1,3], "bottom": [1,3], 
            "right": [2,4], "top": [2,4], 
            "html":["<b>I'm bold</b>", "<span 

style='color:red;font-size:32px;'>BIG RED TEXT</span>"]})) 
    show(fig) 

мне нужно сделать всплывающие подсказки HoverTool придерживаться именно там, где они находятся на щелкая точку, так что если пользователь хочет, чтобы выделить и скопировать текст в подсказки они могли. У этого codepen есть пример типа поведения, которое я хотел бы видеть. Я знаю, что это должно быть возможно либо путем инъекции какого-либо типа CustomJS, либо с изменением BokehJS coffescript, а с BrobehJS с нуля, но я не смог понять это. Кто-нибудь знает, как это сделать?

UPDATE:
Можно было бы к созданию custom tool с помощью tap_tool.coffee, hover_tool.coffee или tooltip.coffee. Я обновлю это, если выясню это.

ответ

1

Это временное решение, создающее ваш собственный текст наведения с использованием models.Label внутри функции «обратного вызова» models.HoverTool. Также models.TapTool используется для переключения текста метки. Вы не можете отредактировать текст в глифе models.Label, но добавлен TextInputwidget, где текст обновляется, как только наведите указатель на график.

import bokeh 
import bokeh.plotting 
fig = bokeh.plotting.figure() 

d_source = bokeh.models.ColumnDataSource({"left": [1,3,1], 
       "bottom": [1,3,3],"right": [2,4,2],"top": [2,4,4]}) 
h_source = bokeh.models.ColumnDataSource({"do_hover":[True,True] }) 
fig.quad(left="left", top="top", bottom="bottom", right="right", 
     source=d_source) 

myToolTip = bokeh.models.Label(x=2.5,y=2.5, text="", 
           background_fill_color = "#ffffff") 

HoverCallback = bokeh.models.CustomJS(args=dict(d_source=d_source, 
        myToolTip=myToolTip,h_source=h_source),code=""" 
     function findWhereIam(x,y,s){ 
      // To find where the cursor is. 
      selection = -1; 
      for (i = 0; i < s.data.left.length; i++) { 
       x0 = s.data.left[i]; 
       x1 = s.data.right[i]; 
       y0 = s.data.bottom[i]; 
       y1 = s.data.top[i]; 
       if (x>x0 && x<x1 && y>y0 && y<y1){ 
        // It's inside rectangle!!! 
        selection = i; 
       } 
      } 
      return selection 
     } 
     if (h_source.data.do_hover[0]){ 
      x_data = cb_data['geometry'].x; 
      y_data = cb_data['geometry'].y; 
      var selection = findWhereIam(x_data,y_data,d_source) 
      if (selection>=0){ 
       x0 = d_source.data.left[selection]; 
       x1 = d_source.data.right[selection]; 
       y0 = d_source.data.bottom[selection]; 
       y1 = d_source.data.top[selection]; 
       myToolTip.x = 0.5 * (x0+x1); 
       myToolTip.y = 0.5 * (y0+y1); 
       myToolTip.text = "on:"+selection; 
       myToolTip.text_font_size = "24pt"; 
       myToolTip.background_fill_color = "#ffffff"; 
       myToolTip.border_line_color = "#000000"; 
       myToolTip.text_align = "center"; 
       myToolTip.trigger('change'); 

       current_selection.value = myToolTip.text; 
       current_selection.trigger('change'); 
      }else{ 
       myToolTip.text = ""; //erase 
       myToolTip.trigger('change'); 
       current_selection.value = myToolTip.text; 
       current_selection.trigger('change'); 
      } 
     } 
    """) 

TapCallback = bokeh.models.CustomJS(args=dict(h_source=h_source), code=""" 
     h_source.data.do_hover[0] = !h_source.data.do_hover[0]; 
    """) 

current_selection = bokeh.models.widgets.TextInput(value="", 
                title="Selection") 

HoverCallback.args.update(dict(current_selection=current_selection)) 

fig.add_tools(bokeh.models.HoverTool(tooltips=None,callback=HoverCallback)) 
fig.add_tools(bokeh.models.TapTool(callback=TapCallback)) 
fig.add_layout(myToolTip) 
page = bokeh.plotting.gridplot([[fig],[current_selection]]) 
bokeh.io.output_notebook() 
bokeh.io.show(page) 

enter image description here

+0

это фантастика спасибо! Если позже у вас появятся какие-то мысли о том, как разрешить выбор текста, пожалуйста, дайте мне знать. –

+1

Ну, вы можете создать виджет «InputText», который обновляется при наведении курсора на глифы. Я только что добавил эту функцию в свой ответ. Виджет 'InputText'' доступен для редактирования, поэтому вы можете скопировать его значение в буфер обмена. –

Смежные вопросы