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

To SVG Export #146

Closed
streamich opened this issue Mar 28, 2015 · 23 comments
Closed

To SVG Export #146

streamich opened this issue Mar 28, 2015 · 23 comments
Labels

Comments

@streamich
Copy link

Is there a way to compile text to SVG? Like this:

var svg = mermaid.toSVG(text);

This is by far the most necessary function for this library. Other stuff, like including the full he library and traversing DOM on every mermaid.init() call and attaching data-processed tags to elements is really overkill, makes the library much bigger unnecessarily. The integration specifics should be left to the plugin developers...

@knsv
Copy link
Collaborator

knsv commented Mar 29, 2015

I can see how such function would be useful and I am all for making integration easier.

A bit tricky to achive though as the DOM is used when creating the SVG. Perhaps the shadow DOM could be used or some fake DOM.

There is another approach also being discussed where you instead of running init call with a list of the elements you want processed. This way will be available sooner then the toSVG function.

So I am all for this but further down the roadmap unless someone whats to help out with it.

@knsv knsv added Type: Enhancement New feature or request Contributor needed labels Mar 29, 2015
@streamich
Copy link
Author

I see. I guess, something like .render() function would be very useful, for now.

mermaid.render(text: string, el: HTMLEement);

Then we could get rid of the mermaid.init() function that really should be up to developers (or a separate module) to implement their own way of integrating the library. For example, now you include the he library for the only reason to .decode() the HTML entities in code found in class="mermaid" elements when running mermaid.init() function, which could be avoided all together with a mermaid.render() function.

@streamich
Copy link
Author

And maybe if el argument is not provided the .render() function creates its own HTMLElement and returns it:

var svg = mermaid.render(text: string): HTMLElement;

@knsv
Copy link
Collaborator

knsv commented Mar 30, 2015

I like that idea! It does need to work stand alone as well though. But it would make sense to separate the actual core of mermaid from the code that is used for the standard integration on a website. This way an API could make functionality available for integrators without the parts that are no required in that context.

graph LR
   mermaid    --> mermaidAPI
   mermaid    --> he
   mermaidAPI --> d3
   mermaidAPI --> dagre-d3

@M3kH
Copy link

M3kH commented May 12, 2015

👍 for .render();

@unindented
Copy link

Why is the DOM needed to generate the diagrams? Could it work with something like cheerio?

@streamich
Copy link
Author

@unindented I guess, because it uses D3.js to generate the SVG images.

@unindented
Copy link

@streamich But d3.js can run in node without a real DOM: https://github.com/mbostock/d3/wiki

D3 also runs on Node.js. Use npm install d3 to install, and require("d3") to load. On Node, limited DOM support is provided by JSDOM. D3 can also run within a WebWorker by creating a custom build containing only the desired (non-DOM) features.

@knsv
Copy link
Collaborator

knsv commented May 15, 2015

I think it should be possible but will need some re-work.

For instance d3.select is used in some occasions, per default the selection will look in the DOM for the element. Those needs to be redirected to the virtual DOM instead etc.

This will also simplify rendering tests.

@knsv
Copy link
Collaborator

knsv commented May 15, 2015

Did a POC using jsdom that managed to render the code. The library too quite a leap in size though so this probably not a good option in this case. We have a DOM in the browser so why mock it?

Thinking that using a shadow DOM or a hidden element in the DOM for the rendering is a better alternative. The shadow DOM seems still to have low browser support though.

That leaves us with the option of rendering the svg in a new hidden element where it will only be during the generation. Once the generation is done the svg code could be extracted from the element and returned. The element would then be removed. Not as clean us using cheerio or jsdom I guess but more practical.

Any reassons not to use this approach? If so what are the better options?

@unindented
Copy link

@knsv Because of my use case (generating graphs in node.js), I'd rather not rely on the browser for anything. Spinning up PhantomJS for each diagram is super heavy.

Could we do feature detection, where if the library is running in the browser it uses its DOM, and if not it loads jsdom? I guess d3 is doing something like that, because they don't build their distributable file with jsdom.

@unindented
Copy link

@unindented
Copy link

@knsv Ok, I found the answer. They seem to rely on the document and ownerDocument properties of nodes, instead of hardcoding things like window: d3/d3#2225

@knsv
Copy link
Collaborator

knsv commented May 16, 2015

how about this...

In the rendering code mermaid checks to see if there is a document object available.

If the document object is available it is used.
If it is not (implying serveside code) jsdom is required and used.

jsdom is put as an external dependency meaning that the code using it needs to installing via npm in that project.

@unindented
Copy link

Sounds reasonable to me. jsdom could be a dependency in the package.json, so that if I install mermaid, I don't need to do anything else.

@knsv
Copy link
Collaborator

knsv commented May 17, 2015

Ran into a pit, it seems jsdom wont to the trick either:
dagrejs/dagre-d3#46

It is tempting to start using dagre instead of dagre-d3 but that is a larger project. Will try with phantomjs just to see if it works even though it is super heavy. At least the render method will be in place.

I am open for alternatives ideas though.

@unindented
Copy link

Damn. Thank you for looking into it though.

knsv added a commit that referenced this issue May 26, 2015
…text

Updated build scripts
New way for bundling content in dist, tobe tested, currently to be considered beta
@knsv
Copy link
Collaborator

knsv commented Jun 7, 2015

A fix for this has been released in version 0.5.0. Will however open a new issue to implement the render function using phantomjs for the server side environment.

@knsv knsv closed this as completed Jun 7, 2015
@alinex
Copy link

alinex commented Jun 9, 2016

is there a solution for easy transform of test to svg on the server, now?

@ciarans
Copy link

ciarans commented Nov 4, 2017

I've got this working with https://github.com/exupero/saveSvgAsPng

@robertrita
Copy link

robertrita commented Nov 14, 2017

How to use mermaid on node.js restful api?

I'm not an expert with javascript. Below is how I did it.
expected output: .svg or .png file that I can show on the response as full path.
Please help. thanks.


const express = require('express');
const mermaidAPI = require('mermaid');

app.get('/chart', (req, res) => {
mermaidAPI.initialize({
startOnLoad: true
})
const graphDefinition = 'graph TB\na-->b'
const cb = function(svgGraph) {
console.log(svgGraph)
}
mermaidAPI.render('id1',graphDefinition,cb)

res.status(200).json('.svg or .png file path here!');
})

@tylerlong
Copy link
Collaborator

Guys, please check this project: https://github.com/mermaidjs/mermaid.cli

@tenuki
Copy link
Contributor

tenuki commented Dec 23, 2020

Guys, please check this project: https://github.com/mermaidjs/mermaid.cli

That's nice it seems to work, what isn't nice is having to relay in puppeteer just to export some svg : https://github.com/mermaid-js/mermaid-cli/blob/master/package.json#L19

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

No branches or pull requests

9 participants