- Я хочу сгенерировать статический HTML и выполнить инициализацию данных ровно один раз
< li>Я хочу передать в документ сложную структуру данных и использовать ее с помощью нескольких кнопок/элементов пользовательского интерфейса. - Я не хочу передавать одну и ту же сложную структуру данных каждой кнопке/элементу пользовательского интерфейса. элемент как свойство source, поскольку он создаст HTML-файл большего размера
from bokeh.layouts import column
from bokeh.plotting import show
from bokeh.io import curdoc
dummy_div = Div(text="")
init_code = CustomJS(code="""
window.sharedData = { initialized: true };
console.log("Data initialized in Div change");
""")
#dummy_div.js_on_change("text", init_code)
button1 = Button(label="Log Complex Data", button_type="success")
button1.js_on_click(CustomJS(code="""
console.log("Current shared data:", window.sharedData);
"""))
# button_N = ...
layout = column(dummy_div, button1)
curdoc().add_root(layout)
curdoc().on_event('document_ready', lambda event: init_code.execute(curdoc()))
show(layout)
Можно ли реализовать что-то подобное с помощью этой библиотеки?
Контекст:
Эта часть не нужна для ответа на поставленный выше вопрос, я просто хотел показать вариант использования, потому что без этого некоторые люди не хотят давать простой ответ
У меня есть сложная иерархия источников ColumnDataSource и других данных для очень конкретного шага. логика хранится в виде dict, что мне нужно использовать на стороне JS. Я не могу передать объекты ColumnDataSource отдельно, поскольку количество используемых ColumnDataSource-ов заранее неизвестно. Существует динамическая логика того, как кнопки должны генерироваться и как они должны читать эту иерархию. Логика зависит от количества ключей таймфрейма в словаре. Мне нужно передать этот текст каждой сгенерированной кнопке. Поскольку источник данных упакован, происходит дублирование.
Вот как мне нужно организовать данные для логики шага:
< pre class="lang-py Prettyprint-override">js_data[aggr_interval] = {
'data_source' : ColumnDataSource(dataframe),
'candle_data' : dataframe.to_dict(orient="list"),
}
Это логика шагов:
time_tracker = ColumnDataSource(data=dict(trigger_date=[max_dt]))
# I'VE A LOT OF THESE BUTTONS
# THE ARGUMENT LIST CAN NOT BE FIXED HERE
# I'VE TO PUT DATA SOURCES INTO A HIERARCHY WITH TIMEFRAME KEYS (candle_data_and_sources )
# AND IMPLEMENT A DYNAMIC LOGIC ON JS SIDE
# THE TIMEFRAMES ARE NOT KNOWN IN ADVANCE
# THIS IS WHAT DUPLICATES THE DATA
# AND INCREASES THE SIZE OF THE GENERATED HTML
step_buttons['prev'].js_on_click(CustomJS(
args = dict(
candle_data_and_sources = candle_data_and_sources,
time_tracker = time_tracker,
direction = -1,
min_dt = min_dt,
max_dt = max_dt,
),
code = JS_CODE_STEP_LOGIC,
))
JS_CODE_STEP_LOGIC = """
const trigger_date = new Date(time_tracker.data['trigger_date'][0]);
let new_date = new Date(trigger_date);
new_date.setDate(new_date.getDate() + 1 * direction);
if (direction < 0){
new_date = new Date(Math.max(min_dt, new_date));
} else if (direction > 0){
new_date = new Date(Math.min(max_dt, new_date));
}
time_tracker.data['trigger_date'][0] = new_date.toISOString();
// I NEED TO DO THE FOLLOWING LOGIC FOR EACH TIMEFRAME
// THE NUMBER/VALUE OF TIMEFRAMES HERE ARE DYNAMIC
// THEREFORE THEY ARE ADDRESSING THE DATASOURCE IN THE HIERARCHY
for (const [timeframe, data] of Object.entries(candle_data_and_sources)) {
const filtererd_obejcts = {};
for (const [key, value] of Object.entries(data['candle_data'])) {
if(!filtererd_obejcts[key]){
filtererd_obejcts[key] = [];
}
}
for (let i = 0; i < data['candle_data'].trigger_dt.length; i++) {
if (new Date(data['candle_data'].trigger_dt)
Подробнее здесь: https://stackoverflow.com/questions/793 ... ndler-code
Мобильная версия