clerk/vl doesn't update reactively
sritchie opened this issue · comments
This notebook produces quite a bit of flickering. I've added a recursive fibonacci to create an artificial delay, but in https://probcomp.github.io/gen-finance/ the delay is real:
(ns finance.check
(:require [nextjournal.clerk.viewer :as clerk]))
(clerk/with-viewer
{:render-fn
'(fn [_]
(reagent.core/with-let [!trials (reagent.core/atom 10)]
[:div
[:input {:type :range
:value @!trials
:on-change
#(swap! !trials (constantly (int (.. % -target -value))))}]
[nextjournal.clerk/inspect
(nextjournal.clerk/vl
{:schema "https://vega.github.io/schema/vega-lite/v5.json"
:embed/opts {:actions false}
:width 650 :height 300
:data (letfn [(fib [n]
(if (or (= n 0) (= n 1))
n
(+ (fib (- n 1)) (fib (- n 2)))))]
{:values (for [x (range @!trials)]
(do (fib 16)
{:x (rand)
:y (rand)}))})
:layer
[{:mark :point
:encoding {:x {:field :x :type "quantitative"}
:y {:field :y :type "quantitative"}}}]})]]))}
{})
Since this is all just in a single :render-fn
here's a version that doesn't use the render/inspect
indirection but uses the vega-lite viewer's render-fn, nextjournal.clerk.render/render-vega-lite
directly. This updates without flickering.
I'd recommend this in general since the other parts of Clerk's viewer API like clerk/mark-presented
aren't needed when rendering happens in the same runtime.
(clerk/with-viewer
{:render-fn
'(fn [_]
(reagent.core/with-let [!trials (reagent.core/atom 10)]
[:div
[:input {:type :range
:value @!trials
:on-change
#(swap! !trials (constantly (int (.. % -target -value))))}]
[nextjournal.clerk.render/render-vega-lite
{:schema "https://vega.github.io/schema/vega-lite/v5.json"
:embed/opts {:actions false}
:width 650 :height 300
:data (letfn [(fib [n]
(if (or (= n 0) (= n 1))
n
(+ (fib (- n 1)) (fib (- n 2)))))]
{:values (for [x (range @!trials)]
(do (fib 16)
{:x (rand)
:y (rand)}))})
:layer
[{:mark :point
:encoding {:x {:field :x :type "quantitative"}
:y {:field :y :type "quantitative"}}}]}]]))}
{})
Let me know if using the render-fn directly like this is feasible in your use case. If not, we might want to investigate if we can make inspect work across reactive boundaries like that but for the moment I'd recommend not going through inspect
.