mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-02 23:26:44 +02:00
#945 Rendering of state descriptions
This commit is contained in:
@@ -42,4 +42,16 @@ describe('State diagram', () => {
|
|||||||
);
|
);
|
||||||
cy.get('svg');
|
cy.get('svg');
|
||||||
});
|
});
|
||||||
|
it('should render state descriptions', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
state "Long state description" as XState1
|
||||||
|
state "Another Long state description" as XState2
|
||||||
|
XState2 : New line
|
||||||
|
`,
|
||||||
|
{ logLevel: 0 }
|
||||||
|
);
|
||||||
|
cy.get('svg');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -104,14 +104,14 @@ line
|
|||||||
;
|
;
|
||||||
|
|
||||||
statement
|
statement
|
||||||
: idStatement DESCR
|
: idStatement DESCR {yy.addState($1, 'default');yy.addDescription($1, $2.trim());}
|
||||||
| idStatement '-->' idStatement {yy.addRelation($1, $3);}
|
| idStatement '-->' idStatement {yy.addRelation($1, $3);}
|
||||||
| idStatement '-->' idStatement DESCR {yy.addRelation($1, $3, $4.substr(1).trim());}
|
| idStatement '-->' idStatement DESCR {yy.addRelation($1, $3, $4.substr(1).trim());}
|
||||||
| HIDE_EMPTY
|
| HIDE_EMPTY
|
||||||
| scale WIDTH
|
| scale WIDTH
|
||||||
| COMPOSIT_STATE
|
| COMPOSIT_STATE
|
||||||
| COMPOSIT_STATE STRUCT_START document STRUCT_STOP
|
| COMPOSIT_STATE STRUCT_START document STRUCT_STOP
|
||||||
| STATE_DESCR AS ID
|
| STATE_DESCR AS ID {yy.addState($3, 'default');yy.addDescription($3, $1);}
|
||||||
| STATE_DESCR AS ID STRUCT_START document STRUCT_STOP
|
| STATE_DESCR AS ID STRUCT_START document STRUCT_STOP
|
||||||
| FORK
|
| FORK
|
||||||
| JOIN
|
| JOIN
|
||||||
|
@@ -62,15 +62,14 @@ export const addRelation = function(_id1, _id2, title) {
|
|||||||
relations.push({ id1, id2, title });
|
relations.push({ id1, id2, title });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addMember = function(className, member) {
|
export const addDescription = function(id, _descr) {
|
||||||
const theState = states[className];
|
const theState = states[id];
|
||||||
if (typeof member === 'string') {
|
let descr = _descr;
|
||||||
if (member.substr(-1) === ')') {
|
if (descr[0] === ':') {
|
||||||
theState.methods.push(member);
|
descr = descr.substr(1).trim();
|
||||||
} else {
|
|
||||||
theState.members.push(member);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theState.descriptions.push(descr);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addMembers = function(className, MembersArr) {
|
export const addMembers = function(className, MembersArr) {
|
||||||
@@ -106,7 +105,7 @@ export default {
|
|||||||
getStates,
|
getStates,
|
||||||
getRelations,
|
getRelations,
|
||||||
addRelation,
|
addRelation,
|
||||||
addMember,
|
addDescription,
|
||||||
addMembers,
|
addMembers,
|
||||||
cleanupLabel,
|
cleanupLabel,
|
||||||
lineType,
|
lineType,
|
||||||
|
@@ -222,6 +222,63 @@ const drawSimpleState = (g, stateDef) => {
|
|||||||
|
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Draws a state with descriptions
|
||||||
|
* @param {*} g
|
||||||
|
* @param {*} stateDef
|
||||||
|
*/
|
||||||
|
const drawDescrState = (g, stateDef) => {
|
||||||
|
const addTspan = function(textEl, txt, isFirst) {
|
||||||
|
const tSpan = textEl
|
||||||
|
.append('tspan')
|
||||||
|
.attr('x', 2 * conf.padding)
|
||||||
|
.text(txt);
|
||||||
|
if (!isFirst) {
|
||||||
|
tSpan.attr('dy', conf.textHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const title = g
|
||||||
|
.append('text')
|
||||||
|
.attr('x', 2 * conf.padding)
|
||||||
|
.attr('y', conf.textHeight + 1.5 * conf.padding)
|
||||||
|
.attr('font-size', 24)
|
||||||
|
.attr('class', 'state-title')
|
||||||
|
.text(stateDef.id);
|
||||||
|
|
||||||
|
const titleHeight = title.node().getBBox().height;
|
||||||
|
|
||||||
|
const description = g
|
||||||
|
.append('text') // text label for the x axis
|
||||||
|
.attr('x', conf.padding)
|
||||||
|
.attr('y', titleHeight + conf.padding * 0.2 + conf.dividerMargin + conf.textHeight)
|
||||||
|
.attr('fill', 'white')
|
||||||
|
.attr('class', 'state-description');
|
||||||
|
|
||||||
|
let isFirst = true;
|
||||||
|
stateDef.descriptions.forEach(function(descr) {
|
||||||
|
addTspan(description, descr, isFirst);
|
||||||
|
isFirst = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const descrLine = g
|
||||||
|
.append('line') // text label for the x axis
|
||||||
|
.attr('x1', conf.padding)
|
||||||
|
.attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
|
||||||
|
.attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2)
|
||||||
|
.attr('class', 'descr-divider');
|
||||||
|
const descrBox = description.node().getBBox();
|
||||||
|
descrLine.attr('x2', descrBox.width + 3 * conf.padding);
|
||||||
|
// const classBox = title.node().getBBox();
|
||||||
|
|
||||||
|
g.insert('rect', ':first-child')
|
||||||
|
.attr('x', conf.padding)
|
||||||
|
.attr('y', conf.padding)
|
||||||
|
.attr('width', descrBox.width + 2 * conf.padding)
|
||||||
|
.attr('height', descrBox.height + titleHeight + 2 * conf.padding)
|
||||||
|
.attr('rx', '5');
|
||||||
|
|
||||||
|
return g;
|
||||||
|
};
|
||||||
const drawEndState = g => {
|
const drawEndState = g => {
|
||||||
g.append('circle')
|
g.append('circle')
|
||||||
.style('stroke', 'black')
|
.style('stroke', 'black')
|
||||||
@@ -286,31 +343,11 @@ const drawEdge = function(elem, path, relation) {
|
|||||||
url = url.replace(/\)/g, '\\)');
|
url = url.replace(/\)/g, '\\)');
|
||||||
}
|
}
|
||||||
|
|
||||||
// svgPath.attr(
|
|
||||||
// 'marker-start',
|
|
||||||
// 'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'Start' + ')'
|
|
||||||
// );
|
|
||||||
svgPath.attr(
|
svgPath.attr(
|
||||||
'marker-end',
|
'marker-end',
|
||||||
'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'End' + ')'
|
'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'End' + ')'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Figure ou where to put the label given the points
|
|
||||||
// let x, y;
|
|
||||||
// const l = path.points.length;
|
|
||||||
// if (l % 2 !== 0 && l > 1) {
|
|
||||||
// const p1 = path.points[Math.floor(l / 2)];
|
|
||||||
// const p2 = path.points[Math.ceil(l / 2)];
|
|
||||||
// x = (p1.x + p2.x) / 2;
|
|
||||||
// y = (p1.y + p2.y) / 2;
|
|
||||||
// } else {
|
|
||||||
// const p = path.points[Math.floor(l / 2)];
|
|
||||||
// x = p.x;
|
|
||||||
// y = p.y;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log('calcLabelPosition', utils);
|
|
||||||
|
|
||||||
if (typeof relation.title !== 'undefined') {
|
if (typeof relation.title !== 'undefined') {
|
||||||
const g = elem.append('g').attr('class', 'classLabel');
|
const g = elem.append('g').attr('class', 'classLabel');
|
||||||
const label = g
|
const label = g
|
||||||
@@ -360,16 +397,6 @@ const drawEdge = function(elem, path, relation) {
|
|||||||
const drawState = function(elem, stateDef) {
|
const drawState = function(elem, stateDef) {
|
||||||
// logger.info('Rendering class ' + stateDef);
|
// logger.info('Rendering class ' + stateDef);
|
||||||
|
|
||||||
const addTspan = function(textEl, txt, isFirst) {
|
|
||||||
const tSpan = textEl
|
|
||||||
.append('tspan')
|
|
||||||
.attr('x', conf.padding)
|
|
||||||
.text(txt);
|
|
||||||
if (!isFirst) {
|
|
||||||
tSpan.attr('dy', conf.textHeight);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const id = stateDef.id;
|
const id = stateDef.id;
|
||||||
const stateInfo = {
|
const stateInfo = {
|
||||||
id: id,
|
id: id,
|
||||||
@@ -385,7 +412,9 @@ const drawState = function(elem, stateDef) {
|
|||||||
|
|
||||||
if (stateDef.type === 'start') drawStartState(g);
|
if (stateDef.type === 'start') drawStartState(g);
|
||||||
if (stateDef.type === 'end') drawEndState(g);
|
if (stateDef.type === 'end') drawEndState(g);
|
||||||
if (stateDef.type === 'default') drawSimpleState(g, stateDef);
|
if (stateDef.type === 'default' && stateDef.descriptions.length === 0)
|
||||||
|
drawSimpleState(g, stateDef);
|
||||||
|
if (stateDef.type === 'default' && stateDef.descriptions.length > 0) drawDescrState(g, stateDef);
|
||||||
|
|
||||||
const stateBox = g.node().getBBox();
|
const stateBox = g.node().getBBox();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user