2016-12-15 13 views
9

Mam konkretny projekt pod kątem mojej aplikacji bokeh. Używam bokeh 0.12.3 i serwera bokeh, aby wszystko było zsynchronizowane. Proszę spojrzeć na moje makiety:Układ bokeh dla aranżacji i aranżacji widżetów

enter image description here

po stronie lewej, jest statyczny pasek nawigacyjny, prawa część widoku będzie składać się z działek, które zostały dodane ręcznie. Ilość kolumn działek po prawej stronie zmieni się w.r.t. rozmiar okna. Jestem w pełni świadomy dokumentacji układu bokeh laying out plots and widgets, ale jest to nieco bardziej skomplikowane. Jest to układ Obecnie mam:

doc_layout = layout(children=[[column(radio_buttons, 
             cbx_buttons, 
             div, 
             data_table, 
             plot, 
             button)]], 
        sizing_mode='scale_width') 
curdoc().add_root(doc_layout) 

W celu dodania nowych działek używać:

doc_layout.children[-1].children.append(plot) 
# appends plot to layout children [[column(..), plot]] 

Ale zachowanie jest bardzo dziwne, a nie w ogóle co ja właściwie chcemy osiągnąć. Nowe wykresy są dodawane na górze kolumny (panel menu).

Tutaj krótki przykład, gdzie można wypróbować, aby zobaczyć, co mam na myśli:

from bokeh.io import curdoc 
from bokeh.plotting import figure 
from bokeh.models.sources import ColumnDataSource 
from bokeh.models.widgets import Button, DataTable, TableColumn 
from bokeh.layouts import layout, widgetbox, column, row 

WIDTH = 200 
HEIGHT = 200 

def add_plot(): 
    p = figure(width=WIDTH, height=HEIGHT, tools=[], toolbar_location=None) 
    p.line([0, 1, 2, 3, 4, 5], [0, 1, 4, 9, 16, 25]) 
    doc_layout.children[-1].children.append(p) 

src = ColumnDataSource(dict(x=[0, 1, 2, 3, 4, 5], y=[0, 1, 4, 9, 16, 25])) 
t1 = DataTable(source=src, width=WIDTH, height=HEIGHT, 
       columns=[TableColumn(field='x', title='x'), 
         TableColumn(field='y', title='y')]) 
b = Button(label='add plot') 
b.on_click(add_plot) 

doc_layout = layout([[widgetbox(b, t1)]], sizing_mode='scale_width') 
curdoc().add_root(doc_layout) 

Nie jestem pewien, co jest najlepszym rozwiązaniem, aby rozwiązać ten problem. Próbowałem kilku rzeczy, od layout() z różnymi trybami skalowania, gridplot(), column()/row() w różnych kombinacjach. W mojej poprzedniej wersji, gdzie menu nawigacji został umieszczony na górze strony, a nie po stronie lewej, wszystko wydawało się działać:

layout(children=[[widgetbox(radio_button, cbx_button), 
        widgetbox(data_table), 
        widgetbox(div), 
        widgetbox(button)], 
        [Spacer()]], 
     sizing_mode='scale_width') 
+0

walczę z bardzo podobnym problemem, jak mówimy :) – percusse

+0

Cóż, najbardziej wygodny sposób, aby zrobić to byłoby z: 'rzędzie (kolumnie (.., sizing_mode =„fixed”), layout (.., sizing_mode = 'scale_width')) ' Jednak tryby wymiarowania są nadpisywane przez układ górny, tak przypuszczam. – jofroe

Odpowiedz

1

Można zmienić ostatni wiersz w swoim zwrotnego do:

doc_layout.children[0].children[-1].children.append(p) 

I zmienić swój układ do:

doc_layout = layout(sizing_mode='scale_width') 
doc_layout.children.append(row(column(widgetbox(b, t1)), column())) 

ale wtedy to nie propagować dokładnie tak, jak chcesz. Myślę, że do tego trzeba by zrobić jakiś niestandardowy styl CSS.

Zakładając twoja aplikacja jest directory format jednym rozwiązaniem byłoby, aby plik template/index.html gdzie można dodać style bloku w nagłówku, gdzie można spróbować zastąpić css aby dokonać działek inline-block S lub coś.

<style> 
    .bk-whatever-class { 
    ... 
    } 
</style> 

Użyj narzędzia programisty w przeglądarce, aby znaleźć odpowiednie klasy i bawić się nimi. Ale być może nie jest to najlepsze rozwiązanie ...

Dla widżetów istnieje atrybut css_classes, w którym można określić klasę dla tego widgetu, ale niestety nie pomaga to w przypadku kanw reklamowych.

mycol = column(css_classes=['myclass']) 
Powiązane problemy