diff --git a/.build/jsonSchema.ts b/.build/jsonSchema.ts index 6fd8ca3f54..50b9ff097b 100644 --- a/.build/jsonSchema.ts +++ b/.build/jsonSchema.ts @@ -25,6 +25,7 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [ 'sankey', 'block', 'packet', + 'architecture', ] as const; /** diff --git a/.changeset/nice-flowers-yawn.md b/.changeset/nice-flowers-yawn.md new file mode 100644 index 0000000000..31c0e81aff --- /dev/null +++ b/.changeset/nice-flowers-yawn.md @@ -0,0 +1,8 @@ +--- +"mermaid": minor +"@mermaid-js/docs": patch +--- + +New Diagram: Architecture + +Adds architecture diagrams which allows users to show relations between services. diff --git a/.cspell/code-terms.txt b/.cspell/code-terms.txt index d0e40e8f21..8e4c02261a 100644 --- a/.cspell/code-terms.txt +++ b/.cspell/code-terms.txt @@ -55,6 +55,7 @@ GENERICTYPE getBoundarys grammr graphtype +halign iife interp introdcued @@ -66,6 +67,7 @@ Kaufmann keyify LABELPOS LABELTYPE +layoutstop lcov LEFTOF Lexa diff --git a/.cspell/libraries.txt b/.cspell/libraries.txt index 3bfec1d5f4..ad0e3e7011 100644 --- a/.cspell/libraries.txt +++ b/.cspell/libraries.txt @@ -24,6 +24,7 @@ Doctave DokuWiki dompurify elkjs +fcose fontawesome Foswiki Gitea diff --git a/cypress/integration/rendering/architecture.spec.ts b/cypress/integration/rendering/architecture.spec.ts new file mode 100644 index 0000000000..4599319793 --- /dev/null +++ b/cypress/integration/rendering/architecture.spec.ts @@ -0,0 +1,174 @@ +import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; + +describe('architecture diagram', () => { + it('should render a simple architecture diagram with groups', () => { + imgSnapshotTest( + `architecture + group api(cloud)[API] + + service db(database)[Database] in api + service disk1(disk)[Storage] in api + service disk2(disk)[Storage] in api + service server(server)[Server] in api + service gateway(internet)[Gateway] + + db L--R server + disk1 T--B server + disk2 T--B db + server T--B gateway + ` + ); + }); + it('should render an architecture diagram with groups within groups', () => { + imgSnapshotTest( + `architecture + group api[API] + group public[Public API] in api + group private[Private API] in api + + service serv1(server)[Server] in public + + service serv2(server)[Server] in private + service db(database)[Database] in private + + service gateway(internet)[Gateway] in api + + serv1 B--T serv2 + serv2 L--R db + serv1 L--R gateway + ` + ); + }); + it('should render an architecture diagram with the fallback icon', () => { + imgSnapshotTest( + `architecture + service unknown(iconnamedoesntexist)[Unknown Icon] + ` + ); + }); + it('should render an architecture diagram with split directioning', () => { + imgSnapshotTest( + `architecture + service db(database)[Database] + service s3(disk)[Storage] + service serv1(server)[Server 1] + service serv2(server)[Server 2] + service disk(disk)[Disk] + + db L--R s3 + serv1 L--T s3 + serv2 L--B s3 + serv1 T--B disk + ` + ); + }); + it('should render an architecture diagram with directional arrows', () => { + imgSnapshotTest( + `architecture + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC (L--R) servL + servC (R--L) servR + servC (T--B) servT + servC (B--T) servB + + servL (T--L) servT + servL (B--L) servB + servR (T--R) servT + servR (B--R) servB + ` + ); + }); + it('should render an architecture diagram with group edges', () => { + imgSnapshotTest( + `architecture + group left_group(cloud)[Left] + group right_group(cloud)[Right] + group top_group(cloud)[Top] + group bottom_group(cloud)[Bottom] + group center_group(cloud)[Center] + + service left_disk(disk)[Disk] in left_group + service right_disk(disk)[Disk] in right_group + service top_disk(disk)[Disk] in top_group + service bottom_disk(disk)[Disk] in bottom_group + service center_disk(disk)[Disk] in center_group + + left_disk{group} (R--L) center_disk{group} + right_disk{group} (L--R) center_disk{group} + top_disk{group} (B--T) center_disk{group} + bottom_disk{group} (T--B) center_disk{group} + ` + ); + }); + it('should render an architecture diagram with edge labels', () => { + imgSnapshotTest( + `architecture + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC L-[Label]-R servL + servC R-[Label]-L servR + servC T-[Label]-B servT + servC B-[Label]-T servB + + servL T-[Label]-L servT + servL B-[Label]-L servB + servR T-[Label]-R servT + servR B-[Label]-R servB + ` + ); + }); + it('should render an architecture diagram with simple junction edges', () => { + imgSnapshotTest( + `architecture + service left_disk(disk)[Disk] + service top_disk(disk)[Disk] + service bottom_disk(disk)[Disk] + service top_gateway(internet)[Gateway] + service bottom_gateway(internet)[Gateway] + junction juncC + junction juncR + + left_disk R--L juncC + top_disk B--T juncC + bottom_disk T--B juncC + juncC R--L juncR + top_gateway B--T juncR + bottom_gateway T--B juncR + ` + ); + }); + it('should render an architecture diagram with complex junction edges', () => { + imgSnapshotTest( + `architecture + group left + group right + service left_disk(disk)[Disk] in left + service top_disk(disk)[Disk] in left + service bottom_disk(disk)[Disk] in left + service top_gateway(internet)[Gateway] in right + service bottom_gateway(internet)[Gateway] in right + junction juncC in left + junction juncR in right + + left_disk R--L juncC + top_disk B--T juncC + bottom_disk T--B juncC + + + top_gateway (B--T juncR + bottom_gateway (T--B juncR + + juncC{group} R--L) juncR{group} + ` + ); + }); +}); diff --git a/demos/architecture.html b/demos/architecture.html new file mode 100644 index 0000000000..fc65b6bebf --- /dev/null +++ b/demos/architecture.html @@ -0,0 +1,309 @@ + + +
+ + ++ architecture-beta + group api(cloud)[API] + + service db(database)[Database] in api + service disk1(disk)[Storage] in api + service disk2(disk)[Storage] in api + service server(server)[Server] in api + service gateway(internet)[Gateway] + + db:L -- R:server + disk1:T -- B:server + disk2:T -- B:db + server:T -- B:gateway ++
+ architecture-beta + group api[API] + group public[Public API] in api + group private[Private API] in api + + + service serv1(server)[Server] in public + + + service serv2(server)[Server] in private + service db(database)[Database] in private + + service gateway(internet)[Gateway] in api + + serv1:B -- T:serv2 + + serv2:L -- R:db + + serv1:L -- R:gateway ++
+ architecture-beta + service unknown(iconnamedoesntexist)[Unknown Icon] ++
+ architecture-beta + service db(database)[Database] + service s3(disk)[Storage] + service serv1(server)[Server 1] + service serv2(server)[Server 2] + service disk(disk)[Disk] + + db:L -- R:s3 + serv1:L -- T:s3 + serv2:L -- B:s3 + serv1:T -- B:disk ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L <--> R:servL + servC:R <--> L:servR + servC:T <--> B:servT + servC:B <--> T:servB + + servL:T <--> L:servT + servL:B <--> L:servB + servR:T <--> R:servT + servR:B <--> R:servB ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L <--> R:servL + servC:R <--> L:servR + servC:T <--> B:servT + servC:B <--> T:servB + + servT:L <--> T:servL + servB:L <--> B:servL + servT:R <--> T:servR + servB:R <--> B:servR ++
+ architecture-beta + group left_group(cloud)[Left] + group right_group(cloud)[Right] + group top_group(cloud)[Top] + group bottom_group(cloud)[Bottom] + group center_group(cloud)[Center] + + service left_disk(disk)[Disk] in left_group + service right_disk(disk)[Disk] in right_group + service top_disk(disk)[Disk] in top_group + service bottom_disk(disk)[Disk] in bottom_group + service center_disk(disk)[Disk] in center_group + + left_disk{group}:R <--> L:center_disk{group} + right_disk{group}:L <--> R:center_disk{group} + top_disk{group}:B <--> T:center_disk{group} + bottom_disk{group}:T <--> B:center_disk{group} ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L -[Label]- R:servL + servC:R -[Label]- L:servR + servC:T -[Label]- B:servT + servC:B -[Label]- T:servB + + servL:T -[Label]- L:servT + servL:B -[Label]- L:servB + servR:T -[Label]- R:servT + servR:B -[Label]- R:servB ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L -[Label that is Long]- R:servL + servC:R -[Label that is Long]- L:servR + servC:T -[Label that is Long]- B:servT + servC:B -[Label that is Long]- T:servB + + servL:T -[Label that is Long]- L:servT + servL:B -[Label that is Long]- L:servB + servR:T -[Label that is Long]- R:servT + servR:B -[Label that is Long]- R:servB ++ +
+ architecture-beta + service left_disk(disk)[Disk] + service top_disk(disk)[Disk] + service bottom_disk(disk)[Disk] + service top_gateway(internet)[Gateway] + service bottom_gateway(internet)[Gateway] + junction juncC + junction juncR + + left_disk:R -- L:juncC + top_disk:B -- T:juncC + bottom_disk:T -- B:juncC + juncC:R -- L:juncR + top_gateway:B -- T:juncR + bottom_gateway:T -- B:juncR ++
+ architecture-beta + group left + group right + service left_disk(disk)[Disk] in left + service top_disk(disk)[Disk] in left + service bottom_disk(disk)[Disk] in left + service top_gateway(internet)[Gateway] in right + service bottom_gateway(internet)[Gateway] in right + junction juncC in left + junction juncR in right + + left_disk:R -- L:juncC + top_disk:B -- T:juncC + bottom_disk:T -- B:juncC + + + top_gateway:B <-- T:juncR + bottom_gateway:T <-- B:juncR + + juncC{group}:R --> L:juncR{group} ++
+ architecture-beta + service s3(aws:s3)[Cloud Store] + service ec2(aws:ec2)[Server] + service wave(aws:wavelength)[Wave] + service droplet(do:droplet)[Droplet] + service repo(gh:github)[Repository] ++ + + + diff --git a/demos/index.html b/demos/index.html index 61a86a2aa0..07b51a3136 100644 --- a/demos/index.html +++ b/demos/index.html @@ -88,6 +88,9 @@