tlienart / Xranklin.jl

Experimental repo for a refactoring of Franklin.jl
https://tlienart.github.io/Xranklin.jl
MIT License
40 stars 1 forks source link

Including Plotlyjs plots #259

Open cserteGT3 opened 1 year ago

cserteGT3 commented 1 year ago

Back to my favourite topic: how to include Plotly plots. I've worked out the details, but wanted to open an issue for discussion before opening a PR to document it fully.

The following steps are required:

  1. Edit head.html, create and fill head_plotly.html
  2. Add default hasplotly value to config.md
  3. Add lx_plotlyfig() function to ˙utils.jl˙
  4. Edit the page as you wish (include hasplotly=true, save the resulted plot as json, use the \plotlyfig command)

Let me know what you think of this guide!

Edit: one thing would be great, making the plots themselves larger. But I don't know how to achieve that.

Guide itself:

Editing the head htmls

Add this line to your _layout/head.html file:

{{if hasplotly}} {{insert head_plotly.html }} {{end}}

Create the _layout/head_plotly.html file:

<script src="https://cdn.plot.ly/plotly-2.24.1.min.js"></script> 
<script>
// This function is used when calling \plotlyfig{...}
const PlotlyJS_json = async (div, url) => {
    response = await fetch(url); // get file
    fig = await response.json(); // convert it to json
    // Make the plot fit the screen responsively. See the documentation of plotly.js. https://plotly.com/javascript/responsive-fluid-layout/
    if (typeof fig.config === 'undefined') { fig["config"]={} }
    delete fig.layout.width
    delete fig.layout.height
    fig["layout"]["autosize"] = true
    fig["config"]["autosizable"] = true
    fig["config"]["responsive"] = true

    // make it easier to scroll throught the website rather than being blocked by a figure.
    fig.config["scrollZoom"] = false

    // PlotlyJS.savefig by default add the some more attribute to make a static plot.
    // Disable them to make the website fancier.
    delete fig.config.staticPlot
    delete fig.config.displayModeBar
    delete fig.config.doubleClick
    delete fig.config.showTips

    Plotly.newPlot(div, fig);
};
</script>

I suggest using the lib served by CDN, because then one must not replicate it in their git repo (but can be added if one wants to).

config.md

Add a line to your config.md file, that sets the default value for hasplotly. If you will have only a few pages, where plotly plots will be, then it is suggested to set it to false.

hasplotly = false

utils.jl

Add the following function to your utils.jl file. It will define the \plotlyfig{...} command, that we can use in our markdown source.

function lx_plotlyfig(p::Vector{String})::String
    id="fdp-"*Random.randstring('a':'z', 3)
    # add file extension if missing
    fp = endswith(p[1], ".json") ? p[1] : string(p[1], ".json")
    return """
           <div id="$id"></div>
           <script>
           graphDiv = document.getElementById("$id");
           plotlyPromise = PlotlyJS_json(graphDiv, '/assets/plotlyfigs/$fp');
           </script>
           """
end

Edit the desired page

Follow this example and note the followings:

And example page looks like this:

+++
title = "Plotly example"
hasplotly = true
+++

Here you can see a plotly example

```!
using PlotlyJS
z =  [10     10.625  12.5  15.625  20
     5.625  6.25    8.125 11.25   15.625
     2.5    3.125   5.    8.125   12.5
     0.625  1.25    3.125 6.25    10.625
     0      0.625   2.5   5.625   10]

data   = contour(; z=z)
layout = Layout(; title="Basic Contour Plot")
plt    = plot(data, layout)

opath = mkpath(joinpath(Utils.path(:site), "assets", "plotlyfigs"))
PlotlyJS.savejson(plt, joinpath(opath, "example.json"));

Works without extension:

\plotlyfig{example}

Works with extension:

\plotlyfig{example.json}

tlienart commented 1 year ago

That's great :-)

So just please don't open a PR with this because long story short, it's very tricky to maintain docs for all the plotting libs in Julia since each of them has their own requirements / dependencies and it makes the docs ever more complex.

The hope is to move from that to each plotting library gets a single tutorial page (exactly like the one you just so kindly wrote) which is deployed by itself, and the main docs just points to these tutorial pages :-)

I had that a while back, among other things to compare effective TTFX at deployment time, but I lost that work (not very hard to bring back and your tutorial is a good reminder to do it!) once that's in place you can PR this to it 🙏

tlienart commented 1 year ago

Edit: one thing would be great, making the plots themselves larger. But I don't know how to achieve that.

this is all CSS I believe changing the width or max-width of the div that contains the plot, have you tried?

cserteGT3 commented 1 year ago

Edit: one thing would be great, making the plots themselves larger. But I don't know how to achieve that.

this is all CSS I believe changing the width or max-width of the div that contains the plot, have you tried?

Editing the html in the lx_plotlyfig function did not help, but changing the width of the franklin-content class(?) in judoc.css worked. Or at least I achieved what I wanted: make the whole body of the pages larger:

/* on wide screens, fix content width to a max value */
@media (min-width: 940px) {
    .franklin-content {
        width: 900px; /* original was 705px*/
        margin-left: auto;
        margin-right: auto; }
    }

Thanks for the tip, I was putting off this so long and now it looks just like I wanted :D