Skip to content

Commit

Permalink
Merge pull request #5111 from mermaid-js/2408-support-style-for-class
Browse files Browse the repository at this point in the history
Added functionality to support style keyword
  • Loading branch information
jgreywolf committed Dec 20, 2023
2 parents 6e64556 + 2b4940d commit 6028036
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 7 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 } }
);
});
});
25 changes: 23 additions & 2 deletions docs/syntax/classDiagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,9 +766,30 @@ Beginner's tip—a full example using interactive links in an HTML page:

## Styling

### Styling a node
### Styling a node (v\<MERMAID_RELEASE_VERSION>+)

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 an individual node using the `style` keyword.

```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
18 changes: 17 additions & 1 deletion 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 @@ -214,7 +215,7 @@ export const cleanupLabel = function (label: string) {
};

/**
* Called by parser when a special node is found, e.g. a clickable element.
* Called by parser when assigning cssClass to a class
*
* @param ids - Comma separated list of ids
* @param className - Class to add
Expand Down Expand Up @@ -456,6 +457,20 @@ export const addClassesToNamespace = function (id: string, classNames: string[])
}
};

export const setCssStyle = function (id: string, styles: string[]) {
const thisClass = classes[id];
if (!styles || !thisClass) {
return;
}
for (const s of styles) {
if (s.includes(',')) {
thisClass.styles.push(...s.split(','));
} else {
thisClass.styles.push(s);
}
}
};

export default {
setAccTitle,
getAccTitle,
Expand Down Expand Up @@ -492,4 +507,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');
});
});
});
1 change: 1 addition & 0 deletions packages/mermaid/src/diagrams/class/classDiagram.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ class C13["With Città foreign language"]
},
],
"methods": [],
"styles": [],
"type": "",
}
`);
Expand Down
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 @@ -10,6 +10,7 @@ export interface ClassNode {
members: ClassMember[];
annotations: string[];
domId: string;
styles: string[];
parent?: string;
link?: string;
linkTarget?: string;
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 ALPHA {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
17 changes: 15 additions & 2 deletions packages/mermaid/src/docs/syntax/classDiagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,22 @@ Beginner's tip—a full example using interactive links in an HTML page:

## Styling

### Styling a node
### Styling a node (v<MERMAID_RELEASE_VERSION>+)

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 an individual node using the `style` keyword.

```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
```

#### 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

0 comments on commit 6028036

Please sign in to comment.