Replies: 7 comments 13 replies
-
Yes, you can do it now with DataFrames and StippleUI.Tables. |
Beta Was this translation helpful? Give feedback.
-
Well, if you change your dataframe not only by appending but by inserting, atomic update won't help. Moreover, the data rendering of tables is a bit more complex than updating dicts or arrays. If your df_dash_table is directly the dataframe in your datatzble field. The table will anyhow be up to date and you only need to do
Does that make sense to you? |
Beta Was this translation helpful? Give feedback.
-
hi there
to update my dataframe in the UI model. I get the error
in the code below. What should I be using please?
|
Beta Was this translation helpful? Give feedback.
-
You have no handler installed and no global model defined, so your code will not work. route("/") do
global model
model = TontineModel |> init |> ui |> html
end
[...]
notify(model.tontine_data) I'm not sure how fast your ZMQ update is, maybe you have to supply an interval... |
Beta Was this translation helpful? Give feedback.
-
Sorry, I was too quick on my mobile. model = TontineModel |> init after the global declaration and replace the route by model |> ui |> html |
Beta Was this translation helpful? Give feedback.
-
Well let me try, I finally got some time to boot up my computer ... using Stipple
using StippleUI
using StipplePlotly
using CSV, DataFrames, Dates
using ZMQ
dash_columns = ["sym","price","sdmove","hv20","hv10","hv5","iv","iv%ile","prc%ile","volume"]
df_table = DataFrame([col => (col == "sym" ? String : Float64)[] for col in dash_columns ])
zmq_dash = Dict("LAST" => "price","CLOSE" => "price","OPTION_IMPLIED_VOL" => "iv",
"VOLUME" => "volume","IV" => "iv","IV_PERCENTILE" => "iv%ile" ,"HV20" => "hv20",
"HV10" => "hv10","HV5" => "hv5" ,"PRICE_PERCENTILE" => "prc%ile")
@reactive mutable struct TontineModel <: ReactiveModel
tontine_data::R{DataTable} = DataTable(df_table)
end
function ui(model::TontineModel)
page(
model, class="container", title="title TONTINE2 ", head_content=Genie.Assets.favicon_support(),
prepend = style(
),
[
heading("heading Tontine2 7/18/22")
row([
cell(class="st-module", [
h5("h5 tontine data")
table(:tontine_data)
])
])
]
)
end
model = TontineModel |> init
route("/") do
global model
model |> ui |> html
end
up(9000; async = true, server = Stipple.bootstrap())
context = Context()
socket = Socket(context, PULL)
ZMQ.bind(socket, "tcp://*:5555")
println("starting IN Socket 5555")
println("entering main, waiting for message")
while true
message = String(ZMQ.recv(socket))
println("Received request: $message")
if message == "END"
println("dying")
ZMQ.close(socket)
ZMQ.close(context)
break
end
global in_source, sym_in, field_in , value_in = split( message , "~")
global value_fl = parse(Float64, value_in) # convert to Float64
try
global field_out = zmq_dash[ field_in] # ie field_in "OPTION_IMPLIED_VOL" => field_out "iv"
println("message to add : ", in_source," ",sym_in," ",field_out," " ,value_in)
catch e
println("field_in : ", field_in, " not in cols" )
end
if sym_in in df_table[!,:sym]
df_table[findfirst(==(sym_in),df_table.sym),findfirst(==(field_out),names(df_table))] = value_fl
else
push!(df_table, (sym_in, 0.0, 0.0, 0.0 , 0.0, 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ) )
df_table[findfirst(==(sym_in),df_table.sym),findfirst(==(field_out),names(df_table))] = value_fl
end
model.isready[] && notify(model.tontine_data) # prevents that the model is updated without a connected client.
# println(df_table)
end
should most probably work |
Beta Was this translation helpful? Give feedback.
-
Happy that this worked :-) @essenciary, @AbhimanyuAryan What would you think about the following approach? using Stipple
using StippleUI
using StipplePlotly
using CSV, DataFrames, Dates
dash_columns = ["sym","price","sdmove","hv20","hv10","hv5","iv","iv%ile","prc%ile","volume"]
df = DataFrame([col => (col == "sym" ? String : Float64)[] for col in dash_columns])
df_table = Observable(df)
zmq_dash = Dict("LAST" => "price","CLOSE" => "price","OPTION_IMPLIED_VOL" => "iv",
"VOLUME" => "volume","IV" => "iv","IV_PERCENTILE" => "iv%ile" ,"HV20" => "hv20",
"HV10" => "hv10","HV5" => "hv5" ,"PRICE_PERCENTILE" => "prc%ile")
@reactive mutable struct TontineModel <: ReactiveModel
tontine_data::R{DataTable} = DataTable(df_table[])
end
function ui(model::TontineModel)
page(
model, class="container", title="title TONTINE2 ", head_content=Genie.Assets.favicon_support(),
[
heading("heading Tontine2 7/18/22")
row([
cell(class="st-module", [
h5("h5 tontine data")
table(:tontine_data)
])
])
]
)
end
function handlers(model)
on(df_table) do _
notify(model.tontine_data)
end
model
end
route("/") do
TontineModel |> init |> handlers |> ui |> html
end
# up(9000; async = true, server = Stipple.bootstrap())
up()
for _ in 1:10
# generate a random entry
message = join([
["A", "B", "C", "D", "E", "F", "G"][rand(1:7)],
["a", "b", "c", "d", "e", "f", "g"][rand(1:7)],
collect(keys(zmq_dash))[rand(1:length(zmq_dash))],
string(rand())
], "~")
sleep(0.5)
global in_source, sym_in, field_in, value_in = split(message , "~")
global value_fl = parse(Float64, value_in) # convert to Float64
try
global field_out = zmq_dash[field_in] # ie field_in "OPTION_IMPLIED_VOL" => field_out "iv"
println("message to add : $in_source, $sym_in, $field_out, $value_in")
catch e
println("field_in : ", field_in, " not in cols" )
end
sym_in in df_table[][!,:sym] || push!(df_table[], (sym_in, 0.0, 0.0, 0.0 , 0.0, 0.0 , 0.0 , 0.0 , 0.0 , 0.0))
df_table[][findfirst(==(sym_in), df_table[].sym), findfirst(==(field_out), names(df_table[]))] = value_fl
notify(df_table)
end I replaced the ZMQ by a random generator ... |
Beta Was this translation helpful? Give feedback.
-
Hi all
I just found out about Stipple and considering changing from looking into Dash for my usecase. So far I am VERY impressed with Stipple as it just makes sense the way it is laid out and it's plan for the future.
I have a concern about Stipple.jl current ability to handle realtime update of a dataframe.
Here is my usecase.
I open a ZMQ pipe and receive a STREAM ( 1 - 10 every second) of messages
the dataframe will have 100 rows and 20 columns. The row and column are in the message together with the VALUE to be used to update.
each message contains information that will be used to UPDATE a value in a dataframe by locating the row and value to be updated.
so the dataframe is a realtime dashboard.
In dash this is probably handled by callbacks but haven't tried it out just yet as I am looking into Stipple.jl.
I just want to know if this is something that I can do NOW or will it be something in the future.
Beta Was this translation helpful? Give feedback.
All reactions