From 0e79070ad81d926b28fc52da32e7edba82b4c777 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 7 Aug 2019 16:39:39 +0200 Subject: [PATCH 1/4] create syncplot at show/display --- src/backends/plotlyjs.jl | 146 ++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 56 deletions(-) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 83952c71..ede8cbf6 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -2,77 +2,111 @@ # -------------------------------------------------------------------------------------- - -function _create_backend_figure(plt::Plot{PlotlyJSBackend}) - if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot) - PlotlyJS.SyncPlot(PlotlyJS.Plot(), options = current().o.options) - else - PlotlyJS.plot() +function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend}) + plt[:overwrite_figure] && closeall() + plt.o = PlotlyJS.plot() + traces = PlotlyJS.GenericTrace[] + for series_dict in plotly_series(plt) + plotly_type = pop!(series_dict, :type) + push!(traces, PlotlyJS.GenericTrace(plotly_type; series_dict...)) end + PlotlyJS.addtraces!(plt.o, traces...) + layout = plotly_layout(plt) + w, h = plt[:size] + PlotlyJS.relayout!(plt.o, layout, width = w, height = h) + return plt.o end -function _series_added(plt::Plot{PlotlyJSBackend}, series::Series) - syncplot = plt.o - pdicts = plotly_series(plt, series) - for pdict in pdicts - typ = pop!(pdict, :type) - gt = PlotlyJS.GenericTrace(typ; pdict...) - PlotlyJS.addtraces!(syncplot, gt) - end -end - -function _series_updated(plt::Plot{PlotlyJSBackend}, series::Series) - xsym, ysym = (ispolar(series) ? (:t,:r) : (:x,:y)) - kw = KW(xsym => (series.plotattributes[:x],), ysym => (series.plotattributes[:y],)) - z = series[:z] - if z != nothing - kw[:z] = (isa(z,Surface) ? transpose_z(series, series[:z].surf, false) : z,) - end - PlotlyJS.restyle!( - plt.o, - findfirst(isequal(series), plt.series_list), - kw - ) -end +# function _create_backend_figure(plt::Plot{PlotlyJSBackend}) +# if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot) +# PlotlyJS.SyncPlot(PlotlyJS.Plot(), options = current().o.options) +# else +# PlotlyJS.plot() +# end +# end +# +# +# function _series_added(plt::Plot{PlotlyJSBackend}, series::Series) +# syncplot = plt.o +# pdicts = plotly_series(plt, series) +# for pdict in pdicts +# typ = pop!(pdict, :type) +# gt = PlotlyJS.GenericTrace(typ; pdict...) +# PlotlyJS.addtraces!(syncplot, gt) +# end +# end +# +# function _series_updated(plt::Plot{PlotlyJSBackend}, series::Series) +# xsym, ysym = (ispolar(series) ? (:t,:r) : (:x,:y)) +# kw = KW(xsym => (series.plotattributes[:x],), ysym => (series.plotattributes[:y],)) +# z = series[:z] +# if z != nothing +# kw[:z] = (isa(z,Surface) ? transpose_z(series, series[:z].surf, false) : z,) +# end +# PlotlyJS.restyle!( +# plt.o, +# findfirst(isequal(series), plt.series_list), +# kw +# ) +# end +# +# +# # ---------------------------------------------------------------- +# +# function _update_plot_object(plt::Plot{PlotlyJSBackend}) +# pdict = plotly_layout(plt) +# syncplot = plt.o +# w,h = plt[:size] +# PlotlyJS.relayout!(syncplot, pdict, width = w, height = h) +# end # ---------------------------------------------------------------- -function _update_plot_object(plt::Plot{PlotlyJSBackend}) - pdict = plotly_layout(plt) - syncplot = plt.o - w,h = plt[:size] - PlotlyJS.relayout!(syncplot, pdict, width = w, height = h) +const _plotlyjs_mimeformats = Dict( + "application/pdf" => "pdf", + "image/png" => "png", + "image/svg+xml" => "svg", + "image/eps" => "eps", +) + +for (mime, fmt) in _plotlyjs_mimeformats + @eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt) end +const _plotlyjs_showformats = ["text/html", "application/vnd.plotly.v1+json"] -# ---------------------------------------------------------------- - -_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = show(io, MIME("text/html"), plt.o) -_show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="svg") -_show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="png") -_show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="pdf") -_show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="eps") - -function _show(io::IO, m::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) - show(io, m, plt.o) +for mime in ["text/html", "application/vnd.plotly.v1+json"] + @eval _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = show(io, mime, plotlyjs_syncplot(plt)) end +# _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = show(io, ::MIME"text/html", plt.o) +# _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="svg") +# _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="png") +# _show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="pdf") +# _show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="eps") -function write_temp_html(plt::Plot{PlotlyJSBackend}) - filename = string(tempname(), ".html") - savefig(plt, filename) - filename -end +# function _show(io::IO, m::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) +# show(io, m, plt.o) +# end -function _display(plt::Plot{PlotlyJSBackend}) - if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") - display(plt.o) - else - standalone_html_window(plt) - end -end + +# function write_temp_html(plt::Plot{PlotlyJSBackend}) +# filename = string(tempname(), ".html") +# savefig(plt, filename) +# filename +# end + +_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt)) + +# function _display(plt::Plot{PlotlyJSBackend}) +# if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") +# display(plt.o) +# else +# standalone_html_window(plt) +# end +# end @require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin function WebIO.render(plt::Plot{PlotlyJSBackend}) From 7ae43ee9f6a437adec17dfa47c35df044791c808 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 7 Aug 2019 16:40:52 +0200 Subject: [PATCH 2/4] use plotly implementation for html/js/ijulia --- src/backends/plotly.jl | 20 +++++++++++++------- src/backends/plotlyjs.jl | 14 +++++++++++--- src/ijulia.jl | 5 ++++- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 007c3d05..1896d37a 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -804,9 +804,12 @@ 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) + const ijulia_initialized = Ref(false) -function html_head(plt::Plot{PlotlyBackend}) +function plotly_html_head(plt::Plot) local_file = ("file://" * plotly_local_file_path) plotly = use_local_dependencies[] ? local_file : plotly_remote_file_path if isijulia() && !ijulia_initialized[] @@ -825,7 +828,7 @@ function html_head(plt::Plot{PlotlyBackend}) return "" end -function html_body(plt::Plot{PlotlyBackend}, style = nothing) +function plotly_html_body(plt, style = nothing) if style == nothing w, h = plt[:size] style = "width:$(w)px;height:$(h)px;" @@ -841,17 +844,14 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing) html end -function js_body(plt::Plot{PlotlyBackend}, uuid) +function js_body(plt::Plot, uuid) js = """ PLOT = document.getElementById('$(uuid)'); Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt))); """ end - -# ---------------------------------------------------------------- - -function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{PlotlyBackend}) +function plotly_show_js(io::IO, plot::Plot) data = [] for series in plot.series_list append!(data, plotly_series(plot, series)) @@ -860,6 +860,12 @@ function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{Plotly JSON.print(io, Dict(:data => data, :layout => layout)) end +# ---------------------------------------------------------------- + +function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{PlotlyBackend}) + plotly_show_js(io, plot) +end + function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) write(io, standalone_html(plt)) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index ede8cbf6..8e742e4f 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -77,9 +77,17 @@ end const _plotlyjs_showformats = ["text/html", "application/vnd.plotly.v1+json"] -for mime in ["text/html", "application/vnd.plotly.v1+json"] - @eval _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = show(io, mime, plotlyjs_syncplot(plt)) -end +# for mime in ["text/html", "application/vnd.plotly.v1+json"] +# @eval _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = show(io, mime, plotlyjs_syncplot(plt)) +# end + +# Use the Plotly implementation for json and html: +_show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) = plotly_show_js(io, plot) + +html_head(plt::Plot{PlotlyJSBackend}) = plotly_html_head(plt) +html_body(plt::Plot{PlotlyJSBackend}) = plotly_html_body(plt) + +_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standalone_html(plt)) # _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = show(io, ::MIME"text/html", plt.o) # _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="svg") diff --git a/src/ijulia.jl b/src/ijulia.jl index a54c0ca9..1f0ef219 100644 --- a/src/ijulia.jl +++ b/src/ijulia.jl @@ -20,7 +20,10 @@ frontends like jupyterlab and nteract. _ijulia__extra_mime_info!(plt::Plot, out::Dict) = out function _ijulia__extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict) - out["application/vnd.plotly.v1+json"] = JSON.lower(plt.o) + out["application/vnd.plotly.v1+json"] = Dict( + :data => plotly_series(plt), + :layout => plotly_layout(plt) + ) out end From ac24a4ae19cf4efd562c51d33d9bccbc01789967 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 7 Aug 2019 16:50:09 +0200 Subject: [PATCH 3/4] cleanup --- src/backends/plotlyjs.jl | 78 +--------------------------------------- 1 file changed, 1 insertion(+), 77 deletions(-) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 8e742e4f..34585d31 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -17,51 +17,6 @@ function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend}) return plt.o end - -# function _create_backend_figure(plt::Plot{PlotlyJSBackend}) -# if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot) -# PlotlyJS.SyncPlot(PlotlyJS.Plot(), options = current().o.options) -# else -# PlotlyJS.plot() -# end -# end -# -# -# function _series_added(plt::Plot{PlotlyJSBackend}, series::Series) -# syncplot = plt.o -# pdicts = plotly_series(plt, series) -# for pdict in pdicts -# typ = pop!(pdict, :type) -# gt = PlotlyJS.GenericTrace(typ; pdict...) -# PlotlyJS.addtraces!(syncplot, gt) -# end -# end -# -# function _series_updated(plt::Plot{PlotlyJSBackend}, series::Series) -# xsym, ysym = (ispolar(series) ? (:t,:r) : (:x,:y)) -# kw = KW(xsym => (series.plotattributes[:x],), ysym => (series.plotattributes[:y],)) -# z = series[:z] -# if z != nothing -# kw[:z] = (isa(z,Surface) ? transpose_z(series, series[:z].surf, false) : z,) -# end -# PlotlyJS.restyle!( -# plt.o, -# findfirst(isequal(series), plt.series_list), -# kw -# ) -# end -# -# -# # ---------------------------------------------------------------- -# -# function _update_plot_object(plt::Plot{PlotlyJSBackend}) -# pdict = plotly_layout(plt) -# syncplot = plt.o -# w,h = plt[:size] -# PlotlyJS.relayout!(syncplot, pdict, width = w, height = h) -# end - - # ---------------------------------------------------------------- const _plotlyjs_mimeformats = Dict( @@ -75,47 +30,16 @@ for (mime, fmt) in _plotlyjs_mimeformats @eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt) end -const _plotlyjs_showformats = ["text/html", "application/vnd.plotly.v1+json"] - -# for mime in ["text/html", "application/vnd.plotly.v1+json"] -# @eval _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = show(io, mime, plotlyjs_syncplot(plt)) -# end - # Use the Plotly implementation for json and html: -_show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) = plotly_show_js(io, plot) +_show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) = plotly_show_js(io, plt) html_head(plt::Plot{PlotlyJSBackend}) = plotly_html_head(plt) html_body(plt::Plot{PlotlyJSBackend}) = plotly_html_body(plt) _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standalone_html(plt)) -# _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = show(io, ::MIME"text/html", plt.o) -# _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="svg") -# _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="png") -# _show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="pdf") -# _show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="eps") - -# function _show(io::IO, m::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) -# show(io, m, plt.o) -# end - - -# function write_temp_html(plt::Plot{PlotlyJSBackend}) -# filename = string(tempname(), ".html") -# savefig(plt, filename) -# filename -# end - _display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt)) -# function _display(plt::Plot{PlotlyJSBackend}) -# if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") -# display(plt.o) -# else -# standalone_html_window(plt) -# end -# end - @require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin function WebIO.render(plt::Plot{PlotlyJSBackend}) prepare_output(plt) From ad051f21c10e6ce1bbe534c6008e7cc0399c2136 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 7 Aug 2019 21:45:55 +0200 Subject: [PATCH 4/4] small cosmetics --- src/backends/plotlyjs.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 34585d31..5893ece3 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -1,6 +1,6 @@ # https://github.com/sglyon/PlotlyJS.jl -# -------------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend}) plt[:overwrite_figure] && closeall() @@ -17,7 +17,7 @@ function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend}) return plt.o end -# ---------------------------------------------------------------- +# ------------------------------------------------------------------------------ const _plotlyjs_mimeformats = Dict( "application/pdf" => "pdf",