Last active
June 29, 2021 10:53
-
-
Save dralletje/131eff9e90703346ca7db09ebcec223f to your computer and use it in GitHub Desktop.
This file contains hidden or 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/[email protected]/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: