From ed29fe1aa9257c55e1afb37cc35f63de347d979b Mon Sep 17 00:00:00 2001 From: Paik Paustian Date: Sun, 3 Jul 2022 11:41:18 +0200 Subject: [PATCH] Fix #3011: Support left- and right-alignment for multi-line messages and notes Previously, messages and notes that had multiple lines (via `
`-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. --- cypress/e2e/rendering/sequencediagram.spec.js | 42 +++++++++++++++++++ src/diagrams/sequence/sequenceRenderer.js | 4 +- src/diagrams/sequence/svgDraw.js | 4 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/cypress/e2e/rendering/sequencediagram.spec.js b/cypress/e2e/rendering/sequencediagram.spec.js index c110f05ad..0559cce20 100644 --- a/cypress/e2e/rendering/sequencediagram.spec.js +++ b/cypress/e2e/rendering/sequencediagram.spec.js @@ -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
but also
multiline + Bob->>Alice: Short as well + `, + { sequence: { noteAlign: 'left' } } + ); + }); it('should render notes aligned to the right when configured', () => { imgSnapshotTest( ` @@ -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
but also
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
but also
multiline + Bob->>Alice: Short as well
and also
multiline + `, + { sequence: { messageAlign: 'left' } } + ); + }); + it('should render multi-line messages aligned to the right when configured', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice->>Bob: I'm short
but also
multiline + Bob->>Alice: Short as well
and also
multiline + `, + { sequence: { messageAlign: 'right' } } + ); + }); }); context('auth width scaling', () => { it('should render long actor descriptions', () => { diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index d83d9dc2b..c76662332 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -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); @@ -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; diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index a00d10169..3d9a0bbf2 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -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': @@ -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; }