diff --git a/cypress/integration/rendering/timeline.spec.ts b/cypress/integration/rendering/timeline.spec.ts index c748b54d3c..5d38ca0042 100644 --- a/cypress/integration/rendering/timeline.spec.ts +++ b/cypress/integration/rendering/timeline.spec.ts @@ -161,4 +161,42 @@ describe('Timeline diagram', () => { {} ); }); + + it('11: should render a simple timeline with a custom width of 300', () => { + imgSnapshotTest( + `%%{init: { 'logLevel': 'debug', 'timeline': { 'width': 300 } } }%% + timeline + title History of Social Media Platform + 2002 : LinkedIn + 2004 : Facebook : Google + 2005 : Youtube + 2006 : Twitter + 2007 : Tumblr + 2008 : Instagram + 2010 : Pinterest + `, + { + timeline: { + width: 300, + }, + } + ); + }); + + it('12: should render a simple timeline with default width of 150', () => { + imgSnapshotTest( + `%%{init: { 'logLevel': 'debug', 'timeline': { 'width': 150 } } }%% + timeline + title History of Social Media Platform + 2002 : LinkedIn + 2004 : Facebook : Google + 2005 : Youtube + 2006 : Twitter + 2007 : Tumblr + 2008 : Instagram + 2010 : Pinterest + `, + {} + ); + }); }); diff --git a/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts b/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts index b3405bc1bf..8d718d3299 100644 --- a/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts +++ b/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts @@ -25,12 +25,17 @@ interface TimelineTask { score: number; events: string[]; } + +const DEFAULT_TASK_WIDTH = 150; + export const draw = function (text: string, id: string, version: string, diagObj: Diagram) { //1. Fetch the configuration const conf = getConfig(); // @ts-expect-error - wrong config? const LEFT_MARGIN = conf.leftMargin ?? 50; + const taskWidth = conf?.timeline?.width ?? DEFAULT_TASK_WIDTH; + log.debug('timeline', diagObj.db); const securityLevel = conf.securityLevel; @@ -82,7 +87,7 @@ export const draw = function (text: string, id: string, version: string, diagObj number: sectionNumber, descr: section, section: sectionNumber, - width: 150, + width: taskWidth, padding: 20, maxHeight: maxSectionHeight, }; @@ -103,7 +108,7 @@ export const draw = function (text: string, id: string, version: string, diagObj number: i, descr: task, section: task.section, - width: 150, + width: taskWidth, padding: 20, maxHeight: maxTaskHeight, }; @@ -120,7 +125,7 @@ export const draw = function (text: string, id: string, version: string, diagObj descr: event, section: task.section, number: task.section, - width: 150, + width: taskWidth, padding: 20, maxHeight: 50, }; @@ -132,6 +137,8 @@ export const draw = function (text: string, id: string, version: string, diagObj log.debug('maxSectionHeight before draw', maxSectionHeight); log.debug('maxTaskHeight before draw', maxTaskHeight); + const sectionWidth = taskWidth + 50; + if (sections && sections.length > 0) { sections.forEach((section) => { //filter task where tasks.section == section @@ -141,7 +148,7 @@ export const draw = function (text: string, id: string, version: string, diagObj number: sectionNumber, descr: section, section: sectionNumber, - width: 200 * Math.max(tasksForSection.length, 1) - 50, + width: sectionWidth * Math.max(tasksForSection.length, 1) - 50, padding: 20, maxHeight: maxSectionHeight, }; @@ -171,7 +178,7 @@ export const draw = function (text: string, id: string, version: string, diagObj ); } // todo replace with total width of section and its tasks - masterX += 200 * Math.max(tasksForSection.length, 1); + masterX += sectionWidth * Math.max(tasksForSection.length, 1); masterY = sectionBeginY; sectionNumber++; @@ -246,6 +253,8 @@ export const drawTasks = function ( maxSectionHeight: number, isWithoutSections: boolean ) { + const taskWidth = conf?.timeline?.width ?? DEFAULT_TASK_WIDTH; + // Draw the tasks for (const task of tasks) { // create node from task @@ -253,7 +262,7 @@ export const drawTasks = function ( descr: task.task, section: sectionColor, number: sectionColor, - width: 150, + width: taskWidth, padding: 20, maxHeight: maxTaskHeight, }; @@ -282,11 +291,13 @@ export const drawTasks = function ( lineLength + drawEvents(diagram, task.events, sectionColor, masterX, masterY, conf); masterY -= 100; + const xWidth = masterX + (taskWidth + 40) / 2; + lineWrapper .append('line') - .attr('x1', masterX + 190 / 2) + .attr('x1', xWidth) .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', xWidth) // Subtract stroke width so arrow point is retained .attr( 'y2', masterY + @@ -301,7 +312,7 @@ export const drawTasks = function ( .attr('stroke-dasharray', '5,5'); } - masterX = masterX + 200; + masterX = masterX + (taskWidth + 50); if (isWithoutSections && !conf.timeline?.disableMulticolor) { sectionColor++; } @@ -322,6 +333,9 @@ export const drawEvents = function ( let maxEventHeight = 0; const eventBeginY = masterY; masterY = masterY + 100; + + const eventNodeWidth = conf?.timeline?.width ?? DEFAULT_TASK_WIDTH; + // Draw the events for (const event of events) { // create node from event @@ -329,7 +343,7 @@ export const drawEvents = function ( descr: event, section: sectionColor, number: sectionColor, - width: 150, + width: eventNodeWidth, padding: 20, maxHeight: 50, };