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

Add mermaid support in markdown #185

Merged
merged 5 commits into from
Sep 13, 2023
Merged

Add mermaid support in markdown #185

merged 5 commits into from
Sep 13, 2023

Conversation

Steve-Mcl
Copy link
Contributor

@Steve-Mcl Steve-Mcl commented Sep 10, 2023

Adds mermaid support by way of a ```mermaid code fence.

Shortcomings

This 1st implementation has some short comings. Some will not be so easy to overcome without some kind of custom renderer and/or an AST

  • Charts are static only at this time
  • Elements in the mermaid charts are not reactive
  • Cannot provide mermaid definition dynamically via msg
  • Mermaid theme setting is not exposed to user (though classes can be set up in a template style or the graph definition and used to colourise the output)
  • does not detect dark mode / not mapped to the vue instance to match vue light/dark mode

Demo of code highlights and mermaid in one page

chrome_gtGgUBbgzi

Demo flow used for above image

[{"id":"4e6b79383a29a265","type":"ui-markdown","z":"1ca1817447127d22","group":"e8bfd3d67a748cb0","name":"mermaid","order":1,"width":0,"height":0,"content":"### Markdown with mermaid\n\n```mermaid\nflowchart LR\n    A:::foo & B:::bar --> C:::foobar\n    classDef foo stroke:#f00\n    classDef bar stroke:#0f0\n    classDef foobar stroke:#00f\n```\n\n```mermaid\n%%{init: { 'width':150, 'theme':'dark' } }%%\ntimeline\n    title History of Social Media Platform\n    2002 : LinkedIn\n    2004 : Facebook\n         : Google\n    2005 : Youtube\n    2006 : Twitter\n```    \n\n```mermaid\n    gantt\n      dateFormat  YYYY-MM-DD\n\n      section Clickable\n      See some jokes         :active, cl1, 2014-01-07, 3d\n      Alert something         :cl2, after cl1, 3d\n\n      click cl1 href \"https://pun.me/jokes/funny/\"\n      click cl2 call window.alert(\"test1\", \"test2\", test3)\n```\n```mermaid\nsequenceDiagram\n    Alice ->> Bob: Hello Bob, have you heard?\n    Bob--x Alice: Thanks, very funny\n    Alice->Bob: Yes... I thought so 🤣\n```","className":"","x":900,"y":480,"wires":[[]]},{"id":"a3f3fac9583a21de","type":"ui-markdown","z":"1ca1817447127d22","group":"75131c1651916e26","name":"code","order":2,"width":0,"height":0,"content":"### Markdown with code\n\n```js\n// javascript\nconst greeting = \"hello\"\nconst feeling = \"{{msg?.payload || 'fine'}}\"\nconsole.log(greeting + ' world, I am feeling ' + feeling)\n/* hello world */\n```\n\n```yaml\n# yaml\noptions:\n    greeting: hello\n    feeling: \"{{msg?.payload || 'fine'}}\"\n    image: wave.png\n    # image: adios.png\n```\n\n```html\n<!-- html -->\n<h1>hello world</h1>\n<h2>welcome to earth</h2>\n<div>feeling {{msg?.payload || 'fine'}}</div>\n```\n\n\n","className":"","x":890,"y":520,"wires":[[]]},{"id":"50fa079a034f82d1","type":"inject","z":"1ca1817447127d22","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"great","payloadType":"str","x":710,"y":480,"wires":[["a3f3fac9583a21de"]]},{"id":"d990899e49d2dc93","type":"inject","z":"1ca1817447127d22","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sick as a parrot","payloadType":"str","x":700,"y":520,"wires":[["a3f3fac9583a21de"]]},{"id":"e8bfd3d67a748cb0","type":"ui-group","name":"Group 3b","page":"57b37ea2bd364116","width":"6","height":"1","order":-1,"disp":true},{"id":"75131c1651916e26","type":"ui-group","name":"Group3","page":"57b37ea2bd364116","width":"6","height":"1","order":"-1","disp":true},{"id":"57b37ea2bd364116","type":"ui-page","name":"Page 3","ui":"ID-BASE-1","path":"/","layout":"grid","theme":"4bff2b59c4c518e1"},{"id":"ID-BASE-1","type":"ui-base","name":"Dashboard","path":"/dashboard"},{"id":"4bff2b59c4c518e1","type":"ui-theme","name":"Another Theme","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"}}]

@Steve-Mcl Steve-Mcl linked an issue Sep 10, 2023 that may be closed by this pull request
@joepavitt
Copy link
Collaborator

What's the TLDR on why it's so difficult to make the Mermaid content dynamic/reactive?

@Steve-Mcl
Copy link
Contributor Author

What's the TLDR on why it's so difficult to make the Mermaid content dynamic/reactive?

Mostly because it generates a an SVG. We would need to somehow inject bound elements into the SVG (I think?) - not impossible, but tricky. I spent far too long Sunday & failed miserably. Maybe a fresh set of eyes can solve it?

As for dynamically generating a mermaid chart by sending full markdown, that might be easier to achieve.

@joepavitt
Copy link
Collaborator

joepavitt commented Sep 12, 2023

I have dynamic content working with a trick found here:

Screen.Recording.2023-09-12.at.19.57.21.mov

It doesn't like it when the content of msg.payload is empty, so need to do a little more digging tomorrow, but thought I'd share progress, and also need to scope the .mermaid selector a little better.

@joepavitt
Copy link
Collaborator

Cleaner demo by wiring it to a Slider:

Screen.Recording.2023-09-13.at.08.28.20.mov

@joepavitt
Copy link
Collaborator

If we try to inject something that mermaid doesn't like (e.g. a string when we need a number), we will see the following:

Screenshot 2023-09-13 at 08 30 58

@Steve-Mcl
Copy link
Contributor Author

I have dynamic content working

See, a fresh set of eyes never hurt :D
Good stuff Joe.

If we try to inject something that mermaid doesn't like (e.g. a string when we need a number), we will see the following:

Screenshot 2023-09-13 at 08 30 58

This is to be expected and is what happens on their own site.


Q:

Can you confirm:

  • can have values reactive with {{ msg.payload }} as part of text/value/graph definition inside the mermaid code fence?
  • can post a complete new mermaid diagram via msg e.g. msg.payload = '```mermaid\nsequenceDiagram\n diagram_def\n diagram_def\n```'?
  • can post the internals of a mermaid code fence e.g. msg.payload = 'sequenceDiagram\n diagram_def\n diagram_def'?

@joepavitt
Copy link
Collaborator

can have values reactive with {{ msg.payload }} as part of text/value/graph definition inside the mermaid code fence?

This is the definition for the chart above:

Screenshot 2023-09-13 at 08 45 22

@joepavitt
Copy link
Collaborator

can post the internals of a mermaid code fence e.g. msg.payload = 'sequenceDiagram\n diagram_def\n diagram_def'?

Yes

Screen.Recording.2023-09-13.at.08.54.22.mov

@joepavitt
Copy link
Collaborator

can post a complete new mermaid diagram via msg e.g. msg.payload = 'mermaid\nsequenceDiagram\n diagram_def\n diagram_def\n'?

No, it just renders the raw text, I'm guessing because the mermaid.initialize(config) is run before the existence of any mermaid injection. Whilst we could look to add this in, I'm not sure it's worth the effort, given that injection of the internals does work

@joepavitt joepavitt merged commit eabcf56 into main Sep 13, 2023
1 check passed
@joepavitt joepavitt deleted the markdown-mermaid branch September 13, 2023 08:53
@sieteunoseis
Copy link

You still get "Syntax error in text" for dynamic mermaid content if you have multiple pages configured and you switch between them.

@joepavitt
Copy link
Collaborator

Thanks @sieteunoseis - I've raised the issue for tracking here: #263 - will take a look soon.

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

Successfully merging this pull request may close these issues.

Support Mermaid Charts in ui-markdown
3 participants