TrueCommerce / MermaidJS.Blazor

A simple MermaidDiagram component for Blazor.
MIT License
27 stars 11 forks source link

SVG transform #11

Open johankson opened 2 years ago

johankson commented 2 years ago

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.

DotJoshJohnson commented 2 years ago

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.

johankson commented 2 years ago

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 :)

DotJoshJohnson commented 2 years ago

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!

johankson commented 2 years ago

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;
    }