MermaidJS.Blazor icon indicating copy to clipboard operation
MermaidJS.Blazor copied to clipboard

SVG transform

Open johankson opened this issue 3 years ago • 4 comments

I played around with adding a SVG transform attribute thingy

<MermaidDiagram Definition="@diagramDefinition" OnClick="OnClickNode" SvgTransform="SvgTransform" />

so that one can intercept the SVG and make modifications to it. Fairly simple.

private string SvgTransform(string svg)
{
    return svg.Replace(">A<", "><font color='red'>A</font><");
}

And in the interop file

  window.mermaid.mermaidAPI.render(`${componentId}-svg`, definition, async (svg, bind) => { // Made this async
                svg = await componentRef.invokeMethodAsync("OnSvgCreated", svg); // Added this
                

And the component

[JSInvokable]
public async Task<string> OnSvgCreated(string svg)
{
    if (SvgTransform != null)
    {
        svg = SvgTransform(svg);
    }

    return svg;
}

Are you interested in stuff like this? If you are I can clean it up and make a PR for it. I also created a demo for Blazor Server.

I use Mermaid in a React project that I would like to port to Blazor for fun and I need to do some modifications on the SVG.

johankson avatar Apr 11 '22 21:04 johankson

Nice! I wouldn't have any problem with merging in a feature like that.

We'll probably just want to put some thought into ensuring we're only invoking the callback if the SvgTransform delegate is defined to avoid marshalling data between .NET and Javascript more often than needed. If the feature isn't being used, we don't want to impact performance for large diagrams as we'll be effectively tripling the amount of marshalling for each render.

DotJoshJohnson avatar Apr 12 '22 01:04 DotJoshJohnson

Yup! Do you want to keep it at .net 5? Should I create a server app demo as well?

I have a fork at https://github.com/johankson/MermaidJS.Blazor which should not be merged since I'm playing around a bit with it.

I'll create a new branch that is aligned with your main and work from that.

Can't give you a timeline though :)

johankson avatar Apr 12 '22 07:04 johankson

Yeah, I'd prefer to keep it on 5 unless we need to use an API exclusive to 6+.

And no worries! There were no plans for this project aside from maintenance in the near future anyway, so take your time!

DotJoshJohnson avatar Apr 12 '22 12:04 DotJoshJohnson

For reference,

This is what I'm using the SVG transform function to at the moment (while porting a React app to Blazor for fun). I need to make the messageText in a Sequence Diagram clickable, so I replace the text with an a tag and attach the onClickMermaidNode() function to it.

Again, hacky code that could be refactored, but for proof of concept, it works.

    private string SvgTransform(string svg)
    {
        var regex = new Regex("<text[a-zA-Z\"0-9=# &;:,-]*messageText[a-zA-Z\"0-9=# &;:,-]*>([a-zA-Z0-9=.?]*)</text>");
        foreach (Match match in regex.Matches(svg))
        {
            var textMatch = match.Groups[1].Value;
            var shortId = textMatch.Split("?").Last();
            var messageName = textMatch.Split("?").First();
            var link = $"<a id=\"message-{shortId}\" onclick=\"onClickMermaidNode('message-{shortId}')\" style=\"cursor: hand\">{messageName}</a>";
            svg = svg.Replace(textMatch, link);
        }
        
        return svg;
    }

johankson avatar Apr 12 '22 14:04 johankson