- Ich möchte statisches HTML generieren und die Dateninitialisierung genau einmal durchführen
< li>Ich möchte eine komplexe Datenstruktur an das Dokument übergeben und diese von mehreren Schaltflächen/UI-Elementen verwenden - Ich möchte nicht an jede Schaltfläche/Benutzeroberfläche dieselbe komplexe Datenstruktur übergeben Element als Quelle-Eigenschaft, da dadurch eine größere HTML-Datei generiert wird
Code: Select all
from bokeh.models import Div, CustomJS
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)
Kontext:
Dieser Teil wird für die Beantwortung der obigen Frage nicht benötigt, ich wollte nur den Anwendungsfall zeigen, da einige Leute ohne diesen Teil keine einfache Antwort geben möchten
Ich habe eine komplexe Hierarchie von ColumnDataSource-es und anderen Daten für eine ganz bestimmte Schrittlogik gespeichert in Form eines Diktats, was ich auf der JS-Seite verwenden muss. Ich kann die ColumnDataSource-Objekte nicht separat übergeben, da die Anzahl der zu verwendenden ColumnDataSource-s im Voraus unbekannt ist. Es gibt eine dynamische Logik, wie die Schaltflächen generiert werden sollen und wie sie diese Hierarchie lesen sollen. Die Logik hängt von einer Reihe von Zeitrahmenschlüsseln innerhalb des Diktats ab. Ich muss dieses Diktat an jede generierte Schaltfläche übergeben. Da die DataSource umschlossen ist, kommt es zu Duplikaten.
So muss ich die Daten für die Schrittlogik organisieren:
< pre class="lang-py Prettyprint-override">
Code: Select all
js_data[aggr_interval] = {
'data_source' : ColumnDataSource(dataframe),
'candle_data' : dataframe.to_dict(orient="list"),
}
Code: Select all
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,
))
Code: Select all
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[i])