2017-02-03 10 views
3

Есть ли способ активировать/деактивировать hovertool в обратном вызове?Bokeh: как включить или отключить HoverTool от обратного вызова?

Я попытался сделать это одновременно с переключением видимости линии с помощью флажков. Каждая строка имеет hovertool, когда строка имеет «visible = false». Я установил атрибут «names» соответствующего инструмента в фиктивную строку; в противном случае я устанавливаю его равным первоначальному атрибуту «name» строки.

Он работает в первый раз, когда проверяется всякая коробка, две другие линии исчезают, а hovertool не отображается на них. Но он не работает, чтобы активировать hovertool.

Вот моя попытка:

from bokeh.plotting import figure, output_file 
from bokeh.models import CustomJS, HoverTool, CheckboxGroup, ColumnDataSource 
from bokeh.layouts import gridplot 
from bokeh.resources import CDN 
from bokeh.embed import file_html 

from collections import OrderedDict 

TOOLTIPS = [ ("x", "$~x"), ("y", "$~y") ] 

TOOLS = ['crosshair'] 

source = ColumnDataSource(data={'x':range(10),'y0':range(10),'y1':range(10)[::-1],'y2':[i**0.5 for i in range(10)]}) 

fig = figure(tools=TOOLS) 

fig.tools[0].dimensions = 'height' 

plots = [] 
plots.append(fig.line(x='x',y='y0', name="0", source=source)) 
plots.append(fig.line(x='x',y='y1', name="1", source=source)) 
plots.append(fig.line(x='x',y='y2', name="2", source=source)) 


names = ['first','second','third'] 
ID=0 
for plot in plots: 
    fig.add_tools(HoverTool(mode='vline',line_policy='interp',renderers=[plot],names=[str(ID)],tooltips=OrderedDict([('name',names[ID])]+TOOLTIPS))) 
    ID+=1 

N_plots = range(len(plots)) 

checkbox = CheckboxGroup(labels=names,active=[],width=200) 
checkbox_iterable =[('p'+str(i),plots[i]) for i in N_plots]+[('hover'+str(i),fig.tools[1:][i]) for i in N_plots]+[('checkbox',checkbox)] 
checkbox_code = """var indexOf = [].indexOf;"""+''.join(['p'+str(i)+'.visible = indexOf.call(checkbox.active, '+str(i)+') >= 0;' for i in N_plots]) 
checkbox_code += ''.join(['if(p'+str(i)+'.visible) hover'+str(i)+'.names = ["'+str(i)+'"];' for i in N_plots])+''.join(['if(p'+str(i)+'.visible==false) hover'+str(i)+'.names = ["no"];' for i in N_plots]) 
checkbox_code += ''.join(['console.log(hover'+str(i)+'.names);' for i in N_plots]) 
checkbox.callback = CustomJS(args={key: value for key,value in checkbox_iterable}, code=checkbox_code) 

grid = gridplot([[fig,checkbox]],toolbar_location='left') 

outfile=open('hovtest.html','w') 
outfile.write(file_html(grid,CDN,'test')) 
outfile.close() 

Я использую бок 0.12.4

ответ

1

Кто-то из группы бока обсуждения нашло хороший способ сделать это (bokeh discussion thread).

Мы можем изменить свойство отображения инструмента наведения на основе списка checkbox.active. Ниже приведен пример кода:

from bokeh.plotting import figure, output_file 
from bokeh.models import CustomJS, HoverTool, CheckboxGroup, ColumnDataSource 
from bokeh.layouts import gridplot 
from bokeh.resources import CDN 
from bokeh.embed import file_html 

from collections import OrderedDict 

TOOLTIPS = [ ("x", "$~x"), ("y", "$~y") ] 

TOOLS = ['crosshair'] 

data = {'x':range(10), 
     'y0':range(10), 
     'y1':range(10)[::-1], 
     'y2':[i**0.5 for i in range(10)] 
     } 

source = ColumnDataSource(data=data) 

fig = figure(tools=TOOLS) 

fig.tools[0].dimensions = 'height' 

plots = [] 
plots.append(fig.line(x='x',y='y0', name="first", source=source)) 
plots.append(fig.line(x='x',y='y1', name="second", source=source)) 
plots.append(fig.line(x='x',y='y2', name="third", source=source)) 

checkbox = CheckboxGroup( 
    labels=[plot.name for plot in plots], 
    active=[0,1,2], 
    width=200, 
    callback = CustomJS( args=dict(p0=plots[0],p1=plots[1],p2=plots[2]), 
          code = """ 
           p0.visible = cb_obj.active.includes(0); 
           p1.visible = cb_obj.active.includes(1); 
           p2.visible = cb_obj.active.includes(2); 
           """ 
         ) 
    ) 

for ID,plot in enumerate(plots): 
    fig.add_tools( 
     HoverTool( 
      mode='vline', 
      line_policy='interp', 
      renderers=[plot], 
      names=[plot.name], 
      tooltips=OrderedDict([('name',plot.name)]+TOOLTIPS), 
      callback=CustomJS( args=dict(cb=checkbox), 
           code=""" 
            if(!cb.active.includes(%d)) { 
            document.getElementsByClassName('bk-tooltip')[%d].style.display = 'none'; 
            } 
            """ % (ID,ID) 
           ) 
      ) 
    ) 

grid = gridplot([[fig,checkbox]],toolbar_location='left') 

outfile=open('hovtest.html','w') 
outfile.write(file_html(grid,CDN,'hovtest')) 
outfile.close()