Some experimental components to run dashboards #1513
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Can we use Pluto as a framework to build dashboards? (Yes!) We already have a great environment for writing your model, for making it interactive and for visualizing results. The 'only' thing that's missing is layout: instead of showing all these elements linearly, you want to combine them into a single compact dashboard.
You can use
@htl
from HypertextLiteral to put multiple Pluto outputs in one cell, and with CSS flex and CSS grid, you can make any dashboard layout that your heart desires. I also addedembed_display(x)
to have Pluto's object viewer as a web component. This means that you can embed images, interactive arrays, tables, etc, inside@htl
expressions. Cool!Still missing: partial DOM updates
One problem arises when embedding bonds together with dependent variables:
Now, whenever you move the slider,
data
andcoolplot
will re-run, causing the final cell to re-run, which will re-rendermyslider
. This causes the DOM element to lose focus, and you can't click-and-drag. Oops!Schermopname.2021-09-27.om.12.42.22.mov
My initial solution was to use
this
(see JavaScript sample notebook) inside theembed_display
web component to persist its last displayed element, instead of re-rendering it, when the HTML data did not change. This almost works, exceptembed_display
now needs a way to identify itself. From which previous embed will it take the output? (We have some ideas but let's skip over this for now.)Solution in this PR
There is a new special output object, a
DivElement
:If a cell outputs a
DivElement
, it won't render it as HTML in the julia process, but send the "div element data" to the frontend, which constructs it using a simple react component. If the cell re-renders, and only one of its children updates, then Pluto's diff-based state management will make sure that only the data for that child changes, and react will only update the HTML contents of that child, leaving the parent div and siblings as-is, solving the problem!DivElement
s can be nested and can have user-defined styles, so you can use it to create any layout.Our example becomes:
And everything works as expected! Thanks @andreypopp for convincing me that this is necessary!
Still missing: intermediate DOM updates
Let's say that we have the same app as before, but our code takes a long time to execute:
In this case, moving the slider will re-run
data
, then re-runcoolplot
, and then re-run the last cell. This means that you have to wait 6 seconds to see anything. Ideally, we would see the new data after 1 second, and the new plot after 6 seconds. This does not play nicely with our reactivity model (it can't trigger re-running a cell multiple times). Thanks @dralletje for pointing this out!Schermopname.2021-09-26.om.17.59.55.mov
Solution in this PR
There is a new special output object, a
CellOutputMirror
:Wherever this
CellOutputMirror
is displayed, it will magically show a mirror of the output of another cell. It refreshes automatically, without having to re-run.The example becomes:
Let's say that we have the same app as before, but our code takes a long time to execute:
Now, the last cell does not re-run when
data
orcoolplot
changes (because it does depend on those vars). Instead, it contains magical mirror that update on their own.Schermopname.2021-09-26.om.16.39.27.mov