#2017 Standardization of requirement diagrams

This commit is contained in:
Knut Sveidqvist
2021-04-26 19:08:16 +02:00
parent 45918da48e
commit 8f09514dd7
11 changed files with 186 additions and 74 deletions

View File

@@ -12,18 +12,19 @@
/* background: rgb(221, 208, 208); */ /* background: rgb(221, 208, 208); */
/* background:#333; */ /* background:#333; */
font-family: 'Arial'; font-family: 'Arial';
/* font-size: 18px !important; */
} }
h1 { color: grey;} h1 { color: grey;}
.mermaid2 { .mermaid2 {
display: none; display: none;
} }
.mermaid svg { .mermaid svg {
font-size: 12px !important; /* font-size: 18px !important; */
} }
</style> </style>
</head> </head>
<body> <body>
<h1>info below</h1> <div>info below</div>
<div class="flex"> <div class="flex">
<div class="mermaid2" style="width: 100%; height: 400px;"> <div class="mermaid2" style="width: 100%; height: 400px;">
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%% %%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
@@ -54,21 +55,50 @@ flowchart TD
class T TestSub class T TestSub
linkStyle 0,1 color:orange, stroke: orange; linkStyle 0,1 color:orange, stroke: orange;
</div> </div>
<div class="mermaid" style="width: 50%; height: 20%;"> <div class="mermaid" style="width: 100%; height: 20%;">
%%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%% graph TD
flowchart LR C --text fyra fem -->F[text ett två tre]
subgraph A
a --> b
end
subgraph B
i -->f
end
A --> B </div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart TD
C -->|fa:fa-car Car| F[fa:fa-car Car]
</div> </div>
<div class="mermaid" style="width: 50%; height: 20%;">
<div class="mermaid" style="width: 100%; height: 20%;">
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
functionalRequirement test_req2 {
id: 1.1
text: the second test text.
risk: low
verifymethod: inspection
}
performanceRequirement test_req3 {
id: 1.2
text: the third test text.
risk: medium
verifymethod: demonstration
}
element test_entity {
type: simulation
}
element test_entity2 {
type: word doc
docRef: reqs/test_entity
}
test_entity - satisfies -> test_req2
test_req - traces -> test_req2
test_req - contains -> test_req3
test_req <- copies - test_entity2
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart LR flowchart LR
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
Lorem --> Ipsum --> Dolor Lorem --> Ipsum --> Dolor
@@ -124,9 +154,8 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff
// console.error('Mermaid error: ', err); // console.error('Mermaid error: ', err);
}; };
mermaid.initialize({ mermaid.initialize({
// theme: 'forest', theme: 'neutral',
// themeVariables:{primaryColor: '#ff0000'}, arrowMarkerAbsolute: true,
// arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0, logLevel: 0,
flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true }, flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true },
@@ -134,10 +163,12 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff
// gantt: { axisFormat: '%m/%d/%Y' }, // gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false }, sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated // sequenceDiagram: { actorMargin: 300 } // deprecated
fontFamily: '"arial", sans-serif', // fontFamily: '"times", sans-serif',
fontFamily: 'courier', // fontFamily: 'courier',
fontSize: 18,
curve: 'cardinal', curve: 'cardinal',
securityLevel: 'loose', securityLevel: 'loose',
// themeVariables: {relationLabelColor: 'red'}
}); });
function callback(){alert('It worked');} function callback(){alert('It worked');}
</script> </script>

View File

@@ -84,7 +84,8 @@
%% /* language grammar */ %% /* language grammar */
start start
: directive start : directive NEWLINE start
| directive start
| RD NEWLINE diagram EOF; | RD NEWLINE diagram EOF;
directive directive
@@ -108,6 +109,7 @@ diagram
| requirementDef diagram | requirementDef diagram
| elementDef diagram | elementDef diagram
| relationshipDef diagram | relationshipDef diagram
| directive diagram
| NEWLINE diagram; | NEWLINE diagram;
requirementDef requirementDef

View File

@@ -20,8 +20,8 @@ const insertLineEndings = (parentNode, conf) => {
.attr('cx', conf.line_height / 2) .attr('cx', conf.line_height / 2)
.attr('cy', conf.line_height / 2) .attr('cy', conf.line_height / 2)
.attr('r', conf.line_height / 2) .attr('r', conf.line_height / 2)
.attr('stroke', conf.rect_border_color) // .attr('stroke', conf.rect_border_color)
.attr('stroke-width', 1) // .attr('stroke-width', 1)
.attr('fill', 'none'); .attr('fill', 'none');
containsNode containsNode
@@ -30,7 +30,7 @@ const insertLineEndings = (parentNode, conf) => {
.attr('x2', conf.line_height) .attr('x2', conf.line_height)
.attr('y1', conf.line_height / 2) .attr('y1', conf.line_height / 2)
.attr('y2', conf.line_height / 2) .attr('y2', conf.line_height / 2)
.attr('stroke', conf.rect_border_color) // .attr('stroke', conf.rect_border_color)
.attr('stroke-width', 1); .attr('stroke-width', 1);
containsNode containsNode
@@ -39,7 +39,7 @@ const insertLineEndings = (parentNode, conf) => {
.attr('y2', conf.line_height) .attr('y2', conf.line_height)
.attr('x1', conf.line_height / 2) .attr('x1', conf.line_height / 2)
.attr('x2', conf.line_height / 2) .attr('x2', conf.line_height / 2)
.attr('stroke', conf.rect_border_color) // .attr('stroke', conf.rect_border_color)
.attr('stroke-width', 1); .attr('stroke-width', 1);
parentNode parentNode
@@ -59,8 +59,8 @@ const insertLineEndings = (parentNode, conf) => {
M${conf.line_height},${conf.line_height / 2} M${conf.line_height},${conf.line_height / 2}
L0,${conf.line_height}` L0,${conf.line_height}`
) )
.attr('stroke-width', 1) .attr('stroke-width', 1);
.attr('stroke', conf.rect_border_color); // .attr('stroke', conf.rect_border_color);
}; };
export default { export default {

View File

@@ -1,7 +1,7 @@
import { line, select } from 'd3'; import { line, select } from 'd3';
import dagre from 'dagre'; import dagre from 'dagre';
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import * as configApi from '../../config'; // import * as configApi from '../../config';
import { log } from '../../logger'; import { log } from '../../logger';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import common from '../common/common'; import common from '../common/common';
@@ -26,10 +26,6 @@ const newRectNode = (parentNode, id) => {
return parentNode return parentNode
.insert('rect', '#' + id) .insert('rect', '#' + id)
.attr('class', 'req reqBox') .attr('class', 'req reqBox')
.attr('fill', conf.rect_fill)
.attr('fill-opacity', '100%')
.attr('stroke', conf.rect_border_color)
.attr('stroke-size', conf.rect_border_size)
.attr('x', 0) .attr('x', 0)
.attr('y', 0) .attr('y', 0)
.attr('width', conf.rect_min_width + 'px') .attr('width', conf.rect_min_width + 'px')
@@ -45,12 +41,11 @@ const newTitleNode = (parentNode, id, txts) => {
.attr('id', id) .attr('id', id)
.attr('x', x) .attr('x', x)
.attr('y', conf.rect_padding) .attr('y', conf.rect_padding)
.attr('dominant-baseline', 'hanging') .attr('dominant-baseline', 'hanging');
.attr( // .attr(
'style', // 'style',
'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px' // 'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px'
); // )
let i = 0; let i = 0;
txts.forEach(textStr => { txts.forEach(textStr => {
if (i == 0) { if (i == 0) {
@@ -77,11 +72,11 @@ const newTitleNode = (parentNode, id, txts) => {
parentNode parentNode
.append('line') .append('line')
.attr('class', 'req-title-line')
.attr('x1', '0') .attr('x1', '0')
.attr('x2', conf.rect_min_width) .attr('x2', conf.rect_min_width)
.attr('y1', totalY) .attr('y1', totalY)
.attr('y2', totalY) .attr('y2', totalY);
.attr('style', `stroke: ${conf.rect_border_color}; stroke-width: 1`);
return { return {
titleNode: title, titleNode: title,
@@ -96,11 +91,11 @@ const newBodyNode = (parentNode, id, txts, yStart) => {
.attr('id', id) .attr('id', id)
.attr('x', conf.rect_padding) .attr('x', conf.rect_padding)
.attr('y', yStart) .attr('y', yStart)
.attr('dominant-baseline', 'hanging') .attr('dominant-baseline', 'hanging');
.attr( // .attr(
'style', // 'style',
'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px' // 'font-family: ' + configApi.getConfig().fontFamily + '; font-size: ' + conf.fontSize + 'px'
); // );
let currentRow = 0; let currentRow = 0;
const charLimit = 30; const charLimit = 30;
@@ -145,13 +140,13 @@ const addEdgeLabel = (parentNode, svgPath, conf, txt) => {
const labelNode = parentNode const labelNode = parentNode
.append('text') .append('text')
.attr('class', 'er relationshipLabel') .attr('class', 'req relationshipLabel')
.attr('id', labelId) .attr('id', labelId)
.attr('x', labelPoint.x) .attr('x', labelPoint.x)
.attr('y', labelPoint.y) .attr('y', labelPoint.y)
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.attr('dominant-baseline', 'middle') .attr('dominant-baseline', 'middle')
.attr('style', 'font-family: ' + conf.fontFamily + '; font-size: ' + conf.fontSize + 'px') // .attr('style', 'font-family: ' + conf.fontFamily + '; font-size: ' + conf.fontSize + 'px')
.text(txt); .text(txt);
// Figure out how big the opaque 'container' rectangle needs to be // Figure out how big the opaque 'container' rectangle needs to be
@@ -187,7 +182,6 @@ const drawRelationshipFromLayout = function(svg, rel, g, insert) {
.insert('path', '#' + insert) .insert('path', '#' + insert)
.attr('class', 'er relationshipLine') .attr('class', 'er relationshipLine')
.attr('d', lineFunction(edge.points)) .attr('d', lineFunction(edge.points))
.attr('stroke', conf.rect_border_color)
.attr('fill', 'none'); .attr('fill', 'none');
if (rel.type == requirementDb.Relationships.CONTAINS) { if (rel.type == requirementDb.Relationships.CONTAINS) {

View File

@@ -1,3 +1,42 @@
const getStyles = () => ``; const getStyles = options => `
marker {
fill: ${options.relationColor};
stroke: ${options.relationColor};
}
marker.cross {
stroke: ${options.lineColor};
}
svg {
font-family: ${options.fontFamily};
font-size: ${options.fontSize};
}
.reqBox {
fill: ${options.requirementBackground};
fill-opacity: 100%;
stroke: ${options.requirementBorderColor};
stroke-size: ${options.requirementBorderSize};
}
.reqLabelBox {
fill: ${options.relationLabelBackground};
fill-opacity: 100%;
}
.req-title-line {
stroke: ${options.requirementBorderColor};
stroke-width: 1;
}
.relationshipLine {
stroke: ${options.relationColor};
stroke-width: 1;
}
.relationshipLabel {
fill: ${options.relationLabelColor};
}
`;
// fill', conf.rect_fill)
export default getStyles; export default getStyles;

View File

@@ -81,8 +81,6 @@ const getStyles = (type, userStyles, options) => {
${themes[type](options)} ${themes[type](options)}
${userStyles} ${userStyles}
${type} { fill: apa;}
`; `;
}; };

View File

@@ -125,6 +125,17 @@ class Theme {
this.fillType5 = this.fillType5 || adjust(this.secondaryColor, { h: -64 }); this.fillType5 = this.fillType5 || adjust(this.secondaryColor, { h: -64 });
this.fillType6 = this.fillType6 || adjust(this.primaryColor, { h: 128 }); this.fillType6 = this.fillType6 || adjust(this.primaryColor, { h: 128 });
this.fillType7 = this.fillType7 || adjust(this.secondaryColor, { h: 128 }); this.fillType7 = this.fillType7 || adjust(this.secondaryColor, { h: 128 });
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground =
this.relationLabelBackground ||
(this.darkMode ? darken(this.secondaryColor, 30) : this.secondaryColor);
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
} }
calculate(overrides) { calculate(overrides) {
if (typeof overrides !== 'object') { if (typeof overrides !== 'object') {

View File

@@ -140,6 +140,17 @@ class Theme {
this.fillType7 = adjust(this.secondaryColor, { h: 128 }); this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* class */ /* class */
this.classText = this.primaryTextColor; this.classText = this.primaryTextColor;
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground =
this.relationLabelBackground ||
(this.darkMode ? darken(this.secondaryColor, 30) : this.secondaryColor);
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
} }
calculate(overrides) { calculate(overrides) {
if (typeof overrides !== 'object') { if (typeof overrides !== 'object') {

View File

@@ -150,6 +150,15 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 }); this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 }); this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 }); this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground = this.relationLabelBackground || this.labelBackground;
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
} }
calculate(overrides) { calculate(overrides) {
if (typeof overrides !== 'object') { if (typeof overrides !== 'object') {

View File

@@ -120,6 +120,15 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 }); this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 }); this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 }); this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground = this.relationLabelBackground || this.edgeLabelBackground;
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
} }
calculate(overrides) { calculate(overrides) {
if (typeof overrides !== 'object') { if (typeof overrides !== 'object') {

View File

@@ -157,6 +157,14 @@ class Theme {
this.fillType5 = adjust(this.secondaryColor, { h: -64 }); this.fillType5 = adjust(this.secondaryColor, { h: -64 });
this.fillType6 = adjust(this.primaryColor, { h: 128 }); this.fillType6 = adjust(this.primaryColor, { h: 128 });
this.fillType7 = adjust(this.secondaryColor, { h: 128 }); this.fillType7 = adjust(this.secondaryColor, { h: 128 });
/* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor;
this.requirementBorderColor = this.requirementBorderColor || this.primaryBorderColor;
this.requirementBorderSize = this.requirementBorderSize || this.primaryBorderColor;
this.requirementTextColor = this.requirementTextColor || this.primaryTextColor;
this.relationColor = this.relationColor || this.lineColor;
this.relationLabelBackground = this.relationLabelBackground || this.edgeLabelBackground;
this.relationLabelColor = this.relationLabelColor || this.actorTextColor;
} }
calculate(overrides) { calculate(overrides) {
if (typeof overrides !== 'object') { if (typeof overrides !== 'object') {