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

Text in notes displays incorrectly when combining Mermaid and Remark (with example) #360

Closed
hartzell opened this issue Jun 14, 2016 · 14 comments
Labels
Type: New Shape Request for new shape

Comments

@hartzell
Copy link

hartzell commented Jun 14, 2016

When I combine remark and mermaid text in notes in sequence diagrams does not seem to be taken into account when the diagram is drawn if the diagram is not on the slide currently being displayed.

I see the problem on a Mac running 10.10.5 in Chrome and in Safari.

I've created a repository, https://github.com/hartzell/remark-mermaid, that contains a demonstration of the problem.

The file bad.jpg in the repository shows what it looks like when it's wrong.

If you redraw the slide, then that slide is correct, but other slides are still screwy.

The file good.jpg in the repository shows what it looks like when it's right.

If you clone the repository and open talk.html you should see an example of the problem.

@hartzell hartzell changed the title Text in notes displays incorrectly when combining Mermaid and Remark. Text in notes displays incorrectly when combining Mermaid and Remark (with example) Jun 14, 2016
@RReverser
Copy link

Same issue when using with Reveal.js - renders correctly on active & nearby slides, but not on the lazy ones.

@utdrmac
Copy link

utdrmac commented Jul 8, 2016

+1'ing this as well. Have been using RemarkJS for some time. Recently discovered Mermaid. Trying to integrate the two. As above, slides that are hidden get incorrect SVG. I suspect this has something to do with mermaid needing to know the size of the parent DIV. Since the parent DIV on a hidden slide is sorta 'undefined', mermaid does the best it can.

Is there any way in mermaid to explicitly set the size? Slides don't change size during presentation.

@RReverser
Copy link

I actually fixed my problem with Reveal.js by applying Mermaid only to the current slide on slidechange event.

@utdrmac
Copy link

utdrmac commented Jul 8, 2016

@RReverser Could you share that code snippet?

@RReverser
Copy link

@utdrmac

Sure, it's here: https://github.com/RReverser/odessajs-2016/blob/gh-pages/index.html#L101-L104

@utdrmac
Copy link

utdrmac commented Jul 11, 2016

I take that back. Looks like I got it.

mermaid.initialize({
  startOnLoad: false,
  cloneCssStyles: false
});

slideshow.on('afterShowSlide', function(s) {
    if (s.properties.mermaid !== undefined)
    {
        var divId = s.properties.mermaid;
        mermaid.init(undefined, document.getElementById(divId));
    }
});

Caveats: You'll have to manually create the div for each slide and give it a unique ID instead of using the RemarkJS dot-div syntax:

<div class="mermaid" id="diagram1">..mermaid code..</div>

Add a slide property mermaid: diagram1

A little CSS magic to get things centered within the display area. You will have to adjust for your sized slides:

.mermaid { width: 780px; }
.mermaid svg {
  display: block;
  margin: auto;
  max-width: 780px;
}

One final caveat, since the JS only fires off on slide change, if you reload the page on a slide with Mermaid syntax, you will not see it render. You must navigate away then back.

@knsv
Copy link
Collaborator

knsv commented Aug 24, 2016

@utdrmac nice one!

It is possible to tweak this slightly so that the ids can be avoided. I have not tested this in all browsers but in Chrome at least this works:

      slideshow.on('afterShowSlide', function(s) {
          var diagrams = document.querySelectorAll('.mermaid');
          var i;
          for(i=0;i<diagrams.length;i++){
            if(diagrams[i].offsetWidth>0){
              mermaid.init(undefined, diagrams[i]);
            }
          }
      });

The caveat also remains ofc. Maybe this should be document in the Remark wiki...

@utdrmac
Copy link

utdrmac commented Aug 24, 2016

Yea, I got it working but abandoned Mermaid integration because I couldn't get Mermaid to draw boxes the way I needed them. When attempting to draw a simple 3-level B-Tree (7 total nodes), the 2 nodes on level 1 would not align horizontally. I couldn't find any CSS tricks or documentation that would constrain or "force" horizontal/vertical alignment.

@geirsagberg
Copy link

I added a snippet to initalize mermaid for the current slide (if reloading on a slide with a graph, e.g.):

var slideshow = remark.create({
  ratio: '16:9',
  highlightStyle: 'monokai',
  highlightLanguage: 'javascript'
});
mermaid.initialize({
  startOnLoad: false,
  cloneCssStyles: false
});
function initMermaid(s) {
  var diagrams = document.querySelectorAll('.mermaid');
  var i;
  for(i=0;i<diagrams.length;i++){
    if(diagrams[i].offsetWidth>0){
      mermaid.init(undefined, diagrams[i]);
    }
  }
}
slideshow.on('afterShowSlide', initMermaid);
initMermaid(slideshow.getSlides()[slideshow.getCurrentSlideIndex()]);

@kuulemart
Copy link

kuulemart commented Mar 7, 2017

@geirsagberg How this code is supposed to work? Maybe I'm missing something but initMermaid function does not use it's input parameter s. So basically every call to initMermaid initializes all diagrams with offsetWidth > 0 and that current slide logic is pretty useless.

@geirsagberg
Copy link

Not sure, that was 6 months ago ;-) there is probably a better way to do it, but it worked for me.

@zuozhiw
Copy link

zuozhiw commented Aug 20, 2018

If anyone is still having problems with remarkJS integrating mermaid, I wrote this snippet that works for me:

// don't let mermaid automatically load on start
mermaid.initialize({
  startOnLoad: false,
  cloneCssStyles: false
});

function initMermaidInSlide(slide) {
  var slideIndex = slide.getSlideIndex();
  // caution: no API to get the DOM element of current slide in remark, this might break in the future
  var currentSlideElement = document.querySelectorAll(".remark-slides-area .remark-slide")[slideIndex];
  var currentSlideMermaids = currentSlideElement.querySelectorAll(".mermaid");
  if (currentSlideMermaids.length !== 0) {
    mermaid.init(undefined, currentSlideMermaids);
  }
}

// first starting slide won't trigger the slide event, manually init mermaid
initMermaidInSlide(slideshow.getSlides()[slideshow.getCurrentSlideIndex()])
// on each slide event, trigger init mermaid
slideshow.on('afterShowSlide', initMermaidInSlide);

@nickredmark
Copy link

Here is my solution:

slideshow.on("afterShowSlide", s => {
  const [slide] = document.getElementsByClassName("remark-visible");
  mermaid.init(Array.from(slide.getElementsByClassName("mermaid")));
});

@stale
Copy link

stale bot commented Jun 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Type: New Shape Request for new shape label Jun 29, 2019
mgenereu pushed a commit to mgenereu/mermaid that referenced this issue Jun 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: New Shape Request for new shape
Projects
None yet
Development

No branches or pull requests

8 participants