Getting closer

This commit is contained in:
chris moran 2020-06-28 08:37:26 -04:00
parent 6915634729
commit fcd2126330
No known key found for this signature in database
GPG Key ID: 7E303019E6BB02D7
4 changed files with 144 additions and 116 deletions

View File

@ -292,9 +292,9 @@ const config = {
wrap: false, wrap: false,
/** /**
* This sets the auto-wrap padding for the diagram (sides only) * This sets the auto-wrap padding for the diagram (sides only)
* **Default value 15. * **Default value 10.
*/ */
wrapPadding: 15, wrapPadding: 10,
/** /**
* This sets the width of the loop-box (loop, alt, opt, par) * This sets the width of the loop-box (loop, alt, opt, par)
* **Default value 50. * **Default value 50.
@ -306,24 +306,27 @@ const config = {
*/ */
labelBoxHeight: 20, labelBoxHeight: 20,
messageFont: () => { messageFont: () => {
const c = getConfig();
return { return {
fontFamily: config.messageFontFamily, fontFamily: c.messageFontFamily,
fontSize: config.messageFontSize, fontSize: c.messageFontSize,
fontWeight: config.messageFontWeight fontWeight: c.messageFontWeight
}; };
}, },
noteFont: () => { noteFont: () => {
const c = getConfig();
return { return {
fontFamily: config.noteFontFamily, fontFamily: c.noteFontFamily,
fontSize: config.noteFontSize, fontSize: c.noteFontSize,
fontWeight: config.noteFontWeight fontWeight: c.noteFontWeight
}; };
}, },
actorFont: () => { actorFont: () => {
const c = getConfig();
return { return {
fontFamily: config.actorFontFamily, fontFamily: c.actorFontFamily,
fontSize: config.actorFontSize, fontSize: c.actorFontSize,
fontWeight: config.actorFontWeight fontWeight: c.actorFontWeight
}; };
} }
}, },

View File

@ -136,7 +136,7 @@ export const bounds = {
}, },
newActivation: function(message, diagram, actors) { newActivation: function(message, diagram, actors) {
const actorRect = actors[message.from.actor]; const actorRect = actors[message.from.actor];
const stackedSize = actorActivations(message.from.actor).length; const stackedSize = actorActivations(message.from.actor).length || 0;
const x = actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2; const x = actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
this.activations.push({ this.activations.push({
startx: x, startx: x,
@ -248,13 +248,16 @@ const drawNote = function(elem, noteModel) {
* @param msgModel - the model containing fields describing a message * @param msgModel - the model containing fields describing a message
*/ */
const drawMessage = function(g, msgModel) { const drawMessage = function(g, msgModel) {
bounds.bumpVerticalPos(conf.messageMargin); const { startx, stopx, starty, message, type, sequenceIndex, wrap } = msgModel;
msgModel.height += conf.messageMargin; const lines = message.split(common.lineBreakRegex).length;
msgModel.starty = bounds.getVerticalPos(); let textDims = utils.calculateTextDimensions(message, conf);
const { startx, stopx, starty: verticalPos, message, type, sequenceIndex, wrap } = msgModel; const lineHeight = textDims.height / lines;
msgModel.height += lineHeight;
bounds.bumpVerticalPos(lineHeight);
const textObj = svgDraw.getTextObj(); const textObj = svgDraw.getTextObj();
textObj.x = startx; textObj.x = startx;
textObj.y = verticalPos; textObj.y = starty;
textObj.width = stopx - startx; textObj.width = stopx - startx;
textObj.class = 'messageText'; textObj.class = 'messageText';
textObj.dy = '1em'; textObj.dy = '1em';
@ -268,18 +271,11 @@ const drawMessage = function(g, msgModel) {
textObj.tspan = false; textObj.tspan = false;
textObj.wrap = wrap; textObj.wrap = wrap;
let textElem = drawText(g, textObj); drawText(g, textObj);
const lineHeight = (textElem[0]._groups || textElem[0])[0][0].getBBox().height;
textElem.forEach(te => te.attr('y', verticalPos - 7 - lineHeight / 2));
const lines = message.split(common.lineBreakRegex).length - 1; let totalOffset = textDims.height;
let totalOffset = Math.round(lineHeight + lines * lineHeight); let textWidth = textDims.width;
let textWidth = Math.max.apply(
null,
textElem.map(te => (te._groups || te)[0][0].getBBox().width)
);
let line; let line;
if (startx === stopx) { if (startx === stopx) {
@ -288,7 +284,8 @@ const drawMessage = function(g, msgModel) {
.append('path') .append('path')
.attr( .attr(
'd', 'd',
`M ${startx},${verticalPos + totalOffset} H ${startx + conf.width / 2} V ${verticalPos + `M ${startx},${bounds.getVerticalPos() + totalOffset} H ${startx +
Math.max(conf.width / 2, textWidth / 2)} V ${bounds.getVerticalPos() +
25 + 25 +
totalOffset} H ${startx}` totalOffset} H ${startx}`
); );
@ -302,49 +299,43 @@ const drawMessage = function(g, msgModel) {
'M ' + 'M ' +
startx + startx +
',' + ',' +
(verticalPos + totalOffset) + (bounds.getVerticalPos() + totalOffset) +
' C ' + ' C ' +
(startx + 60) + (startx + 60) +
',' + ',' +
(verticalPos - 10 + totalOffset) + (bounds.getVerticalPos() - 10 + totalOffset) +
' ' + ' ' +
(startx + 60) + (startx + 60) +
',' + ',' +
(verticalPos + 30 + totalOffset) + (bounds.getVerticalPos() + 30 + totalOffset) +
' ' + ' ' +
startx + startx +
',' + ',' +
(verticalPos + 20 + totalOffset) (bounds.getVerticalPos() + 20 + totalOffset)
); );
} }
bounds.bumpVerticalPos(30); totalOffset += 30;
msgModel.height += 30; const dx = Math.max(textWidth / 2, conf.width / 2);
const dx = Math.max(textWidth / 2, 100);
bounds.insert( bounds.insert(
startx - dx, startx - dx,
bounds.getVerticalPos() - 10 + totalOffset, bounds.getVerticalPos() - 10 + totalOffset,
stopx + dx, stopx + dx,
bounds.getVerticalPos() + 30 + totalOffset bounds.getVerticalPos() + 30 + totalOffset
); );
bounds.bumpVerticalPos(10);
msgModel.height += 10;
} else { } else {
totalOffset += conf.boxMargin;
line = g.append('line'); line = g.append('line');
line.attr('x1', startx); line.attr('x1', startx);
line.attr('y1', verticalPos + totalOffset); line.attr('y1', bounds.getVerticalPos() + totalOffset);
line.attr('x2', stopx); line.attr('x2', stopx);
line.attr('y2', verticalPos + totalOffset); line.attr('y2', bounds.getVerticalPos() + totalOffset);
bounds.bumpVerticalPos(10);
msgModel.height += 10;
bounds.insert( bounds.insert(
startx, startx,
bounds.getVerticalPos() - 10 + totalOffset, bounds.getVerticalPos() - 10 + totalOffset,
stopx, stopx,
bounds.getVerticalPos() + totalOffset bounds.getVerticalPos() + totalOffset
); );
msgModel.height += 10;
bounds.bumpVerticalPos(10);
} }
// Make an SVG Container // Make an SVG Container
// Draw the line // Draw the line
@ -387,7 +378,7 @@ const drawMessage = function(g, msgModel) {
line.attr('marker-start', 'url(' + url + '#sequencenumber)'); line.attr('marker-start', 'url(' + url + '#sequencenumber)');
g.append('text') g.append('text')
.attr('x', startx) .attr('x', startx)
.attr('y', verticalPos + 4 + totalOffset) .attr('y', bounds.getVerticalPos() + 4 + totalOffset)
.attr('font-family', 'sans-serif') .attr('font-family', 'sans-serif')
.attr('font-size', '12px') .attr('font-size', '12px')
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
@ -395,9 +386,10 @@ const drawMessage = function(g, msgModel) {
.attr('class', 'sequenceNumber') .attr('class', 'sequenceNumber')
.text(sequenceIndex); .text(sequenceIndex);
} }
bounds.bumpVerticalPos(totalOffset);
msgModel.height += totalOffset;
msgModel.stopy = msgModel.starty + msgModel.height; msgModel.stopy = msgModel.starty + msgModel.height;
bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy); bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy);
logger.debug(`mm.h:${msgModel.height} vs c.h:${msgModel.stopy - msgModel.starty}`);
}; };
export const drawActors = function(diagram, actors, actorKeys, verticalPos) { export const drawActors = function(diagram, actors, actorKeys, verticalPos) {
@ -472,8 +464,11 @@ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoop
msg.message = utils.wrapLabel(`[${msg.message}]`, loopWidth - 2 * conf.wrapPadding, textConf); msg.message = utils.wrapLabel(`[${msg.message}]`, loopWidth - 2 * conf.wrapPadding, textConf);
msg.width = loopWidth; msg.width = loopWidth;
const textHeight = utils.calculateTextHeight(msg.message, textConf); // const lines = msg.message.split(common.lineBreakRegex).length;
heightAdjust += textHeight; const textDims = utils.calculateTextDimensions(msg.message, textConf);
const totalOffset = textDims.height - conf.labelBoxHeight;
heightAdjust = postMargin + totalOffset;
logger.debug(`${totalOffset} - ${msg.message}`);
} }
addLoopFn(msg); addLoopFn(msg);
bounds.bumpVerticalPos(heightAdjust); bounds.bumpVerticalPos(heightAdjust);
@ -488,8 +483,9 @@ export const draw = function(text, id) {
parser.yy.clear(); parser.yy.clear();
parser.yy.setWrap(conf.wrap); parser.yy.setWrap(conf.wrap);
parser.parse(text + '\n'); parser.parse(text + '\n');
bounds.init(); bounds.init();
logger.debug(`C:${JSON.stringify(conf, null, 2)}`);
const diagram = select(`[id="${id}"]`); const diagram = select(`[id="${id}"]`);
// Fetch data from the parsing // Fetch data from the parsing
@ -553,7 +549,7 @@ export const draw = function(text, id) {
break; break;
case parser.yy.LINETYPE.LOOP_END: case parser.yy.LINETYPE.LOOP_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'loop', conf, bounds); svgDraw.drawLoop(diagram, loopModel, 'loop', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
break; break;
@ -635,6 +631,7 @@ export const draw = function(text, id) {
try { try {
// lastMsg = msg // lastMsg = msg
msgModel = msg.msgModel; msgModel = msg.msgModel;
msgModel.starty = bounds.getVerticalPos();
msgModel.sequenceIndex = sequenceIndex; msgModel.sequenceIndex = sequenceIndex;
drawMessage(diagram, msgModel); drawMessage(diagram, msgModel);
bounds.models.addMessage(msgModel); bounds.models.addMessage(msgModel);
@ -706,7 +703,7 @@ export const draw = function(text, id) {
' ' + ' ' +
(height + extraVertForTitle) (height + extraVertForTitle)
); );
logger.debug(`models: ${JSON.stringify(bounds.models, null, 2)}`); logger.debug(`models:`, bounds.models);
}; };
/** /**
@ -767,6 +764,11 @@ const getMaxMessageWidthPerActor = function(actors, messages) {
maxMessageWidthPerActor[msg.to] || 0, maxMessageWidthPerActor[msg.to] || 0,
messageWidth messageWidth
); );
} else if (isMessage && msg.from === actor.prevActor) {
maxMessageWidthPerActor[msg.from] = Math.max(
maxMessageWidthPerActor[msg.from] || 0,
messageWidth
);
} else if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) { } else if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) {
maxMessageWidthPerActor[msg.from] = Math.max( maxMessageWidthPerActor[msg.from] = Math.max(
maxMessageWidthPerActor[msg.from] || 0, maxMessageWidthPerActor[msg.from] || 0,
@ -861,7 +863,6 @@ const buildNoteModel = function(msg, actors) {
shouldWrap ? utils.wrapLabel(msg.message, conf.width, conf.noteFont()) : msg.message, shouldWrap ? utils.wrapLabel(msg.message, conf.width, conf.noteFont()) : msg.message,
conf.noteFont() conf.noteFont()
); );
logger.debug(`TD:[${textDimensions.width},${textDimensions.height}]`);
let noteModel = { let noteModel = {
width: shouldWrap width: shouldWrap
? conf.width ? conf.width
@ -892,14 +893,18 @@ const buildNoteModel = function(msg, actors) {
} else if (msg.to === msg.from) { } else if (msg.to === msg.from) {
textDimensions = utils.calculateTextDimensions( textDimensions = utils.calculateTextDimensions(
shouldWrap shouldWrap
? utils.wrapLabel(msg.message, Math.max(conf.width, actors[msg.to].width), conf.noteFont()) ? utils.wrapLabel(
msg.message,
Math.max(conf.width, actors[msg.from].width),
conf.noteFont()
)
: msg.message, : msg.message,
conf.noteFont() conf.noteFont()
); );
noteModel.width = shouldWrap noteModel.width = shouldWrap
? Math.max(conf.width, actors[msg.to].width) ? Math.max(conf.width, actors[msg.from].width)
: Math.max(actors[msg.to].width, conf.width, textDimensions.width + 2 * conf.noteMargin); : Math.max(actors[msg.from].width, conf.width, textDimensions.width + 2 * conf.noteMargin);
noteModel.startx = startx + (actors[msg.to].width - noteModel.width) / 2; noteModel.startx = startx + (actors[msg.from].width - noteModel.width) / 2;
} else { } else {
noteModel.width = noteModel.width =
Math.abs(startx + actors[msg.from].width / 2 - (stopx + actors[msg.to].width / 2)) + Math.abs(startx + actors[msg.from].width / 2 - (stopx + actors[msg.to].width / 2)) +
@ -916,6 +921,9 @@ const buildNoteModel = function(msg, actors) {
conf.noteFont() conf.noteFont()
); );
} }
logger.debug(
`NM:[${noteModel.startx},${noteModel.stopx},${noteModel.starty},${noteModel.stopy}:${noteModel.width},${noteModel.height}=${msg.message}]`
);
return noteModel; return noteModel;
}; };
@ -957,7 +965,7 @@ const buildMessageModel = function(msg, actors) {
if (msg.wrap && msg.message && !common.lineBreakRegex.test(msg.message)) { if (msg.wrap && msg.message && !common.lineBreakRegex.test(msg.message)) {
msgModel.message = utils.wrapLabel( msgModel.message = utils.wrapLabel(
msg.message, msg.message,
Math.max(msgModel.width, conf.width), Math.max(msgModel.width - 2 * conf.wrapPadding, conf.width),
conf.messageFont() conf.messageFont()
); );
} }
@ -1028,44 +1036,31 @@ const calculateLoopBounds = function(messages, actors) {
if (isNote) { if (isNote) {
noteModel = buildNoteModel(msg, actors); noteModel = buildNoteModel(msg, actors);
msg.noteModel = noteModel; msg.noteModel = noteModel;
let depth = 0;
stack.forEach(stk => { stack.forEach(stk => {
current = stk; current = stk;
current.from = Math.min(current.from, noteModel.startx); current.from = Math.min(current.from, noteModel.startx);
current.to = Math.max(current.to, noteModel.startx + noteModel.width); current.to = Math.max(current.to, noteModel.startx + noteModel.width);
current.width = current.width =
Math.max(current.width, Math.abs(current.from - current.to)) - Math.max(current.width, Math.abs(current.from - current.to)) - conf.labelBoxWidth;
50 -
conf.boxMargin * depth;
depth++;
}); });
} else { } else {
msgModel = buildMessageModel(msg, actors); msgModel = buildMessageModel(msg, actors);
msg.msgModel = msgModel; msg.msgModel = msgModel;
if (msg.from && msg.to && stack.length > 0) { if (msgModel.startx && msgModel.stopx && stack.length > 0) {
let depth = 0;
stack.forEach(stk => { stack.forEach(stk => {
current = stk; current = stk;
let from = actors[msg.from]; if (msgModel.startx === msgModel.stopx) {
let to = actors[msg.to]; let from = actors[msg.from];
if (from.x === to.x) { let to = actors[msg.to];
current.from = Math.min(current.from, from.x); current.from = Math.min(from.x - from.width / 2, current.from);
current.to = Math.max(current.to, to.x); current.to = Math.max(to.x + from.width / 2, current.to);
current.width = Math.max(current.width, from.width) - 50 - conf.boxMargin * depth;
} else {
if (from.x < to.x) {
current.from = Math.min(current.from, from.x);
current.to = Math.max(current.to, to.x);
} else {
current.from = Math.min(current.from, to.x);
current.to = Math.max(current.to, from.x);
}
current.width = current.width =
Math.max(current.width, Math.abs(current.from - current.to)) - Math.max(current.width, Math.abs(current.to - current.from)) - conf.labelBoxWidth;
50 - } else {
conf.boxMargin * depth; current.from = Math.min(msgModel.startx, current.from);
current.to = Math.max(msgModel.stopx, current.to);
current.width = Math.max(current.width, msgModel.width) - conf.labelBoxWidth;
} }
depth++;
}); });
} }
} }

View File

@ -1,4 +1,6 @@
import common from '../common/common'; import common from '../common/common';
import utils from '../../utils';
import { logger } from '../../logger';
export const drawRect = function(elem, rectData) { export const drawRect = function(elem, rectData) {
const rectElem = elem.append('rect'); const rectElem = elem.append('rect');
@ -36,18 +38,21 @@ export const drawText = function(elem, textData) {
switch (textData.valign) { switch (textData.valign) {
case 'top': case 'top':
case 'start': case 'start':
yfunc = () => textData.y + textData.textMargin; yfunc = () => Math.round(textData.y + textData.textMargin);
break; break;
case 'middle': case 'middle':
case 'center': case 'center':
yfunc = () => textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2; yfunc = () =>
Math.round(textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2);
break; break;
case 'bottom': case 'bottom':
case 'end': case 'end':
yfunc = () => yfunc = () =>
textData.y + Math.round(
(prevTextHeight + textHeight + 2 * textData.textMargin) - textData.y +
textData.textMargin; (prevTextHeight + textHeight + 2 * textData.textMargin) -
textData.textMargin
);
break; break;
} }
} }
@ -59,21 +64,21 @@ export const drawText = function(elem, textData) {
switch (textData.anchor) { switch (textData.anchor) {
case 'left': case 'left':
case 'start': case 'start':
textData.x = textData.x + textData.textMargin; textData.x = Math.round(textData.x + textData.textMargin);
textData.anchor = 'start'; textData.anchor = 'start';
textData.dominantBaseline = 'text-after-edge'; textData.dominantBaseline = 'text-after-edge';
textData.alignmentBaseline = 'middle'; textData.alignmentBaseline = 'middle';
break; break;
case 'middle': case 'middle':
case 'center': case 'center':
textData.x = textData.x + textData.width / 2; textData.x = Math.round(textData.x + textData.width / 2);
textData.anchor = 'middle'; textData.anchor = 'middle';
textData.dominantBaseline = 'middle'; textData.dominantBaseline = 'middle';
textData.alignmentBaseline = 'middle'; textData.alignmentBaseline = 'middle';
break; break;
case 'right': case 'right':
case 'end': case 'end':
textData.x = textData.x + textData.width - textData.textMargin; textData.x = Math.round(textData.x + textData.width - textData.textMargin);
textData.anchor = 'end'; textData.anchor = 'end';
textData.dominantBaseline = 'text-before-edge'; textData.dominantBaseline = 'text-before-edge';
textData.alignmentBaseline = 'middle'; textData.alignmentBaseline = 'middle';
@ -256,6 +261,15 @@ export const drawActivation = function(elem, bounds, verticalPos, conf, actorAct
* @param conf - diagrom configuration * @param conf - diagrom configuration
*/ */
export const drawLoop = function(elem, loopModel, labelText, conf) { export const drawLoop = function(elem, loopModel, labelText, conf) {
const {
boxMargin,
boxTextMargin,
labelBoxHeight,
labelBoxWidth,
messageFontFamily: fontFamily,
messageFontSize: fontSize,
messageFontWeight: fontWeight
} = conf;
const g = elem.append('g'); const g = elem.append('g');
const drawLoopLine = function(startx, starty, stopx, stopy) { const drawLoopLine = function(startx, starty, stopx, stopy) {
return g return g
@ -283,45 +297,51 @@ export const drawLoop = function(elem, loopModel, labelText, conf) {
txt.text = labelText; txt.text = labelText;
txt.x = loopModel.startx; txt.x = loopModel.startx;
txt.y = loopModel.starty; txt.y = loopModel.starty;
const msgFont = conf.messageFont(); txt.fontFamily = fontFamily;
txt.fontFamily = msgFont.fontFamily; txt.fontSize = fontSize;
txt.fontSize = msgFont.fontSize; txt.fontWeight = fontWeight;
txt.fontWeight = msgFont.fontWeight;
txt.anchor = 'middle'; txt.anchor = 'middle';
txt.valign = 'middle'; txt.valign = 'middle';
txt.tspan = false; txt.tspan = false;
txt.width = conf.labelBoxWidth || 50; txt.width = labelBoxWidth || 50;
txt.height = conf.labelBoxHeight || 20; txt.height = labelBoxHeight || 20;
txt.textMargin = conf.boxTextMargin; txt.textMargin = boxTextMargin;
txt.class = 'labelText'; txt.class = 'labelText';
drawLabel(g, txt); drawLabel(g, txt);
txt = getTextObj(); txt = getTextObj();
txt.text = loopModel.title; txt.text = loopModel.title;
txt.x = loopModel.startx + conf.labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2; txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2;
txt.y = loopModel.starty + conf.boxMargin + conf.boxTextMargin; txt.y = loopModel.starty + boxMargin + boxTextMargin;
txt.anchor = 'middle'; txt.anchor = 'middle';
txt.valign = 'middle';
txt.textMargin = boxTextMargin;
txt.class = 'loopText'; txt.class = 'loopText';
txt.fontFamily = msgFont.fontFamily; txt.fontFamily = fontFamily;
txt.fontSize = msgFont.fontSize; txt.fontSize = fontSize;
txt.fontWeight = msgFont.fontWeight; txt.fontWeight = fontWeight;
txt.wrap = true; txt.wrap = true;
let textElem = drawText(g, txt); let textElem = drawText(g, txt);
let textHeight = Math.round(
textElem.map(te => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr)
);
const textDims = utils.calculateTextDimensions(txt.text, txt);
logger.debug(`loop: ${textHeight} vs ${textDims.height} ${txt.text}`, textDims);
if (typeof loopModel.sectionTitles !== 'undefined') { if (typeof loopModel.sectionTitles !== 'undefined') {
loopModel.sectionTitles.forEach(function(item, idx) { loopModel.sectionTitles.forEach(function(item, idx) {
if (item.message) { if (item.message) {
txt.text = item.message; txt.text = item.message;
txt.x = loopModel.startx + (loopModel.stopx - loopModel.startx) / 2; txt.x = loopModel.startx + (loopModel.stopx - loopModel.startx) / 2;
txt.y = loopModel.sections[idx].y + conf.boxMargin + conf.boxTextMargin; txt.y = loopModel.sections[idx].y + boxMargin + boxTextMargin;
txt.class = 'loopText'; txt.class = 'loopText';
txt.anchor = 'middle'; txt.anchor = 'middle';
txt.valign = 'middle'; txt.valign = 'middle';
txt.tspan = false; txt.tspan = false;
txt.fontFamily = msgFont.fontFamily; txt.fontFamily = fontFamily;
txt.fontSize = msgFont.fontSize; txt.fontSize = fontSize;
txt.fontWeight = msgFont.fontWeight; txt.fontWeight = fontWeight;
txt.wrap = loopModel.wrap; txt.wrap = loopModel.wrap;
textElem = drawText(g, txt); textElem = drawText(g, txt);
let sectionHeight = Math.round( let sectionHeight = Math.round(
@ -329,7 +349,7 @@ export const drawLoop = function(elem, loopModel, labelText, conf) {
.map(te => (te._groups || te)[0][0].getBBox().height) .map(te => (te._groups || te)[0][0].getBBox().height)
.reduce((acc, curr) => acc + curr) .reduce((acc, curr) => acc + curr)
); );
loopModel.sections[idx].height += sectionHeight - (conf.boxMargin + conf.boxTextMargin); loopModel.sections[idx].height += sectionHeight - (boxMargin + boxTextMargin);
} }
}); });
} }

View File

@ -627,21 +627,21 @@ export const calculateTextDimensions = function(text, config) {
// of sans-serif. // of sans-serif.
const fontFamilies = ['sans-serif', fontFamily]; const fontFamilies = ['sans-serif', fontFamily];
const lines = text.split(common.lineBreakRegex); const lines = text.split(common.lineBreakRegex);
let maxWidth = 0, let dims = [];
height = 0;
const body = select('body'); const body = select('body');
// We don't want to leak DOM elements - if a removal operation isn't available // We don't want to leak DOM elements - if a removal operation isn't available
// for any reason, do not continue. // for any reason, do not continue.
if (!body.remove) { if (!body.remove) {
return { width: 0, height: 0 }; return { width: 0, height: 0, lineHeight: 0 };
} }
const g = body.append('svg'); const g = body.append('svg');
for (let line of lines) { for (let fontFamily of fontFamilies) {
let cheight = 0; let cheight = 0;
for (let fontFamily of fontFamilies) { let dim = { width: 0, height: 0, lineHeight: 0 };
for (let line of lines) {
const textObj = getTextObj(); const textObj = getTextObj();
textObj.text = line; textObj.text = line;
const textElem = drawSimpleText(g, textObj) const textElem = drawSimpleText(g, textObj)
@ -650,16 +650,26 @@ export const calculateTextDimensions = function(text, config) {
.style('font-family', fontFamily); .style('font-family', fontFamily);
let bBox = (textElem._groups || textElem)[0][0].getBBox(); let bBox = (textElem._groups || textElem)[0][0].getBBox();
maxWidth = Math.max(maxWidth, bBox.width); dim.width = Math.round(Math.max(dim.width, bBox.width));
cheight = Math.max(bBox.height, cheight); cheight = Math.round(bBox.height);
dim.height += cheight;
dim.lineHeight = Math.round(Math.max(dim.lineHeight, cheight));
} }
height += cheight; dims.push(dim);
} }
g.remove(); g.remove();
// Adds some padding, so the text won't sit exactly within the actor's borders let index =
const result = { width: Math.round(maxWidth), height: Math.round(height) }; isNaN(dims[1].height) ||
isNaN(dims[1].width) ||
isNaN(dims[1].lineHeight) ||
(dims[0].height > dims[1].height &&
dims[0].width > dims[1].width &&
dims[0].lineHeight > dims[1].lineHeight)
? 0
: 1;
const result = dims[index];
calculateTextDimensions[cacheKey] = result; calculateTextDimensions[cacheKey] = result;
return result; return result;
}; };