Grammar/rendering for setting style on class node

This commit is contained in:
Justin Greywolf
2023-12-04 13:28:31 -08:00
parent f81e4d4361
commit 239fad94ee
8 changed files with 93 additions and 4 deletions

View File

@@ -571,4 +571,14 @@ class C13["With Città foreign language"]
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
});
it('should render a simple class diagram with style definition', () => {
imgSnapshotTest(
`
classDiagram-v2
class Class10
style Class10 fill:#f9f,stroke:#333,stroke-width:4px
`,
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
});
});

View File

@@ -768,7 +768,28 @@ Beginner's tip—a full example using interactive links in an HTML page:
### Styling a node
It is possible to apply specific styles such as a thicker border or a different background color to individual nodes. This is done by predefining classes in css styles that can be applied from the graph definition using the `cssClass` statement or the `:::` short hand.
It is possible to apply specific styles such as a thicker border or a different background color to a node.
```mermaid-example
classDiagram
class Animal
class Mineral
style Animal fill:#f9f,stroke:#333,stroke-width:4px
style Mineral fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
```
```mermaid
classDiagram
class Animal
class Mineral
style Animal fill:#f9f,stroke:#333,stroke-width:4px
style Mineral fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
```
#### Classes
More convenient than defining the style every time is to define a class of styles and attach this class to the nodes that
should have a different look. This is done by predefining classes in css styles that can be applied from the graph definition using the `cssClass` statement or the `:::` short hand.
```html
<style>

View File

@@ -1013,6 +1013,7 @@ const class_box = (parent, node) => {
});
rect
.attr('style', node.style)
.attr('class', 'outer title-state')
.attr('x', -maxWidth / 2 - halfPadding)
.attr('y', -(maxHeight / 2) - halfPadding)

View File

@@ -84,6 +84,7 @@ export const addClass = function (_id: string) {
methods: [],
members: [],
annotations: [],
styles: [],
domId: MERMAID_DOM_ID_PREFIX + name + '-' + classCounter,
} as ClassNode;
@@ -454,6 +455,24 @@ export const addClassesToNamespace = function (id: string, classNames: string[])
}
};
export const setCssStyle = function (id: string, style: string[]) {
if (style !== undefined && style !== null) {
const thisClass = classes[id];
if (thisClass !== undefined) {
style.forEach(function (s) {
if (s.includes(',')) {
const styles = s.split(',');
styles.forEach(function (newStyle) {
thisClass.styles.push(newStyle);
});
} else {
thisClass.styles.push(s);
}
});
}
}
};
export default {
setAccTitle,
getAccTitle,
@@ -490,4 +509,5 @@ export default {
addClassesToNamespace,
getNamespace,
getNamespaces,
setCssStyle,
};

View File

@@ -56,5 +56,18 @@ describe('class diagram, ', function () {
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
expect(parser.yy.getClass('Class02').cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a style to an individual node', function () {
const str =
'classDiagram\n' +
'class Class01\n class Class02\n style Class01 fill:#f9f,stroke:#333,stroke-width:4px';
parser.parse(str);
const styleElements = parser.yy.getClass('Class01').styles;
expect(styleElements[0]).toBe('fill:#f9f');
expect(styleElements[1]).toBe('stroke:#333');
expect(styleElements[2]).toBe('stroke-width:4px');
});
});
});

View File

@@ -104,7 +104,7 @@ export const addClasses = function (
*/
const cssClassStr = vertex.cssClasses.join(' ');
const styles = { labelStyle: '', style: '' }; //getStylesFromArray(vertex.styles);
const styles = getStylesFromArray(vertex.styles);
// Use vertex id as text in the box if no text is provided by the graph definition
const vertexText = vertex.label ?? vertex.id;

View File

@@ -15,6 +15,7 @@ export interface ClassNode {
linkTarget?: string;
haveCallback?: boolean;
tooltip?: string;
styles?: string[];
}
export type Visibility = '#' | '+' | '~' | '-' | '';

View File

@@ -60,6 +60,7 @@ Function arguments are optional: 'call <callback_name>()' simply executes 'callb
<string>["] this.popState();
<string>[^"]* return "STR";
<*>["] this.begin("string");
"style" return 'STYLE';
<INITIAL,namespace>"namespace" { this.begin('namespace'); return 'NAMESPACE'; }
<namespace>\s*(\r?\n)+ { this.popState(); return 'NEWLINE'; }
@@ -127,6 +128,10 @@ line was introduced with 'click'.
<*>\- return 'MINUS';
<*>"." return 'DOT';
<*>\+ return 'PLUS';
":" return 'COLON';
"," return 'COMMA';
\# return 'BRKT';
"#" return 'BRKT';
<*>\% return 'PCT';
<*>"=" return 'EQUALS';
<*>\= return 'EQUALS';
@@ -198,6 +203,7 @@ line was introduced with 'click'.
[\uFFD2-\uFFD7\uFFDA-\uFFDC]
return 'UNICODE_TEXT';
<*>\s return 'SPACE';
\s return 'SPACE';
<*><<EOF>> return 'EOF';
/lex
@@ -254,6 +260,7 @@ statement
| memberStatement
| annotationStatement
| clickStatement
| styleStatement
| cssClassStatement
| noteStatement
| direction
@@ -365,10 +372,26 @@ clickStatement
| CLICK className HREF STR STR LINK_TARGET {$$ = $1;yy.setLink($2, $4, $6);yy.setTooltip($2, $5);}
;
cssClassStatement
: CSSCLASS STR alphaNumToken {yy.setCssClass($2, $3);}
styleStatement
:STYLE ALPHA stylesOpt {$$ = $STYLE;yy.setCssStyle($2,$stylesOpt);}
;
cssClassStatement
: CSSCLASS STR stylesOpt {yy.setCssClass($2, $3);}
;
stylesOpt
: style {$$ = [$style]}
| stylesOpt COMMA style {$stylesOpt.push($style);$$ = $stylesOpt;}
;
style
: styleComponent
| style styleComponent {$$ = $style + $styleComponent;}
;
styleComponent: ALPHA | NUM | COLON | UNIT | SPACE | BRKT | STYLE | PCT | LABEL;
commentToken : textToken | graphCodeTokens ;
textToken : textNoTagsToken | TAGSTART | TAGEND | '==' | '--' | PCT | DEFAULT;