A small package with interactive elements to be used in Pluto.jl.
@bind x PlutoUI.Slider(1:100)
repeat("Hello ", x)
For documentation, read the PlutoUI.jl featured notebook.
Home Page: https://featured.plutojl.org/basic/plutoui.jl
License: The Unlicense
A small package with interactive elements to be used in Pluto.jl.
@bind x PlutoUI.Slider(1:100)
repeat("Hello ", x)
For documentation, read the PlutoUI.jl featured notebook.
A date and time selection widget that returns a DateTime
would be nice.
I can already get a string of the date and time with
@bind dateandtime html"""<input type="datetime-local">"""
which i can convert to DateTime
with
parse(DateTime, date)
It would be nice to have a ready made widget that does this all in one step.
Hi, small issue which confused me for a while, is that the value shown might not match the value of the bound variable.
Here's a basic reproduction in Pluto.jl:
begin
using Pkg
Pkg.activate(mktempdir())
end
begin
Pkg.add(["PlutoUI",])
using PlutoUI
end
@bind someval Slider(0.01:0.001:1, default=0.002, show_value=true)
Note that someval now shows 0.002 near the Slider. Also note that 0.002 is outside of the provided slider range.
someval
Note that someval is actual equal to 0.01 (i.e. it really is clamped to the slider range).
Thanks,
Roman
I like the Clock
feature a lot. But is there a possibility to set an end point? Now, when I let the clock run, it will eventually error, given that it tries to go on even when there are no more data to plot. Looping back would be an alternative.
Nice work on fonsp/Pluto.jl#17, design looks nice and works like a charm.
How would you recommend doing animations? One can now drive animations from javascript by doing something along the lines of:
@bind t html"""
<div id='time'>
<input id='speed' type='range' min='-1' max='1'/>
<label id='time' for='speed'/>
<script>
const time = document.querySelector("div#time")
const label = document.querySelector("label#time")
const speed = document.querySelector("input#speed")
let t = 0;
setInterval(dt, 10);
function dt()
{
t = t + speed.valueAsNumber * 0.01;
time.value = t;
label.innerHTML = t.toFixed(2);
time.dispatchEvent(new CustomEvent("input"))
}
</script>
</div>
"""
and then using t
to animate other cells.
@fonsp is there a better / simpler way you'd recommend?
I also tried driving an animation from julia, using @async
or @spawn
to increment a global time variable in the background. The time variable does get updated, but the asynchronous updates do not trigger reactive evaluation of dependent cells. Is there is a way to trigger reactive eval from asynchronous blocks of code?
The code @bind temp Radio(["neat", "drop"], default="neat")
correctly creates radio buttons in the UI, and defaults to "neat". However, any click of the radio buttons leads to the bound value temp
being set to nothing
.
I double-checked the javascript and on cell initialization do get this error:
"CellOutput.js:200 TypeError: Cannot read property 'querySelector' of undefined"
This line being suspect: const form = this.querySelector('#jqeekved')
. On JavaScript's strict mode, isn't a global invocation of this
supposed to be undefined
? As this is a top-level script block, it to mean would make sense if the script fails to execute for this reason; replacing this
with window
may solve the issue.
I disabled my popup blocker. Let me know if you need me to check anything else. Thanks!
NumberField()
and NumberField(default=37)
should also work
Like a slider, but for tracking scroll in x & y direction
@bind x, y Slider2D(1:50, 1:100)
to create a canvas with given ranges
Sliders are more useful when the value is displayed next to them.
It would be great to have the name of the variable displayed too.
Edit from @fonsp: In this issue we are referring to:
@bind x Slider(1:100, show_value=true)
and whether to make it true
by default.
How can one create a slider that is indexed onto an array but that binds to the values of the array?
E.g., say I have an array of values with a custom type, e.g.,
using Unitful: m
my_array = [0.0, 1.0, 3.0, 5.0, 10.0, 30.0, 50.0]m
I would like a slider to pick one of these values.
Ideally, it'd be great to be able to create that slider with just
Slider(my_array)
I would like to use the Select
element to select different matrices with different names in the select combobox. I want the name to be displayed in the combobox and the matrix bound to the variable I @bind
the Select
to. So
@bind M Select([M1 => "Diagonal Matrix", M2 => "Symmetric Matrix"])
This currently does not work since Select
binds the keys (which currently have to be strings) of the passed dict to the variable and displays the values.
Can we just change Select
to support arbitrary keys instead just Strings?
issue description:
The return type of PlutoUI.Slider is Int64 in few instances and Float64 in few instances
expected behavior:
the return type must be stable
remarks
right now, the possible workaround is using Float64(var) or Int64(var) where ever required. But, it is not ideal to explicitly type Float64 everywhere.
Hi Fons,
I attempted to add radio buttons but I don't believe it's possible to get the value without some JavaScript. Is this correct? Here's what I have so far:
struct Radio
options::Array{Pair{AbstractString,Any},1}
groupname::AbstractString
checked::AbstractString
end
Radio(options::Array{<:AbstractString,1}, groupname::AbstractString, checked::AbstractString="") = Radio([o => o for o in options], groupname, checked)
function show(io::IO, ::MIME"text/html", radio::Radio)
for o in radio.options
println(io, """<input type="radio" id="$(htmlesc(o.first))" name="$(radio.groupname)" value="$(htmlesc(o.first))" $(htmlesc(radio.checked) == htmlesc(o.first) ? "checked" : "")>""")
println(io, """<label for=$(htmlesc(o.first))>""")
if showable(MIME("text/html"), o.second)
show(io, MIME("text/html"), o.second)
else
print(io, o.second)
end
print(io, """</option>""")
println(io, """</label><br>""")
end
end
get(radio::Radio) = first(radio.options).first
This produces the following:
As you can see, the value of the checked button is not bound to the variable. Do you know the best way to make this work? If you can point me in the right direction I'll keep chipping away at it. : )
A feature that I love in Jupyter is the ability to take a screenshot of the task at hand (especially in a school setting, as is the case for me), and paste it directly into the notebook, so that you have it right there as you solve the task. This is a fast and easy fix to the problem of having to tab back and forth from the problem to the notebook.
When I tried to paste a picture from my clipboard into a pluto notebook, nothing happened. I don't know if I am doing it wrong, but I am unable to find a way to paste a picture, so I guess it is not a feature yet. Would it be possible to make this a thing in Pluto?
I am imagining that the data for the screenshot could be put into an array of the type that holds RGB data and printed directly, as demonstrated by Grant Sanderson in some detail in the "Computational thinking" series. This would also maintain the ideal of reproducibility, and "everything needed is right there in the notebook".
Are there others that would like this feature?
Would something like this be hard to implement?
Bumping from #1 (comment)
Basically the clock widget, but bound to a slider-like range of times. It'd be extra nice to provide an enumerate
-like interface returning both the index and value of the range:
@bind (i, val) Playback(range(0, 1, length=100); rate = 30) # playback at 30 fps
Feature idea (soft request)...
Having made a big table of parameter values for my notebook, I found myself wanting to capture ("grab") and reload ("load") the values. This provides a means for a notebook user to save the parameters for a later analysis, or send them to other users or the developer to share their experience.
Being a neophyte JS programmer, I hacked it into existence, It looks like this:
The section of the notebook that makes this is here
This is all ok, but it sure would be easier if there were PlutoUI features to attach an id
to an input, build a table or layout of inputs, and provide a function to grab/load inputs based on the id
s. Bonus points on integrating this with Julia code somehow... that was a bridge too far for me. The string syntax was also a bit of a hack, json would be nicer, but that would be easier on the Julia side.
It would be nice to provide a way of creating and using counters within notebooks. (These maybe most commonly interpolated into Markdown).
The basic idea is that there is a global dictionary of counters, and they are incremented as they appear in the notebook, and not as they get evaluated. Then we can use these to number sections, exercises ;), figures, or LaTeX snippets, or footnotes.
Section 2.1 of the LaTeX doc https://www.ntg.nl/doc/lamport/latex2e.pdf describes how to create and use counters in LaTeX. This is a good starting point!
A widget that shows a little preview of the (webcam) camera and sends an image to the bound variable when you click it.
Because it makes this package more stable because we will never have HTML errors. The other option is to use a HTML parser in our testing to verify the output, but using Hyperscript is much nicer.
Also it's a nice package to work with!
Is it possible to show the value of the slider in the same cell in Pluto? I think not from
Separate definition and reference
If you put a bond and a reference to the same variable together, it will keep evaluating in a loop.
So do not write
md""\"$(@bind r html"<input type='range'>") $(r^2)""\"Instead, create two cells:
md""\"$(@bind r html"<input type='range'>")""\"r^2
but maybe I missed something? I would like something like
begin
r_slider = @bind r html"<input type='range'>"
md"""
r = $r $r_slider
"""
end
A widget (does not @bind
anything) that takes an array of objects and displays them in a slideshow:
Slideshow([md"# Hey!", image_1, image_2])
with extra options to auto-advance (setting it to delay = 1/30
will make it an animation :)).
For example:
functions = [sin, cos, tan]
map(plot, functions)
gives an array of three plots, but it would be cool of you could do
Slideshow(map(plot, functions))
and click through the plots using buttons.
These should also work in the exported HTML.
Sizing of the slideshow box might be tricky
I would like to see a shorthand to make some cell fixed or sticky, this will be very convenient for cells that have boxes or input fields of parameters that affect many cells.
Up to this moment my solution is making a cell that contains custom styles, and searching the id of the target cell in the DOM to make it sticky or fixed.
Sometimes I need to reload a configuration file from my disk. An intuitive approach is to pick the same file. It would be nice to refresh the value automatically.
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
Using the Date widget with a default value like
begin
using Dates
using PlutoUI
@bind date PlutoUI.DateField(Date(2020, 1,1))
end
does not display the default value on startup.
This is because html expects the date format to be Y-mm-dd
but PlutoUI uses Y-m-d
.
The same goes for TimeField
:
@bind date2 PlutoUI.TimeField(Time(1,1,1))
does not work while
@bind date2 PlutoUI.TimeField(Time(10,10,10))
does.
Also DateField and TimeField are not exported.
I can provide a PR to fix this later.
Right now the Button always returns the same: the label of the button (String). This is fine, you can use the button to "trigger reactivity" just by referencing the bound variable somewhere:
https://github.com/fonsp/PlutoUI.jl/blob/v0.6.1/src/Builtins.jl#L64-L86
But if you only want to do something after the button is clicked, you need to write that logic yourself:
begin
clicked_ref = Ref(false)
@bind click Button("Do it!")
end
begin
if clicked_ref[]
something()
end
clicked_ref[] = true
end
Instead we could have the bound value be the number of times it was clicked:
@bind click Button("Do it!")
if click > 0
something()
end
An object that you can put something else inside (like an markdown text) that sends the currently selected text to the bound variable.
I saw this awesome tweet and I want it too!
https://twitter.com/Mr_Auk/status/1289080703376924675
Streaming an entire audio stream might not work well, but constantly sending short audio snippets (say, a 10ms recording every 100ms) would definitely work! But maybe all of it can be sent live?
Use like:
PlutoUI.PlutoVersionWarning(v"0.12.1")
will output nothing
when the version is higher than 0.12.1, and output a big warning when it is not.
I already wrote this, it just needs to be polished up and put into this package
html"""
<script>
const warning = html`
<h2 style="color: #800">Oopsie! You need to update Pluto to the latest version</h2>
<p>Close Pluto, go to the REPL, and type:
<pre><code>julia> import Pkg
julia> Pkg.update("Pluto")
</code></pre>
`
// this needs some work: in Pluto 0.12.0 you get Pluto's version number as:
// window.version_info_pluto
// in Pluto <0.12 it is:
// window.pluto_version
// I THINK but you should check
// https://github.com/fonsp/Pluto.jl/blob/master/CONTRIBUTING.md#how-to-run-specific-version-of-pluto
// for this code, I just wanted to warn for <0.12.1, but you should make it more general
const super_old = window.version_info == null || window.version_info.pluto == null
if(super_old) {
return warning
}
const version_str = window.version_info.pluto.substring(1)
const numbers = version_str.split(".").map(Number)
console.log(numbers)
if(numbers[0] > 0 || numbers[1] > 12 || numbers[2] > 1) {
} else {
return warning
}
</script>
"""
In practice generally we don't want a number field larger than 2-3 digits, so I think it would be interesting to add the possibility to setup the width of the number fields to avoid using CSS. By example you can setup the width of all number fields in the whole notebook with pluto-output input[type=number] { width: ... ; }
, or for some specific cell using it id instead of the pluto-output tag.
I think the FilePicker would be a better choice here.
This can be based on the rectangle drawing demo in the Interactivity sample notebook inside Pluto.
Speed might not be great yet, but this should improve a lot once Pluto uses MsgPack instead of JSON.
Running the PlutoUI demo, you can see the Stop buttons for both Clock() examples are not working.
This problem may be related to this Pluto issue
I am seeing the same issue in my custom HTML & JS code, which contains buttons that don't seem to get their click events.
Platform: macOS, Julia 1.5.2, latest release Chrome & Safari both
Instead of writing n, nn, nnn etc., can we have sections of pluto notebooks reacting rather than the whole notebook?
An object that you can put something else inside (like an image or a plot) that sends the mouse coordinates on click to the bound variable.
Most often sliders are used to evaluate something at different values. Can we implement a macro/function that takes some function f(t)
to be evaluated, and a range
.
Internally, it
range
When the MemoizedFunction object is called, it evaluates f(t) and stores it in the array. At the next call, it checks whether f(t) had been evaled and returns that value, else evaluates and returns.
It also returns the slider.
I'm not sure whether this idea will work with Pluto's reactivity, but I'd be super happy if we could make it work!
Hi,
can you please tell me how to use the Button? It always seems to have the value given as argument "label" to the constructor.
Thank you!, z.
I had so much fun playing with PlutoUI, thank the developers.
In order to make the Web UI feel real, I made some widgets here
https://gist.github.com/GiggleLiu/aff2af66a896cf8a05310b8ba66f540f
Two issues are addressed in this gist to make the UI real
However, both are not yet perfectly resolved.
Enter tables and get the values in Julia? But it might be annoying that it is not persistent.
Or it doesn't have to send something back through @bind
- a lazy, interactive table view would also be great:
https://discourse.julialang.org/t/interactive-data-table-in-pluto-jl-via-a-silly-hack/44678/3
I have the impression that with the following PR a bug has been introduced into the Select function.
https://github.com/fonsp/PlutoUI.jl/pull/15/files
function show(io::IO, ::MIME"text/html", select::Select)
withtag(io, :select) do
for o in select.options
# this print opens an `option` tag and fills its value property, but not its content
print(io, """<option value="$(htmlesc(o.first))"$(select.default === o.first ? " selected" : "")>""")
# here, a new `option` tag is created, with content (but without default selection). This results in duplicate entries in the selector.
withtag(io, :option, :value=>o.first) do
if showable(MIME"text/html"(), o.second)
show(io, MIME"text/html"(), o.second)
else
print(io, o.second)
end
end
print(io, "</option>")
end
end
end
Removing the withtag(io, :option, :value=>o.first) do
line (and the corresponding end
) fixes this issue for me.
It would be nice to pass a label to the input so that you don't need to use a different cell to display the value. Maybe as an optional keyword arg?
Something like:
@bind balloons Slider(1:100; label = "Number of Balloons")
?
Not sure if this is being discussed elsewhere, but I would be important to have with_terminal
(or a macro version) that could print out in real-time (instead of all at once after execution).
E.g.
with_terminal() do
for i in 1:10
println(i)
sleep(0.1)
end
end
We'd want this to print 1
2
etc. every 10th of a second and not all at once.
When using PlutoUI, I get the following warning message:
julia> Pluto.run(1234)
Go to http://localhost:1234/ to start writing ~ have fun!
Press Ctrl+C in this terminal to stop Pluto
From worker 2: ┌ Warning: Package PlutoUI does not have Random in its dependencies:
From worker 2: │ - If you have PlutoUI checked out for development and have
From worker 2: │ added Random as a dependency but haven't updated your primary
From worker 2: │ environment's manifest file, try `Pkg.resolve()`.
From worker 2: │ - Otherwise you may need to report an issue with PlutoUI
From worker 2: └ Loading Random into PlutoUI from project dependency, future warnings for PlutoUI are suppressed.
The issue seems to be that Random is used in Builtins.jl, but not defined as a dependency in the Project.toml.
I wrote a debouncer! Let's put it into PlutoUI
begin
struct Debounced
x::Any
wait::Real
end
debounced(x, wait=1000) = Debounced(x, wait)
function Base.show(io::IO, m::MIME"text/html", d::Debounced)
id = String(rand('a':'z',10))
print(io, "<span id=$(id)></span>")
show(io, m, d.x)
print(io, """
<script>
const span = document.querySelector('#$(id)')
const el = span.nextElementSibling
const _ = window._
el.addEventListener("input", (e) => {
e.stopPropagation()
})
var value = null
const debounced_setter = _.debounce(() => {
span.value = value
span.dispatchEvent(new CustomEvent("input", {}))
}, $(d.wait))
const dothing = async () => {
for(const value_promise of Generators.input(el)) {
value = await value_promise
debounced_setter()
}
}
dothing()
</script>
""")
end
Base.get(d::Debounced) = try
Base.get(d.x)
catch
missing
end
end
It would be nice to say
@animate fps=20 for n=1:100, m=1:100
<expr>
end
And have Pluto
repr
of expr for all values of n
, then send them all to the UI.repr(expr)
s it has stored.n
and m
.It would be awesome if one could use Select
on arbitrary key => value
pairs:
names = ["Hamburg", "Berlin", "Magdeburg"]
populations = [1_900_000, 3_700_000, 240_000]
@bind city Select(pairs(names))
@show populations[k]
name = Dict(:hr => "Human Resources",
:x => "Research & Development")
manager = Dict(:hr => "Jane Doe",
:x => "Max Mustermann")
@bind division Select(name) # pairs(name) === name
@show manager[division]
I assume allowing Int
and Symbol
should cover most use cases.
I don't know JavaScript, so I would try to manage the state mostly in Julia. One could split the internal representation of value => representation
into seperate arrays, so that the only exchange with the frontend would be index::Int
corresponding to the selection (and a handle to the s::Select
object itself, maybe its hash(s)::UInt64
). set_bond
would then have to be adjusted to ask the Select
object, what the actual new value should be.
The benefit of this approach is that we don't need to deal with conversions/representations of Julia types from and to JavaScript.
A big downside of this that this would introduce a new global Dict{UInt64,Select}
object of sorts.
Hi there,
I use Jupyter (specifically Jupyter Lab) to make project reports every 3 months or so. As a result, the reports get quite large. I structure them in detail with markdown headers and sections. Jupyter provides an excellent extension, called simply "table of contents" that does two things:
Example:
Is this possible to be done in Pluto.jl? Is it planned?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.