Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions PlotsBase/src/init.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
using Scratch: @get_scratch!
using REPL

const _plotly_local_file_path = Ref{Union{Nothing, String}}(nothing)
# use fixed version of Plotly instead of the latest one for stable dependency
# see github.com/JuliaPlots/Plots.jl/pull/2779
const _plotly_min_js_filename = "plotly-2.3.0.min.js" # must match https://github.com/JuliaPlots/PlotlyJS.jl/blob/master/deps/plotly_cdn_version.jl

const _requirejs_version = v"2.3.7"

const _use_local_dependencies = Ref(false)
const _use_local_plotlyjs = Ref(false)
import Base64

_plots_defaults() =
if isdefined(Main, :PLOTSBASE_DEFAULTS)
Expand All @@ -23,20 +13,8 @@ function _plots_theme_defaults()
return theme(pop!(user_defaults, :theme, :default); user_defaults...)
end

function _plots_plotly_defaults()
if Base.get_bool_env("PLOTSBASE_HOST_DEPENDENCY_LOCAL", false)
_plotly_local_file_path[] =
fn = joinpath(@get_scratch!("plotly"), _plotly_min_js_filename)
isfile(fn) ||
Downloads.download("https://cdn.plot.ly/$(_plotly_min_js_filename)", fn)
_use_local_plotlyjs[] = true
end
return _use_local_dependencies[] = _use_local_plotlyjs[]
end

function __init__()
_plots_theme_defaults()
_plots_plotly_defaults()

insert!(
Base.Multimedia.displays,
Expand Down
104 changes: 49 additions & 55 deletions PlotsBase/src/plotly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import RecipesPipeline
import Statistics
import UUIDs
import JSON
import PlotsBase: Base64, Downloads
using Scratch: @get_scratch!


using PlotUtils

Expand Down Expand Up @@ -1224,78 +1227,69 @@ plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt), 4)
html_head(plt::Plot{PlotlyBackend}) = plotly_html_head(plt)
html_body(plt::Plot{PlotlyBackend}) = plotly_html_body(plt)

plotly_url() =
if PlotsBase._use_local_dependencies[]
"file:///$(PlotsBase._plotly_local_file_path[])"
else
"https://cdn.plot.ly/$(PlotsBase._plotly_min_js_filename)"
end

function plotly_html_head(plt::Plot)
plotly = plotly_url()

include_mathjax = get(plt[:extra_plot_kwargs], :include_mathjax, "")

mathjax_file = if include_mathjax != "cdn"
"file://" * include_mathjax
else
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"
end

mathjax_head = if isempty(include_mathjax)
""
function plotly_url(plt::Plot)
include_plotly = get(plt[:extra_plot_kwargs], :include_plotly, "cdn")
plotly_version = get(plt[:extra_plot_kwargs], :mathjax_version, "2.35.2")
plotly_cdn = "https://cdn.jsdelivr.net/npm/plotly.js-dist-min@$plotly_version/plotly.min.js"
return if include_plotly != "cdn"
if !isdir(include_plotly)
include_plotly = joinpath(@get_scratch!("plotly"), "plotly$plotly_version.min.js")
end
if !isfile(include_plotly)
Downloads.download(plotly_cdn, include_plotly)
end
"data:application/javascript;base64,$(Base64.base64encode(read(include_plotly)))"
else
"<script src=\"$mathjax_file\"></script>\n\t\t"
plotly_cdn
end
end

return if PlotsBase.isijulia()
mathjax_head
function mathjax_url(plt::Plot)
include_mathjax = get(plt[:extra_plot_kwargs], :include_mathjax, "")
mathjax_version = get(plt[:extra_plot_kwargs], :mathjax_version, "3.2.2")
mathjax_cdn = "https://cdn.jsdelivr.net/npm/mathjax@$mathjax_version/es5/tex-svg-full.js"
return if include_mathjax != "cdn"
if !isdir(include_mathjax)
include_mathjax = joinpath(@get_scratch!("mathjax"), "mathjax$mathjax_version.js")
end
if !isfile(include_mathjax)
Downloads.download(mathjax_cdn, include_mathjax)
end
"data:application/javascript;base64,$(Base64.base64encode(read(include_mathjax)))"
else
"$mathjax_head<script src=$(repr(plotly))></script>"
mathjax_cdn
end
end
function plotly_html_head(plt::Plot)
return ""
end

function plotly_html_body(plt, style = nothing)
if style ≡ nothing
w, h = plt[:size]
style = "width:$(w)px;height:$(h)px;"
end

requirejs_prefix = requirejs_suffix = ""
if PlotsBase.isijulia()
# require.js adds .js automatically
plotly_no_ext = plotly_url() |> splitext |> first

requirejs_prefix = """
requirejs.config({
paths: {
plotly: '$(plotly_no_ext)'
}
});
require(['plotly'], function (Plotly) {
"""
requirejs_suffix = "});"
end

unique_tag = "id_$(replace(string(UUIDs.uuid4()), '-' => '_'))"

return """
<div id=\"$unique_tag\" style=\"$style\"></div>
<script>
;(()=> {
function plots_jl_plotly_$unique_tag() {
$requirejs_prefix
<div id=\"$unique_tag\" style=\"$style\"></div>

<link id="plotlyjs-julia" href="$(plotly_url(plt))" >
<link id="mathjax-julia" href="$(mathjax_url(plt))" >

<script type="module" id="plotsjl-plotly-script">
if(window.MathJax == null)
// Calling `await import` will load the library, and return when loaded.
await import(document.querySelector(`link#mathjax-julia`).href)

if(window.Plotly == null)
await import(document.querySelector(`link#plotlyjs-julia`).href)

$(js_body(plt, unique_tag))
$requirejs_suffix
}
let plotlyloader = window.document.createElement("script")
let src="https://requirejs.org/docs/release/$(PlotsBase._requirejs_version)/minified/require.js"
plotlyloader.addEventListener("load", plots_jl_plotly_$unique_tag);
plotlyloader.src = src
document.querySelector("#$unique_tag").appendChild(plotlyloader)
})()
</script>
"""

</script>
"""
end

js_body(
Expand Down
8 changes: 1 addition & 7 deletions PlotsBase/src/web.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,9 @@ function write_temp_html(plt::AbstractPlot)
end

function standalone_html_window(plt::AbstractPlot)
old = _use_local_dependencies[] # save state to restore afterwards
# if we open a browser ourself, we can host local files, so
# when we have a local plotly downloaded this is the way to go!
_use_local_dependencies[] =
_plotly_local_file_path[] ≡ nothing ? false : isfile(_plotly_local_file_path[])
filename = write_temp_html(plt)
open_browser_window(filename)
# restore for other backends
return _use_local_dependencies[] = old
return nothing
end

# uses wkhtmltopdf/wkhtmltoimage: http://wkhtmltopdf.org/downloads.html
Expand Down
1 change: 0 additions & 1 deletion docs/src/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ plot(1:10, Any[rand(10), sin]) # 2 series: rand(10) and map(sin,x)
### Environment variables

A few environment variables control `PlotsBase` internals:
- `PLOTSBASE_HOST_DEPENDENCY_LOCAL`: use a local `plotly` resource instead of a cloud hosted one.
- `PLOTSBASE_DEFAULT_BACKEND`: default backend, preempting the one set through the `Preferences` based mechanism.
- `PLOTSBASE_TMPDIR`: temporary files prefix for (html) files (some browser are denied access to temporary directories such as `/tmp`).

Expand Down
Loading