Merge branch 'mermaid-js-develop' into develop

This commit is contained in:
Chris Moran
2020-06-19 13:32:23 -04:00
26 changed files with 2192 additions and 1432 deletions

View File

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

View File

@@ -171,7 +171,9 @@ export const validate = graph => {
export const findNonClusterChild = (id, graph) => {
// const node = graph.node(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) {
log.trace('This is a valid node', id);
return id;
@@ -213,7 +215,7 @@ export const adjustClustersAndEdges = (graph, depth) => {
graph.nodes().forEach(function(id) {
const children = graph.children(id);
if (children.length > 0) {
log.trace(
log.warn(
'Cluster identified',
id,
' Replacement id in edges: ',
@@ -266,17 +268,17 @@ export const adjustClustersAndEdges = (graph, depth) => {
// 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]);
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);
w = getAnchorId(e.w);
graph.removeEdge(e.v, e.w, e.name);
if (v !== e.v) edge.fromCluster = e.v;
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);
}
});
log.debug('Adjusted Graph', graphlib.json.write(graph));
log.warn('Adjusted Graph', graphlib.json.write(graph));
log.trace(clusterDb);

View File

@@ -10,6 +10,7 @@ function addConf(conf, key, value) {
}
return conf;
}
describe('when parsing a sequenceDiagram', function() {
beforeEach(function() {
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!
Note left of Alice: Bob thinks
Bob->>Alice: Fine!`;
parser.parse(str);
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!
Note left of Alice: Bob thinks
Bob->>Alice: Fine!`;
parser.parse(str);
// renderer.setConf(mermaidAPI.getConfig().sequence);
renderer.draw(str, 'tst');
@@ -1242,7 +1241,6 @@ Alice->Bob: Hello Bob, how are you?
loop Cheers
Bob->Alice: Fine!
end`;
parser.parse(str);
renderer.draw(str, 'tst');
@@ -1274,38 +1272,6 @@ end`;
});
});
describe('issue fixes', function() {
beforeEach(() => {
parser.yy = sequenceDb;
parser.yy.clear();
mermaidAPI.reset();
mermaidAPI.initialize({ logLevel: 0, theme: 'dark' });
renderer.bounds.init();
});
it('should fix issue 1480', function() {
const str = `
sequenceDiagram
participant Event as Very long name goes here
participant API as Some API
participant API2 as A different API
participant Client as Another very long name goes here
activate Event
Event ->> Event: Something important happens
Note over Event,Client: Some explanation goes here
activate Client
Event --x Client: Publish event
deactivate Event
deactivate Client`;
parser.parse(str);
renderer.draw(str, 'tst');
const bounds = renderer.bounds.getBounds();
const actors = parser.yy.getActors();
const messages = parser.yy.getMessages();
expect(bounds).toBeTruthy();
})
});
describe('when rendering a sequenceDiagram with actor mirror activated', function() {
let conf;

View File

@@ -460,7 +460,7 @@ export const drawActors = function(diagram, actors, actorKeys, verticalPos) {
// Add some rendering data to the object
actor.width = actor.width ? actor.width : conf.width;
actor.height = conf.height;
actor.margin = conf.actorMargin;
actor.margin = actor.margin || conf.actorMargin;
actor.x = prevWidth + prevMargin;
actor.y = verticalPos;
@@ -565,7 +565,6 @@ export const draw = function(text, id) {
drawActors(diagram, actors, actorKeys, 0);
const loopWidths = calculateLoopMargins(messages, actors);
logger.debug('actors:', actors);
// The arrow head definition is attached to the svg once
svgDraw.insertArrowHead(diagram);
svgDraw.insertArrowCrossHead(diagram);
@@ -966,6 +965,7 @@ const getMaxMessageWidthPerActor = function(actors, messages) {
}
});
logger.debug('MaxMessages:', maxMessageWidthPerActor);
return maxMessageWidthPerActor;
};
@@ -1077,7 +1077,6 @@ const calculateLoopMargins = function(messages, actors) {
});
}
});
logger.debug('LoopWidths:', { loops, actors });
return loops;
};

View File

@@ -148,7 +148,7 @@ let actorCnt = -1;
* Draws an actor in the diagram with the attaced line
* @param elem - The diagram we'll draw to.
* @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) {
const center = actor.x + actor.width / 2;

View File

@@ -130,8 +130,6 @@ const init = function() {
const initialize = function(config) {
mermaidAPI.reset();
// console.log('mermaid.initialize1', config);
if (typeof config.mermaid !== 'undefined') {
if (typeof config.mermaid.startOnLoad !== 'undefined') {
mermaid.startOnLoad = config.mermaid.startOnLoad;
@@ -140,9 +138,7 @@ const initialize = function(config) {
mermaid.htmlLabels = config.mermaid.htmlLabels;
}
}
// console.log('Initializing mermaid 2', 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);
if (element) {
element.innerHTML = '';
element.remove();
}
select('body')
@@ -959,7 +959,6 @@ function initialize(options) {
updateRendererConfigs(config);
}
setConfig(config);
setLogLevel(config.logLevel);
logger.debug('mermaidAPI.initialize: ', config);
}

View File

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

View File

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

View File

@@ -36,7 +36,7 @@ const anyComment = /\s*%%.*\n/gm;
/**
* @function detectInit
* Detects the init config object from the text and (re)initializes mermaid
* Detects the init config object from the text
* ```mermaid
* %%{init: {"theme": "debug", "logLevel": 1 }}%%
* graph LR