mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-31 10:54:15 +01:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			mermaid@11
			...
			6777-er-re
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | fca17f3b10 | ||
|   | 94dfdf31b8 | ||
|   | f981d3d5b7 | ||
|   | 7139e1e5f7 | ||
|   | 299226f8c2 | 
							
								
								
									
										5
									
								
								.changeset/angry-trains-fall.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.changeset/angry-trains-fall.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | --- | ||||||
|  | 'mermaid': patch | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | fix: Make relationship-label optional in ER diagrams | ||||||
| @@ -322,6 +322,18 @@ ORDER ||--|{ LINE-ITEM : contains | |||||||
|     ); |     ); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|  |   it('should render an ER diagram  without labels also', () => { | ||||||
|  |     imgSnapshotTest( | ||||||
|  |       ` | ||||||
|  |     erDiagram | ||||||
|  |         BOOK }|..|{ AUTHOR  | ||||||
|  |         BOOK }|..|{ GENRE | ||||||
|  |         AUTHOR }|..|{ GENRE  | ||||||
|  |       `, | ||||||
|  |       { logLevel: 1 } | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   it('should render relationship labels with line breaks', () => { |   it('should render relationship labels with line breaks', () => { | ||||||
|     imgSnapshotTest( |     imgSnapshotTest( | ||||||
|       ` |       ` | ||||||
|   | |||||||
| @@ -135,6 +135,44 @@ erDiagram | |||||||
|     "This **is** _Markdown_" |     "This **is** _Markdown_" | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | #### Optional Relationship Labels | ||||||
|  |  | ||||||
|  | Starting from Mermaid version 11.11.0, the relationship label in ER diagrams is optional. You can define relationships without specifying a label, and the diagram will render correctly. | ||||||
|  |  | ||||||
|  | For example, the following is valid: | ||||||
|  |  | ||||||
|  | ```mermaid-example | ||||||
|  | erDiagram | ||||||
|  |     BOOK }|..|{ AUTHOR | ||||||
|  |     BOOK }|..|{ GENRE | ||||||
|  |     AUTHOR }|..|{ GENRE | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ```mermaid | ||||||
|  | erDiagram | ||||||
|  |     BOOK }|..|{ AUTHOR | ||||||
|  |     BOOK }|..|{ GENRE | ||||||
|  |     AUTHOR }|..|{ GENRE | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | This will show the relationships between the entities without any labels on the connecting lines. | ||||||
|  |  | ||||||
|  | You can still add a label if you want to describe the relationship: | ||||||
|  |  | ||||||
|  | ```mermaid-example | ||||||
|  | erDiagram | ||||||
|  |     BOOK }|..|{ AUTHOR : written_by | ||||||
|  |     BOOK }|..|{ GENRE : categorized_as | ||||||
|  |     AUTHOR }|..|{ GENRE : specializes_in | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ```mermaid | ||||||
|  | erDiagram | ||||||
|  |     BOOK }|..|{ AUTHOR : written_by | ||||||
|  |     BOOK }|..|{ GENRE : categorized_as | ||||||
|  |     AUTHOR }|..|{ GENRE : specializes_in | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ### Relationship Syntax | ### Relationship Syntax | ||||||
|  |  | ||||||
| The `relationship` part of each statement can be broken down into three sub-components: | The `relationship` part of each statement can be broken down into three sub-components: | ||||||
|   | |||||||
| @@ -94,6 +94,22 @@ start | |||||||
|     : 'ER_DIAGRAM' document 'EOF' { /*console.log('finished parsing');*/ } |     : 'ER_DIAGRAM' document 'EOF' { /*console.log('finished parsing');*/ } | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|  | relationship | ||||||
|  |   : ENTITY relationType ENTITY maybeRole | ||||||
|  |     { | ||||||
|  |       yy.addRelationship($1, $4, $3, $2); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  | maybeRole | ||||||
|  |   : COLON role | ||||||
|  |     { | ||||||
|  |       $$ = $2; | ||||||
|  |     } | ||||||
|  |   | /* empty */ | ||||||
|  |     { | ||||||
|  |       $$ = ''; | ||||||
|  |     }; | ||||||
|  |  | ||||||
| document | document | ||||||
| 	: /* empty */ { $$ = [] } | 	: /* empty */ { $$ = [] } | ||||||
| 	| document line {$1.push($2);$$ = $1} | 	| document line {$1.push($2);$$ = $1} | ||||||
| @@ -108,32 +124,34 @@ line | |||||||
|  |  | ||||||
|  |  | ||||||
| statement | statement | ||||||
|     : entityName relSpec entityName COLON role |     : entityName relSpec entityName maybeRole | ||||||
|       { |       { | ||||||
|           yy.addEntity($1); |           yy.addEntity($1); | ||||||
|           yy.addEntity($3); |           yy.addEntity($3); | ||||||
|           yy.addRelationship($1, $5, $3, $2); |           yy.addRelationship($1, $4, $3, $2); | ||||||
|       } |       } | ||||||
|     | entityName STYLE_SEPARATOR idList relSpec entityName STYLE_SEPARATOR idList COLON role |     | entityName STYLE_SEPARATOR idList relSpec entityName STYLE_SEPARATOR idList maybeRole | ||||||
|  |  | ||||||
|       { |       { | ||||||
|           yy.addEntity($1); |           yy.addEntity($1); | ||||||
|           yy.addEntity($5); |           yy.addEntity($5); | ||||||
|           yy.addRelationship($1, $9, $5, $4); |           yy.addRelationship($1, $8, $5, $4); | ||||||
|           yy.setClass([$1], $3); |           yy.setClass([$1], $3); | ||||||
|           yy.setClass([$5], $7); |           yy.setClass([$5], $7); | ||||||
|       } |       } | ||||||
|     | entityName STYLE_SEPARATOR idList relSpec entityName COLON role |     | entityName STYLE_SEPARATOR idList relSpec entityName maybeRole | ||||||
|  |  | ||||||
|       { |       { | ||||||
|           yy.addEntity($1); |           yy.addEntity($1); | ||||||
|           yy.addEntity($5); |           yy.addEntity($5); | ||||||
|           yy.addRelationship($1, $7, $5, $4); |           yy.addRelationship($1, $6, $5, $4); | ||||||
|           yy.setClass([$1], $3); |           yy.setClass([$1], $3); | ||||||
|       } |       } | ||||||
|     | entityName relSpec entityName STYLE_SEPARATOR idList COLON role |     | entityName relSpec entityName STYLE_SEPARATOR idList maybeRole | ||||||
|       { |       { | ||||||
|           yy.addEntity($1); |           yy.addEntity($1); | ||||||
|           yy.addEntity($3); |           yy.addEntity($3); | ||||||
|           yy.addRelationship($1, $7, $3, $2); |           yy.addRelationship($1, $6, $3, $2); | ||||||
|           yy.setClass([$3], $5); |           yy.setClass([$3], $5); | ||||||
|       } |       } | ||||||
|     | entityName BLOCK_START attributes BLOCK_STOP |     | entityName BLOCK_START attributes BLOCK_STOP | ||||||
|   | |||||||
| @@ -981,6 +981,12 @@ describe('when parsing ER diagram it...', function () { | |||||||
|       expect(rels[0].roleA).toBe('places'); |       expect(rels[0].roleA).toBe('places'); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     it('should allow label as optional', function () { | ||||||
|  |       erDiagram.parser.parse('erDiagram\nCUSTOMER ||--|{ ORDER'); | ||||||
|  |       const rels = erDb.getRelationships(); | ||||||
|  |       expect(rels[0].roleA).toBe(''); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     it('should represent parent-child relationship correctly', function () { |     it('should represent parent-child relationship correctly', function () { | ||||||
|       erDiagram.parser.parse('erDiagram\nPROJECT u--o{ TEAM_MEMBER : "parent"'); |       erDiagram.parser.parse('erDiagram\nPROJECT u--o{ TEAM_MEMBER : "parent"'); | ||||||
|       const rels = erDb.getRelationships(); |       const rels = erDb.getRelationships(); | ||||||
| @@ -989,6 +995,20 @@ describe('when parsing ER diagram it...', function () { | |||||||
|       expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.MD_PARENT); |       expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.MD_PARENT); | ||||||
|       expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ZERO_OR_MORE); |       expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ZERO_OR_MORE); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     it('should handle whitespace-only relationship labels', function () { | ||||||
|  |       erDiagram.parser.parse('erDiagram\nBOOK }|..|{ AUTHOR : "   "'); | ||||||
|  |       let rels = erDb.getRelationships(); | ||||||
|  |       expect(rels[rels.length - 1].roleA).toBe('   '); | ||||||
|  |  | ||||||
|  |       erDiagram.parser.parse('erDiagram\nBOOK }|..|{ GENRE : "\t"'); | ||||||
|  |       rels = erDb.getRelationships(); | ||||||
|  |       expect(rels[rels.length - 1].roleA).toBe('\t'); | ||||||
|  |  | ||||||
|  |       erDiagram.parser.parse('erDiagram\nAUTHOR }|..|{ GENRE : "      "'); | ||||||
|  |       rels = erDb.getRelationships(); | ||||||
|  |       expect(rels[rels.length - 1].roleA).toBe('      '); | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   describe('prototype properties', function () { |   describe('prototype properties', function () { | ||||||
|   | |||||||
| @@ -89,6 +89,30 @@ erDiagram | |||||||
|     "This **is** _Markdown_" |     "This **is** _Markdown_" | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | #### Optional Relationship Labels | ||||||
|  |  | ||||||
|  | Starting from Mermaid version 11.11.0, the relationship label in ER diagrams is optional. You can define relationships without specifying a label, and the diagram will render correctly. | ||||||
|  |  | ||||||
|  | For example, the following is valid: | ||||||
|  |  | ||||||
|  | ```mermaid-example | ||||||
|  | erDiagram | ||||||
|  |     BOOK }|..|{ AUTHOR | ||||||
|  |     BOOK }|..|{ GENRE | ||||||
|  |     AUTHOR }|..|{ GENRE | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | This will show the relationships between the entities without any labels on the connecting lines. | ||||||
|  |  | ||||||
|  | You can still add a label if you want to describe the relationship: | ||||||
|  |  | ||||||
|  | ```mermaid-example | ||||||
|  | erDiagram | ||||||
|  |     BOOK }|..|{ AUTHOR : written_by | ||||||
|  |     BOOK }|..|{ GENRE : categorized_as | ||||||
|  |     AUTHOR }|..|{ GENRE : specializes_in | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ### Relationship Syntax | ### Relationship Syntax | ||||||
|  |  | ||||||
| The `relationship` part of each statement can be broken down into three sub-components: | The `relationship` part of each statement can be broken down into three sub-components: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user