Lint Fixes

This commit is contained in:
ashishj
2023-01-25 17:49:35 +01:00
parent df1e9c4117
commit 49ce5222c9
18 changed files with 188 additions and 144 deletions

View File

@@ -166,8 +166,8 @@ if (watch) {
if (!mermaidOnly) { if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
// build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); // build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline' })); build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline' }));
//build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline-detector' })); //build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline-detector' }));
} }
} else if (visualize) { } else if (visualize) {
await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' })); await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));

View File

@@ -71,7 +71,21 @@
I am a big big big tasks I am a big big big tasks
I am not so big tasks I am not so big tasks
</pre> </pre>
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid">
timeline
title MermaidChart 2023 Timeline
section 2023 Q1 &lt;br&gt; Release Personal Tier
Buttet 1 : sub-point 1a : sub-point 1b
: sub-point 1c
Bullet 2 : sub-point 2a : sub-point 2b
section 2023 Q2 <br> Release XYZ Tier
Buttet 3 : sub-point <br/> 3a : sub-point 3b
: sub-point 3c
Bullet 4 : sub-point 4a : sub-point 4b
</pre>
<pre id="diagram" class="mermaid2">
timeline timeline
title England's History Timeline title England's History Timeline
section Stone Age section Stone Age
@@ -96,7 +110,7 @@
2008s : Instagram 2008s : Instagram
2010 : Pinterest 2010 : Pinterest
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'themeVariables': { %%{init: { 'logLevel': 'debug', 'theme': 'base', 'themeVariables': {
'cScale0': '#ff0000', 'cScale0': '#ff0000',
'cScale1': '#00ff00', 'cScale1': '#00ff00',
@@ -113,7 +127,7 @@
2010 : Pinterest 2010 : Pinterest
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': { %%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
'cScale0': '#ff0000', 'cScale0': '#ff0000',
'cScale1': '#00ff00', 'cScale1': '#00ff00',
@@ -173,11 +187,11 @@ mindmap
<!-- <script src="./mermaid-example-diagram-detector.js"></script> --> <!-- <script src="./mermaid-example-diagram-detector.js"></script> -->
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> --> <!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
<script type="module"> <script type="module">
import mindmap from '../../packages/mermaid-mindmap/src/detector'; //import mindmap from '../../packages/mermaid-mindmap/src/detector';
// import example from '../../packages/mermaid-example-diagram/src/detector'; // import example from '../../packages/mermaid-example-diagram/src/detector';
import timeline from '../../packages/mermaid-timeline/src/detector'; import timeline from '../../packages/mermaid-timeline/src/detector';
import mermaid from '../../packages/mermaid/src/mermaid'; import mermaid from '../../packages/mermaid/src/mermaid';
await mermaid.registerExternalDiagrams([mindmap, timeline]); await mermaid.registerExternalDiagrams([timeline]);
mermaid.parseError = function (err, hash) { mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err); // console.error('Mermaid error: ', err);
}; };
@@ -187,7 +201,7 @@ mindmap
logLevel: 0, logLevel: 0,
flowchart: { flowchart: {
useMaxWidth: false, useMaxWidth: false,
htmlLabels: true, htmlLabels: false,
}, },
gantt: { gantt: {
useMaxWidth: false, useMaxWidth: false,
@@ -195,7 +209,7 @@ mindmap
timeline: { timeline: {
disableMulticolor: false, disableMulticolor: false,
}, },
useMaxWidth: false, useMaxWidth: true,
lazyLoadedDiagrams: [ lazyLoadedDiagrams: [
// './mermaid-mindmap-detector.esm.mjs', // './mermaid-mindmap-detector.esm.mjs',
// './mermaid-example-diagram-detector.esm.mjs', // './mermaid-example-diagram-detector.esm.mjs',

View File

@@ -42,7 +42,7 @@ export let setupGraphViewbox: (
* @param _getConfig - getConfig from mermaid/src/diagramAPI.ts * @param _getConfig - getConfig from mermaid/src/diagramAPI.ts
* @param _sanitizeText - sanitizeText from mermaid/src/diagramAPI.ts * @param _sanitizeText - sanitizeText from mermaid/src/diagramAPI.ts
* @param _setupGraphViewbox - setupGraphViewbox from mermaid/src/diagramAPI.ts * @param _setupGraphViewbox - setupGraphViewbox from mermaid/src/diagramAPI.ts
* @param _commonDb * @param _commonDb -`commonDb` from mermaid/src/diagramAPI.ts
*/ */
export const injectUtils = ( export const injectUtils = (
_log: Record<keyof typeof LEVELS, typeof console.log>, _log: Record<keyof typeof LEVELS, typeof console.log>,
@@ -64,5 +64,4 @@ export const injectUtils = (
sanitizeText = _sanitizeText; sanitizeText = _sanitizeText;
setupGraphViewbox = _setupGraphViewbox; setupGraphViewbox = _setupGraphViewbox;
commonDb = _commonDb; commonDb = _commonDb;
}; };

View File

@@ -55,5 +55,5 @@ export const injectUtils = (
getConfig = _getConfig; getConfig = _getConfig;
sanitizeText = _sanitizeText; sanitizeText = _sanitizeText;
setupGraphViewbox = _setupGraphViewbox; setupGraphViewbox = _setupGraphViewbox;
commonDb= _commonDb; commonDb = _commonDb;
}; };

View File

@@ -11,7 +11,7 @@ cytoscape.use(coseBilkent);
/** /**
* @param {any} svg The svg element to draw the diagram onto * @param {any} svg The svg element to draw the diagram onto
* @param {object} mindmap The maindmap data and hierarchy * @param {object} mindmap The mindmap data and hierarchy
* @param section * @param section
* @param {object} conf The configuration object * @param {object} conf The configuration object
*/ */
@@ -110,7 +110,7 @@ function layoutMindmap(node, conf) {
renderEl.remove(); renderEl.remove();
addNodes(node, cy, conf, 0); addNodes(node, cy, conf, 0);
// Make cytoscape care about the dimensisions of the nodes // Make cytoscape care about the dimensions of the nodes
cy.nodes().forEach(function (n) { cy.nodes().forEach(function (n) {
n.layoutDimensions = () => { n.layoutDimensions = () => {
const data = n.data(); const data = n.data();
@@ -173,7 +173,7 @@ export const draw = async (text, id, version, diagObj) => {
log.debug('Renering info diagram\n' + text); log.debug('Renering info diagram\n' + text);
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sandbox mode
let sandboxElement; let sandboxElement;
if (securityLevel === 'sandbox') { if (securityLevel === 'sandbox') {
sandboxElement = select('#i' + id); sandboxElement = select('#i' + id);

View File

@@ -55,4 +55,4 @@
"**/*.css", "**/*.css",
"**/*.scss" "**/*.scss"
] ]
} }

View File

@@ -26,7 +26,7 @@ export let sanitizeText: (str: string) => string;
export const getCommonDb = () => localCommonDb; export const getCommonDb = () => localCommonDb;
export let parseDirective = (p: any, statement: string, context: string, type: string) => { export let parseDirective = (p: any, statement: string, context: string, type: string) => {
return; return;
} };
/** /**
* Placeholder for the real function that will be injected by mermaid. * Placeholder for the real function that will be injected by mermaid.
*/ */
@@ -38,8 +38,6 @@ export let setupGraphViewbox: (
useMaxWidth: boolean useMaxWidth: boolean
) => void; ) => void;
/** /**
* Function called by mermaid that injects utility functions that help the diagram to be a good citizen. * Function called by mermaid that injects utility functions that help the diagram to be a good citizen.
* @param _log - The log function to use * @param _log - The log function to use
@@ -71,5 +69,4 @@ export const injectUtils = (
setupGraphViewbox = _setupGraphViewbox; setupGraphViewbox = _setupGraphViewbox;
localCommonDb = _commonDb; localCommonDb = _commonDb;
parseDirective = _parseDirective; parseDirective = _parseDirective;
}; };

View File

@@ -1,4 +1,4 @@
import { arc as d3arc , select} from 'd3'; import { arc as d3arc, select } from 'd3';
const MAX_SECTIONS = 12; const MAX_SECTIONS = 12;
export const drawRect = function (elem, rectData) { export const drawRect = function (elem, rectData) {
@@ -12,7 +12,7 @@ export const drawRect = function (elem, rectData) {
rectElem.attr('rx', rectData.rx); rectElem.attr('rx', rectData.rx);
rectElem.attr('ry', rectData.ry); rectElem.attr('ry', rectData.ry);
if (typeof rectData.class !== 'undefined') { if (rectData.class !== undefined) {
rectElem.attr('class', rectData.class); rectElem.attr('class', rectData.class);
} }
@@ -117,11 +117,11 @@ export const drawCircle = function (element, circleData) {
circleElement.attr('stroke', circleData.stroke); circleElement.attr('stroke', circleData.stroke);
circleElement.attr('r', circleData.r); circleElement.attr('r', circleData.r);
if (typeof circleElement.class !== 'undefined') { if (circleElement.class !== undefined) {
circleElement.attr('class', circleElement.class); circleElement.attr('class', circleElement.class);
} }
if (typeof circleData.title !== 'undefined') { if (circleData.title !== undefined) {
circleElement.append('title').text(circleData.title); circleElement.append('title').text(circleData.title);
} }
@@ -139,7 +139,7 @@ export const drawText = function (elem, textData) {
textElem.style('text-anchor', textData.anchor); textElem.style('text-anchor', textData.anchor);
if (typeof textData.class !== 'undefined') { if (textData.class !== undefined) {
textElem.attr('class', textData.class); textElem.attr('class', textData.class);
} }
@@ -517,9 +517,7 @@ export const drawNode = function (elem, node, fullSection, conf) {
node.section = section; node.section = section;
nodeElem.attr( nodeElem.attr(
'class', 'class',
(node.class ? node.class + ' ' : '') + (node.class ? node.class + ' ' : '') + 'timeline-node ' + ('section-' + section)
'timeline-node ' +
('section-' + section)
); );
const bkgElem = nodeElem.append('g'); const bkgElem = nodeElem.append('g');
@@ -535,7 +533,8 @@ export const drawNode = function (elem, node, fullSection, conf) {
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.call(wrap, node.width); .call(wrap, node.width);
const bbox = txt.node().getBBox(); const bbox = txt.node().getBBox();
const fontSize = conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize; const fontSize =
conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding; node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
node.height = Math.max(node.height, node.maxHeight); node.height = Math.max(node.height, node.maxHeight);
node.width = node.width + 2 * node.padding; node.width = node.width + 2 * node.padding;
@@ -545,13 +544,12 @@ export const drawNode = function (elem, node, fullSection, conf) {
// Create the background element // Create the background element
defaultBkg(bkgElem, node, section, conf); defaultBkg(bkgElem, node, section, conf);
return node; return node;
}; };
export const getVirtualNodeHeight = function (elem,node,conf) { export const getVirtualNodeHeight = function (elem, node, conf) {
const textElem = elem.append('g'); const textElem = elem.append('g');
const txt = textElem const txt = textElem
.append('text') .append('text')
.text(node.descr) .text(node.descr)
.attr('dy', '1em') .attr('dy', '1em')
@@ -560,12 +558,12 @@ export const drawNode = function (elem, node, fullSection, conf) {
.attr('text-anchor', 'middle') .attr('text-anchor', 'middle')
.call(wrap, node.width); .call(wrap, node.width);
const bbox = txt.node().getBBox(); const bbox = txt.node().getBBox();
const fontSize = conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize; const fontSize =
conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
textElem.remove(); textElem.remove();
return bbox.height + fontSize * 1.1 * 0.5 + node.padding; return bbox.height + fontSize * 1.1 * 0.5 + node.padding;
}; };
const defaultBkg = function (elem, node, section) { const defaultBkg = function (elem, node, section) {
const rd = 5; const rd = 5;
elem elem

View File

@@ -1,4 +1,8 @@
import { getCommonDb as _getCommonDb, parseDirective as _parseDirective ,log } from './mermaidUtils'; import {
getCommonDb as _getCommonDb,
parseDirective as _parseDirective,
log,
} from './mermaidUtils';
let currentSection = ''; let currentSection = '';
let currentTaskId = 0; let currentTaskId = 0;
@@ -9,7 +13,7 @@ const rawTasks = [];
export const getCommonDb = _getCommonDb; export const getCommonDb = _getCommonDb;
export const parseDirective = ( statement, context, type) => { export const parseDirective = (statement, context, type) => {
_parseDirective(this, statement, context, type); _parseDirective(this, statement, context, type);
}; };
@@ -45,27 +49,25 @@ export const getTasks = function () {
}; };
export const addTask = function (period, length, event) { export const addTask = function (period, length, event) {
const rawTask = { const rawTask = {
id: currentTaskId++, id: currentTaskId++,
section: currentSection, section: currentSection,
type: currentSection, type: currentSection,
task: period, task: period,
score : length?length:0, score: length ? length : 0,
//if event is defined, then add it the events array //if event is defined, then add it the events array
events: event?[event]:[], events: event ? [event] : [],
}; };
rawTasks.push(rawTask); rawTasks.push(rawTask);
}; };
export const addEvent = function (event) { export const addEvent = function (event) {
// fetch current task with currnetTaskId // fetch current task with currnetTaskId
const currentTask = rawTasks.find((task) => task.id === currentTaskId - 1); const currentTask = rawTasks.find((task) => task.id === currentTaskId - 1);
//add event to the events array //add event to the events array
currentTask.events.push(event); currentTask.events.push(event);
}; };
export const addTaskOrg = function (descr) { export const addTaskOrg = function (descr) {
const newTask = { const newTask = {
section: currentSection, section: currentSection,
@@ -100,6 +102,5 @@ export default {
addTask, addTask,
addTaskOrg, addTaskOrg,
addEvent, addEvent,
parseDirective parseDirective,
}; };

View File

@@ -14,7 +14,7 @@ export const setConf = function (cnf) {
export const draw = function (text, id, version, diagObj) { export const draw = function (text, id, version, diagObj) {
//1. Fetch the configuration //1. Fetch the configuration
const conf = getConfig(); const conf = getConfig();
const LEFT_MARGIN = conf.leftMargin?conf.leftMargin:50; const LEFT_MARGIN = conf.leftMargin ? conf.leftMargin : 50;
//2. Clear the diagram db before parsing //2. Clear the diagram db before parsing
diagObj.db.clear(); diagObj.db.clear();
@@ -42,7 +42,7 @@ export const draw = function (text, id, version, diagObj) {
//4. Fetch the diagram data //4. Fetch the diagram data
const tasks = diagObj.db.getTasks(); const tasks = diagObj.db.getTasks();
const title = diagObj.db.getCommonDb().getDiagramTitle(); const title = diagObj.db.getCommonDb().getDiagramTitle();
log.debug('task',tasks); log.debug('task', tasks);
//5. Initialize the diagram //5. Initialize the diagram
svgDraw.initGraphics(svg); svgDraw.initGraphics(svg);
@@ -59,7 +59,7 @@ export const draw = function (text, id, version, diagObj) {
let masterX = 50 + LEFT_MARGIN; let masterX = 50 + LEFT_MARGIN;
//sectionBeginX = masterX; //sectionBeginX = masterX;
let masterY = 50; let masterY = 50;
sectionBeginY=50; sectionBeginY = 50;
//draw sections //draw sections
let sectionNumber = 0; let sectionNumber = 0;
let hasSections = true; let hasSections = true;
@@ -76,17 +76,16 @@ export const draw = function (text, id, version, diagObj) {
}; };
const sectionHeight = svgDraw.getVirtualNodeHeight(svg, sectionNode, conf); const sectionHeight = svgDraw.getVirtualNodeHeight(svg, sectionNode, conf);
log.debug('sectionHeight before draw', sectionHeight); log.debug('sectionHeight before draw', sectionHeight);
maxSectionHeight = Math.max(maxSectionHeight, sectionHeight +20); maxSectionHeight = Math.max(maxSectionHeight, sectionHeight + 20);
}); });
//tasks length and maxEventCount //tasks length and maxEventCount
let maxEventCount = 0; let maxEventCount = 0;
let maxEventLineLength = 0; let maxEventLineLength = 0;
log.debug('tasks.length', tasks.length); log.debug('tasks.length', tasks.length);
//calculate max task height //calculate max task height
// for loop till tasks.length // for loop till tasks.length
for (const [i, task] of tasks.entries()) { for (const [i, task] of tasks.entries()) {
const taskNode = { const taskNode = {
number: i, number: i,
descr: task, descr: task,
@@ -105,27 +104,24 @@ export const draw = function (text, id, version, diagObj) {
let maxEventLineLengthTemp = 0; let maxEventLineLengthTemp = 0;
for (let j = 0; j < task.events.length; j++) { for (let j = 0; j < task.events.length; j++) {
const event = task.events[j]; const event = task.events[j];
const eventNode = { const eventNode = {
descr: event, descr: event,
section: task.section, section: task.section,
number : task.section, number: task.section,
width: 150, width: 150,
padding: 20, padding: 20,
maxHeight: 50, maxHeight: 50,
}; };
maxEventLineLengthTemp += svgDraw.getVirtualNodeHeight(svg, eventNode, conf); maxEventLineLengthTemp += svgDraw.getVirtualNodeHeight(svg, eventNode, conf);
} }
maxEventLineLength = Math.max(maxEventLineLength, maxEventLineLengthTemp); maxEventLineLength = Math.max(maxEventLineLength, maxEventLineLengthTemp);
} }
log.debug('maxSectionHeight before draw', maxSectionHeight); log.debug('maxSectionHeight before draw', maxSectionHeight);
log.debug('maxTaskHeight before draw', maxTaskHeight); log.debug('maxTaskHeight before draw', maxTaskHeight);
if (sections && sections.length > 0) { if (sections && sections.length > 0) {
sections.forEach((section) => { sections.forEach((section) => {
const sectionNode = { const sectionNode = {
number: sectionNumber, number: sectionNumber,
descr: section, descr: section,
@@ -139,22 +135,27 @@ export const draw = function (text, id, version, diagObj) {
const node = svgDraw.drawNode(sectionNodeWrapper, sectionNode, sectionNumber, conf); const node = svgDraw.drawNode(sectionNodeWrapper, sectionNode, sectionNumber, conf);
log.debug('sectionNode output', node); log.debug('sectionNode output', node);
sectionNodeWrapper.attr( sectionNodeWrapper.attr('transform', `translate(${masterX}, ${sectionBeginY})`);
'transform',
`translate(${masterX}, ${sectionBeginY})`
);
masterY += maxSectionHeight + 50; masterY += maxSectionHeight + 50;
//draw tasks for this section //draw tasks for this section
//filter task where tasks.section == section //filter task where tasks.section == section
const tasksForSection = tasks.filter((task) => task.section === section); const tasksForSection = tasks.filter((task) => task.section === section);
if (tasksForSection.length > 0) { if (tasksForSection.length > 0) {
drawTasks(
svg,
drawTasks(svg, tasksForSection, sectionNumber, masterX, masterY, maxTaskHeight, conf, maxEventCount,maxEventLineLength,maxSectionHeight,false); tasksForSection,
sectionNumber,
masterX,
masterY,
maxTaskHeight,
conf,
maxEventCount,
maxEventLineLength,
maxSectionHeight,
false
);
} }
// todo replace with total width of section and its tasks // todo replace with total width of section and its tasks
masterX += 200 * Math.max(tasksForSection.length, 1); masterX += 200 * Math.max(tasksForSection.length, 1);
@@ -165,10 +166,22 @@ export const draw = function (text, id, version, diagObj) {
} else { } else {
//draw tasks //draw tasks
hasSections = false; hasSections = false;
drawTasks(svg, tasks, sectionNumber, masterX, masterY, maxTaskHeight, conf, maxEventCount,maxEventLineLength,maxSectionHeight,true); drawTasks(
svg,
tasks,
sectionNumber,
masterX,
masterY,
maxTaskHeight,
conf,
maxEventCount,
maxEventLineLength,
maxSectionHeight,
true
);
} }
// Get BBox of the diagram // Get BBox of the diagram
const box = svg.node().getBBox(); const box = svg.node().getBBox();
log.debug('bounds', box); log.debug('bounds', box);
@@ -176,7 +189,7 @@ export const draw = function (text, id, version, diagObj) {
svg svg
.append('text') .append('text')
.text(title) .text(title)
.attr('x', (box.width/2)-LEFT_MARGIN) .attr('x', box.width / 2 - LEFT_MARGIN)
.attr('font-size', '4ex') .attr('font-size', '4ex')
.attr('font-weight', 'bold') .attr('font-weight', 'bold')
.attr('y', 20); .attr('y', 20);
@@ -184,33 +197,49 @@ export const draw = function (text, id, version, diagObj) {
//5. Draw the diagram //5. Draw the diagram
depthY = hasSections ? maxSectionHeight + maxTaskHeight + 150 : maxTaskHeight + 100; depthY = hasSections ? maxSectionHeight + maxTaskHeight + 150 : maxTaskHeight + 100;
const lineWrapper = svg.append('g').attr('class', 'lineWrapper'); const lineWrapper = svg.append('g').attr('class', 'lineWrapper');
// Draw activity line // Draw activity line
lineWrapper lineWrapper
.append('line') .append('line')
.attr('x1', LEFT_MARGIN) .attr('x1', LEFT_MARGIN)
.attr('y1', depthY) // One section head + one task + margins .attr('y1', depthY) // One section head + one task + margins
.attr('x2', (box.width)+3*LEFT_MARGIN) // Subtract stroke width so arrow point is retained .attr('x2', box.width + 3 * LEFT_MARGIN) // Subtract stroke width so arrow point is retained
.attr('y2', depthY) .attr('y2', depthY)
.attr('stroke-width', 4) .attr('stroke-width', 4)
.attr('stroke', 'black') .attr('stroke', 'black')
.attr('marker-end', 'url(#arrowhead)'); .attr('marker-end', 'url(#arrowhead)');
// Setup the view box and size of the svg element // Setup the view box and size of the svg element
setupGraphViewbox(undefined, svg, conf.timeline.padding?conf.timeline.padding:50, conf.timeline.useMaxWidth?conf.timeline.useMaxWidth:false); setupGraphViewbox(
undefined,
svg,
conf.timeline.padding ? conf.timeline.padding : 50,
conf.timeline.useMaxWidth ? conf.timeline.useMaxWidth : false
);
// addSVGAccessibilityFields(diagObj.db, diagram, id); // addSVGAccessibilityFields(diagObj.db, diagram, id);
}; };
export const drawTasks = function (
export const drawTasks = function (diagram, tasks, sectionColor, masterX, masterY, maxTaskHeight,conf,maxEventCount,maxEventLineLength,maxSectionHeight, isWithoutSections) { diagram,
tasks,
sectionColor,
masterX,
masterY,
maxTaskHeight,
conf,
maxEventCount,
maxEventLineLength,
maxSectionHeight,
isWithoutSections
) {
// Draw the tasks // Draw the tasks
for (const task of tasks) { for (const task of tasks) {
// create node from task // create node from task
const taskNode = { const taskNode = {
descr: task.task, descr: task.task,
section: sectionColor, section: sectionColor,
number : sectionColor, number: sectionColor,
width: 150, width: 150,
padding: 20, padding: 20,
maxHeight: maxTaskHeight, maxHeight: maxTaskHeight,
@@ -223,63 +252,62 @@ export const drawTasks = function (diagram, tasks, sectionColor, masterX, master
const taskHeight = node.height; const taskHeight = node.height;
//log task height //log task height
log.debug('taskHeight after draw', taskHeight); log.debug('taskHeight after draw', taskHeight);
taskWrapper.attr( taskWrapper.attr('transform', `translate(${masterX}, ${masterY})`);
'transform',
`translate(${masterX}, ${masterY})`
);
// update max task height // update max task height
maxTaskHeight = Math.max(maxTaskHeight, taskHeight); maxTaskHeight = Math.max(maxTaskHeight, taskHeight);
// if task has events, draw them
// if task has events, draw them
if (task.events) { if (task.events) {
// draw a line between the task and the events // draw a line between the task and the events
const lineWrapper = diagram.append('g').attr('class', 'lineWrapper'); const lineWrapper = diagram.append('g').attr('class', 'lineWrapper');
let linelength = maxTaskHeight; let linelength = maxTaskHeight;
//add margin to task //add margin to task
masterY += 100; masterY += 100;
linelength = linelength+ drawEvents(diagram, task.events, sectionColor, masterX, masterY, conf); linelength =
masterY -= 100; linelength + drawEvents(diagram, task.events, sectionColor, masterX, masterY, conf);
masterY -= 100;
lineWrapper lineWrapper
.append('line') .append('line')
.attr('x1', masterX + 190/2) .attr('x1', masterX + 190 / 2)
.attr('y1', masterY + maxTaskHeight) // One section head + one task + margins .attr('y1', masterY + maxTaskHeight) // One section head + one task + margins
.attr('x2', masterX + 190/2) // Subtract stroke width so arrow point is retained .attr('x2', masterX + 190 / 2) // Subtract stroke width so arrow point is retained
.attr('y2', masterY + maxTaskHeight + (isWithoutSections?maxTaskHeight:maxSectionHeight) + maxEventLineLength+ 120) .attr(
.attr('stroke-width', 2) 'y2',
.attr('stroke', 'black') masterY +
.attr('marker-end', 'url(#arrowhead)') maxTaskHeight +
.attr('stroke-dasharray', "5,5"); (isWithoutSections ? maxTaskHeight : maxSectionHeight) +
maxEventLineLength +
120
)
.attr('stroke-width', 2)
.attr('stroke', 'black')
.attr('marker-end', 'url(#arrowhead)')
.attr('stroke-dasharray', '5,5');
} }
masterX = masterX + 200; masterX = masterX + 200;
if (isWithoutSections && !getConfig().timeline.disableMulticolor) { if (isWithoutSections && !getConfig().timeline.disableMulticolor) {
sectionColor++; sectionColor++;
} }
} }
// reset Y coordinate for next section
// reset Y coordinate for next section masterY = masterY - 10;
masterY= masterY -10; ;
}; };
export const drawEvents = function (diagram, events, sectionColor, masterX, masterY, conf) { export const drawEvents = function (diagram, events, sectionColor, masterX, masterY, conf) {
let maxEventHeight = 0; let maxEventHeight = 0;
const eventBeginY = masterY; const eventBeginY = masterY;
masterY = masterY + 100 masterY = masterY + 100;
// Draw the events // Draw the events
for (const event of events) { for (const event of events) {
// create node from event // create node from event
const eventNode = { const eventNode = {
descr: event, descr: event,
section: sectionColor, section: sectionColor,
number : sectionColor, number: sectionColor,
width: 150, width: 150,
padding: 20, padding: 20,
maxHeight: 50, maxHeight: 50,
@@ -289,20 +317,15 @@ export const drawEvents = function (diagram, events, sectionColor, masterX, mast
log.debug('eventNode', eventNode); log.debug('eventNode', eventNode);
// create event wrapper // create event wrapper
const eventWrapper = diagram.append('g').attr('class', 'eventWrapper'); const eventWrapper = diagram.append('g').attr('class', 'eventWrapper');
const node = svgDraw.drawNode(eventWrapper, eventNode, sectionColor, conf) const node = svgDraw.drawNode(eventWrapper, eventNode, sectionColor, conf);
const eventHeight = node.height; const eventHeight = node.height;
maxEventHeight= maxEventHeight + eventHeight; maxEventHeight = maxEventHeight + eventHeight;
eventWrapper.attr( eventWrapper.attr('transform', `translate(${masterX}, ${masterY})`);
'transform',
`translate(${masterX}, ${masterY})`
);
masterY = masterY + 10 + eventHeight; masterY = masterY + 10 + eventHeight;
} }
// set masterY back to eventBeginY // set masterY back to eventBeginY
masterY = eventBeginY; masterY = eventBeginY;
return maxEventHeight; return maxEventHeight;
}; };
export default { export default {

View File

@@ -985,8 +985,6 @@ const config: Partial<MermaidConfig> = {
*/ */
useMaxWidth: true, useMaxWidth: true,
/** /**
* | Parameter | Description | Type | Required | Values | * | Parameter | Description | Type | Required | Values |
* | ----------- | --------------------------------- | ---- | -------- | ----------- | * | ----------- | --------------------------------- | ---- | -------- | ----------- |

View File

@@ -5,9 +5,8 @@ import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox'; import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
import { addStylesForDiagram } from '../styles'; import { addStylesForDiagram } from '../styles';
import { DiagramDefinition, DiagramDetector } from './types'; import { DiagramDefinition, DiagramDetector } from './types';
import * as _commonDb from '../commonDb'; import * as _commonDb from '../commonDb';
import { parseDirective as _parseDirective} from '../directiveUtils'; import { parseDirective as _parseDirective } from '../directiveUtils';
/* /*
Packaging and exposing resources for external diagrams so that they can import Packaging and exposing resources for external diagrams so that they can import
@@ -19,8 +18,11 @@ export const setLogLevel = _setLogLevel;
export const getConfig = _getConfig; export const getConfig = _getConfig;
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig()); export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
export const setupGraphViewbox = _setupGraphViewbox; export const setupGraphViewbox = _setupGraphViewbox;
export const getCommonDb = () => { return _commonDb }; export const getCommonDb = () => {
export const parseDirective = (p: any, statement: string, context: string, type: string)=>_parseDirective(p, statement, context, type); return _commonDb;
};
export const parseDirective = (p: any, statement: string, context: string, type: string) =>
_parseDirective(p, statement, context, type);
const diagrams: Record<string, DiagramDefinition> = {}; const diagrams: Record<string, DiagramDefinition> = {};
export interface Detectors { export interface Detectors {
@@ -51,7 +53,15 @@ export const registerDiagram = (
addStylesForDiagram(id, diagram.styles); addStylesForDiagram(id, diagram.styles);
if (diagram.injectUtils) { if (diagram.injectUtils) {
diagram.injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox,getCommonDb(),parseDirective); diagram.injectUtils(
log,
setLogLevel,
getConfig,
sanitizeText,
setupGraphViewbox,
getCommonDb(),
parseDirective
);
} }
}; };

View File

@@ -33,7 +33,7 @@ export interface DiagramDefinition {
_sanitizeText: InjectUtils['_sanitizeText'], _sanitizeText: InjectUtils['_sanitizeText'],
_setupGraphViewbox: InjectUtils['_setupGraphViewbox'], _setupGraphViewbox: InjectUtils['_setupGraphViewbox'],
_commonDb: InjectUtils['_commonDb'], _commonDb: InjectUtils['_commonDb'],
_parseDirective: InjectUtils['_parseDirective'], _parseDirective: InjectUtils['_parseDirective']
) => void; ) => void;
} }

View File

@@ -1,5 +1,3 @@
import * as configApi from './config'; import * as configApi from './config';
import { log } from './logger'; import { log } from './logger';
@@ -7,7 +5,12 @@ import { directiveSanitizer } from './utils';
let currentDirective: { type?: string; args?: any } | undefined = {}; let currentDirective: { type?: string; args?: any } | undefined = {};
export const parseDirective = function (p: any, statement: string, context: string, type: string): void { export const parseDirective = function (
p: any,
statement: string,
context: string,
type: string
): void {
log.debug('parseDirective is being called', statement, context, type); log.debug('parseDirective is being called', statement, context, type);
try { try {
if (statement !== undefined) { if (statement !== undefined) {

View File

@@ -4,7 +4,7 @@ import timeline from '@mermaid-js/mermaid-timeline';
const init = (async () => { const init = (async () => {
try { try {
await mermaid.registerExternalDiagrams([mindmap,timeline]); await mermaid.registerExternalDiagrams([mindmap, timeline]);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }

View File

@@ -15,7 +15,6 @@ timeline
2006 : Twitter 2006 : Twitter
``` ```
## Syntax ## Syntax
The syntax for creating Timeline diagram is simple. You always start with the `timeline` keyword to let mermaid know that you want to create a timeline diagram. The syntax for creating Timeline diagram is simple. You always start with the `timeline` keyword to let mermaid know that you want to create a timeline diagram.
@@ -24,15 +23,18 @@ After that there is a possibility to add a title to the timeline. This is done b
Then you add the timeline data, where you always start with a time period, followed by a colon and then the text for the event. Optionally you can add a second colon and then the text for the event. So, you can have one or more events per time period. Then you add the timeline data, where you always start with a time period, followed by a colon and then the text for the event. Optionally you can add a second colon and then the text for the event. So, you can have one or more events per time period.
```json ```json
{time period} : {event} {time period} : {event}
``` ```
or or
```json ```json
{time period} : {event} : {event} {time period} : {event} : {event}
``` ```
or or
```json ```json
{time period} : {event} {time period} : {event}
: {event} : {event}
@@ -41,7 +43,6 @@ or
NOTE: Both time period and event are simple text, and not limited to numbers. NOTE: Both time period and event are simple text, and not limited to numbers.
Let us look at the syntax for the example above. Let us look at the syntax for the example above.
```mermaid-example ```mermaid-example
@@ -59,6 +60,7 @@ The sequence of time period and events is important, as it will be used to draw
Similarly, the first event will be placed at the top for that specific time period, and the last event will be placed at the bottom. Similarly, the first event will be placed at the top for that specific time period, and the last event will be placed at the bottom.
## Grouping of time periods in sections/ages ## Grouping of time periods in sections/ages
You can group time periods in sections/ages. This is done by adding a line with the keyword `section` followed by the section name. You can group time periods in sections/ages. This is done by adding a line with the keyword `section` followed by the section name.
All subsequent time periods will be placed in this section until a new section is defined. All subsequent time periods will be placed in this section until a new section is defined.
@@ -78,12 +80,13 @@ timeline
Industry 4.0 : Internet, Robotics, Internet of Things Industry 4.0 : Internet, Robotics, Internet of Things
Industry 5.0 : Artificial intelligence, Big data,3D printing Industry 5.0 : Artificial intelligence, Big data,3D printing
``` ```
As you can see, the time periods are placed in the sections, and the sections are placed in the order they are defined. As you can see, the time periods are placed in the sections, and the sections are placed in the order they are defined.
All time periods and events under a given section follow a similar color scheme. This is done to make it easier to see the relationship between time periods and events. All time periods and events under a given section follow a similar color scheme. This is done to make it easier to see the relationship between time periods and events.
## Wrapping of text for long time-periods or events ## Wrapping of text for long time-periods or events
By default, the text for time-periods and events will be wrapped if it is too long. This is done to avoid that the text is drawn outside the diagram. By default, the text for time-periods and events will be wrapped if it is too long. This is done to avoid that the text is drawn outside the diagram.
You can also use `<br>` to force a line break. You can also use `<br>` to force a line break.
@@ -120,6 +123,7 @@ However, if there is no section defined, then we have two possibilities:
2006 : Twitter 2006 : Twitter
``` ```
Note that this is no, section defined, and each time period and its corresponding events will have its own color scheme. Note that this is no, section defined, and each time period and its corresponding events will have its own color scheme.
2. Disable the multiColor option using the `disableMultiColor` option. This will make all time periods and events follow the same color scheme. 2. Disable the multiColor option using the `disableMultiColor` option. This will make all time periods and events follow the same color scheme.
@@ -139,6 +143,7 @@ mermaid.initialize({
``` ```
let us look at same example, where we have disabled the multiColor option. let us look at same example, where we have disabled the multiColor option.
```mermaid-example ```mermaid-example
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'timeline': {'disableMulticolor': true}}}%% %%{init: { 'logLevel': 'debug', 'theme': 'base', 'timeline': {'disableMulticolor': true}}}%%
timeline timeline
@@ -149,6 +154,7 @@ let us look at same example, where we have disabled the multiColor option.
2006 : Twitter 2006 : Twitter
``` ```
### Customizing Color scheme ### Customizing Color scheme
You can customize the color scheme using the `cScale0` to `cScale11` theme variables. Mermaid allows you to set unique colors for up-to 12, where `cScale0` variable will drive the value of the first section or time-period, `cScale1` will drive the value of the second section and so on. You can customize the color scheme using the `cScale0` to `cScale11` theme variables. Mermaid allows you to set unique colors for up-to 12, where `cScale0` variable will drive the value of the first section or time-period, `cScale1` will drive the value of the second section and so on.
@@ -180,8 +186,8 @@ Now let's override the default values for the `cScale0` to `cScale2` variables:
See how the colors are changed to the values specified in the theme variables. See how the colors are changed to the values specified in the theme variables.
## Themes ## Themes
Mermaid supports a bunch of pre-defined themes which you can use to find the right one for you. PS: you can actually override an existing theme's variable to get your own custom theme going. Learn more about theming your diagram [here](../config/theming.md). Mermaid supports a bunch of pre-defined themes which you can use to find the right one for you. PS: you can actually override an existing theme's variable to get your own custom theme going. Learn more about theming your diagram [here](../config/theming.md).
The following are the different pre-defined theme options: The following are the different pre-defined theme options:
@@ -270,10 +276,6 @@ Let's put them to use, and see how our sample diagram looks in different themes:
2010 : Pinterest 2010 : Pinterest
``` ```
## Integrating with your library/website. ## Integrating with your library/website.
Timeline uses the experimental lazy loading & async rendering features which could change in the future. Timeline uses the experimental lazy loading & async rendering features which could change in the future.

View File

@@ -779,7 +779,6 @@ const renderAsync = async function (
return svgCode; return svgCode;
}; };
/** /**
* @param options - Initial Mermaid options * @param options - Initial Mermaid options
*/ */

View File

@@ -139,7 +139,7 @@ class Theme {
this['cScalePeer' + 2] = this['cScalePeer' + 2] || darken(this.tertiaryColor, 40); this['cScalePeer' + 2] = this['cScalePeer' + 2] || darken(this.tertiaryColor, 40);
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) { for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
// Setup the peer color for the set, useful for borders // Setup the peer color for the set, useful for borders
this['cScale' + i] = darken(this['cScale' + i], 10); this['cScale' + i] = darken(this['cScale' + i], 10);
this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 25); this['cScalePeer' + i] = this['cScalePeer' + i] || darken(this['cScale' + i], 25);
} }
// Setup the inverted color for the set // Setup the inverted color for the set