Skip to content

Commit

Permalink
Fix #3011: Support left- and right-alignment for multi-line messages …
Browse files Browse the repository at this point in the history
…and notes

Previously, messages and notes that had multiple lines (via `<br>`-tags) were only displayed correctly
when using the default `center` value for the `messageAlign` and `noteAlign` configuration options.
Using `left` or `right` for the alignment options caused the text to collapse and become illegible,
as outlined in issue #3011.

This comes as a side-effect from how the internal `valign` text-rendering option was configured for
messages and notes:

```js
// Example from `sequenceRenderer.js: drawMessage()`
textObj.anchor = conf.messageAlign;
textObj.valign = conf.messageAlign;
```

Both the `anchor` option (which controls left-right alignment) and the `valign` option (which controls
vertical top-down placement) were set to the same value, the user-provided `messageAlign` config option.

While `left` and `right` are valid values for the `anchor` option, they were effectively no-ops for the
`valign` option, which only supports `top`, `start`, `middle`, `center`, `bottom`, and `end`.

To fix the issue, the `valign` property is now always set to `center` for notes and messages.
Similarly, the `dominantBaseline` option of texts is now always set to `middle`, rather than setting it to
either `text-{before,after}-edge`, which caused left-aligned multi-line text to always be "top-left" aligned
inside a note (or "bottom-right" when attempting to right-align).

Now, texts in messages and notes are always vertically centered and alignment options correctly apply for
both single and multi-line content.
  • Loading branch information
hype09 committed Jul 3, 2022
1 parent 1509ee6 commit ed29fe1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
42 changes: 42 additions & 0 deletions cypress/e2e/rendering/sequencediagram.spec.js
Expand Up @@ -126,6 +126,17 @@ context('Sequence diagram', () => {
{ sequence: { noteAlign: 'left' } }
);
});
it('should render multi-line notes aligned to the left when configured', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice->>Bob: I'm short
note left of Alice: I am left aligned<br>but also<br>multiline
Bob->>Alice: Short as well
`,
{ sequence: { noteAlign: 'left' } }
);
});
it('should render notes aligned to the right when configured', () => {
imgSnapshotTest(
`
Expand All @@ -137,6 +148,37 @@ context('Sequence diagram', () => {
{ sequence: { noteAlign: 'right' } }
);
});
it('should render multi-line notes aligned to the right when configured', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice->>Bob: I'm short
note left of Alice: I am right aligned<br>but also<br>multiline
Bob->>Alice: Short as well
`,
{ sequence: { noteAlign: 'right' } }
);
});
it('should render multi-line messages aligned to the left when configured', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice->>Bob: I'm short<br>but also<br>multiline
Bob->>Alice: Short as well<br>and also<br>multiline
`,
{ sequence: { messageAlign: 'left' } }
);
});
it('should render multi-line messages aligned to the right when configured', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice->>Bob: I'm short<br>but also<br>multiline
Bob->>Alice: Short as well<br>and also<br>multiline
`,
{ sequence: { messageAlign: 'right' } }
);
});
});
context('auth width scaling', () => {
it('should render long actor descriptions', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/diagrams/sequence/sequenceRenderer.js
Expand Up @@ -230,7 +230,7 @@ const drawNote = function (elem, noteModel) {
textObj.fontWeight = conf.noteFontWeight;
textObj.anchor = conf.noteAlign;
textObj.textMargin = conf.noteMargin;
textObj.valign = conf.noteAlign;
textObj.valign = 'center';

let textElem = drawText(g, textObj);

Expand Down Expand Up @@ -342,7 +342,7 @@ const drawMessage = function (diagram, msgModel, lineStarty) {
textObj.fontSize = conf.messageFontSize;
textObj.fontWeight = conf.messageFontWeight;
textObj.anchor = conf.messageAlign;
textObj.valign = conf.messageAlign;
textObj.valign = 'center';
textObj.textMargin = conf.wrapPadding;
textObj.tspan = false;

Expand Down
4 changes: 2 additions & 2 deletions src/diagrams/sequence/svgDraw.js
Expand Up @@ -193,7 +193,7 @@ export const drawText = function (elem, textData) {
case 'start':
textData.x = Math.round(textData.x + textData.textMargin);
textData.anchor = 'start';
textData.dominantBaseline = 'text-after-edge';
textData.dominantBaseline = 'middle';
textData.alignmentBaseline = 'middle';
break;
case 'middle':
Expand All @@ -207,7 +207,7 @@ export const drawText = function (elem, textData) {
case 'end':
textData.x = Math.round(textData.x + textData.width - textData.textMargin);
textData.anchor = 'end';
textData.dominantBaseline = 'text-before-edge';
textData.dominantBaseline = 'middle';
textData.alignmentBaseline = 'middle';
break;
}
Expand Down

0 comments on commit ed29fe1

Please sign in to comment.