在 .NET 5.0 中使用 Blazor WebAssembly App 渲染美人鱼图

Render Mermaid diagram with Blazor WebAssembly App in .NET 5.0

我在此处遵循 Deploying Mermaid 的指南:

https://mermaid-js.github.io/mermaid/#/?id=deploying-mermaid

直接在codepen上使用即可:

https://codepen.io/Ogglas/pen/MWjWNxR

mermaid.initialize({
  startOnLoad:true
});

<div class="mermaid">
    graph LR
        A[Client] --- B[Load Balancer]
        B-->C[Server01]
        B-->D(Server02)
</div>

为了在 Blazor 中启用它,我编辑了 BlazorApp.Client -> wwwroot -> index.html 并在 <script src="_framework/blazor.webassembly.js"></script>.

下面添加了以下内容
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>

然后我使用以下值编辑了 Index.razor

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="mermaid">
    graph LR
        A[Client] --- B[Load Balancer]
        B-->C[Server01]
        B-->D(Server02)
</div>

然而,这并没有渲染美人鱼图。我做错了什么?

现在通过单击按钮解决了它:

Index.razor:

@page "/"
@inject IJSRuntime JSRuntime

<h1>Hello, world!</h1>

Welcome to your new app.

<div>
    <button @onclick="TriggerClick">
        Trigger Mermaid diagram render
    </button>
</div>

<div>
    Graph:
    <div id="output"></div>
</div>

<SurveyPrompt Title="How is Blazor working for you?" />

@code {

    public async Task TriggerClick()
    {
        await JSRuntime.InvokeVoidAsync("renderMermaidDiagram");
    }
}

index.html,将此添加到 <head> 部分:

<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
    window.renderMermaidDiagram = () => {
        var output = document.getElementById("output");
        var input = "graph LR \n" +
            "A[Client] --- B[Load Balancer] \n" +
            "B-->C[Server01] \n" +
            "B-->D(Server02) \n";
        mermaid.mermaidAPI.render('theGraph', input, function (svgCode) {
            output.innerHTML = svgCode;
        });
    }
</script>

看起来像这样:

请注意,某些美人鱼教程使用的是过时版本,不适用于最新版本。

来源:

https://mermaid-js.github.io/mermaid/#/Tutorials?id=mermaid-with-html

https://docs.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0

对于服务器端,我也有一些渲染问题。 (仍在调查原因,以便我可以解决此问题)

服务器端现状:

参考美人鱼的js文件在你的页面中添加html这部分

<div class="mermaid">
   graph LR
   A[Client] --- B[Load Balancer]
   B-->C[Server01]
   B-->D(Server02)
</div>

这在预渲染部分呈现正常,但第二部分在应用程序引导时再次呈现纯文本。

您可以通过将其添加到页面的“@code”部分来测试它

protected override async Task OnInitializedAsync()
{
   string t = "Set breakpoint on this line, this will be hit 2 times";
}

奇怪的是,如果你添加或不添加“初始化美人鱼的部分”,我会得到相同的行为结果。

mermaid.initialize({
        startOnLoad: true
    });

客户端

我发现这个客户端 nuget 解决方案运行流畅

https://github.com/TrueCommerce/MermaidJS.Blazor

美人鱼(8.11.5 用于测试)+ Blazor 服务端解决方案(未在客户端测试):

我将 JS 互操作放在它自己的对象和文件中,例如blazor-helper.js:

var JsFunctions = window.JsFunctions || {};
JsFunctions = {
    MermaidInitialize: function() {
        mermaid.initialize({
            startOnLoad: true,
            securityLevel: "loose",
            // Other options.
          });
    },

    MermaidRender: function() {
        mermaid.init();
    }
};

显然,不抽象也可以逃避 mermaid.init(),但我认为它提供了清晰度。

然后在您的 blazor 代码中(启用了可为空的 c#9 语法):

    [Inject]
    protected IJSRuntime? JsRuntime { get; set; } = null;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if(this.JsRuntime is not null)
        {
            if(firstRender)
            {
                await this.JsRuntime.InvokeVoidAsync("JsFunctions.MermaidInitialize");
            }

            await this.JsRuntime.InvokeVoidAsync("JsFunctions.MermaidRender");
        }
    }