I want to create a type recipe which will produce a scatter plot with a variable number of points. I tried to use WGLMakie
with the code below
using WGLMakie
using JSServe
using Markdown
using JSServe.DOM
JSServe.browser_display()
struct MyStruct{T}
x::T
y::T
end
struct MyContainer{D,G}
data::D
grid::G
end
function Base.empty!(g::MyStruct)
empty!(g.x)
empty!(g.y)
g
end
function Base.append!(g1::MyStruct, g2::MyStruct)
append!(g1.x, g2.x)
append!(g1.y, g2.y)
g1
end
@recipe(ScatterRecipe) do scene
Attributes(
:size => 1,
# :colormap => :viridis,
)
end
function AbstractPlotting.convert_arguments(P::Type{<:Scatter}, g::MyStruct)
println("update in convert_arguments")
convert_arguments(P, g.x, g.y)
end
function AbstractPlotting.plot!(sc::ScatterRecipe{<:Tuple{MyContainer}})
f = sc[1]
scattergrid = Node(MyStruct{Vector{Float32}}(Float32[], Float32[]))
scattercolor = Node(Float32[])
function update_plot(f)
empty!(scattergrid.val)
empty!(scattercolor.val)
append!(scattergrid.val, f.grid)
append!(scattercolor.val, f.data)
scattergrid[] = scattergrid[]
scattercolor[] = scattercolor[]
end
on(f) do val
update_plot(val)
println("data lenght: $(length(scattergrid.val.x)), color length: $(length(scattercolor.val))")
end
update_plot(f[])
plt = scatter!(sc, scattergrid, color=scattercolor, markersize=7)
return sc
end
function make_plot!(ax, m, i)
x = m.grid.x
y = m.grid.y
data = m.data
slice = map(i) do val
println("Update struct with new length $(length(1:val))")
grid = MyStruct(view(x, 1:val), view(y, 1:val))
new_data = view(data, 1:val)
MyContainer(new_data, grid)
end
scatterrecipe!(ax, slice, color=:red, size=1)
end
function test_problem()
fig = Figure()
sl = Slider(2:10)
sl_label = @lift round($(sl.value), digits=2)
ax = Axis(fig[1,1])
data = rand(10)
x, y = rand(10), rand(10)
grid = MyStruct(x, y)
m = MyContainer(data, grid)
make_plot!(ax, m, sl.value)
on(sl.value) do i
autolimits!(ax)
end
JSServe.App() do
dom = md"""
$(fig.scene)
$(DOM.div("Slice at: ", sl_label, sl))
"""
DOM.div(JSServe.TailwindCSS, JSServe.Styling, dom)
end
end
app = test_problem()
My problem is that when I move the slider I only see 2 points. The axis values change corresponding to the autolimits!
call, but I am not able to see the newly added points.
The initial state
After moving the slider