Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Requirement diagram to unified renderer #6219

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
adec6cd
Change Db to typescript and add types
yari-dewalt Jan 17, 2025
d90609b
Setup renderer and data collection
yari-dewalt Jan 17, 2025
f0e47f2
Create and register requirementBox shape
yari-dewalt Jan 21, 2025
54ee6bd
Update styles
yari-dewalt Jan 21, 2025
809f4eb
Send all edge data and add markers
yari-dewalt Jan 22, 2025
fe833e6
Fix elements not showing up if they were involved in a relation
yari-dewalt Jan 22, 2025
f7648e8
Add support for direction statement
yari-dewalt Jan 22, 2025
081681f
Add styling support for requirement diagram and box shape
yari-dewalt Jan 22, 2025
41d7a54
Add support for classes
yari-dewalt Jan 23, 2025
9ab2761
Make undefined text not display
yari-dewalt Jan 23, 2025
130638f
Change requirement_id to requirementId
yari-dewalt Jan 23, 2025
02f661a
Update and add tests
yari-dewalt Jan 23, 2025
38ca14d
Fix non-htmlLabel text replacement so markdown styling remains
yari-dewalt Jan 24, 2025
fa48f95
Add e2e tests
yari-dewalt Jan 24, 2025
22bc234
Update documentation to include new changes
yari-dewalt Jan 24, 2025
cc2373e
Merge branch 'develop' into update-requirement-diagram
yari-dewalt Jan 24, 2025
42dfa20
Remove old requirement diagram files
yari-dewalt Jan 24, 2025
23bc25e
Merge branch 'update-requirement-diagram' of github.com:yari-dewalt/m…
yari-dewalt Jan 24, 2025
22091f6
Merge branch 'develop' into update-requirement-diagram
sidharthv96 Jan 25, 2025
74edf7a
Merge branch 'develop' into update-requirement-diagram
sidharthv96 Jan 25, 2025
47d4d56
Remove -unified from renderer file name
yari-dewalt Jan 27, 2025
97788df
Change variable casing
yari-dewalt Jan 27, 2025
9609ace
Update requirementDb to class to encapsulate data
yari-dewalt Jan 27, 2025
c296f48
Merge branch 'update-requirement-diagram' of github.com:yari-dewalt/m…
yari-dewalt Jan 27, 2025
523286b
Update test file to work with new Db
yari-dewalt Jan 27, 2025
a3f35f6
Fix parser test file
yari-dewalt Jan 27, 2025
b53cf0a
Fix getConfig to return correct config
yari-dewalt Jan 27, 2025
f005074
Remove unnecessary default export
yari-dewalt Jan 28, 2025
d0768cb
Update shape
yari-dewalt Jan 28, 2025
baf3adf
Merge branch 'develop' into update-requirement-diagram
yari-dewalt Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
703 changes: 703 additions & 0 deletions cypress/integration/rendering/requirementDiagram-unified.spec.js

Large diffs are not rendered by default.

242 changes: 242 additions & 0 deletions docs/syntax/requirementDiagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,37 @@ element user_defined_name {
}
```

### Markdown Formatting

In places where user defined text is possible (like names, requirement text, element docref, etc.), you can:

- Surround the text in quotes: `"example text"`
- Use markdown formatting inside quotes: `"**bold text** and *italics*"`

Example:

```mermaid-example
requirementDiagram

requirement "__test_req__" {
id: 1
text: "*italicized text* **bold text**"
risk: high
verifymethod: test
}
```

```mermaid
requirementDiagram

requirement "__test_req__" {
id: 1
text: "*italicized text* **bold text**"
risk: high
verifymethod: test
}
```

### Relationship

Relationships are comprised of a source node, destination node, and relationship type.
Expand Down Expand Up @@ -250,4 +281,215 @@ This example uses all features of the diagram.
test_req <- copies - test_entity2
```

## Direction

The diagram can be rendered in different directions using the `direction` statement. Valid values are:

- `TB` - Top to Bottom (default)
- `BT` - Bottom to Top
- `LR` - Left to Right
- `RL` - Right to Left

Example:

```mermaid-example
requirementDiagram

direction LR

requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}

element test_entity {
type: simulation
}

test_entity - satisfies -> test_req
```

```mermaid
requirementDiagram

direction LR

requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}

element test_entity {
type: simulation
}

test_entity - satisfies -> test_req
```

## Styling

Requirements and elements can be styled using direct styling or classes. As a rule of thumb, when applying styles or classes, it accepts a list of requirement or element names and a list of class names allowing multiple assignments at a time (The only exception is the shorthand syntax `:::` which can assign multiple classes but only to one requirement or element at a time).

### Direct Styling

Use the `style` keyword to apply CSS styles directly:

```mermaid-example
requirementDiagram

requirement test_req {
id: 1
text: styling example
risk: low
verifymethod: test
}

element test_entity {
type: simulation
}

style test_req fill:#ffa,stroke:#000, color: green
style test_entity fill:#f9f,stroke:#333, color: blue
```

```mermaid
requirementDiagram

requirement test_req {
id: 1
text: styling example
risk: low
verifymethod: test
}

element test_entity {
type: simulation
}

style test_req fill:#ffa,stroke:#000, color: green
style test_entity fill:#f9f,stroke:#333, color: blue
```

### Class Definitions

Define reusable styles using `classDef`:

```mermaid-example
requirementDiagram

requirement test_req {
id: 1
text: "class styling example"
risk: low
verifymethod: test
}

element test_entity {
type: simulation
}

classDef important fill:#f96,stroke:#333,stroke-width:4px
classDef test fill:#ffa,stroke:#000
```

```mermaid
requirementDiagram

requirement test_req {
id: 1
text: "class styling example"
risk: low
verifymethod: test
}

element test_entity {
type: simulation
}

classDef important fill:#f96,stroke:#333,stroke-width:4px
classDef test fill:#ffa,stroke:#000
```

### Default class

If a class is named default it will be applied to all nodes. Specific styles and classes should be defined afterwards to override the applied default styling.

```
classDef default fill:#f9f,stroke:#333,stroke-width:4px;
```

### Applying Classes

Classes can be applied in two ways:

1. Using the `class` keyword:

```
class test_req,test_entity important
```

2. Using the shorthand syntax with `:::` either during the definition or afterwards:

```
requirement test_req:::important {
id: 1
text: class styling example
risk: low
verifymethod: test
}
```

```
element test_elem {
}

test_elem:::myClass
```

### Combined Example

```mermaid-example
requirementDiagram

requirement test_req:::important {
id: 1
text: "class styling example"
risk: low
verifymethod: test
}

element test_entity {
type: simulation
}

classDef important font-weight:bold

class test_entity important
style test_entity fill:#f9f,stroke:#333
```

```mermaid
requirementDiagram

requirement test_req:::important {
id: 1
text: "class styling example"
risk: low
verifymethod: test
}

element test_entity {
type: simulation
}

classDef important font-weight:bold

class test_entity important
style test_entity fill:#f9f,stroke:#333
```

<!--- cspell:ignore reqs --->
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
%x string
%x token
%x unqString
%x style
%x acc_title
%x acc_descr
%x acc_descr_multiline
Expand All @@ -22,6 +23,10 @@ accDescr\s*":"\s* { this.begin("ac
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<acc_descr_multiline>[\}] { this.popState(); }
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
.*direction\s+TB[^\n]* return 'direction_tb';
.*direction\s+BT[^\n]* return 'direction_bt';
.*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr';
(\r?\n)+ return 'NEWLINE';
\s+ /* skip all whitespace */
\#[^\n]* /* skip comments */
Expand All @@ -32,6 +37,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili

"{" return 'STRUCT_START';
"}" return 'STRUCT_STOP';
":"{3} return 'STYLE_SEPARATOR';
":" return 'COLONSEP';

"id" return 'ID';
Expand Down Expand Up @@ -68,6 +74,20 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
"type" return 'TYPE';
"docref" return 'DOCREF';

"style" { this.begin("style"); return 'STYLE'; }
<style>\w+ return 'ALPHA';
<style>":" return 'COLON';
<style>";" return 'SEMICOLON';
<style>"%" return 'PERCENT';
<style>"-" return 'MINUS';
<style>"#" return 'BRKT';
<style>" " /* skip spaces */
<style>["] { this.begin("string"); }
<style>\n { this.popState(); }

"classDef" { this.begin("style"); return 'CLASSDEF'; }
"class" { this.begin("style"); return 'CLASS'; }

"<-" return 'END_ARROW_L';
"->" {return 'END_ARROW_R';}
"-" {return 'LINE';}
Expand All @@ -76,7 +96,11 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
<string>["] { this.popState(); }
<string>[^"]* { return "qString"; }

[\w][^\r\n\{\<\>\-\=]* { yytext = yytext.trim(); return 'unqString';}
[\w][^:,\r\n\{\<\>\-\=]* { yytext = yytext.trim(); return 'unqString';}

<*>\w+ return 'ALPHA';
<*>[0-9]+ return 'NUM';
<*>"," return 'COMMA';

/lex

Expand All @@ -101,11 +125,28 @@ diagram
| elementDef diagram
| relationshipDef diagram
| directive diagram
| NEWLINE diagram;
| direction diagram
| styleStatement diagram
| classDefStatement diagram
| classStatement diagram
| NEWLINE diagram
;

direction
: direction_tb
{ yy.setDirection('TB');}
| direction_bt
{ yy.setDirection('BT');}
| direction_rl
{ yy.setDirection('RL');}
| direction_lr
{ yy.setDirection('LR');}
;

requirementDef
: requirementType requirementName STRUCT_START NEWLINE requirementBody
{ yy.addRequirement($2, $1) };
: requirementType requirementName STRUCT_START NEWLINE requirementBody { yy.addRequirement($2, $1) }
| requirementType requirementName STYLE_SEPARATOR idList STRUCT_START NEWLINE requirementBody { yy.addRequirement($2, $1); yy.setClass([$2], $4); }
;

requirementBody
: ID COLONSEP id NEWLINE requirementBody
Expand Down Expand Up @@ -149,8 +190,9 @@ verifyType
{ $$=yy.VerifyType.VERIFY_TEST;};

elementDef
: ELEMENT elementName STRUCT_START NEWLINE elementBody
{ yy.addElement($2) };
: ELEMENT elementName STRUCT_START NEWLINE elementBody { yy.addElement($2) }
| ELEMENT elementName STYLE_SEPARATOR idList STRUCT_START NEWLINE elementBody { yy.addElement($2); yy.setClass([$2], $4); }
;

elementBody
: TYPE COLONSEP type NEWLINE elementBody
Expand Down Expand Up @@ -182,6 +224,38 @@ relationship
| TRACES
{ $$=yy.Relationships.TRACES;};

classDefStatement
: CLASSDEF idList stylesOpt {$$ = $CLASSDEF;yy.defineClass($idList,$stylesOpt);}
;

classStatement
: CLASS idList idList {yy.setClass($2, $3);}
| id STYLE_SEPARATOR idList {yy.setClass([$1], $3);}
;

idList
: ALPHA { $$ = [$ALPHA]; }
| idList COMMA ALPHA = { $$ = $idList.concat([$ALPHA]); }
| id { $$ = [$id]; }
| idList COMMA id = { $$ = $idList.concat([$id]); }
;

styleStatement
: STYLE idList stylesOpt {$$ = $STYLE;yy.setCssStyle($2,$stylesOpt);}
;

stylesOpt
: style {$$ = [$style]}
| stylesOpt COMMA style {$stylesOpt.push($style);$$ = $stylesOpt;}
;

style
: styleComponent
| style styleComponent {$$ = $style + $styleComponent;}
;

styleComponent: ALPHA | NUM | COLON | UNIT | SPACE | BRKT | PCT | MINUS | LABEL | SEMICOLON;


requirementName: unqString | qString;
id : unqString | qString;
Expand Down
Loading
Loading