fonsp / Pluto.jl

🎈 Simple reactive notebooks for Julia
https://plutojl.org/
MIT License
4.93k stars 284 forks source link

⚑️ AbstractPlutoDingetjes.Display.with_js_link to request calculations and data from Julia dynamically #2726

Closed fonsp closed 5 months ago

fonsp commented 9 months ago

NOTE: documentation at https://plutojl.org/en/docs/abstractplutodingetjes/#with_js_link

New JavaScript API to request calculations and data from Julia dynamically. This is useful for:

Matching AbstractPlutoDingetjes PR: https://github.com/JuliaPluto/AbstractPlutoDingetjes.jl/pull/13

Supersedes #991 and #2392

API

The easiest way to use this API is with HypertextLiteral. The use is very similar to APD.Display.published_to_js: the new function AbstractPlutoDingetjes.Display.with_js_link returns a "piece of JavaScript code" that you interpolate directly into a <script> tag.

In JavaScript, the "piece of JavaScript code" returns a function. You can call this function with an argument (which will be passed to your Julia function), and it returns a Promise that resolves to the answer from your Julia function.

@htl("""
<script>
const sqrt_from_julia = $(AbstractPlutoDingetjes.Display.with_js_link(sqrt))

// I can now call sqrt_from_julia like a JavaScript function. It returns a Promise:
const result = await sqrt_from_julia(9.0)
console.log(result)

</script>
""")

Serialization and inner workings

The request and response use Pluto's internal communication protocol (with MsgPack and WebSocket), so the performance is optimal. The same serialization is used as published_to_js, so in particular, Vector{Float64} or Vector{UInt8} are really fast.

Since this API is designed for one-off requests, this communication does not go through Pluto's state management (the request and response are not stored in the state). If multiple clients are connected in parallel, then the messages are not shared between clients.

When not to use it

This API is only meant to support use cases that can not be covered with @bind and Display.published_to_js. If possible, the use of these APIs is preferred over with_js_link because they will work with the Static HTML export and PlutoSliderServer.

Example

image
Code ```julia @htl("""

Input:
 

Output:

""") ```

TODO

github-actions[bot] commented 9 months ago

Try this Pull Request!

Open Julia and type:

  julia> import Pkg
  julia> Pkg.activate(temp=true)
  julia> Pkg.add(url="https://github.com/fonsp/Pluto.jl", rev="AbstractPlutoDingetjes.Display.with_js_link")
  julia> using Pluto
SimonDanisch commented 9 months ago

How will this help to better support JSServe?

fonsp commented 9 months ago

@Pangoraw this API could easily be used with a WASM backend, right? E.g. when you export to HTML, each js link could be compiled to WASM, and the WASM blob is inserted?

fonsp commented 9 months ago

Hey @SimonDanisch!

I think the main work for better JSServe support is using the existing AbstractPlutoDingetjes.Display.published_to_js API for the initial state object (e.g. the initial plot data with WebGLMakie), and the JavaScript this and invalidation API for a persistent display that can update instead of just re-render (see the Web notebooks on https://featured.plutojl.org/).

I don't think this PR will help with https://github.com/fonsp/Pluto.jl/issues/2706, but we can use it to make JSServe use Pluto's existing websocket connection instead of a new one. But right now this PR is one-directional (only JS can initiate), not bidirectional.

SimonDanisch commented 9 months ago

but we can use it to make JSServe use Pluto's existing websocket connection instead of a new one.

How will JSServe use the websocket connection if it's not bi-directional?

fonsp commented 9 months ago

Yeah exactly, it's not usable for this yet.

fonsp commented 9 months ago

https://github.com/fonsp/Pluto.jl/assets/6933510/d450fc84-723c-4f06-8364-f932487203ad

Pangoraw commented 9 months ago

@Pangoraw this API could easily be used with a WASM backend, right? E.g. when you export to HTML, each js link could be compiled to WASM, and the WASM blob is inserted?

Yes! Though, it will probably need to provide the signature to know which method to compile:

const sqrt_from_julia = $(AbstractPlutoDingetjes.Display.with_js_link(sqrt, (Float32,)))
SimonDanisch commented 9 months ago

So, it's not really superseding those PRs, right? Is there a plan to actually implement those features still?

SimonDanisch commented 9 months ago

I think the main work for better JSServe support is using the existing AbstractPlutoDingetjes.Display.published_to_js API

Are there any docs that explain well, what I will need to do?

fonsp commented 9 months ago

@SimonDanisch Can we continue this another time? We'll work on better docs πŸ’›

disberd commented 9 months ago

Implementing the explorable mandelbrot set is so much easier with this PR!

https://github.com/fonsp/Pluto.jl/assets/12846528/009a01c1-8ad5-49c5-b7e1-98ff68ac8c5e

This code simply recomputes the mandelbrot set with a fixed number of points per dimension (500 over x and 500 over y) over the current range of the axes of the plot. So it is recomputed upon zoom or upon panning.

The notebook code hidden below should use the version of AbstractPlutoDingetjes from this branch, but it will be overwritten to the latest registered version when adding or removing packages (I believe)

Notebook Code ```julia ### A Pluto.jl notebook ### # v0.19.32 using Markdown using InteractiveUtils # ╔═║ d6a4d6f0-8920-11ee-1360-dbb4ff626eb6 begin using PlutoPlotly using HypertextLiteral using AbstractPlutoDingetjes end # ╔═║ b4655ee1-dfe3-47a4-8b19-48c9fb2b6349 # This code is taken from a Mandelbrot notebook shared in https://discourse.julialang.org/t/mandelbrot-with-plots-jl/52410 begin to_range(raw_range, n) = range(minimum(raw_range), maximum(raw_range); length=n) function mandel(z:: Complex) c = z maxiter = 128 for n = 1:maxiter if abs2(z) > 4 return n-1 end z = z^2 + c end return maxiter end function mandel_slice!(grid, ix, x, yrange) @inbounds for (iy, y) in enumerate(yrange) grid[iy, ix] = mandel(Complex(x,y)) end end function mandel_grid(xrange, yrange) grid = Matrix{UInt8}(undef, length(xrange), length(yrange)) futures = Vector{Task}(undef, length(xrange)) @inbounds for (ix, x) in enumerate(xrange) futures[ix] = Threads.@spawn mandel_slice!(grid, ix, x, yrange) end wait.(futures) grid end end # ╔═║ 059bbb92-5a68-46d7-a210-69fc1ce91aff let # This code generates the plot with re-computation upon zooming n = 500 x = to_range([-1, 1], n) y = to_range([-1, 1], n) z = mandel_grid(x,y) data = heatmap(;x,y,z) p = plot(data, Layout(xaxis_range = [-1, 1], yaxis = attr(; range = [-1,1], scaleanchor = "x", scaleratio = 1, ))) add_plotly_listener!(p, "plotly_relayout", htl_js("async (e) => { let xrange = PLOT._fullLayout.xaxis.range let yrange = PLOT._fullLayout.yaxis.range if (PLOT.updated_data == undefined) {return} console.log(PLOT.updated_data) let update = await PLOT.updated_data({x: xrange, y: yrange}) Plotly.restyle(PLOT, update) }")) f(d) = let x = range(d["x"]..., n) |> collect y = range(d["y"]..., n) |> collect z = mandel_grid(x,y) |> PlutoPlotly._preprocess out = (; x = [x], y = [y], z = [z], ) out end @htl(""" $p """) end # ╔═║ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ [deps] AbstractPlutoDingetjes = "6e696c72-6542-2067-7265-42206c756150" HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" PlutoPlotly = "8e989ff0-3d88-8e9f-f020-2b208a939ff0" [compat] AbstractPlutoDingetjes = "~1.2.0" HypertextLiteral = "~0.9.5" PlutoPlotly = "~0.4.3" """ # ╔═║ 00000000-0000-0000-0000-000000000002 PLUTO_MANIFEST_TOML_CONTENTS = """ # This file is machine-generated - editing it directly is not advised julia_version = "1.10.0-beta3" manifest_format = "2.0" project_hash = "cc56535668b6e8901cb9ab7a99dbc6e210e21f3b" [[deps.AbstractPlutoDingetjes]] deps = ["Pkg"] git-tree-sha1 = "308ee5441d5a481d4ce0152d04f3ef411b05c2b4" repo-rev = "Display.with_js_link" repo-url = "https://github.com/JuliaPluto/AbstractPlutoDingetjes.jl.git" uuid = "6e696c72-6542-2067-7265-42206c756150" version = "1.2.0" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.1" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BaseDirs]] git-tree-sha1 = "1c9b6f39f40dba0ef22244a175e2d4e42c8f6ee7" uuid = "18cc8868-cbac-4acf-b575-c8ff214dc66f" version = "1.2.0" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" version = "3.24.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" version = "0.10.0" [deps.ColorVectorSpace.extensions] SpecialFunctionsExt = "SpecialFunctions" [deps.ColorVectorSpace.weakdeps] SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.12.10" [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.0.5+1" [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelimitedFiles]] deps = ["Mmap"] git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" version = "0.9.3" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FixedPointNumbers]] deps = ["Statistics"] git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.4" [[deps.HypertextLiteral]] deps = ["Tricks"] git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" version = "0.9.5" [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.21.4" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" version = "1.3.1" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" version = "8.0.1+1" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[deps.LibGit2_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" version = "1.6.4+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" version = "1.11.0+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.2+1" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.1.10" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" version = "0.3.23+2" [[deps.OrderedCollections]] git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.2" [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] git-tree-sha1 = "a935806434c9d4c506ba941871b327b96d41f2bf" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.8.0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.10.0" [[deps.PlotlyBase]] deps = ["ColorSchemes", "Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Parameters", "Pkg", "REPL", "Requires", "Statistics", "UUIDs"] git-tree-sha1 = "56baf69781fc5e61607c3e46227ab17f7040ffa2" uuid = "a03496cd-edff-5a9b-9e67-9cda94a718b5" version = "0.8.19" [[deps.PlutoPlotly]] deps = ["AbstractPlutoDingetjes", "BaseDirs", "Colors", "Dates", "Downloads", "HypertextLiteral", "InteractiveUtils", "LaTeXStrings", "Markdown", "Pkg", "PlotlyBase", "Reexport", "TOML"] git-tree-sha1 = "0b8880a45f96d8404ae1cf6e4d715e3a79369441" uuid = "8e989ff0-3d88-8e9f-f020-2b208a939ff0" version = "0.4.3" [deps.PlutoPlotly.extensions] PlotlyKaleidoExt = "PlotlyKaleido" UnitfulExt = "Unitful" [deps.PlutoPlotly.weakdeps] PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" version = "1.2.0" [[deps.Preferences]] deps = ["TOML"] git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" [[deps.Random]] deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "1.2.2" [[deps.Requires]] deps = ["UUIDs"] git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" version = "1.10.0" [[deps.Statistics]] deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" version = "1.10.0" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.0+1" [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" version = "1.0.3" [[deps.Tar]] deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" version = "1.10.0" [[deps.TensorCore]] deps = ["LinearAlgebra"] git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" version = "0.1.1" [[deps.Tricks]] git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" version = "0.1.8" [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" [[deps.UnPack]] git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" version = "1.0.2" [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" version = "1.2.13+1" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+1" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" version = "1.52.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" """ # ╔═║ Cell order: # ╠═d6a4d6f0-8920-11ee-1360-dbb4ff626eb6 # ╠═b4655ee1-dfe3-47a4-8b19-48c9fb2b6349 # ╠═059bbb92-5a68-46d7-a210-69fc1ce91aff # β•Ÿβ”€00000000-0000-0000-0000-000000000001 # β•Ÿβ”€00000000-0000-0000-0000-000000000002 ```
fonsp commented 8 months ago

@disberd thanks for the encouragement! I updated the TODO list, we should be able to merge it soon :)

vambrosi commented 6 months ago

Any progress with this pull request? I was actually developing a package to visualize the analogues of the Mandelbrot and Julia sets for other families of functions and having an UI integrated with Pluto would be ideal! I'm using GLMakie currently, but I like how responsive @disberd plots were in the video.

Also, what do I need to do to run that notebook? I tried installing both Pluto and AbstractPlutoDingetjes using the branches from this PR, but the plots don't update after the initial plot. The sqrt example also doesn't work (I get an Uncaught (in promise) TypeError: pluto_actions.request_js_link_response(...) is not iterable in the browser console, but no errors in Julia).

disberd commented 6 months ago

I confirm that with the current status of this branch I am not able to reproduce any of the examples currently shown here as I also get a JS error about some object not being iterable.

This simple cell code

@htl("""
<script>
let asd = $(AbstractPlutoDingetjes.Display.with_js_link(x -> x+1))
const lol = await(asd(1))
</script>
""")

produces this error on JS: image

@fonsp is there anything we can do to help finalize this PR? I find new cool use cases for this functionality basically every week so it would be very cool to have it available :D

fonsp commented 6 months ago

Hey all! Sorry, this feature is taking a lot of work to go from a prototype to a release. Once we release, we ideally don't need to change the API again, so I am trying to cover as many use cases as possible from the start.

Difficult things are:

fonsp commented 5 months ago

I recently made the with_js_link callback run synchronous with execution instead of as a background task. This fixed all edge cases, but now it's no longer possible to make a bidirectional callback out of it (which you need for JSServe).

I'm considering releasing this first API first, maybe as with_js_link_sync, and try to support an async link (maybe with #2780) in the future.

fonsp commented 5 months ago

Hmmm never mind I think #2780 is good enough to work, and it's much cooler to have an async API :)

fonsp commented 5 months ago

Bidirectional link with multiple clients in https://github.com/fonsp/disorganised-mess/blob/main/APD%20with_js_link%20bidirectional%203.jl using #2780

fonsp commented 5 months ago

@disberd and @vambrosi there you go! It's merged but not yet released. Can you test your apps with the latest version to make sure everything works? Also check out the new docs on https://github.com/JuliaPluto/AbstractPlutoDingetjes.jl/pull/13

disberd commented 5 months ago

Amazing @fonsp, I am gonna start trying out many things to see if it breaks :D.

The mandelbrot notebook works with Pluto#main and AbstractPlutoDingetjes@v1.3

πŸŽ‰πŸŽ‰πŸŽ‰

Updated Mandelbrot notebook ```julia ### A Pluto.jl notebook ### # v0.19.40 using Markdown using InteractiveUtils # ╔═║ 28a24682-9a36-48d0-88c2-88841854df46 begin using PlutoPlotly using HypertextLiteral using AbstractPlutoDingetjes end # ╔═║ 572b1939-b61a-4d81-8000-10cac4048c8d # This code is taken from a Mandelbrot notebook shared in https://discourse.julialang.org/t/mandelbrot-with-plots-jl/52410 begin to_range(raw_range, n) = range(minimum(raw_range), maximum(raw_range); length=n) function mandel(z:: Complex) c = z maxiter = 128 for n = 1:maxiter if abs2(z) > 4 return n-1 end z = z^2 + c end return maxiter end function mandel_slice!(grid, ix, x, yrange) @inbounds for (iy, y) in enumerate(yrange) grid[iy, ix] = mandel(Complex(x,y)) end end function mandel_grid(xrange, yrange) grid = Matrix{UInt8}(undef, length(xrange), length(yrange)) futures = Vector{Task}(undef, length(xrange)) @inbounds for (ix, x) in enumerate(xrange) futures[ix] = Threads.@spawn mandel_slice!(grid, ix, x, yrange) end wait.(futures) grid end end # ╔═║ da487aae-0670-4199-a8d4-ebea52ab2896 let # This code generates the plot with re-computation upon zooming n = 500 x = to_range([-1, 1], n) y = to_range([-1, 1], n) z = mandel_grid(x,y) data = heatmap(;x,y,z) p = plot(data, Layout(xaxis_range = [-1, 1], yaxis = attr(; range = [-1,1], scaleanchor = "x", scaleratio = 1, ))) add_plotly_listener!(p, "plotly_relayout", htl_js("async (e) => { let xrange = PLOT._fullLayout.xaxis.range let yrange = PLOT._fullLayout.yaxis.range if (PLOT.updated_data == undefined) {return} let update = await PLOT.updated_data({x: xrange, y: yrange}) Plotly.restyle(PLOT, update) }")) f(d) = let x = range(d["x"]..., n) |> collect y = range(d["y"]..., n) |> collect z = mandel_grid(x,y) |> PlutoPlotly._preprocess out = (; x = [x], y = [y], z = [z], ) out end @htl(""" $p """) end # ╔═║ 00000000-0000-0000-0000-000000000001 PLUTO_PROJECT_TOML_CONTENTS = """ [deps] AbstractPlutoDingetjes = "6e696c72-6542-2067-7265-42206c756150" HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" PlutoPlotly = "8e989ff0-3d88-8e9f-f020-2b208a939ff0" [compat] AbstractPlutoDingetjes = "~1.3.0" HypertextLiteral = "~0.9.5" PlutoPlotly = "~0.4.5" """ # ╔═║ 00000000-0000-0000-0000-000000000002 PLUTO_MANIFEST_TOML_CONTENTS = """ # This file is machine-generated - editing it directly is not advised julia_version = "1.10.1" manifest_format = "2.0" project_hash = "d816ed2045a595d53cb3c87792dc8e3c6d5b003e" [[deps.AbstractPlutoDingetjes]] deps = ["Pkg"] git-tree-sha1 = "0f748c81756f2e5e6854298f11ad8b2dfae6911a" uuid = "6e696c72-6542-2067-7265-42206c756150" version = "1.3.0" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.1" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BaseDirs]] git-tree-sha1 = "3e93fcd95fe8db4704e98dbda14453a0bfc6f6c3" uuid = "18cc8868-cbac-4acf-b575-c8ff214dc66f" version = "1.2.3" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" version = "3.24.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" version = "0.10.0" [deps.ColorVectorSpace.extensions] SpecialFunctionsExt = "SpecialFunctions" [deps.ColorVectorSpace.weakdeps] SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.12.10" [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.1.0+0" [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelimitedFiles]] deps = ["Mmap"] git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" version = "0.9.3" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FixedPointNumbers]] deps = ["Statistics"] git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.4" [[deps.HypertextLiteral]] deps = ["Tricks"] git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" version = "0.9.5" [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.21.4" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" version = "1.3.1" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" version = "8.4.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[deps.LibGit2_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" version = "1.6.4+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" version = "1.11.0+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.2+1" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.1.10" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" version = "0.3.23+4" [[deps.OrderedCollections]] git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.3" [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.8.1" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.10.0" [[deps.PlotlyBase]] deps = ["ColorSchemes", "Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Parameters", "Pkg", "REPL", "Requires", "Statistics", "UUIDs"] git-tree-sha1 = "56baf69781fc5e61607c3e46227ab17f7040ffa2" uuid = "a03496cd-edff-5a9b-9e67-9cda94a718b5" version = "0.8.19" [[deps.PlutoPlotly]] deps = ["AbstractPlutoDingetjes", "BaseDirs", "Colors", "Dates", "Downloads", "HypertextLiteral", "InteractiveUtils", "LaTeXStrings", "Markdown", "Pkg", "PlotlyBase", "Reexport", "TOML"] git-tree-sha1 = "fbf637823ec24c5669b1a66f3771c2306f60857c" uuid = "8e989ff0-3d88-8e9f-f020-2b208a939ff0" version = "0.4.5" [deps.PlutoPlotly.extensions] PlotlyKaleidoExt = "PlotlyKaleido" UnitfulExt = "Unitful" [deps.PlutoPlotly.weakdeps] PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" version = "1.2.0" [[deps.Preferences]] deps = ["TOML"] git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" [[deps.Random]] deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "1.2.2" [[deps.Requires]] deps = ["UUIDs"] git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" version = "1.10.0" [[deps.Statistics]] deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" version = "1.10.0" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" version = "1.0.3" [[deps.Tar]] deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" version = "1.10.0" [[deps.TensorCore]] deps = ["LinearAlgebra"] git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" version = "0.1.1" [[deps.Tricks]] git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" version = "0.1.8" [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" [[deps.UnPack]] git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" version = "1.0.2" [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" version = "1.2.13+1" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+1" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" version = "1.52.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" """ # ╔═║ Cell order: # ╠═28a24682-9a36-48d0-88c2-88841854df46 # ╠═572b1939-b61a-4d81-8000-10cac4048c8d # ╠═da487aae-0670-4199-a8d4-ebea52ab2896 # β•Ÿβ”€00000000-0000-0000-0000-000000000001 # β•Ÿβ”€00000000-0000-0000-0000-000000000002 ```
fonsp commented 5 months ago

Super cool!!

vambrosi commented 5 months ago

Thanks @fonsp, it looks great!

https://github.com/fonsp/Pluto.jl/assets/42151837/90fbdd18-6751-470e-8779-082532c7a309

I just get this flickering though, not sure if this is because of Plotly (you can see it in the video). It also happens with @disberd updated notebook.

disberd commented 5 months ago

@vambrosi, on my laptop I do not see the same flickering as you (at least on my notebook). There is some kind of misalignment only seldomly when zooming in (twice in this video below despite zooming more than twice):

https://github.com/fonsp/Pluto.jl/assets/12846528/b2b1bb5a-ee98-40a1-b46f-06cf97c0995d

fonsp commented 5 months ago

Would be nice if you could debug this before I make the release! To me it looks like a plotly issue

fonsp commented 5 months ago

Any update?

vambrosi commented 5 months ago

Just one thing, I figured out that it happens on Firefox, but not on Safari or Chrome. So I am guessing is a Plotly issue.

vambrosi commented 5 months ago

In case it is still relevant @fonsp, the flickering seems to be an old Plotly issue: https://github.com/plotly/plotly.js/issues/4377 (still checking to see if it is the exact same problem).

fonsp commented 4 months ago

@vambrosi This notebook is super cool! Would you be interested in submitting it to https://github.com/JuliaPluto/featured ? Make a PR and we can discuss more there!