Compare commits

..

1 Commits

Author SHA1 Message Date
Sidharth Vinod
c0b17f2a10 docs: Update to new pricing tiers 2025-11-21 12:31:15 +05:30
11 changed files with 71 additions and 207 deletions

View File

@@ -32,9 +32,7 @@ jobs:
node-version-file: '.node-version'
- name: Install Packages
run: |
pnpm install --frozen-lockfile
npm install -g npm@11
run: pnpm install --frozen-lockfile
- name: Create Release Pull Request or Publish to npm
id: changesets

View File

@@ -833,34 +833,4 @@ describe('Gantt diagram', () => {
{}
);
});
it('should handle seconds-only format with tickInterval (issue #5496)', () => {
imgSnapshotTest(
`
gantt
tickInterval 1second
dateFormat ss
axisFormat %s
section Network Request
RTT : rtt, 0, 20
`,
{}
);
});
it('should handle dates with year typo like 202 instead of 2024 (issue #5496)', () => {
imgSnapshotTest(
`
gantt
title Schedule
dateFormat YYYY-MM-DD
tickInterval 1week
axisFormat %m-%d
section Vacation
London : 2024-12-01, 7d
London : 202-12-01, 7d
`,
{}
);
});
});

View File

@@ -47,16 +47,18 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
## Plans
- **Free** - A free plan that includes six diagrams.
- **Basic** - A free plan that includes three diagrams and limited AI usage.
- **Pro** - A paid plan that includes unlimited diagrams, access to the collaboration feature, and more.
- **Plus** - A paid plan that includes unlimited diagrams, scalable AI usage, and centralized billing for small teams.
- **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more.
- **Premium** - A paid plan for larger teams that need massive AI or diagram usage along with team collaboration, knowledge management, and security features like SSO.
To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
- **Enterprise** - A paid plan for enterprise use that includes all Premium features, custom contracts, support, and more.
Mermaid Chart is currently offering a 7-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
To learn more, visit our [Pricing](https://www.mermaidchart.com/pricing) page.
Sign up for a free account on the [Mermaid](https://www.mermaidchart.com/app/sign-up) website and trial paid features at any time for 7 days free.
## Mermaid JS contributions
First time contributors are eligible for a free Pro tier account for 1 year.
First time contributors are eligible for a free Premium tier account for 1 year.

View File

@@ -1,11 +1,5 @@
# mermaid
## 11.12.2
### Patch Changes
- [#7200](https://github.com/mermaid-js/mermaid/pull/7200) [`de7ed10`](https://github.com/mermaid-js/mermaid/commit/de7ed1033996d702e3983dcf8114f33faea89577) Thanks [@shubhamparikh2704](https://github.com/shubhamparikh2704)! - fix: validate dates and tick interval to prevent UI freeze/crash in gantt diagramtype
## 11.12.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "11.12.2",
"version": "11.12.1",
"description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
"type": "module",
"module": "./dist/mermaid.core.mjs",

View File

@@ -268,15 +268,7 @@ const fixTaskDates = function (startTime, endTime, dateFormat, excludes, include
const getStartDate = function (prevTime, dateFormat, str) {
str = str.trim();
// Helper function to check if format is a timestamp format (x or X)
const isTimestampFormat = (format) => {
const trimmedFormat = format.trim();
return trimmedFormat === 'x' || trimmedFormat === 'X';
};
// Handle timestamp formats (x, X) with numeric strings
if (isTimestampFormat(dateFormat) && /^\d+$/.test(str)) {
if ((dateFormat.trim() === 'x' || dateFormat.trim() === 'X') && /^\d+$/.test(str)) {
return new Date(Number(str));
}
// Test for after
@@ -301,15 +293,13 @@ const getStartDate = function (prevTime, dateFormat, str) {
return today;
}
// Check for actual date set using dayjs strict parsing
// Check for actual date set
let mDate = dayjs(str, dateFormat.trim(), true);
if (mDate.isValid()) {
return mDate.toDate();
} else {
log.debug('Invalid date:' + str);
log.debug('With date format:' + dateFormat.trim());
// Timestamp formats can fall back to new Date()
const d = new Date(str);
if (
d === undefined ||

View File

@@ -505,27 +505,4 @@ describe('when using the ganttDb', function () {
ganttDb.addTask('test1', 'id1,202304,1d');
expect(() => ganttDb.getTasks()).toThrowError('Invalid date:202304');
});
it('should handle seconds-only format with valid numeric values (issue #5496)', function () {
ganttDb.setDateFormat('ss');
ganttDb.addSection('Network Request');
ganttDb.addTask('RTT', 'rtt, 0, 20');
const tasks = ganttDb.getTasks();
expect(tasks).toHaveLength(1);
expect(tasks[0].task).toBe('RTT');
expect(tasks[0].id).toBe('rtt');
});
it('should handle dates with year typo like 202 instead of 2024 (issue #5496)', function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.addSection('Vacation');
ganttDb.addTask('London Trip 1', '2024-12-01, 7d');
ganttDb.addTask('London Trip 2', '202-12-01, 7d');
const tasks = ganttDb.getTasks();
expect(tasks).toHaveLength(2);
// First task should be in year 2024
expect(tasks[0].startTime.getFullYear()).toBe(2024);
// Second task will be parsed as year 202 (fallback to new Date())
expect(tasks[1].startTime.getFullYear()).toBe(202);
});
});

View File

@@ -1,5 +1,4 @@
import dayjs from 'dayjs';
import dayjsDuration from 'dayjs/plugin/duration.js';
import { log } from '../../logger.js';
import {
select,
@@ -29,8 +28,6 @@ import common from '../common/common.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import { configureSvgSize } from '../../setupGraphViewbox.js';
dayjs.extend(dayjsDuration);
export const setConf = function () {
log.debug('Something is calling, setConf, remove the call');
};
@@ -81,7 +78,6 @@ const getMaxIntersections = (tasks, orderOffset) => {
};
let w;
const MAX_TICK_COUNT = 10000;
export const draw = function (text, id, version, diagObj) {
const conf = getConfig().gantt;
@@ -606,27 +602,6 @@ export const draw = function (text, id, version, diagObj) {
.attr('class', 'exclude-range');
}
/**
* Calculates the estimated number of ticks based on the time domain and tick interval.
* Returns the estimated number of ticks as a number.
* @param {Date} minTime - The minimum time in the domain
* @param {Date} maxTime - The maximum time in the domain
* @param {number} every - The interval count (e.g., 1 for "1second")
* @param {string} interval - The interval unit (e.g., "second", "day")
* @returns {number} The estimated number of ticks
*/
function getEstimatedTickCount(minTime, maxTime, every, interval) {
if (every <= 0 || minTime > maxTime) {
return Infinity;
}
const timeDiffMs = maxTime - minTime;
const intervalMs = dayjs.duration({ [interval ?? 'day']: every }).asMilliseconds();
if (intervalMs <= 0) {
return Infinity;
}
return Math.ceil(timeDiffMs / intervalMs);
}
/**
* @param theSidePad
* @param theTopPad
@@ -655,54 +630,32 @@ export const draw = function (text, id, version, diagObj) {
);
if (resultTickInterval !== null) {
const every = parseInt(resultTickInterval[1], 10);
if (isNaN(every) || every <= 0) {
log.warn(
`Invalid tick interval value: "${resultTickInterval[1]}". Skipping custom tick interval.`
);
// Skip applying custom ticks
} else {
const interval = resultTickInterval[2];
const weekday = diagObj.db.getWeekday() || conf.weekday;
const every = resultTickInterval[1];
const interval = resultTickInterval[2];
const weekday = diagObj.db.getWeekday() || conf.weekday;
// Get the time domain to check tick count
const domain = timeScale.domain();
const minTime = domain[0];
const maxTime = domain[1];
const estimatedTicks = getEstimatedTickCount(minTime, maxTime, every, interval);
if (estimatedTicks > MAX_TICK_COUNT) {
log.warn(
`The tick interval "${every}${interval}" would generate ${estimatedTicks} ticks, ` +
`which exceeds the maximum allowed (${MAX_TICK_COUNT}). ` +
`This may indicate an invalid date or time range. Skipping custom tick interval.`
);
// D3 will use its default automatic tick generation
} else {
switch (interval) {
case 'millisecond':
bottomXAxis.ticks(timeMillisecond.every(every));
break;
case 'second':
bottomXAxis.ticks(timeSecond.every(every));
break;
case 'minute':
bottomXAxis.ticks(timeMinute.every(every));
break;
case 'hour':
bottomXAxis.ticks(timeHour.every(every));
break;
case 'day':
bottomXAxis.ticks(timeDay.every(every));
break;
case 'week':
bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
break;
case 'month':
bottomXAxis.ticks(timeMonth.every(every));
break;
}
}
switch (interval) {
case 'millisecond':
bottomXAxis.ticks(timeMillisecond.every(every));
break;
case 'second':
bottomXAxis.ticks(timeSecond.every(every));
break;
case 'minute':
bottomXAxis.ticks(timeMinute.every(every));
break;
case 'hour':
bottomXAxis.ticks(timeHour.every(every));
break;
case 'day':
bottomXAxis.ticks(timeDay.every(every));
break;
case 'week':
bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
break;
case 'month':
bottomXAxis.ticks(timeMonth.every(every));
break;
}
}
@@ -724,48 +677,32 @@ export const draw = function (text, id, version, diagObj) {
.tickFormat(timeFormat(axisFormat));
if (resultTickInterval !== null) {
const every = parseInt(resultTickInterval[1], 10);
if (isNaN(every) || every <= 0) {
log.warn(
`Invalid tick interval value: "${resultTickInterval[1]}". Skipping custom tick interval.`
);
// Skip applying custom ticks
} else {
const interval = resultTickInterval[2];
const weekday = diagObj.db.getWeekday() || conf.weekday;
const every = resultTickInterval[1];
const interval = resultTickInterval[2];
const weekday = diagObj.db.getWeekday() || conf.weekday;
// Get the time domain to check tick count
const domain = timeScale.domain();
const minTime = domain[0];
const maxTime = domain[1];
const estimatedTicks = getEstimatedTickCount(minTime, maxTime, every, interval);
// Only apply custom ticks if the count is reasonable
if (estimatedTicks <= MAX_TICK_COUNT) {
switch (interval) {
case 'millisecond':
topXAxis.ticks(timeMillisecond.every(every));
break;
case 'second':
topXAxis.ticks(timeSecond.every(every));
break;
case 'minute':
topXAxis.ticks(timeMinute.every(every));
break;
case 'hour':
topXAxis.ticks(timeHour.every(every));
break;
case 'day':
topXAxis.ticks(timeDay.every(every));
break;
case 'week':
topXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
break;
case 'month':
topXAxis.ticks(timeMonth.every(every));
break;
}
}
switch (interval) {
case 'millisecond':
topXAxis.ticks(timeMillisecond.every(every));
break;
case 'second':
topXAxis.ticks(timeSecond.every(every));
break;
case 'minute':
topXAxis.ticks(timeMinute.every(every));
break;
case 'hour':
topXAxis.ticks(timeHour.every(every));
break;
case 'day':
topXAxis.ticks(timeDay.every(every));
break;
case 'week':
topXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
break;
case 'month':
topXAxis.ticks(timeMonth.every(every));
break;
}
}

View File

@@ -41,16 +41,18 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
## Plans
- **Free** - A free plan that includes six diagrams.
- **Basic** - A free plan that includes three diagrams and limited AI usage.
- **Pro** - A paid plan that includes unlimited diagrams, access to the collaboration feature, and more.
- **Plus** - A paid plan that includes unlimited diagrams, scalable AI usage, and centralized billing for small teams.
- **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more.
- **Premium** - A paid plan for larger teams that need massive AI or diagram usage along with team collaboration, knowledge management, and security features like SSO.
To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
- **Enterprise** - A paid plan for enterprise use that includes all Premium features, custom contracts, support, and more.
Mermaid Chart is currently offering a 7-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
To learn more, visit our [Pricing](https://www.mermaidchart.com/pricing) page.
Sign up for a free account on the [Mermaid](https://www.mermaidchart.com/app/sign-up) website and trial paid features at any time for 7 days free.
## Mermaid JS contributions
First time contributors are eligible for a free Pro tier account for 1 year.
First time contributors are eligible for a free Premium tier account for 1 year.

View File

@@ -1,11 +1,5 @@
# mermaid
## 11.12.2
### Patch Changes
- [#7200](https://github.com/mermaid-js/mermaid/pull/7200) [`de7ed10`](https://github.com/mermaid-js/mermaid/commit/de7ed1033996d702e3983dcf8114f33faea89577) Thanks [@shubhamparikh2704](https://github.com/shubhamparikh2704)! - fix: validate dates and tick interval to prevent UI freeze/crash in gantt diagramtype
## 11.12.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@mermaid-js/tiny",
"version": "11.12.2",
"version": "11.12.1",
"description": "Tiny version of mermaid",
"type": "commonjs",
"main": "./dist/mermaid.tiny.js",