Skip to content

Commit

Permalink
Grammar/rendering for setting style on class node
Browse files Browse the repository at this point in the history
  • Loading branch information
jgreywolf committed Dec 4, 2023
1 parent f81e4d4 commit 239fad9
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 3 deletions.
10 changes: 10 additions & 0 deletions cypress/integration/rendering/classDiagram-v2.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 } }
);
});
});
23 changes: 22 additions & 1 deletion docs/syntax/classDiagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions packages/mermaid/src/dagre-wrapper/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
20 changes: 20 additions & 0 deletions packages/mermaid/src/diagrams/class/classDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const addClass = function (_id: string) {
methods: [],
members: [],
annotations: [],
styles: [],
domId: MERMAID_DOM_ID_PREFIX + name + '-' + classCounter,
} as ClassNode;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -490,4 +509,5 @@ export default {
addClassesToNamespace,
getNamespace,
getNamespaces,
setCssStyle,
};
13 changes: 13 additions & 0 deletions packages/mermaid/src/diagrams/class/classDiagram-styles.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});
});
2 changes: 1 addition & 1 deletion packages/mermaid/src/diagrams/class/classRenderer-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions packages/mermaid/src/diagrams/class/classTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface ClassNode {
linkTarget?: string;
haveCallback?: boolean;
tooltip?: string;
styles?: string[];
}

export type Visibility = '#' | '+' | '~' | '-' | '';
Expand Down
25 changes: 24 additions & 1 deletion packages/mermaid/src/diagrams/class/parser/classDiagram.jison
Original file line number Diff line number Diff line change
Expand Up @@ -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'; }
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -254,6 +260,7 @@ statement
| memberStatement
| annotationStatement
| clickStatement
| styleStatement
| cssClassStatement
| noteStatement
| direction
Expand Down Expand Up @@ -365,10 +372,26 @@ clickStatement
| CLICK className HREF STR STR LINK_TARGET {$$ = $1;yy.setLink($2, $4, $6);yy.setTooltip($2, $5);}
;

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

cssClassStatement
: CSSCLASS STR alphaNumToken {yy.setCssClass($2, $3);}
: 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;
Expand Down

0 comments on commit 239fad9

Please sign in to comment.