Merge pull request #3798 from weedySeaDragon/bug/1952-stateDiagram--classDef-fix-classes-type
bug: State diagram fix classes type
This commit is contained in:
commit
461236030c
|
@ -31,9 +31,20 @@ const FILL_KEYWORD = 'fill';
|
||||||
const BG_FILL = 'bgFill';
|
const BG_FILL = 'bgFill';
|
||||||
const STYLECLASS_SEP = ',';
|
const STYLECLASS_SEP = ',';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new list of classes.
|
||||||
|
* In the future, this can be replaced with a class common to all diagrams.
|
||||||
|
* ClassDef information = { id: id, styles: [], textStyles: [] }
|
||||||
|
*
|
||||||
|
* @returns {{}}
|
||||||
|
*/
|
||||||
|
function newClassesList() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
let direction = DEFAULT_DIAGRAM_DIRECTION;
|
let direction = DEFAULT_DIAGRAM_DIRECTION;
|
||||||
let rootDoc = [];
|
let rootDoc = [];
|
||||||
let classes = []; // style classes defined by a classDef
|
let classes = newClassesList(); // style classes defined by a classDef
|
||||||
|
|
||||||
const newDoc = () => {
|
const newDoc = () => {
|
||||||
return {
|
return {
|
||||||
|
@ -270,11 +281,9 @@ export const clear = function (saveCommon) {
|
||||||
};
|
};
|
||||||
currentDocument = documents.root;
|
currentDocument = documents.root;
|
||||||
|
|
||||||
currentDocument = documents.root;
|
|
||||||
|
|
||||||
// number of start and end nodes; used to construct ids
|
// number of start and end nodes; used to construct ids
|
||||||
startEndCount = 0;
|
startEndCount = 0;
|
||||||
classes = [];
|
classes = newClassesList();
|
||||||
if (!saveCommon) {
|
if (!saveCommon) {
|
||||||
commonClear();
|
commonClear();
|
||||||
}
|
}
|
||||||
|
@ -300,7 +309,7 @@ export const getRelations = function () {
|
||||||
* else return the given id
|
* else return the given id
|
||||||
*
|
*
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @returns {{id: string, type: string}} - the id and type that should be used
|
* @returns {string} - the id (original or constructed)
|
||||||
*/
|
*/
|
||||||
function startIdIfNeeded(id = '') {
|
function startIdIfNeeded(id = '') {
|
||||||
let fixedId = id;
|
let fixedId = id;
|
||||||
|
@ -329,7 +338,7 @@ function startTypeIfNeeded(id = '', type = DEFAULT_STATE_TYPE) {
|
||||||
* else return the given id
|
* else return the given id
|
||||||
*
|
*
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @returns {{id: string, type: string}} - the id and type that should be used
|
* @returns {string} - the id (original or constructed)
|
||||||
*/
|
*/
|
||||||
function endIdIfNeeded(id = '') {
|
function endIdIfNeeded(id = '') {
|
||||||
let fixedId = id;
|
let fixedId = id;
|
||||||
|
@ -442,12 +451,12 @@ const getDividerId = () => {
|
||||||
* @example classDef my-style fill:#f96;
|
* @example classDef my-style fill:#f96;
|
||||||
*
|
*
|
||||||
* @param {string} id - the id of this (style) class
|
* @param {string} id - the id of this (style) class
|
||||||
* @param {string} styleAttributes - the string with 1 or more style attributes (each separated by a comma)
|
* @param {string | null} styleAttributes - the string with 1 or more style attributes (each separated by a comma)
|
||||||
*/
|
*/
|
||||||
export const addStyleClass = function (id, styleAttributes = '') {
|
export const addStyleClass = function (id, styleAttributes = '') {
|
||||||
// create a new style class object with this id
|
// create a new style class object with this id
|
||||||
if (typeof classes[id] === 'undefined') {
|
if (typeof classes[id] === 'undefined') {
|
||||||
classes[id] = { id: id, styles: [], textStyles: [] };
|
classes[id] = { id: id, styles: [], textStyles: [] }; // This is a classDef
|
||||||
}
|
}
|
||||||
const foundClass = classes[id];
|
const foundClass = classes[id];
|
||||||
if (typeof styleAttributes !== 'undefined') {
|
if (typeof styleAttributes !== 'undefined') {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import stateDb from './stateDb';
|
||||||
import stateDiagram from './parser/stateDiagram.jison';
|
import stateDiagram from './parser/stateDiagram.jison';
|
||||||
|
|
||||||
describe('state diagram V2, ', function () {
|
describe('state diagram V2, ', function () {
|
||||||
|
// TODO - these examples should be put into ./parser/stateDiagram.spec.js
|
||||||
describe('when parsing an info graph it', function () {
|
describe('when parsing an info graph it', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
parser.yy = stateDb;
|
parser.yy = stateDb;
|
||||||
|
|
|
@ -58,11 +58,6 @@ const G_EDGE_LABELTYPE = 'text';
|
||||||
const G_EDGE_THICKNESS = 'normal';
|
const G_EDGE_THICKNESS = 'normal';
|
||||||
|
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
// When information is parsed and processed (extracted) by stateDb.extract()
|
|
||||||
// These are globals so the information can be accessed as needed (e.g. in setUpNode, etc.)
|
|
||||||
let diagramStates = [];
|
|
||||||
let diagramClasses = [];
|
|
||||||
|
|
||||||
// List of nodes created from the parsed diagram statement items
|
// List of nodes created from the parsed diagram statement items
|
||||||
let nodeDb = {};
|
let nodeDb = {};
|
||||||
|
|
||||||
|
@ -81,25 +76,20 @@ export const setConf = function (cnf) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the all the styles from classDef statements in the graph definition.
|
* Returns the all the classdef styles (a.k.a. classes) from classDef statements in the graph definition.
|
||||||
*
|
*
|
||||||
* @param {string} text - the diagram text to be parsed
|
* @param {string} text - the diagram text to be parsed
|
||||||
* @param {Diagram} diagramObj
|
* @param diagramObj
|
||||||
* @returns {object} ClassDef styles
|
* @returns {object} ClassDef styles (a Map with keys = strings, values = )
|
||||||
*/
|
*/
|
||||||
export const getClasses = function (text, diagramObj) {
|
export const getClasses = function (text, diagramObj) {
|
||||||
log.trace('Extracting classes');
|
log.trace('Extracting classes');
|
||||||
if (diagramClasses.length > 0) {
|
|
||||||
return diagramClasses; // we have already extracted the classes
|
|
||||||
}
|
|
||||||
|
|
||||||
diagramObj.db.clear();
|
diagramObj.db.clear();
|
||||||
try {
|
try {
|
||||||
// Parse the graph definition
|
// Parse the graph definition
|
||||||
diagramObj.parser.parse(text);
|
diagramObj.parser.parse(text);
|
||||||
// must run extract() to turn the parsed statements into states, relationships, classes, etc.
|
// must run extract() to turn the parsed statements into states, relationships, classes, etc.
|
||||||
diagramObj.db.extract(diagramObj.db.getRootDocV2());
|
diagramObj.db.extract(diagramObj.db.getRootDocV2());
|
||||||
|
|
||||||
return diagramObj.db.getClasses();
|
return diagramObj.db.getClasses();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e;
|
return e;
|
||||||
|
@ -107,7 +97,7 @@ export const getClasses = function (text, diagramObj) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get classes from the db info item.
|
* Get classes from the db for the info item.
|
||||||
* If there aren't any or if dbInfoItem isn't defined, return an empty string.
|
* If there aren't any or if dbInfoItem isn't defined, return an empty string.
|
||||||
* Else create 1 string from the list of classes found
|
* Else create 1 string from the list of classes found
|
||||||
*
|
*
|
||||||
|
@ -132,7 +122,7 @@ function getClassesFromDbInfo(dbInfoItem) {
|
||||||
*
|
*
|
||||||
* @param itemId
|
* @param itemId
|
||||||
* @param counter
|
* @param counter
|
||||||
* @param type
|
* @param {string | null} type
|
||||||
* @param typeSpacer
|
* @param typeSpacer
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
|
@ -147,10 +137,11 @@ export function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOM
|
||||||
* @param g - graph
|
* @param g - graph
|
||||||
* @param {object} parent
|
* @param {object} parent
|
||||||
* @param {object} parsedItem - parsed statement item
|
* @param {object} parsedItem - parsed statement item
|
||||||
|
* @param {object[]} diagramStates - the list of all known states for the diagram
|
||||||
* @param {object} diagramDb
|
* @param {object} diagramDb
|
||||||
* @param {boolean} altFlag - for clusters, add the "statediagram-cluster-alt" CSS class
|
* @param {boolean} altFlag - for clusters, add the "statediagram-cluster-alt" CSS class
|
||||||
*/
|
*/
|
||||||
const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => {
|
const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => {
|
||||||
const itemId = parsedItem.id;
|
const itemId = parsedItem.id;
|
||||||
const classStr = getClassesFromDbInfo(diagramStates[itemId]);
|
const classStr = getClassesFromDbInfo(diagramStates[itemId]);
|
||||||
|
|
||||||
|
@ -307,7 +298,7 @@ const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => {
|
||||||
}
|
}
|
||||||
if (parsedItem.doc) {
|
if (parsedItem.doc) {
|
||||||
log.trace('Adding nodes children ');
|
log.trace('Adding nodes children ');
|
||||||
setupDoc(g, parsedItem, parsedItem.doc, diagramDb, !altFlag);
|
setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -318,25 +309,26 @@ const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => {
|
||||||
* @param g
|
* @param g
|
||||||
* @param parentParsedItem - parsed Item that is the parent of this document (doc)
|
* @param parentParsedItem - parsed Item that is the parent of this document (doc)
|
||||||
* @param doc - the document to set up
|
* @param doc - the document to set up
|
||||||
|
* @param {object} diagramStates - the list of all known states for the diagram
|
||||||
* @param diagramDb
|
* @param diagramDb
|
||||||
* @param altFlag
|
* @param {boolean} altFlag
|
||||||
* @todo This duplicates some of what is done in stateDb.js extract method
|
* @todo This duplicates some of what is done in stateDb.js extract method
|
||||||
*/
|
*/
|
||||||
const setupDoc = (g, parentParsedItem, doc, diagramDb, altFlag) => {
|
const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => {
|
||||||
// graphItemCount = 0;
|
// graphItemCount = 0;
|
||||||
log.trace('items', doc);
|
log.trace('items', doc);
|
||||||
doc.forEach((item) => {
|
doc.forEach((item) => {
|
||||||
switch (item.stmt) {
|
switch (item.stmt) {
|
||||||
case STMT_STATE:
|
case STMT_STATE:
|
||||||
setupNode(g, parentParsedItem, item, diagramDb, altFlag);
|
setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag);
|
||||||
break;
|
break;
|
||||||
case DEFAULT_STATE_TYPE:
|
case DEFAULT_STATE_TYPE:
|
||||||
setupNode(g, parentParsedItem, item, diagramDb, altFlag);
|
setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag);
|
||||||
break;
|
break;
|
||||||
case STMT_RELATION:
|
case STMT_RELATION:
|
||||||
{
|
{
|
||||||
setupNode(g, parentParsedItem, item.state1, diagramDb, altFlag);
|
setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag);
|
||||||
setupNode(g, parentParsedItem, item.state2, diagramDb, altFlag);
|
setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag);
|
||||||
const edgeData = {
|
const edgeData = {
|
||||||
id: 'edge' + graphItemCount,
|
id: 'edge' + graphItemCount,
|
||||||
arrowhead: 'normal',
|
arrowhead: 'normal',
|
||||||
|
@ -407,8 +399,7 @@ export const draw = function (text, id, _version, diag) {
|
||||||
diag.db.extract(diag.db.getRootDocV2());
|
diag.db.extract(diag.db.getRootDocV2());
|
||||||
log.info(diag.db.getRootDocV2());
|
log.info(diag.db.getRootDocV2());
|
||||||
|
|
||||||
diagramStates = diag.db.getStates();
|
const diagramStates = diag.db.getStates();
|
||||||
diagramClasses = diag.db.getClasses();
|
|
||||||
|
|
||||||
// Create the input mermaid.graph
|
// Create the input mermaid.graph
|
||||||
const g = new graphlib.Graph({
|
const g = new graphlib.Graph({
|
||||||
|
@ -426,7 +417,7 @@ export const draw = function (text, id, _version, diag) {
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
||||||
setupNode(g, undefined, diag.db.getRootDocV2(), diag.db, true);
|
setupNode(g, undefined, diag.db.getRootDocV2(), diagramStates, diag.db, true);
|
||||||
|
|
||||||
// Set up an SVG group so that we can translate the final graph.
|
// Set up an SVG group so that we can translate the final graph.
|
||||||
let sandboxElement;
|
let sandboxElement;
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { expectTypeOf } from 'vitest';
|
||||||
|
|
||||||
|
import { parser } from './parser/stateDiagram';
|
||||||
|
import stateDb from './stateDb';
|
||||||
|
import stateRendererV2 from './stateRenderer-v2';
|
||||||
|
|
||||||
|
// Can use this instead of having to register diagrams and load/orchestrate them, etc.
|
||||||
|
class FauxDiagramObj {
|
||||||
|
db = stateDb;
|
||||||
|
parser = parser;
|
||||||
|
renderer = stateRendererV2;
|
||||||
|
|
||||||
|
constructor(options = { db: stateDb, parser: parser, renderer: stateRendererV2 }) {
|
||||||
|
this.db = options.db;
|
||||||
|
this.parser = options.parser;
|
||||||
|
this.renderer = options.renderer;
|
||||||
|
this.parser.yy = this.db;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('stateRenderer-v2', () => {
|
||||||
|
describe('getClasses', () => {
|
||||||
|
const diagramText = 'statediagram-v2\n';
|
||||||
|
const fauxStateDiagram = new FauxDiagramObj();
|
||||||
|
|
||||||
|
it('returns a {}', () => {
|
||||||
|
const result = stateRendererV2.getClasses(diagramText, fauxStateDiagram);
|
||||||
|
expectTypeOf(result).toBeObject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -32,7 +32,7 @@ import { evaluate } from './diagrams/common/common';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
// diagram names that support classDef statements
|
// diagram names that support classDef statements
|
||||||
const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram'];
|
const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram', 'stateDiagram-v2'];
|
||||||
|
|
||||||
const MAX_TEXTLENGTH_EXCEEDED_MSG =
|
const MAX_TEXTLENGTH_EXCEEDED_MSG =
|
||||||
'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
|
'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
|
||||||
|
|
Loading…
Reference in New Issue