Last active
June 29, 2021 10:53
-
-
Save dralletje/131eff9e90703346ca7db09ebcec223f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### A Pluto.jl notebook ### | |
# v0.14.0 | |
using Markdown | |
using InteractiveUtils | |
# ╔═╡ 46b1e7b2-8460-11eb-3454-f7fa9542f903 | |
begin | |
import Pkg | |
Pkg.add([ | |
"Dash", | |
"DashCoreComponents", | |
"DashHtmlComponents", | |
"DashTable", | |
"HTTP", | |
]) | |
end | |
# ╔═╡ b6963f48-81ce-4332-94b7-acc5740376be | |
using Dash | |
# ╔═╡ 7209c5f8-47f8-4d64-89e2-b08e121eb227 | |
using DashHtmlComponents | |
# ╔═╡ 007a8782-2487-41bc-82cc-c26ef7e6a6f9 | |
using DashCoreComponents | |
# ╔═╡ c8f8d722-96a9-49b3-a566-58f73dc1f4c4 | |
md""" | |
# Example of Dash app in Pluto | |
It just creates a server and then proxies requests through Pluto. | |
In the end I want to render individual components directly in your cell. | |
It is also still a bit jittery when you refresh. | |
""" | |
# ╔═╡ 17f86bb0-4960-4980-9ba6-2f3ada6ceee3 | |
md"## Appendix" | |
# ╔═╡ b53711ab-7d12-40f1-8457-146b665ea9ca | |
md"### Packages" | |
# ╔═╡ db3b4012-52b8-4711-b81d-7dc54f914add | |
import HTTP | |
# ╔═╡ fd894b9d-0844-4627-a833-e79c9355972c | |
md"### Dash setup" | |
# ╔═╡ 2685e3f7-2c70-4e1f-a6ae-bdce5e07fedb | |
"I still have to make it so that the port isn't awkward" | |
PORT = 8086 | |
# ╔═╡ c250c492-ad8d-4e59-8520-0c3a86135e69 | |
base_url = "/integrations/Dash/$(PlutoRunner.workspace_info.notebook_id)/$(PORT)/" | |
# base_url = "./" * PlutoRunner.IntegrationsWithOtherPackages.get_base_url()[3:end] * "/$(PORT)/" | |
# ╔═╡ 74a80b9f-663d-4fa4-b1d6-56db206cb167 | |
HTML(""" | |
<a href="$(base_url)" target="_blank">Open app in seperate tab</a> | |
""") | |
# ╔═╡ 4e12b92f-c372-4628-9c9d-dc3568635611 | |
PREVIOUS_RESULTS = Dict{Any,Any}() | |
# ╔═╡ 265c7672-980e-4bcf-a07d-375a4a35ca49 | |
function make_dash_app(make_layout) | |
app = dash( | |
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"], | |
url_base_pathname=base_url, | |
) | |
app.layout = make_layout() | |
app | |
end | |
# ╔═╡ 0a8ed9fd-eb72-420f-93ff-8368cf0fc0e8 | |
begin | |
app = make_dash_app() do | |
html_div() do | |
dcc_input(id="graphTitle", value="Let's Dance!!", type = "text"), | |
html_div(id="outputID"), | |
dcc_graph(id="graph", | |
figure = ( | |
data = [(x = [1,2,3], y = [3,2,8], type="bar")], | |
layout = Dict(:title => "Graph") | |
) | |
) | |
end | |
end | |
callback!(app, Output("outputID", "children"), Input("graphTitle","value"), State("graphTitle","type")) do value, type | |
@info "SAY WHAAT" value | |
"You've entered: '$(value)' into a '$(type)' input control" | |
end | |
callback!(app, Output("graph", "figure"), Input("graphTitle", "value")) do value | |
( | |
data = [ | |
(x = [1,2,3], y = abs.(randn(3)), type="bar"), | |
(x = [1,2,3], y = abs.(randn(3)), type="scatter", mode = "lines+markers", line = (width = 4,)) | |
], | |
layout = (title = value,) | |
) | |
end | |
end; | |
# ╔═╡ 1eb65acd-3385-4f7c-9e05-d4af5456c3cf | |
server_task = PREVIOUS_RESULTS["dash_server_task"] = begin | |
# Ideally I want @cell_id() here or something | |
# This closes the server, but only if we are starting a new one. | |
# This is not a very reliable technique | |
if haskey(PREVIOUS_RESULTS, "dash_server_task") | |
try | |
local previous_task = PREVIOUS_RESULTS["dash_server_task"] | |
schedule(previous_task, InterruptException(), error=true) | |
catch e | |
end | |
end | |
@async begin | |
println("Startng dash server @ http://127.0.0.1:$(PORT)") | |
local server = run_server(app, "127.0.0.1", PORT) | |
end | |
end | |
# ╔═╡ ad6afe08-b802-4b38-80af-0cd343d12a41 | |
server_task; HTML(""" | |
<div style="position: relative"> | |
<div | |
id="loading" | |
style=" | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background-color: rgba(255,255,255); | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-size: 32px; | |
" | |
><span>Loading</span></div> | |
<iframe src="$(base_url)" style="border: none; width: 100%;"></iframe> | |
</div> | |
<script> | |
let \$iframe = currentScript.closest('pluto-output').querySelector('iframe') | |
let \$loading = currentScript.closest('pluto-output').querySelector('#loading') | |
// Code below here is borrowed from CellOutput.js in Pluto | |
let iframeref = { | |
current: \$iframe, | |
} | |
await new Promise((resolve) => iframeref.current.addEventListener("load", () => resolve())) | |
let iframeDocument = iframeref.current.contentWindow.document | |
// Insert iframe resizer inside the iframe | |
let x = iframeDocument.createElement("script") | |
x.src = "https://cdn.jsdelivr.net/npm/iframe-resizer@4.2.11/js/iframeResizer.contentWindow.min.js" | |
x.integrity = "sha256-EH+7IdRixWtW5tdBwMkTXL+HvW5tAqV4of/HbAZ7nEc=" | |
x.crossOrigin = "anonymous" | |
iframeDocument.head.appendChild(x) | |
// Apply iframe resizer from the host side | |
new Promise((resolve) => x.addEventListener("load", () => resolve())) | |
// @ts-ignore | |
window.iFrameResize({ checkOrigin: false }, iframeref.current) | |
// End of borrowed code | |
\$loading.style.display = "none" | |
</script> | |
""") | |
# ╔═╡ 084ebaf4-ba36-413c-b409-35e25b7b9ca5 | |
""" | |
For Dash I am just running the Dash server as normal, and proxying all the requests 🙃 | |
This works remarkably well. | |
""" | |
function PlutoRunner.IntegrationsWithOtherPackages.on_request(::Val{:Dash}, request) | |
_1, _2, _3, _4, port = split(request[:target], "/") | |
url = "http://localhost:$(port)$(request[:target])" | |
@info "request[:method]" request[:method] | |
response = HTTP.request( | |
request[:method], | |
url, | |
[], | |
request[:body], | |
) | |
return Dict( | |
:status => Int64(response.status), | |
:headers => response.headers, | |
:body => response.body, | |
) | |
end | |
# ╔═╡ Cell order: | |
# ╟─c8f8d722-96a9-49b3-a566-58f73dc1f4c4 | |
# ╟─74a80b9f-663d-4fa4-b1d6-56db206cb167 | |
# ╟─ad6afe08-b802-4b38-80af-0cd343d12a41 | |
# ╠═0a8ed9fd-eb72-420f-93ff-8368cf0fc0e8 | |
# ╟─17f86bb0-4960-4980-9ba6-2f3ada6ceee3 | |
# ╟─b53711ab-7d12-40f1-8457-146b665ea9ca | |
# ╠═46b1e7b2-8460-11eb-3454-f7fa9542f903 | |
# ╠═db3b4012-52b8-4711-b81d-7dc54f914add | |
# ╠═b6963f48-81ce-4332-94b7-acc5740376be | |
# ╠═7209c5f8-47f8-4d64-89e2-b08e121eb227 | |
# ╠═007a8782-2487-41bc-82cc-c26ef7e6a6f9 | |
# ╟─fd894b9d-0844-4627-a833-e79c9355972c | |
# ╠═2685e3f7-2c70-4e1f-a6ae-bdce5e07fedb | |
# ╠═c250c492-ad8d-4e59-8520-0c3a86135e69 | |
# ╟─4e12b92f-c372-4628-9c9d-dc3568635611 | |
# ╠═1eb65acd-3385-4f7c-9e05-d4af5456c3cf | |
# ╠═265c7672-980e-4bcf-a07d-375a4a35ca49 | |
# ╠═084ebaf4-ba36-413c-b409-35e25b7b9ca5 |
@dralletje @fonsp Can we use DashCoreComponents and DashHtmlComponents Directly in Pluto. Just Like PlutoUI Functions
@coprem Try it out yourself and let us know
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I added Pkg.activate and matched a variable rename that i did to your PR: