diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index 499c7cd9a0f..e2d8499d75a 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -49,6 +49,7 @@ + diff --git a/src/BootstrapBlazor.Server/Components/Pages/Coms.razor b/src/BootstrapBlazor.Server/Components/Pages/Coms.razor index f42765c165a..9b01b6ec053 100644 --- a/src/BootstrapBlazor.Server/Components/Pages/Coms.razor +++ b/src/BootstrapBlazor.Server/Components/Pages/Coms.razor @@ -120,6 +120,7 @@ + diff --git a/src/BootstrapBlazor.Server/Components/Samples/Mermaids.razor b/src/BootstrapBlazor.Server/Components/Samples/Mermaids.razor new file mode 100644 index 00000000000..35a3b084ae2 --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Mermaids.razor @@ -0,0 +1,30 @@ +@page "/mermaid" +@inject IStringLocalizer Localizer + +

@Localizer["MermaidTitle"]

+ +

@Localizer["MermaidDescription"]

+ + + + +
+
+
+ @foreach (var diagram in Diagrams) + { + + } +
+ + + + + + + + diff --git a/src/BootstrapBlazor.Server/Components/Samples/Mermaids.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Mermaids.razor.cs new file mode 100644 index 00000000000..1a73ac981ce --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Samples/Mermaids.razor.cs @@ -0,0 +1,211 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +using System.ComponentModel; + +namespace BootstrapBlazor.Server.Components.Samples; + +/// +/// MermaidViews +/// +public partial class Mermaids +{ + private MermaidType Options { get; set; } = new(); + + private string CustomStyleString { get; } = """ + flowchart LR + A[start] --> + B{Whether the conditions are met?} + B -- yes --> C[Perform tasks 1] + B -- no --> D[Perform tasks 2] + C --> E{Condition checks} + D --> E + E -- The conditions are established --> F[Sub-processes] + F --> G[Complete the subprocess] + E -- The condition failed --> H[Error handling] + H --> I[Keep a log] + G --> J[end] + I --> J + + style A fill:#ffe0b3,stroke:#ff9900,stroke-width:2px; + style B fill:#ffcccc,stroke:#ff0000,stroke-width:2px; + style C fill:#e6ffcc,stroke:#009933,stroke-width:2px; + style D fill:#cce6ff,stroke:#0033cc,stroke-width:2px; + style E fill:#ffccff,stroke:#9900cc,stroke-width:2px; + style F fill:#ccccff,stroke:#3300cc,stroke-width:2px; + style G fill:#b3ffff,stroke:#00cccc,stroke-width:2px; + style H fill:#ffd9b3,stroke:#ff6600,stroke-width:2px; + style I fill:#d9d9d9,stroke:#808080,stroke-width:2px; + style J fill:#ccffcc,stroke:#009900,stroke-width:2px; + + linkStyle 0 stroke:#00cc00,stroke-width:2px; + linkStyle 1 fill:#006600,stroke:#009933,stroke-width:2px,font-size:12px; + linkStyle 2 fill:#990000,stroke:#ff3300,stroke-width:2px,font-size:12px; + linkStyle 3 stroke:#ff33cc,stroke-width:2px; + linkStyle 4 stroke:#cc33ff,stroke-width:2px; + linkStyle 5 stroke:#33ccff,stroke-width:2px; + linkStyle 6 stroke:#ff6600,stroke-width:2px,stroke-dasharray: 10,10; + linkStyle 7 stroke:#999999,stroke-width:2px; + linkStyle 8 stroke:#009900,stroke-width:2px; + linkStyle 9 stroke:#ff6600,stroke-width:2px; + """; + + private Dictionary Diagrams { get; } = new Dictionary + { + { MermaidType.None, + """ + flowchart LR + + A[Hard] -->|Text| B(Round) + B --> C{Decision} + C -->|One| D[Result 1] + C -->|Two| E[Result 2] + """ + }, + { MermaidType.Flowchart, + """ + A[Start] --> B{Is it working?} + B -- Yes --> C[Keep going] + B -- No --> D[Fix it] + D --> B + """ + }, + { MermaidType.SequenceDiagram, + """ + participant Alice + participant Bob + Alice->>John: Hello John, how are you? + loop HealthCheck + John->>John: Fight against hypochondria + end + Note right of John: Rational thoughts
prevail! + John-->>Alice: Great! + John->>Bob: How about you? + Bob-->>John: Jolly good! + """ + }, + { MermaidType.ClassDiagram, + """ + Class01 <|-- AveryLongClass : Cool + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + """ + }, + { MermaidType.StateDiagram, + """ + [*] --> Still + Still --> [*] + + Still --> Moving + Moving --> Still + Moving --> Crash + Crash --> [*] + """ + }, + { MermaidType.ErDiagram, + """ + CUSTOMER ||--o{ ORDER : places + ORDER ||--|{ LINE-ITEM : contains + CUSTOMER }|..|{ DELIVERY-ADDRESS : uses + """ + }, + { MermaidType.Journey, + """ + section Go to work + Make tea: 5: Me + Go upstairs: 3: Me + Do work: 1: Me, Cat + section Go home + Go downstairs: 5: Me + Sit down: 5: Me + """ + }, + { MermaidType.Gantt, + """ + dateFormat YYYY-MM-DD + excludes weekdays 2014-01-10 + + section A section + Completed task :done, des1, 2014-01-06,2014-01-08 + Active task :active, des2, 2014-01-09, 3d + Future task : des3, after des2, 5d + Future task2 : des4, after des3, 5d + """ + }, + { MermaidType.Pie, + """ + "Dogs" : 386 + "Cats" : 85 + "Rats" : 15 + """ + } + }; + + /// + /// GetAttributes + /// + /// + private AttributeItem[] GetAttributes() => + [ + new() + { + Name = "DiagramString", + Description = Localizer["DiagramString"], + Type = "string", + ValueList = " — ", + DefaultValue = " — " + }, + + new() + { + Name = "Title", + Description = Localizer["Title"], + Type = "string", + ValueList = " — ", + DefaultValue = " — " + }, + new() + { + Name = "Direction", + Description = Localizer["Direction"], + Type = "MermaidDirection", + ValueList = "TB / BT / LR / RL", + DefaultValue = "TB" + }, + new() + { + Name = "Type", + Description = Localizer["Type"], + Type = "MermaidType", + ValueList = "None / Flowchart / SequenceDiagram / ClassDiagram / StateDiagram / ErDiagram / Journey / Gantt / Pie", + DefaultValue = "None" + } + ]; + + /// + /// Methods + /// + /// + private MethodItem[] GetMethods() => + [ + new() + { + Name = "ExportBase64MermaidAsync", + Description = Localizer["ExportBase64Mermaid"], + Parameters = " — ", + ReturnValue = "string" + } + ]; +} diff --git a/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs b/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs index f97d3f60ad3..c93338281a2 100644 --- a/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs +++ b/src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs @@ -657,6 +657,11 @@ void AddData(DemoMenuItem item) Url = "mind-map" }, new() + { + Text = Localizer["Mermaid"], + Url = "mermaid" + }, + new() { Text = Localizer["PdfReader"], Url = "pdf-reader" diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index cf20ef6f8a1..664730ddd15 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -1696,6 +1696,7 @@ "FileViewerText": "FileViewer", "WebSerialText": "SerialService", "MindMapText": "MindMap", + "MermaidText": "Mermaid", "WebSpeechText": "WebSpeech", "ImageCropperText": "ImageCropper", "BarcodeGeneratorText": "BarcodeGenerator" @@ -4768,6 +4769,7 @@ "QueryBuilder": "QueryBuilder", "SerialService": "ISerialService", "MindMap": "Mind Map", + "Mermaid": "Mermaid", "Marquee": "Marquee", "Stack": "Stack", "Segmented": "Segmented", @@ -6359,6 +6361,15 @@ "Layout": "Layout", "Theme": "Theme" }, + "BootstrapBlazor.Server.Components.Samples.Mermaids": { + "MermaidTitle": "Mermaid", + "MermaidDescription": "This component renders Markdown-inspired text definitions to dynamically create and modify diagrams.", + "MermaidNormalTitle": "Basic usage", + "NormalIntro": "Mermaid basic style", + "MermaidStyleTitle": "Custom styles", + "MermaidStyleIntro": "", + "MermaidType": "Type" + }, "BootstrapBlazor.Server.Components.Samples.Speeches.WebSpeeches": { "WebSpeechTitle": "Web Speech Api", "WebSpeechSubTitle": "Provide speech recognition/synthesis services using browser interface functions", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 9dbb3e0df12..2b11d8fb889 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -1696,6 +1696,7 @@ "FileViewerText": "文件预览器 FileViewer", "WebSerialText": "串口服务 ISerialService", "MindMapText": "思维导图 Mind Map", + "MermaidText": "图表工具 Mermaid", "WebSpeechText": "语音识别/合成 WebSpeech", "ImageCropperText": "图像裁剪 ImageCropper", "BarcodeGeneratorText": "条码生成器 BarcodeGenerator" @@ -4768,6 +4769,7 @@ "QueryBuilder": "条件生成器 QueryBuilder", "WebSerial": "串口服务 ISerialService", "MindMap": "思维导图 MindMap", + "Mermaid": "图表工具 Mermaid", "Marquee": "文字滚动 Marquee", "Stack": "堆叠布局 Stack", "Segmented": "分段控制器 Segmented", @@ -6359,6 +6361,15 @@ "Layout": "布局", "Theme": "主题" }, + "BootstrapBlazor.Server.Components.Samples.Mermaids": { + "MermaidTitle": "Mermaid 构图工具", + "MermaidDescription": "本组件可渲染 Markdown 启发的文本定义以动态创建和修改图表。", + "MermaidNormalTitle": "基本用法", + "MermaidNormalIntro": "Mermaid 基本样式", + "MermaidStyleTitle": "增加自定义样式", + "MermaidStyleIntro": "", + "MermaidType": "图表类型" + }, "BootstrapBlazor.Server.Components.Samples.Speeches.WebSpeeches": { "WebSpeechTitle": "Web Speech Api 网页原生语音处理 API", "WebSpeechSubTitle": "使用浏览器接口功能提供语音识别/合成服务", diff --git a/src/BootstrapBlazor.Server/docs.json b/src/BootstrapBlazor.Server/docs.json index 87b91f4b556..cd8baaa8c40 100644 --- a/src/BootstrapBlazor.Server/docs.json +++ b/src/BootstrapBlazor.Server/docs.json @@ -111,6 +111,7 @@ "menu": "Menus", "message": "Messages", "mind-map": "MindMaps", + "mermaid": "Mermaids", "modal": "Modals", "mouse-follower": "MouseFollowers", "multi-select": "MultiSelects", diff --git a/src/BootstrapBlazor.Server/wwwroot/images/Mermaid.png b/src/BootstrapBlazor.Server/wwwroot/images/Mermaid.png new file mode 100644 index 00000000000..24e91a7a384 Binary files /dev/null and b/src/BootstrapBlazor.Server/wwwroot/images/Mermaid.png differ