在 .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 解决方案运行流畅
美人鱼(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");
}
}
我在此处遵循 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 解决方案运行流畅
美人鱼(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");
}
}