Merge pull request #1484 from chrismoran-bkt/develop

PR 1482 redux
This commit is contained in:
Knut Sveidqvist 2020-06-19 20:04:15 +02:00 committed by GitHub
commit 280c89a78d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 2339 additions and 1528 deletions

View File

@ -214,7 +214,7 @@ pie
## Related projects ## Related projects
- [Command Line Interface](https://github.com/mermaid-js/mermaid-cli) - [Command Line Interface](https://github.com/mermaid-js/mermaid.cli)
- [Live Editor](https://github.com/mermaid-js/mermaid-live-editor) - [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
- [HTTP Server](https://github.com/TomWright/mermaid-server) - [HTTP Server](https://github.com/TomWright/mermaid-server)

View File

@ -88,7 +88,7 @@ describe('Configuration', () => {
C -->|Three| F[fa:fa-car Car] C -->|Three| F[fa:fa-car Car]
`, `,
{ {
logLevel:0, arrowMarkerAbsolute: true,fontFamily: '"Noto Sans SC", sans-serif' arrowMarkerAbsolute: true
} }
); );

View File

@ -1,5 +1,11 @@
/* eslint-env jest */ /* eslint-env jest */
describe('Rerendering', () => { describe('Rerendering', () => {
it('should be able to render after an error has occured', () => {
const url = 'http://localhost:9000/render-after-error.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('#graphDiv').should('exist');
});
it('should be able to render and rerender a graph via API', () => { it('should be able to render and rerender a graph via API', () => {
const url = 'http://localhost:9000/rerender.html'; const url = 'http://localhost:9000/rerender.html';

View File

@ -4,15 +4,16 @@
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet" rel="stylesheet"
/> />
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style> <style>
body { body {
/* background: rgb(221, 208, 208); */ /* background: rgb(221, 208, 208); */
background:#333; /* background:#333; */
font-family: 'Arial'; font-family: 'Arial';
} }
h1 { color: white;} h1 { color: grey;}
.mermaid2 { .mermaid2 {
display: none; display: none;
} }
@ -20,44 +21,58 @@
</head> </head>
<body> <body>
<h1>info below</h1> <h1>info below</h1>
<div class="flex">
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart BT
subgraph two
b1
end
subgraph three
c1-->c2
end
c1 --apa apa apa--> b1
two --> c2
</div>
<div class="mermaid" style="width: 50%; height: 20%;"> <div class="mermaid" style="width: 50%; height: 20%;">
sequenceDiagram sequenceDiagram
Alice->>Bob:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be Alice->>Bob:Extremely utterly long line of longness which had preivously overflown the actor box as it is much longer than what it should be
Bob->>Alice: I'm short though Bob->>Alice: I'm short though
</div> </div>
<div class="mermaid2" style="width: 50%; height: 20%;"> <div class="mermaid2" style="width: 50%; height: 20%;">
flowchart TB flowchart TB
subgraph 1 subgraph two
A --> B; b1
A -.-> C; end
A ==> D; subgraph three
A ==> E; c1-->c2
B <--> F end
C <--> F c1 --apa apa apa--> b1
D <--> F b1 --> c2
E <--> F </div>
end <div class="mermaid" style="width: 50%; height: 20%;">
subgraph 2
A2 --x B2; flowchart BT
A2 -.-x C2; subgraph a
A2 ==x D2; b1 -- ok --> b2
A2 ==x E2; end
B2 x--x F2 a -- sert --> c
C2 x--x F2 c --> d
D2 x--x F2 b1 --> d
E2 x--x F2 a --asd123 --> d
end </div>
subgraph 3 <div class="mermaid2" style="width: 50%; height: 20%;">
A3 --o B3; stateDiagram-v2
A3 -.-o C3; state A {
A3 ==o D3; B1 --> B2: ok
A3 ==o E3; }
B3 o--o F3 A --> C: sert
C3 o--o F3 C --> D
D3 o--o F3 B1 --> D
E3 o--o F3 A --> D: asd123
end </div>
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
</div> </div>
<script src="./mermaid.js"></script> <script src="./mermaid.js"></script>
@ -66,18 +81,17 @@ flowchart TB
// console.error('Mermaid error: ', err); // console.error('Mermaid error: ', err);
}; };
mermaid.initialize({ mermaid.initialize({
theme: 'dark', // theme: 'dark',
// arrowMarkerAbsolute: true, // arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0, logLevel: 0,
flowchart: { curve: 'linear',htmlLabels: false }, flowchart: { curve: 'linear', "htmlLabels": false },
// gantt: { axisFormat: '%m/%d/%Y' }, // gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50, showSequenceNumbers: true }, sequence: { actorMargin: 50, showSequenceNumbers: true },
// sequenceDiagram: { actorMargin: 300 } // deprecated // sequenceDiagram: { actorMargin: 300 } // deprecated
fontFamily: '"arial", sans-serif', fontFamily: '"arial", sans-serif',
curve: 'linear', curve: 'linear',
securityLevel: 'loose', securityLevel: 'loose'
htmlLabels: false
}); });
function callback(){alert('It worked');} function callback(){alert('It worked');}
</script> </script>

View File

@ -6,12 +6,12 @@
<style> <style>
body { body {
/* font-family: 'Mansalva', cursive;*/ /* font-family: 'Mansalva', cursive;*/
font-family: '"Noto Sans SC", sans-serif'; font-family: 'Mansalva', cursive;
}
.mermaid-main-font {
font-family: '"Noto Sans SC", sans-serif';
/* font-family: var(--mermaid-font-family); */
} }
/* .mermaid-main-font {
font-family: "trebuchet ms", verdana, arial;
font-family: var(--mermaid-font-family);
} */
/* :root { /* :root {
--mermaid-font-family: '"trebuchet ms", verdana, arial'; --mermaid-font-family: '"trebuchet ms", verdana, arial';
--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive; --mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
@ -27,7 +27,7 @@
<script> <script>
// Notice startOnLoad=false // Notice startOnLoad=false
// This prevents default handling in mermaid from render before the e2e logic is applied // This prevents default handling in mermaid from render before the e2e logic is applied
window.mermaidDefault = { mermaid.initialize({
startOnLoad: false, startOnLoad: false,
useMaxWidth: true, useMaxWidth: true,
// "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}", // "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
@ -35,8 +35,7 @@
// fontFamily: '"Comic Sans MS", "Comic Sans", cursive' // fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
// fontFamily: '"Mansalva", cursive', // fontFamily: '"Mansalva", cursive',
fontFamily: '"Noto Sans SC", sans-serif' fontFamily: '"Noto Sans SC", sans-serif'
}; });
mermaid.initialize(window.mermaidDefault);
</script> </script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
</head>
<body>
<div id="graph">
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.init({ startOnLoad: false });
mermaid.mermaidAPI.initialize();
try{
mermaid.mermaidAPI.render("graphDiv",
`>`);
} catch(e){}
mermaid.mermaidAPI.render("graphDiv",
`graph LR\n a --> b`, html => {
document.getElementById('graph').innerHTML=html;
});
</script>
</body>
</html>

View File

@ -30,11 +30,6 @@ const contentLoaded = function() {
div.innerHTML = graphObj.code; div.innerHTML = graphObj.code;
document.getElementsByTagName('body')[0].appendChild(div); document.getElementsByTagName('body')[0].appendChild(div);
} }
if (window.mermaidDefault.fontFamily) {
graphObj.mermaid.fontFamily = window.mermaidDefault.fontFamily;
}
global.mermaid.initialize(graphObj.mermaid); global.mermaid.initialize(graphObj.mermaid);
global.mermaid.init(); global.mermaid.init();
} }

1609
dist/mermaid.core.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1609
dist/mermaid.js vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

12
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -34,7 +34,7 @@
window.$docsify = { window.$docsify = {
search: 'auto', search: 'auto',
name: 'mermaid', name: 'mermaid',
repo: 'https://github.com/mermaid-js/mermaid', repo: 'https://github.com/knsv/mermaid',
loadSidebar: true, loadSidebar: true,
mergeNavbar: true, mergeNavbar: true,
maxLevel: 4, maxLevel: 4,

View File

@ -2,6 +2,8 @@ import { logger } from '../logger'; // eslint-disable-line
import createLabel from './createLabel'; import createLabel from './createLabel';
import { line, curveBasis, select } from 'd3'; import { line, curveBasis, select } from 'd3';
import { getConfig } from '../config'; import { getConfig } from '../config';
import utils from '../utils';
// import { calcLabelPosition } from '../utils';
let edgeLabels = {}; let edgeLabels = {};
@ -39,11 +41,19 @@ export const insertEdgeLabel = (elem, edge) => {
edge.height = bbox.height; edge.height = bbox.height;
}; };
export const positionEdgeLabel = edge => { export const positionEdgeLabel = (edge, points) => {
logger.info('Moving label', edge.id, edge.label, edgeLabels[edge.id]); logger.info('Moving label', edge.id, edge.label, edgeLabels[edge.id]);
if (edge.label) { if (edge.label) {
const el = edgeLabels[edge.id]; const el = edgeLabels[edge.id];
el.attr('transform', 'translate(' + edge.x + ', ' + edge.y + ')'); let x = edge.x;
let y = edge.y;
if (points) {
// debugger;
const pos = utils.calcLabelPosition(points);
x = pos.x;
y = pos.y;
}
el.attr('transform', 'translate(' + x + ', ' + y + ')');
} }
}; };
@ -61,47 +71,80 @@ export const positionEdgeLabel = edge => {
// }; // };
const outsideNode = (node, point) => { const outsideNode = (node, point) => {
// logger.warn('Checking bounds ', node, point);
const x = node.x; const x = node.x;
const y = node.y; const y = node.y;
const dx = Math.abs(point.x - x); const dx = Math.abs(point.x - x);
const dy = Math.abs(point.y - y); const dy = Math.abs(point.y - y);
const w = node.width / 2; const w = node.width / 2;
const h = node.height / 2; const h = node.height / 2;
if (dx > w || dy > h) { if (dx >= w || dy >= h) {
return true; return true;
} }
return false; return false;
}; };
const intersection = (node, outsidePoint, insidePoint) => { export const intersection = (node, outsidePoint, insidePoint) => {
logger.trace('intersection o:', outsidePoint, ' i:', insidePoint, node); logger.warn('intersection calc o:', outsidePoint, ' i:', insidePoint, node);
const x = node.x; const x = node.x;
const y = node.y; const y = node.y;
const dx = Math.abs(x - insidePoint.x); const dx = Math.abs(x - insidePoint.x);
const w = node.width / 2; const w = node.width / 2;
let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;
const dy = Math.abs(y - insidePoint.y);
const h = node.height / 2; const h = node.height / 2;
let q = insidePoint.y < outsidePoint.y ? h - dy : h - dy;
const edges = {
x1: x - w,
x2: x + w,
y1: y - h,
y2: y + h
};
if (
outsidePoint.x === edges.x1 ||
outsidePoint.x === edges.x2 ||
outsidePoint.y === edges.y1 ||
outsidePoint.y === edges.y2
) {
// logger.warn('calc equals on edge');
return outsidePoint;
}
const Q = Math.abs(outsidePoint.y - insidePoint.y); const Q = Math.abs(outsidePoint.y - insidePoint.y);
const R = Math.abs(outsidePoint.x - insidePoint.x); const R = Math.abs(outsidePoint.x - insidePoint.x);
if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h || false) { // eslint-disable-line // log.warn();
if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { // eslint-disable-line
// Intersection is top or bottom of rect. // Intersection is top or bottom of rect.
// let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;
let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;
r = (R * q) / Q; r = (R * q) / Q;
const res = {
return { x: insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - r,
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - r, y: outsidePoint.y + q
y: insidePoint.y + q
}; };
logger.warn(`topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res);
return res;
} else { } else {
q = (Q * r) / R; // Intersection onn sides of rect
r = (R * q) / Q; // q = (Q * r) / R;
// q = 2;
// r = (R * q) / Q;
if (insidePoint.x < outsidePoint.x) {
r = outsidePoint.x - w - x;
} else {
// r = outsidePoint.x - w - x;
r = x - w - outsidePoint.x;
}
let q = (q = (Q * r) / R);
logger.warn(`sides calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, {
x: insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x + dx - w,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q
});
return { return {
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x + dx - w, x: insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x + dx - w,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q y: insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q
}; };
} }
@ -110,7 +153,7 @@ const intersection = (node, outsidePoint, insidePoint) => {
//(edgePaths, e, edge, clusterDb, diagramtype, graph) //(edgePaths, e, edge, clusterDb, diagramtype, graph)
export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph) { export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph) {
let points = edge.points; let points = edge.points;
let pointsHasChanged = false;
const tail = graph.node(e.v); const tail = graph.node(e.v);
var head = graph.node(e.w); var head = graph.node(e.w);
@ -147,11 +190,12 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
} }
lastPointOutside = point; lastPointOutside = point;
}); });
pointsHasChanged = true;
} }
if (edge.fromCluster) { if (edge.fromCluster) {
logger.trace('edge', edge); logger.trace('edge', edge);
logger.trace('from cluster', clusterDb[edge.toCluster]); logger.warn('from cluster', clusterDb[edge.fromCluster]);
const updatedPoints = []; const updatedPoints = [];
let lastPointOutside; let lastPointOutside;
let isInside = false; let isInside = false;
@ -160,7 +204,7 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
const node = clusterDb[edge.fromCluster].node; const node = clusterDb[edge.fromCluster].node;
if (!outsideNode(node, point) && !isInside) { if (!outsideNode(node, point) && !isInside) {
logger.trace('inside', edge.toCluster, point); logger.warn('inside', edge.fromCluster, point, node);
// First point inside the rect // First point inside the rect
const insterection = intersection(node, lastPointOutside, point); const insterection = intersection(node, lastPointOutside, point);
@ -176,6 +220,7 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
lastPointOutside = point; lastPointOutside = point;
} }
points = updatedPoints; points = updatedPoints;
pointsHasChanged = true;
} }
// The data for our line // The data for our line
@ -275,4 +320,8 @@ export const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph)
break; break;
default: default:
} }
if (pointsHasChanged) {
return points;
}
}; };

View File

@ -0,0 +1,63 @@
import { intersection } from './edges';
import { setLogLevel, logger } from '../logger';
describe('Graphlib decorations', () => {
let node;
beforeEach(function () {
setLogLevel(1);
node = { x:171, y:100, width: 210, height: 184};
});
describe('intersection', function () {
it('case 1 - intersection on left edge of box', function () {
const o = {x: 31, y: 143.2257070163421};
const i = {x: 99.3359375, y: 100}
const int = intersection(node, o, i);
expect(int.x).toBe(66)
expect(int.y).toBeCloseTo(122.139)
});
it('case 2 - intersection on left edge of box', function () {
const o = {x: 310.2578125, y: 169.88002060631462};
const i = {x: 127.96875, y: 100};
const node2 = {
height: 337.5,
width: 184.4609375,
x: 100.23046875,
y: 176.75
}
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(192.4609375)
expect(int.y).toBeCloseTo(145.15711441743503)
});
it('case 3 - intersection on otop of box outside point greater then inside point', function () {
const o = {x: 157.21875, y: 38.83361558001693};
const i = {x: 104.1328125, y: 105};
const node2 = {
width: 211.96875,
x: 113.984375,
y: 164.25,
height: 176.5
}
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(127.39979619565217)
expect(int.y).toBeCloseTo(76)
});
it('case 4 - intersection on top of box inside point greater then inside point', function () {
const o = {x: 144.65625, y: 38.83361558001693};
const i = {x: 197.7421875, y: 105};
const node2 = {
width: 211.96875,
x: 113.984375,
y: 164.25,
height: 176.5
}
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(167.9232336956522)
expect(int.y).toBeCloseTo(76)
});
});
});

View File

@ -124,8 +124,8 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
const edge = graph.edge(e); const edge = graph.edge(e);
log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge); log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
insertEdge(edgePaths, e, edge, clusterDb, diagramtype, graph); const updatedPath = insertEdge(edgePaths, e, edge, clusterDb, diagramtype, graph);
positionEdgeLabel(edge); positionEdgeLabel(edge, updatedPath);
}); });
return elem; return elem;

View File

@ -171,7 +171,9 @@ export const validate = graph => {
export const findNonClusterChild = (id, graph) => { export const findNonClusterChild = (id, graph) => {
// const node = graph.node(id); // const node = graph.node(id);
log.trace('Searching', id); log.trace('Searching', id);
const children = graph.children(id); // const children = graph.children(id).reverse();
const children = graph.children(id); //.reverse();
log.trace('Searching children of id ', id, children);
if (children.length < 1) { if (children.length < 1) {
log.trace('This is a valid node', id); log.trace('This is a valid node', id);
return id; return id;
@ -213,7 +215,7 @@ export const adjustClustersAndEdges = (graph, depth) => {
graph.nodes().forEach(function(id) { graph.nodes().forEach(function(id) {
const children = graph.children(id); const children = graph.children(id);
if (children.length > 0) { if (children.length > 0) {
log.trace( log.warn(
'Cluster identified', 'Cluster identified',
id, id,
' Replacement id in edges: ', ' Replacement id in edges: ',
@ -266,17 +268,17 @@ export const adjustClustersAndEdges = (graph, depth) => {
// Check if link is either from or to a cluster // Check if link is either from or to a cluster
log.trace('Fix', clusterDb, 'ids:', e.v, e.w, 'Translateing: ', clusterDb[e.v], clusterDb[e.w]); log.trace('Fix', clusterDb, 'ids:', e.v, e.w, 'Translateing: ', clusterDb[e.v], clusterDb[e.w]);
if (clusterDb[e.v] || clusterDb[e.w]) { if (clusterDb[e.v] || clusterDb[e.w]) {
log.trace('Fixing and trixing - removing', e.v, e.w, e.name); log.warn('Fixing and trixing - removing', e.v, e.w, e.name);
v = getAnchorId(e.v); v = getAnchorId(e.v);
w = getAnchorId(e.w); w = getAnchorId(e.w);
graph.removeEdge(e.v, e.w, e.name); graph.removeEdge(e.v, e.w, e.name);
if (v !== e.v) edge.fromCluster = e.v; if (v !== e.v) edge.fromCluster = e.v;
if (w !== e.w) edge.toCluster = e.w; if (w !== e.w) edge.toCluster = e.w;
log.trace('Replacing with', v, w, e.name); log.warn('Replacing with', v, w, e.name);
graph.setEdge(v, w, edge, e.name); graph.setEdge(v, w, edge, e.name);
} }
}); });
log.debug('Adjusted Graph', graphlib.json.write(graph)); log.warn('Adjusted Graph', graphlib.json.write(graph));
log.trace(clusterDb); log.trace(clusterDb);

View File

@ -10,6 +10,7 @@ function addConf(conf, key, value) {
} }
return conf; return conf;
} }
describe('when parsing a sequenceDiagram', function() { describe('when parsing a sequenceDiagram', function() {
beforeEach(function() { beforeEach(function() {
parser.yy = sequenceDb; parser.yy = sequenceDb;
@ -1190,7 +1191,6 @@ sequenceDiagram
Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can! Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can!
Note left of Alice: Bob thinks Note left of Alice: Bob thinks
Bob->>Alice: Fine!`; Bob->>Alice: Fine!`;
parser.parse(str); parser.parse(str);
renderer.draw(str, 'tst'); renderer.draw(str, 'tst');
@ -1214,7 +1214,6 @@ sequenceDiagram
Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can! Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can!
Note left of Alice: Bob thinks Note left of Alice: Bob thinks
Bob->>Alice: Fine!`; Bob->>Alice: Fine!`;
parser.parse(str); parser.parse(str);
// renderer.setConf(mermaidAPI.getConfig().sequence); // renderer.setConf(mermaidAPI.getConfig().sequence);
renderer.draw(str, 'tst'); renderer.draw(str, 'tst');
@ -1242,7 +1241,6 @@ Alice->Bob: Hello Bob, how are you?
loop Cheers loop Cheers
Bob->Alice: Fine! Bob->Alice: Fine!
end`; end`;
parser.parse(str); parser.parse(str);
renderer.draw(str, 'tst'); renderer.draw(str, 'tst');
@ -1274,6 +1272,7 @@ end`;
}); });
}); });
describe('when rendering a sequenceDiagram with actor mirror activated', function() { describe('when rendering a sequenceDiagram with actor mirror activated', function() {
let conf; let conf;
beforeEach(function() { beforeEach(function() {

View File

@ -55,7 +55,29 @@ const conf = {
// wrap text // wrap text
wrapEnabled: false, wrapEnabled: false,
// padding for wrapped text // padding for wrapped text
wrapPadding: 15 wrapPadding: 15,
messageFont: () => {
return {
fontFamily: conf.messageFontFamily,
fontSize: conf.messageFontSize,
fontWeight: conf.messageFontWeight
};
},
noteFont: () => {
return {
fontFamily: conf.noteFontFamily,
fontSize: conf.noteFontSize,
fontWeight: conf.noteFontWeight
};
},
actorFont: () => {
return {
fontFamily: conf.actorFontFamily,
fontSize: conf.actorFontSize,
fontWeight: conf.actorFontWeight
};
}
}; };
export const bounds = { export const bounds = {
@ -128,10 +150,10 @@ export const bounds = {
this.updateBounds(_startx, _starty, _stopx, _stopy); this.updateBounds(_startx, _starty, _stopx, _stopy);
}, },
newActivation: function(message, diagram) { newActivation: function(message, diagram, actors) {
const actorRect = parser.yy.getActors()[message.from.actor]; const actorRect = actors[message.from.actor];
const stackedSize = actorActivations(message.from.actor).length; const stackedSize = actorActivations(message.from.actor).length;
const x = actorRect.x + conf.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,
starty: this.verticalPos + 2, starty: this.verticalPos + 2,
@ -436,9 +458,9 @@ export const drawActors = function(diagram, actors, actorKeys, verticalPos) {
const actor = actors[actorKeys[i]]; const actor = actors[actorKeys[i]];
// Add some rendering data to the object // Add some rendering data to the object
actor.width = typeof actor.width === 'undefined' ? calculateActorWidth(actor) : actor.width; actor.width = actor.width ? actor.width : conf.width;
actor.height = conf.height; actor.height = conf.height;
actor.margin = conf.actorMargin; actor.margin = actor.margin || conf.actorMargin;
actor.x = prevWidth + prevMargin; actor.x = prevWidth + prevMargin;
actor.y = verticalPos; actor.y = verticalPos;
@ -489,52 +511,23 @@ const actorFlowVerticaBounds = function(actor) {
return [left, right]; return [left, right];
}; };
/**
* This calculates the actor's width, taking into account both the statically configured width,
* and the actor's description.
*
* If the description text has greater length, we extend the width of the actor, so it's description
* won't overflow.
*
* @param actor - An actor object
* @return - The width for the given actor
*/
const calculateActorWidth = function(actor) {
if (!actor.description) {
return conf.width;
}
return actor.wrap
? conf.width
: Math.max(
conf.width,
utils.calculateTextWidth(actor.description, {
fontSize: conf.actorFontSize,
fontFamily: conf.actorFontFamily,
fontWeight: conf.actorFontWeight,
margin: conf.wrapPadding
})
);
};
function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) { function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) {
let heightAdjust = 0; let heightAdjust = 0;
bounds.bumpVerticalPos(preMargin); bounds.bumpVerticalPos(preMargin);
if (msg.message && msg.wrap && loopWidths[msg.message]) { if (msg.message && loopWidths[msg.message]) {
let loopWidth = loopWidths[msg.message].width; let loopWidth = loopWidths[msg.message].width;
let minSize = let minSize =
Math.round((3 * conf.fontSize) / 4) < 10 Math.round((3 * conf.messageFontSize) / 4) < 10
? conf.fontSize ? conf.messageFontSize
: Math.round((3 * conf.fontSize) / 4); : Math.round((3 * conf.messageFontSize) / 4);
let textConf = { let textConf = conf.messageFont();
fontSize: minSize, textConf.fontSize = minSize;
fontFamily: conf.messageFontFamily, msg.message = utils.wrapLabel(
fontWeight: conf.messageFontWeight, `[${msg.message}]`,
margin: conf.wrapPadding loopWidth - 20 - 2 * conf.wrapPadding,
}; textConf
msg.message = msg.message );
? utils.wrapLabel(`[${msg.message}]`, loopWidth, textConf)
: msg.message;
heightAdjust = Math.max( heightAdjust = Math.max(
0, 0,
utils.calculateTextHeight(msg.message, textConf) - (preMargin + postMargin) utils.calculateTextHeight(msg.message, textConf) - (preMargin + postMargin)
@ -559,7 +552,6 @@ export const draw = function(text, id) {
let startx; let startx;
let stopx; let stopx;
let forceWidth;
// Fetch data from the parsing // Fetch data from the parsing
const actors = parser.yy.getActors(); const actors = parser.yy.getActors();
@ -600,8 +592,9 @@ export const draw = function(text, id) {
messages.forEach(function(msg) { messages.forEach(function(msg) {
let loopData, let loopData,
noteWidth, noteWidth,
noteStart,
noteEnd,
textWidth, textWidth,
textConf,
shouldWrap = msg.wrap && msg.message && !common.lineBreakRegex.test(msg.message); shouldWrap = msg.wrap && msg.message && !common.lineBreakRegex.test(msg.message);
switch (msg.type) { switch (msg.type) {
@ -610,18 +603,27 @@ export const draw = function(text, id) {
startx = actors[msg.from].x; startx = actors[msg.from].x;
stopx = actors[msg.to].x; stopx = actors[msg.to].x;
textConf = { noteStart = startx + actors[msg.from].width / 2;
fontSize: conf.noteFontSize, noteEnd = stopx + actors[msg.to].width / 2;
fontFamily: conf.noteFontFamily, textWidth = utils.calculateTextWidth(
fontWeight: conf.noteFontWeight, shouldWrap ? utils.wrapLabel(msg.message, conf.width, conf.noteFont()) : msg.message,
margin: conf.wrapPadding conf.noteFont()
}; );
textWidth = utils.calculateTextWidth(msg.message, textConf); noteWidth = shouldWrap ? conf.width : Math.max(conf.width, textWidth + 2 * conf.noteMargin);
noteWidth = shouldWrap ? conf.width : Math.max(conf.width, textWidth);
if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) { if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) {
noteWidth = shouldWrap
? conf.width
: Math.max(
actors[msg.from].width / 2 + actors[msg.to].width / 2,
textWidth + 2 * conf.noteMargin
);
if (shouldWrap) { if (shouldWrap) {
msg.message = utils.wrapLabel(msg.message, noteWidth, textConf); msg.message = utils.wrapLabel(
msg.message,
noteWidth - 2 * conf.wrapPadding,
conf.noteFont()
);
} }
drawNote( drawNote(
diagram, diagram,
@ -631,8 +633,18 @@ export const draw = function(text, id) {
noteWidth noteWidth
); );
} else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) { } else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) {
noteWidth = shouldWrap
? conf.width
: Math.max(
actors[msg.from].width / 2 + actors[msg.to].width / 2,
textWidth + 2 * conf.noteMargin
);
if (shouldWrap) { if (shouldWrap) {
msg.message = utils.wrapLabel(msg.message, noteWidth, textConf); msg.message = utils.wrapLabel(
msg.message,
noteWidth - 2 * conf.wrapPadding,
conf.noteFont()
);
} }
drawNote( drawNote(
diagram, diagram,
@ -643,8 +655,25 @@ export const draw = function(text, id) {
); );
} else if (msg.to === msg.from) { } else if (msg.to === msg.from) {
// Single-actor over // Single-actor over
textWidth = utils.calculateTextWidth(
shouldWrap
? utils.wrapLabel(
msg.message,
Math.max(conf.width, actors[msg.to].width),
conf.noteFont()
)
: msg.message,
conf.noteFont()
);
noteWidth = shouldWrap
? Math.max(conf.width, actors[msg.to].width)
: Math.max(actors[msg.to].width, conf.width, textWidth + 2 * conf.noteMargin);
if (shouldWrap) { if (shouldWrap) {
msg.message = utils.wrapLabel(msg.message, noteWidth, textConf); msg.message = utils.wrapLabel(
msg.message,
noteWidth - 2 * conf.wrapPadding,
conf.noteFont()
);
} }
drawNote( drawNote(
diagram, diagram,
@ -655,23 +684,19 @@ export const draw = function(text, id) {
); );
} else { } else {
// Multi-actor over // Multi-actor over
forceWidth = Math.abs(startx - stopx) + conf.actorMargin / 2; noteWidth = Math.abs(noteStart - noteEnd) + conf.actorMargin;
if (shouldWrap) { if (shouldWrap) {
noteWidth = forceWidth; msg.message = utils.wrapLabel(msg.message, noteWidth, conf.noteFont());
msg.message = utils.wrapLabel(msg.message, noteWidth, textConf);
} else {
noteWidth = Math.max(forceWidth, textWidth - 2 * conf.noteMargin);
} }
let x = let x =
startx < stopx startx < stopx
? startx + (actors[msg.from].width - conf.actorMargin / 2) / 2 ? startx + actors[msg.from].width / 2 - conf.actorMargin / 2
: stopx + (actors[msg.to].width - conf.actorMargin / 2) / 2; : stopx + actors[msg.to].width / 2 - conf.actorMargin / 2;
drawNote(diagram, x, bounds.getVerticalPos(), msg, noteWidth);
drawNote(diagram, x, bounds.getVerticalPos(), msg, forceWidth);
} }
break; break;
case parser.yy.LINETYPE.ACTIVE_START: case parser.yy.LINETYPE.ACTIVE_START:
bounds.newActivation(msg, diagram); bounds.newActivation(msg, diagram, actors);
break; break;
case parser.yy.LINETYPE.ACTIVE_END: case parser.yy.LINETYPE.ACTIVE_END:
activeEnd(msg, bounds.getVerticalPos()); activeEnd(msg, bounds.getVerticalPos());
@ -761,12 +786,6 @@ export const draw = function(text, id) {
const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1; const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1;
startx = fromBounds[fromIdx]; startx = fromBounds[fromIdx];
stopx = toBounds[toIdx]; stopx = toBounds[toIdx];
textConf = {
fontSize: conf.messageFontSize,
fontFamily: conf.messageFontFamily,
fontWeight: conf.messageFontWeight,
margin: conf.wrapPadding
};
if (shouldWrap) { if (shouldWrap) {
msg.message = utils.wrapLabel( msg.message = utils.wrapLabel(
msg.message, msg.message,
@ -774,7 +793,7 @@ export const draw = function(text, id) {
Math.abs(stopx - startx) + conf.messageMargin * 2, Math.abs(stopx - startx) + conf.messageMargin * 2,
conf.width + conf.messageMargin * 2 conf.width + conf.messageMargin * 2
), ),
textConf conf.messageFont()
); );
} }
@ -887,19 +906,11 @@ const getMaxMessageWidthPerActor = function(actors, messages) {
const isNote = msg.placement !== undefined; const isNote = msg.placement !== undefined;
const isMessage = !isNote; const isMessage = !isNote;
const fontSize = isNote ? conf.noteFontSize : conf.messageFontSize; const textFont = isNote ? conf.noteFont() : conf.messageFont();
const fontFamily = isNote ? conf.noteFontFamily : conf.messageFontFamily;
const fontWeight = isNote ? conf.noteFontWeight : conf.messageFontWeight;
const textConf = { fontFamily, fontSize, fontWeight, margin: conf.wrapPadding };
let wrappedMessage = msg.wrap let wrappedMessage = msg.wrap
? utils.wrapLabel(msg.message, conf.width - conf.noteMargin, textConf) ? utils.wrapLabel(msg.message, conf.width - conf.noteMargin, textFont)
: msg.message; : msg.message;
const messageDimensions = utils.calculateTextDimensions(wrappedMessage, { const messageDimensions = utils.calculateTextDimensions(wrappedMessage, textFont);
fontSize,
fontFamily,
fontWeight,
margin: conf.wrapPadding
});
const messageWidth = messageDimensions.width; const messageWidth = messageDimensions.width;
/* /*
@ -954,6 +965,7 @@ const getMaxMessageWidthPerActor = function(actors, messages) {
} }
}); });
logger.debug('MaxMessages:', maxMessageWidthPerActor);
return maxMessageWidthPerActor; return maxMessageWidthPerActor;
}; };
@ -969,6 +981,24 @@ const getMaxMessageWidthPerActor = function(actors, messages) {
*/ */
const calculateActorMargins = function(actors, actorToMessageWidth) { const calculateActorMargins = function(actors, actorToMessageWidth) {
let maxHeight = 0; let maxHeight = 0;
Object.keys(actors).forEach(prop => {
const actor = actors[prop];
if (actor.wrap) {
actor.description = utils.wrapLabel(
actor.description,
conf.width - 2 * conf.wrapPadding,
conf.actorFont()
);
}
const actDims = utils.calculateTextDimensions(actor.description, conf.actorFont());
actor.width = actor.wrap
? conf.width
: Math.max(conf.width, actDims.width + 2 * conf.wrapPadding);
actor.height = actor.wrap ? Math.max(actDims.height, conf.height) : conf.height;
maxHeight = Math.max(maxHeight, actor.height);
});
for (let actorKey in actorToMessageWidth) { for (let actorKey in actorToMessageWidth) {
const actor = actors[actorKey]; const actor = actors[actorKey];
@ -976,13 +1006,6 @@ const calculateActorMargins = function(actors, actorToMessageWidth) {
continue; continue;
} }
const textConf = {
fontSize: conf.actorFontSize,
fontFamily: conf.actorFontFamily,
fontWeight: conf.actorFontWeight,
margin: conf.wrapPadding
};
const nextActor = actors[actor.nextActor]; const nextActor = actors[actor.nextActor];
// No need to space out an actor that doesn't have a next link // No need to space out an actor that doesn't have a next link
@ -990,18 +1013,6 @@ const calculateActorMargins = function(actors, actorToMessageWidth) {
continue; continue;
} }
[actor, nextActor].forEach(function(act) {
if (act.wrap) {
act.description = utils.wrapLabel(act.description, conf.width, textConf);
}
const actDims = utils.calculateTextDimensions(act.description, textConf);
act.width = act.wrap ? conf.width : Math.max(conf.width, actDims.width);
act.height = act.wrap ? Math.max(actDims.height, conf.height) : conf.height;
logger.debug(`Actor h:${act.height} ${actDims.height} d:${act.description}`);
maxHeight = Math.max(maxHeight, act.height);
});
const messageWidth = actorToMessageWidth[actorKey]; const messageWidth = actorToMessageWidth[actorKey];
const actorWidth = messageWidth + conf.actorMargin - actor.width / 2 - nextActor.width / 2; const actorWidth = messageWidth + conf.actorMargin - actor.width / 2 - nextActor.width / 2;
@ -1050,18 +1061,22 @@ const calculateLoopMargins = function(messages, actors) {
current = stk; current = stk;
let from = actors[msg.from]; let from = actors[msg.from];
let to = actors[msg.to]; let to = actors[msg.to];
if (from.x < to.x) { if (from.x === to.x) {
current.from = Math.min(current.from, from.x); current.from = current.to = from.x;
current.to = Math.max(current.to, to.x); current.width = from.width;
} else { } else {
current.from = Math.min(current.from, to.x); if (from.x < to.x) {
current.to = Math.max(current.to, from.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 = Math.abs(current.from - current.to) - 20 + 2 * conf.wrapPadding;
} }
current.width = Math.abs(current.from - current.to) - 20 + 2 * conf.wrapPadding;
}); });
} }
}); });
logger.debug('LoopWidths:', { loops, actors });
return loops; return loops;
}; };

View File

@ -148,7 +148,7 @@ let actorCnt = -1;
* Draws an actor in the diagram with the attaced line * Draws an actor in the diagram with the attaced line
* @param elem - The diagram we'll draw to. * @param elem - The diagram we'll draw to.
* @param actor - The actor to draw. * @param actor - The actor to draw.
* @param conf - utils.drawText implementation discriminator object * @param conf - drawText implementation discriminator object
*/ */
export const drawActor = function(elem, actor, conf) { export const drawActor = function(elem, actor, conf) {
const center = actor.x + actor.width / 2; const center = actor.x + actor.width / 2;
@ -241,16 +241,18 @@ export const drawLoop = function(elem, bounds, labelText, conf) {
} }
let minSize = let minSize =
Math.round((3 * conf.fontSize) / 4) < 10 ? conf.fontSize : Math.round((3 * conf.fontSize) / 4); Math.round((3 * conf.messageFontSize) / 4) < 10
? conf.messageFontSize
: Math.round((3 * conf.messageFontSize) / 4);
let txt = getTextObj(); let txt = getTextObj();
txt.text = labelText; txt.text = labelText;
txt.x = bounds.startx; txt.x = bounds.startx;
txt.y = bounds.starty; txt.y = bounds.starty;
txt.labelMargin = 1.5 * 10; // This is the small box that says "loop" txt.labelMargin = 1.5 * 10; // This is the small box that says "loop"
txt.fontFamily = conf.fontFamily; txt.fontFamily = conf.messageFontFamily;
txt.fontSize = minSize; txt.fontSize = minSize;
txt.fontWeight = conf.fontWeight; txt.fontWeight = conf.messageFontWeight;
txt.class = 'labelText'; // Its size & position are fixed. txt.class = 'labelText'; // Its size & position are fixed.
let labelElem = drawLabel(g, txt); let labelElem = drawLabel(g, txt);
@ -261,10 +263,10 @@ export const drawLoop = function(elem, bounds, labelText, conf) {
txt.y = bounds.starty + conf.boxMargin + conf.boxTextMargin; txt.y = bounds.starty + conf.boxMargin + conf.boxTextMargin;
txt.anchor = 'middle'; txt.anchor = 'middle';
txt.class = 'loopText'; txt.class = 'loopText';
txt.fontFamily = conf.fontFamily; txt.fontFamily = conf.messageFontFamily;
txt.fontSize = minSize; txt.fontSize = minSize;
txt.fontWeight = conf.fontWeight; txt.fontWeight = conf.messageFontWeight;
txt.wrap = bounds.wrap; txt.wrap = true;
drawText(g, txt); drawText(g, txt);
@ -273,12 +275,12 @@ export const drawLoop = function(elem, bounds, labelText, conf) {
if (item.message) { if (item.message) {
txt.text = item.message; txt.text = item.message;
txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2; txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2;
txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin; txt.y = bounds.sections[idx] + conf.boxMargin + conf.boxTextMargin;
txt.class = 'loopText'; txt.class = 'loopText';
txt.anchor = 'middle'; txt.anchor = 'middle';
txt.fontFamily = conf.fontFamily; txt.fontFamily = conf.messageFontFamily;
txt.fontSize = minSize; txt.fontSize = minSize;
txt.fontWeight = conf.fontWeight; txt.fontWeight = conf.messageFontWeight;
txt.wrap = bounds.wrap; txt.wrap = bounds.wrap;
drawText(g, txt); drawText(g, txt);
} }

View File

@ -130,8 +130,6 @@ const init = function() {
const initialize = function(config) { const initialize = function(config) {
mermaidAPI.reset(); mermaidAPI.reset();
// console.log('mermaid.initialize1', config);
if (typeof config.mermaid !== 'undefined') { if (typeof config.mermaid !== 'undefined') {
if (typeof config.mermaid.startOnLoad !== 'undefined') { if (typeof config.mermaid.startOnLoad !== 'undefined') {
mermaid.startOnLoad = config.mermaid.startOnLoad; mermaid.startOnLoad = config.mermaid.startOnLoad;
@ -140,9 +138,7 @@ const initialize = function(config) {
mermaid.htmlLabels = config.mermaid.htmlLabels; mermaid.htmlLabels = config.mermaid.htmlLabels;
} }
} }
// console.log('Initializing mermaid 2', config);
mermaidAPI.initialize(config); mermaidAPI.initialize(config);
// logger.debug('Initializing mermaid 3', config);
}; };
/** /**

View File

@ -735,7 +735,7 @@ const render = function(id, _txt, cb, container) {
} }
const element = document.querySelector('#' + 'd' + id); const element = document.querySelector('#' + 'd' + id);
if (element) { if (element) {
element.innerHTML = ''; element.remove();
} }
select('body') select('body')
@ -959,7 +959,6 @@ function initialize(options) {
updateRendererConfigs(config); updateRendererConfigs(config);
} }
setConfig(config); setConfig(config);
setLogLevel(config.logLevel); setLogLevel(config.logLevel);
logger.debug('mermaidAPI.initialize: ', config); logger.debug('mermaidAPI.initialize: ', config);
} }

View File

@ -1,16 +1,16 @@
$mainBkg: #1f2020; $mainBkg: #1f2020;
$secondBkg: lighten(#1f2020, 24); $secondBkg: lighten(#1f2020, 16);
$mainContrastColor: rgba(226, 226, 226, .75); $mainContrastColor: lightgrey;
$darkTextColor: #323D47; $darkTextColor: #323D47;
$lineColor: lighten($mainContrastColor, 24); $lineColor: $mainContrastColor;
$border1: #81b1db; $border1: #81B1DB;
$border2: darken(#81b1db, 32); $border2: rgba(255, 255, 255, 0.25);
$arrowheadColor: $mainContrastColor; $arrowheadColor: $mainContrastColor;
/* Flowchart variables */ /* Flowchart variables */
$nodeBkg: $mainBkg; $nodeBkg: $mainBkg;
$nodeBorder: purple; $nodeBorder: $border1;
$clusterBkg: $secondBkg; $clusterBkg: $secondBkg;
$clusterBorder: $border2; $clusterBorder: $border2;
$defaultLinkColor: $lineColor; $defaultLinkColor: $lineColor;
@ -31,10 +31,10 @@ $labelTextColor: $mainContrastColor;
$loopTextColor: $mainContrastColor; $loopTextColor: $mainContrastColor;
$noteBorderColor: $border2; $noteBorderColor: $border2;
$noteBkgColor: #fff5ad; $noteBkgColor: #fff5ad;
$noteTextColor: #1f2020; $noteTextColor: $mainBkg;
$activationBorderColor: $border1; $activationBorderColor: $border1;
$activationBkgColor: $secondBkg; $activationBkgColor: $secondBkg;
$sequenceNumberColor: $mainContrastColor; $sequenceNumberColor: white;
/* Gantt chart variables */ /* Gantt chart variables */

View File

@ -18,9 +18,7 @@
} }
/* Classes common for multiple diagrams */ /* Classes common for multiple diagrams */
body {
background-color: $mainBkg;
}
.error-icon { .error-icon {
fill: $errorBkgColor; fill: $errorBkgColor;
} }

View File

@ -36,7 +36,7 @@ const anyComment = /\s*%%.*\n/gm;
/** /**
* @function detectInit * @function detectInit
* Detects the init config object from the text and (re)initializes mermaid * Detects the init config object from the text
* ```mermaid * ```mermaid
* %%{init: {"theme": "debug", "logLevel": 1 }}%% * %%{init: {"theme": "debug", "logLevel": 1 }}%%
* graph LR * graph LR
@ -494,8 +494,11 @@ export const drawSimpleText = function(elem, textData) {
}; };
export const wrapLabel = (label, maxWidth, config) => { export const wrapLabel = (label, maxWidth, config) => {
if (!label) {
return label;
}
config = Object.assign( config = Object.assign(
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15, joinWith: '<br/>' }, { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 0, joinWith: '<br/>' },
config config
); );
if (common.lineBreakRegex.test(label)) { if (common.lineBreakRegex.test(label)) {
@ -527,10 +530,7 @@ export const wrapLabel = (label, maxWidth, config) => {
}; };
const breakString = (word, maxWidth, hyphenCharacter = '-', config) => { const breakString = (word, maxWidth, hyphenCharacter = '-', config) => {
config = Object.assign( config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 0 }, config);
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 },
config
);
const characters = word.split(''); const characters = word.split('');
const lines = []; const lines = [];
let currentLine = ''; let currentLine = '';
@ -596,7 +596,7 @@ export const calculateTextDimensions = function(text, config) {
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 }, { fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 15 },
config config
); );
const { fontSize, fontFamily, fontWeight, margin } = config; const { fontSize, fontFamily, fontWeight } = config;
if (!text) { if (!text) {
return 0; return 0;
} }
@ -638,7 +638,7 @@ export const calculateTextDimensions = function(text, config) {
g.remove(); g.remove();
// Adds some padding, so the text won't sit exactly within the actor's borders // Adds some padding, so the text won't sit exactly within the actor's borders
return { width: maxWidth + 2 * margin, height: height + 2 * margin }; return { width: Math.round(maxWidth), height: Math.round(height) };
}; };
export default { export default {