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

Native Mermaid.js integration #2170

Closed
10 tasks done
squidfunk opened this issue Jan 1, 2021 · 35 comments
Closed
10 tasks done

Native Mermaid.js integration #2170

squidfunk opened this issue Jan 1, 2021 · 35 comments
Labels
change request Issue requests a new feature or improvement

Comments

@squidfunk
Copy link
Owner

squidfunk commented Jan 1, 2021

Experimental support has been released as part of Insiders 1.15.0!

Many users have problems setting up Mermaid for drawing graphs. Material for MkDocs wants to make drawing graphs as simple as adding the relevant graph definition to a Markdown file with everything else automatically being taken care of.

Goals

I'm working on a native Mermaid.js integration as part of Insiders, which will have the following nice properties:

  • The theme will automatically set up Mermaid.js as soon as it sees a .mermaid block
  • This will work perfectly with instant loading and only load the rather bulky mermaid.js when necessary
  • It works with dark mode and is easily customizable through CSS variables
  • The colors and fonts will adapt to those chosen by the author in mkdocs.yml
  • Omit common problems with Mermaid (i.e. duplicate IDs)
  • Consider offline support

While all graph types are supported, not all of them will adapt to the chosen colors and fonts (yet). The progress so far:

  • Flow charts
  • Class diagrams
  • State diagrams
  • Sequence diagrams
  • Entity-Relationship diagrams
  • User Journeys
  • Gantt charts
  • Pie charts

Usage

Support is currently experimental and can be enabled by adding the following configuration to mkdocs.yml:

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid-experimental
          format: !!python/name:pymdownx.superfences.fence_code_format

Material for MkDocs will take care of the rest, only initializing Mermaid.js when necessary. Furthermore, Instant Loading and Mermaid will work perfectly together, so the setup is only necessary once.

Preview Bildschirmfoto 2021-01-01 um 16 50 46 Bildschirmfoto 2021-01-01 um 16 51 02
@squidfunk squidfunk added the change request Issue requests a new feature or improvement label Jan 1, 2021
@squidfunk squidfunk pinned this issue Jan 1, 2021
@facelessuser
Copy link
Contributor

This is pretty exciting, and when you get something testable, if you want, I'd love to test it out as I currently have a vested interest and would like to confirm this won't exhibit any of the issues I've experienced in the past with Mermaid, mainly: mermaid-js/mermaid#1318.

My current solution actually mitigates all known issues (mainly related to leaky IDs) I've dealt with when using Mermaid by using Shadow DOMs, and I'd love to help make sure Material's approach (even if different) doesn't introduce any of those issues. I'd love to migrate to this new solution. I spent a good amount of time getting Mermaid working great in my docs, and would love to never do it again 😅.

@squidfunk
Copy link
Owner Author

I just added the experimental Mermaid integration to Insiders. If Insiders now sees an element with the .mermaid-experimental class, the Mermaid environment is initialized and the graphs are automatically rendered. Note that I choose this class name, so users need to opt-in into this experimental feature. This is essentially equivalent to a feature flag and will be renamed to .mermaid as soon as we're out of experimental state, supporting both for a period of transition. While all graphs should work, I haven't yet added styling support to all types of them. I'll add some more information to the original post to keep track of the progress.

Thus, to enable the Mermaid integration, just configure Superfences as follows:

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid-experimental
          format: !!python/name:pymdownx.superfences.fence_code_format

Note that the Mermaid JavaScript should not be added to extra JS, it's automatically done so by the theme.

@squidfunk squidfunk changed the title Native Mermaid.js integration Native Mermaid.js integration (currently experimental) Jan 2, 2021
@wilhelmer
Copy link
Contributor

The documentation is incorrect. The config snippet includes:

format: !!pymdownx.superfences.fence_code_format

but it should be (as stated above):

format: !!python/name:pymdownx.superfences.fence_code_format

With that change, it runs fine. Looks great, now I have to learn Mermaid 😄

@squidfunk
Copy link
Owner Author

@wilhelmer thanks for noting – fixed in 0c7055f. All feedback appreciated 😊

@wilhelmer
Copy link
Contributor

wilhelmer commented Jan 6, 2021

Thanks! Initial thoughts:

  1. mermaid.min.js is fetched dynamically and only if needed, which is nice to reduce the footprint on pages without diagrams. However, since it fetches from unpkg.com, this doesn't work when working offline. In this case, the original Mermaid code is displayed instead of the diagram, which is a little weird. I know offline browsing is considered an edge case, but if it's not too complicated, you could
    1. ... add a note to the docs that this feature only works online.
    2. ... find a better fallback solution, i.e., display placeholder text.
  2. The font family for diagrams is set to "trebuchet ms", verdana, arial, sans-serif (tested on Windows with FF and Chrome), I guess that should be Roboto
  3. Some rendering issues in Chrome:
    grafik
    Firefox:
    grafik

@facelessuser
Copy link
Contributor

Can you post diagram?

@wilhelmer
Copy link
Contributor

I used the example from the documentation:

graph LR
  A[Start] --> B{Error?};
  B -->|Yes| C[Hmm...];
  C --> D[Debug];
  D --> B;
  B ---->|No| E[Yay!];
Loading

@squidfunk
Copy link
Owner Author

@wilhelmer thanks for test driving!

mermaid.min.js is fetched dynamically and only if needed, which is nice to reduce the footprint on pages without diagrams. However, since it fetches from unpkg.com, this doesn't work when working offline. In this case, the original Mermaid code is displayed instead of the diagram, which is a little weird. I know offline browsing is considered an edge case, but if it's not too complicated, you could
... add a note to the docs that this feature only works online.
... find a better fallback solution, i.e., display placeholder text.

It should actually be not that hard to add offline support. You'd have to add Mermaid to extra_javascript and the theme could detect that it has already been added. The only paintpoint of Mermaid is that it "runs away" when you don't stop it, i.e. it will self-initialize unless told otherwise, so there might be some extra JavaScript necessary. I really hate Mermaid's library design, you have to fight against it on so many levels, yet it seems to be the standard solution. We can add offline support when the integration stabilizes, but it's good to keep it in mind from the start.

The font family for diagrams is set to "trebuchet ms", verdana, arial, sans-serif (tested on Windows with FF and Chrome), I guess that should be Roboto

Some rendering issues in Chrome:

I cannot reproduce the rendering errors. Here, on macOS, everything looks fine on Safari, Firefox and Chrome. Furthermore, the correct font (as set in mkdocs.yml is used for the three diagram types that are already supported). Are you using Windows?

@wilhelmer
Copy link
Contributor

Yes, I'm using Windows. The font issue seems to be caused by my local config, so ignore that. But the rendering issue is definitely a thing, tested it with a minimum setup on Chrome 87 Windows:

mkdocs.yml

site_name: My Docs
use_directory_urls: false
theme:
    name: material
markdown_extensions:
    - pymdownx.superfences:
          custom_fences:
            - name: mermaid
              class: mermaid-experimental
              format: !!python/name:pymdownx.superfences.fence_code_format

grafik

@squidfunk
Copy link
Owner Author

squidfunk commented Jan 6, 2021

I'll try to get my hands on a Windows machine anytime soon. Until then, if somebody feels like debugging - any help is appreciated. Do the flow charts in the Mermaid documentation look correct on your machine?

@wilhelmer
Copy link
Contributor

Yes, the charts in the documentation look fine.

Important observation: I've set the resolution to 2x on my Windows monitor (= "200%" setting in control panel). When I change it to 1x (= 100%), the drawing is rendered correctly! So it must have something to do with the 2x rendering in Windows Chrome. Maybe you can ignore this issue because it will only affect a small fraction of users.

@squidfunk
Copy link
Owner Author

This could come from the use of ems (i.e. relative font units) in Material and for the Mermaid integration and Mermaid hard coding 16px for the SVG image:

Bildschirmfoto 2021-01-06 um 11 46 11

On your machine, did you increase resolution (= zoom) or font-size? It's interesting that it works in the official Mermaid docs, but that shows that there's definitely a way around.

@wilhelmer
Copy link
Contributor

Checked again, the Mermaid docs are also messed up. Sorry for the confusion. So it's a bug on their side.

@facelessuser
Copy link
Contributor

@wilhelmer, @squidfunk
In my current solution, I do not have this problem in my current implementation:

chrome_Qck50t7xq8

I may do some things different than Material though, for instance, I turn off HTML labels which can cause the above issue:

    flowchart: {
      htmlLabels: false
    },

You can see when I turn it on, I get the same issue:

image

@facelessuser
Copy link
Contributor

I am not currently using Material's implementation yet. I worked through all of the common issues I ran into when using Mermaid in my own docs, and I haven't yet taken time to identify which issues Material does not workaround. My config is here if it helps as there may be other things that fix minor issues: https://github.com/facelessuser/pymdown-extensions/blob/master/docs/src/markdown/_snippets/uml.txt.

I agree that the Mermaid library is not as well implemented as I would like, but it is the most powerful in-browser UML library that I known of. You can render UML offline with 3rd party, non Python apps like PlantUML and generate images to include.

I think with Mermaid, you have to understand what it does well and stick to that.

@squidfunk
Copy link
Owner Author

@facelessuser Interesting, I'll play around with the htmlLabels configuration. Note that this integration is still experimental and needs some work, especially the encapsulation problem. I'll continue to work on it as soon as possible.

@facelessuser
Copy link
Contributor

Not a problem. This is also one of the things I documented in my Mermaid guide: https://facelessuser.github.io/pymdown-extensions/extras/mermaid/#configuration. Just an FYI. Most known issues I've worked around and am more than happy to explain if you run into trouble.

@Vasperous
Copy link
Sponsor

Trying to incorporate this now into my docs using a dark background and I am struggling with the marker-end color. It's nearly impossible to see with my background and doesn't seem a whole lot that I can do to fix it.

@facelessuser
Copy link
Contributor

Pic?

@facelessuser
Copy link
Contributor

Possibly diagram example for copy/paste that illustrates the issue?

@Vasperous
Copy link
Sponsor

Vasperous commented Jan 30, 2021

@facelessuser here is what I have thus far:
image

sequenceDiagram
    USI->>+Registration Server:Connect
    USI->>+Registration Server:Registration Request
    Registration Server->>-USI:Registration Response
    Registration Server->>-USI:Disconnect
    USI->>+Connection Server:Connect
Loading

@facelessuser
Copy link
Contributor

You can definitely style those:

Screen Shot 2021-01-29 at 5 13 38 PM

Checkout my config: https://github.com/facelessuser/pymdown-extensions/blob/master/docs/src/markdown/_snippets/uml.txt#L5

@facelessuser
Copy link
Contributor

Keep in mind that I have a custom loader that takes care of loading the config I want, but the format of the individual configs is at least standard. I'm not sure if Material gives instructions how to setup/change the configuration, but official documentation is right here: https://mermaid-js.github.io/mermaid/#/Setup?id=mermaidapi-configuration-defaults.

@Vasperous
Copy link
Sponsor

@facelessuser thank you so much! I guess that leads to my next question which it looks like you have resolved. I was looking through the mermaid docs trying to style sequence diagram. Seeing as there an alternative how can I get pymdownx.superfences to take my configuration? Sorry for the basic question, the help is greatly appreciated!

@Vasperous
Copy link
Sponsor

@facelessuser sorry didn't see your last comment. I will give this a shot, thank you!

@squidfunk
Copy link
Owner Author

@Vasperous thanks for giving this new feature a try! As explained in the footnote, not all diagram types have been adjusted to work out of the box:

While all Mermaid.js features should work out-of-the-box, Material for MkDocs will currently only adjust the fonts and colors for flow charts, class and state diagrams. Support for further diagram types will be added gradually.

The main problem with the sequence diagram is that the sequence lines extend beyond the boxes:

Bildschirmfoto 2021-01-30 um 11 46 19

For the supported charts, we're using a transparent version of the accent color, which will not work here. I have dark mode support for the other diagram types on my list and will try to revisit it as soon as possible. Also, the Shadow DOM approach still needs to be added. For the time being, the integration is still considered experimental. Did you have any further troubles making it work?

@Vasperous
Copy link
Sponsor

@squidfunk not sure how I missed the footnote! Thank you for the help and support. I will wait for the official support in that case :) Thank you!

@kratsg
Copy link

kratsg commented Feb 10, 2021

to sort of get this to automatically work for the theming (if you don't pick a particular theme and use prefers) -- I have this addition to the mermaid2 plugin

plugins:
  - mermaid2:
      arguments:
          theme: |
            ^(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'

which will theme it correspondingly.

@framesetter99
Copy link
Sponsor

Yes, I'm using Windows. The font issue seems to be caused by my local config, so ignore that. But the rendering issue is definitely a thing, tested it with a minimum setup on Chrome 87 Windows:

For me it makes a difference to use flowchart type in mermaid in contrast to graph.
With flowchart I do not see the issues in Chrome.
https://mermaid-js.github.io/mermaid/#/flowchart?id=beta-flowcharts

And as already pointed out, seems to be something on the mermaid side.
I can see the same effect with their documentation.

@facelessuser
Copy link
Contributor

For me it makes a difference to use flowchart type in mermaid in contrast to graph.
With flowchart, I do not see the issues in Chrome.
mermaid-js.github.io/mermaid/#/flowchart?id=beta-flowcharts

Yeah, they seem to be re-writing some of their chart types, but I'm not sure they are completely bug free, but at least maybe from this styling issue 🙂. They are a bit inconsistent in how each chart type is rendered, so I think the rewrite of some of these charts is to bring some unity in approach. I hope that is the case at least. But there is still some flaws depending on the chart, check out impractical diagrams cases here: https://facelessuser.github.io/pymdown-extensions/extras/mermaid/#practical-diagrams. Hopefully, some of the impractical ones will get re-written 🙃.

@include
Copy link

include commented Feb 23, 2021

Hi,

Do you have any idea when Sequence diagrams and Gantt charts will work out-of-the-box? :)

thanks

@squidfunk
Copy link
Owner Author

I'm currently in the process of migrating Insiders over to v7 and will tackle the Mermaid integration in the next weeks! Sorry for the inconvenience.

@include
Copy link

include commented Feb 23, 2021

Thank you very much @squidfunk

@squidfunk
Copy link
Owner Author

Insiders 2.11.0 adds the following things:

  1. Mermaid diagrams are now rendered in a shadow root (as @facelessuser suggested), so ids are always unique.
  2. Support for sequence and entity-relationship diagrams just landed, which means they adapt to the colors and fonts set in mkdocs.yml

For now, I'll pass on Git charts, Gant charts, Pie Charts and User Journeys, as they're rather impractical to use, but maybe we'll add support later on if necessary. Also, offline support (= browsing from file://) is an edge case I'm not considering at the moment, but maybe later on. For now, I'd consider this issue done.

@squidfunk
Copy link
Owner Author

Documentation with demos is here:
https://squidfunk.github.io/mkdocs-material/reference/diagrams/

@squidfunk squidfunk changed the title Native Mermaid.js integration (currently experimental) Native Mermaid.js integration Jul 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
change request Issue requests a new feature or improvement
Projects
None yet
Development

No branches or pull requests

7 participants