Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update mermaid.js version #475

Open
DDorch opened this issue Oct 18, 2022 · 11 comments
Open

Update mermaid.js version #475

DDorch opened this issue Oct 18, 2022 · 11 comments

Comments

@DDorch
Copy link

DDorch commented Oct 18, 2022

This issue is in echo with issues #231, #227, #241, #294, #329, #363, #421, #470, #473 and maybe some others...

The need to update the version of mermaid.js embedded in the DiagrammeR package is pressing.

As suggested in #421, we can manually update the file /DiagrammeR/htmlwidgets/lib/mermaid/dist/mermaid.slim.min.js in the installation folder of the package with the last version downloaded from https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js.

One way to always have the latest version of DiagrammeR in the package could be to add an updateMermaid function in the package:

#'  Update the mermaid library in the package
#' @param version A [character] of the desired version (the latest by default)
#' @return See value returned by [download.file]
updateMermaid <- function(version = "") {
  url <- "https://cdn.jsdelivr.net/npm/mermaid@version/dist/mermaid.min.js"
  if (version != "") {
    stopifnot(grepl("^[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+$", version))
    version <- paste0("@", version)
  }
  url <- gsub("@version", version, url)
  try(
    download.file(url, 
                  system.file("htmlwidgets/lib/mermaid/dist/mermaid.slim.min.js", 
                              package = "DiagrammeR"))
  )
}

There are several issues with this solution:

  • this url could not be the best one to use to get an up to date and persistent reference for downloading the mermaid.js library
  • I don't know if the CRAN authorises to modify the content of the library by itself. But I don't know where to locate the mermaid.js library file elsewhere

@rich-iannone what do you think of that?

@DanGustafssonTelgeEnergi

I have tried this solution on my local installtion in Windows, and it seems to work (for now).
My original issue was to do "erDiagrams" using mermaid from within R - now that works if I update the js-library according to the instructions above.
Mermaid seems to be actively developed, by many, so some kind of updating scheme would be in order?

@DDorch
Copy link
Author

DDorch commented Jan 25, 2023

Duplicate with #480

@Seferin
Copy link

Seferin commented Feb 7, 2023

Before this running this function with updateMermaid(version="9.3.0") I was stuck with mermaid 0.3.0 and unable to use the mermaid Entity Relationship class of diagram (erDiagram). This solved my problem.

@travis-leith
Copy link

@DDorch this appears to break the click functionality introduced in #362. Any idea why?

@DDorch
Copy link
Author

DDorch commented Mar 5, 2023

@DDorch this appears to break the click functionality introduced in #362. Any idea why?

I'm sorry, this needs further investigations to see what has changed in the library that breaks this functionality.
At least, that explains why the mermaid library has not been updated yet. Unfortunately, I don't have time these next weeks/months to solve this issue.

@trafficonese
Copy link
Contributor

@DDorch this appears to break the click functionality introduced in #362. Any idea why?

I just tried with the newest mermaid verion. The click functionality seems to be fine for the first example in #362 and the second one does not render so clicking is not even possible.

This code does not work with the new version:

DiagrammeR("graph LR;A(Rounded)-->B[Squared];B-->C{A Decision};
C-->D[Square One];C-->E[Square Two];
style A fill:#E5E25F;  style B fill:#87AB51; style C fill:#3C8937;
style D fill:#23772C;  style E fill:#B6E6E6;"
 )

You will just see:

Syntax error in graph
mermaid version 9.4.0

@travis-leith
Copy link

@trafficonese the first example isn't mermaid, unless I have misunderstood.

@trafficonese
Copy link
Contributor

you're right, thats a grViz. But since the mermaid example isnt even rendering, I cannot test the click functionality.

@travis-leith
Copy link

On mermaid.live it renders if you take out all the style stuff.

@DavZim
Copy link

DavZim commented Feb 15, 2024

Is there anything that can be done to accelerate this?
It would be great to have the latest version of mermaid in DiagrammeR.

@DavZim
Copy link

DavZim commented Feb 15, 2024

As I see it, the problem with the newer Mermaid versions is that detecting clicks would be broken.
This might be due to changes in security (eg securityLevel: 'loose', see also docs).

I have played around with the newest version to create a MWE in shiny to see if interaction works, this is what I came up with:

library(shiny)

txt <- r"{graph TD
  A[[Start]] --> B(Preview)
  B --o C{decide}
  B -.-> D
  C ==> D[(End)]

  click A node_click "This is a Tooltip"
  click B node_click "This is a Tooltip"
  click C node_click "This is a Tooltip"
  click D node_click "This is a Tooltip"
}"

css <- "
g.nodes > g.node > rect { fill: red !important; }
g.nodes > g.node > polygon { fill: red !important; }
g.nodes > g.node { cursor: pointer; }
"

start_mermaid_js <- "
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true, securityLevel: 'loose' });
"

js <- r"{
node_click = function (id) {
  Shiny.setInputValue("mygraph_click", id, {priority: "event"});
};
}"

ui <- fluidPage(
  tags$head(
    tags$style(HTML(css)),
    tags$script(HTML(start_mermaid_js), type = "module"),
    tags$script(HTML(js)),
  ),
  "Here is a Mermaid JS Diagram",
  div(
    class = "html-widget html-widget-output shiny-report-size html-fill-item",
    id = "mygraph",
    pre(
      class = "mermaid",
      txt
    )
  )
)

server <- function(input, output, session) {
  observe({
    cat(sprintf("R detected that in mygraph Node '%s' was clicked\n",
                input$mygraph_click))
  })
}

shinyApp(ui, server)
# When run and clicked on a node, the following would be seen in the R console
#> R detected that in mygraph Node 'A' was clicked
#> R detected that in mygraph Node 'B' was clicked
#> R detected that in mygraph Node 'C' was clicked
#> R detected that in mygraph Node 'D' was clicked

There are two caveats:

  1. renderUI does not work with this setup as mermaid is not rendering the chart again.
  2. the callback function (node_click) needs to be set for every node and the id (mygraph) for the chart is hardcoded. I had hoped that something like the following would work, but it doesnt as the JS code needs to be rerun after mermaid renders a graph
// NOT WORKING
var nodes = document.querySelectorAll('g.nodes > g.node');
console.log(nodes);
alert('nodes: ' + nodes.length);

nodes.forEach(function(node) {
  node.style.cursor = 'pointer';
  node.addEventListener('click', function(){
    var node_id = node.id;
    console.log("Click on node " + node_id);
  // TODO figure out the id of the chart "mygraph" automatically
   Shiny.setInputValue("mygraph_click", id, {priority: "event"});
  });
});

and of course this is not in the DiagrammeR framework. But I hope this might help @rich-iannone or someone else who has enough insider knowledge to implement this in DiagrammeR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants