mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-18 14:59:53 +02:00
⚗️ Add radar renderer tests
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { it, describe, expect } from 'vitest';
|
||||
import { db } from './db.js';
|
||||
import { parser } from './parser.js';
|
||||
import { renderer, relativeRadius, closedRoundCurve } from './renderer.js';
|
||||
import { Diagram } from '../../Diagram.js';
|
||||
import mermaidAPI from '../../mermaidAPI.js';
|
||||
import { a } from 'vitest/dist/chunks/suite.qtkXWc6R.js';
|
||||
import { buildRadarStyleOptions } from './styles.js';
|
||||
|
||||
const {
|
||||
clear,
|
||||
@@ -135,10 +140,6 @@ describe('radar diagrams', () => {
|
||||
curve mycurve{1,2,3}
|
||||
`;
|
||||
await expect(parser.parse(str)).resolves.not.toThrow();
|
||||
|
||||
// TODO: ✨ Fix this test
|
||||
// expect(getConfig().marginTop).toBe(80);
|
||||
// expect(getConfig().axisLabelFactor).toBe(1.25);
|
||||
});
|
||||
|
||||
it('should parse radar diagram with theme override', async () => {
|
||||
@@ -149,8 +150,6 @@ describe('radar diagrams', () => {
|
||||
curve mycurve{1,2,3}
|
||||
`;
|
||||
await expect(parser.parse(str)).resolves.not.toThrow();
|
||||
|
||||
// TODO: ✨ Add tests for theme override
|
||||
});
|
||||
|
||||
it('should handle radar diagram with radar style override', async () => {
|
||||
@@ -161,7 +160,99 @@ describe('radar diagrams', () => {
|
||||
curve mycurve{1,2,3}
|
||||
`;
|
||||
await expect(parser.parse(str)).resolves.not.toThrow();
|
||||
});
|
||||
|
||||
// TODO: ✨ Add tests for style override
|
||||
describe('renderer', () => {
|
||||
describe('relativeRadius', () => {
|
||||
it('should calculate relative radius', () => {
|
||||
expect(relativeRadius(5, 0, 10, 100)).toBe(50);
|
||||
});
|
||||
|
||||
it('should handle min value', () => {
|
||||
expect(relativeRadius(0, 0, 10, 100)).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle max value', () => {
|
||||
expect(relativeRadius(10, 0, 10, 100)).toBe(100);
|
||||
});
|
||||
|
||||
it('should clip values below min', () => {
|
||||
expect(relativeRadius(-5, 0, 10, 100)).toBe(0);
|
||||
});
|
||||
|
||||
it('should clip values above max', () => {
|
||||
expect(relativeRadius(15, 0, 10, 100)).toBe(100);
|
||||
});
|
||||
|
||||
it('should handle negative min', () => {
|
||||
expect(relativeRadius(5, -10, 10, 100)).toBe(75);
|
||||
});
|
||||
});
|
||||
|
||||
describe('closedRoundCurve', () => {
|
||||
it('should construct a polygon if tension is 0', () => {
|
||||
const points = [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 100, y: 0 },
|
||||
{ x: 100, y: 100 },
|
||||
{ x: 0, y: 100 },
|
||||
];
|
||||
const tension = 0;
|
||||
const path = closedRoundCurve(points, tension);
|
||||
expect(path).toMatchInlineSnapshot(
|
||||
`"M0,0 C0,0 100,0 100,0 C100,0 100,100 100,100 C100,100 0,100 0,100 C0,100 0,0 0,0 Z"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should construct a simple round curve', () => {
|
||||
const points = [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 100, y: 100 },
|
||||
];
|
||||
const tension = 0.5;
|
||||
const path = closedRoundCurve(points, tension);
|
||||
expect(path).toMatchInlineSnapshot(`"M0,0 C0,0 100,100 100,100 C100,100 0,0 0,0 Z"`);
|
||||
});
|
||||
|
||||
it('should construct a closed round curve', () => {
|
||||
const points = [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 100, y: 0 },
|
||||
{ x: 100, y: 100 },
|
||||
{ x: 0, y: 100 },
|
||||
];
|
||||
const tension = 0.5;
|
||||
const path = closedRoundCurve(points, tension);
|
||||
expect(path).toMatchInlineSnapshot(
|
||||
`"M0,0 C50,-50 50,-50 100,0 C150,50 150,50 100,100 C50,150 50,150 0,100 C-50,50 -50,50 0,0 Z"`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('draw', () => {
|
||||
it('should draw a simple radar diagram', async () => {
|
||||
const str = `radar-beta
|
||||
axis A,B,C
|
||||
curve mycurve{1,2,3}`;
|
||||
await mermaidAPI.parse(str);
|
||||
const diagram = await Diagram.fromText(str);
|
||||
await diagram.renderer.draw(str, 'tst', '1.2.3', diagram);
|
||||
});
|
||||
|
||||
it('should draw a complex radar diagram', async () => {
|
||||
const str = `radar-beta
|
||||
title Radar diagram
|
||||
accTitle: Radar accTitle
|
||||
accDescr: Radar accDescription
|
||||
axis A["Axis A"], B["Axis B"] ,C["Axis C"]
|
||||
curve mycurve["My Curve"]{1,2,3}
|
||||
curve mycurve2["My Curve 2"]{ C: 1, A: 2, B: 3 }
|
||||
graticule polygon
|
||||
`;
|
||||
await mermaidAPI.parse(str);
|
||||
const diagram = await Diagram.fromText(str);
|
||||
await diagram.renderer.draw(str, 'tst', '1.2.3', diagram);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -118,7 +118,6 @@ const drawAxes = (
|
||||
}
|
||||
};
|
||||
|
||||
export const renderer: DiagramRenderer = { draw };
|
||||
function drawCurves(
|
||||
g: SVGGroup,
|
||||
axes: RadarAxis[],
|
||||
@@ -159,12 +158,17 @@ function drawCurves(
|
||||
});
|
||||
}
|
||||
|
||||
function relativeRadius(value: number, minValue: number, maxValue: number, radius: number): number {
|
||||
export function relativeRadius(
|
||||
value: number,
|
||||
minValue: number,
|
||||
maxValue: number,
|
||||
radius: number
|
||||
): number {
|
||||
const clippedValue = Math.min(Math.max(value, minValue), maxValue);
|
||||
return (radius * (clippedValue - minValue)) / (maxValue - minValue);
|
||||
}
|
||||
|
||||
function closedRoundCurve(points: { x: number; y: number }[], tension: number): string {
|
||||
export function closedRoundCurve(points: { x: number; y: number }[], tension: number): string {
|
||||
// Catmull-Rom spline helper function
|
||||
const numPoints = points.length;
|
||||
let d = `M${points[0].x},${points[0].y}`;
|
||||
@@ -224,3 +228,5 @@ function drawLegend(
|
||||
.text(curve.label);
|
||||
});
|
||||
}
|
||||
|
||||
export const renderer: DiagramRenderer = { draw };
|
||||
|
@@ -30,12 +30,18 @@ const genIndexStyles = (
|
||||
return sections;
|
||||
};
|
||||
|
||||
export const styles: DiagramStylesProvider = ({ radar }: { radar?: RadarStyleOptions } = {}) => {
|
||||
export const buildRadarStyleOptions = (radar?: RadarStyleOptions) => {
|
||||
const defaultThemeVariables = getThemeVariables();
|
||||
const currentConfig = getConfigAPI();
|
||||
|
||||
const themeVariables = cleanAndMerge(defaultThemeVariables, currentConfig.themeVariables);
|
||||
const radarOptions: RadarStyleOptions = cleanAndMerge(themeVariables.radar, radar);
|
||||
|
||||
return { themeVariables, radarOptions };
|
||||
};
|
||||
|
||||
export const styles: DiagramStylesProvider = ({ radar }: { radar?: RadarStyleOptions } = {}) => {
|
||||
const { themeVariables, radarOptions } = buildRadarStyleOptions(radar);
|
||||
return `
|
||||
.radarTitle {
|
||||
font-size: ${themeVariables.fontSize};
|
||||
|
@@ -28,16 +28,16 @@ export interface RadarDB extends DiagramDBBase<RadarDiagramConfig> {
|
||||
}
|
||||
|
||||
export interface RadarStyleOptions {
|
||||
axisColor: string;
|
||||
axisStrokeWidth: number;
|
||||
axisLabelFontSize: number;
|
||||
curveOpacity: number;
|
||||
curveStrokeWidth: number;
|
||||
graticuleColor: string;
|
||||
graticuleOpacity: number;
|
||||
graticuleStrokeWidth: number;
|
||||
legendBoxSize: number;
|
||||
legendFontSize: number;
|
||||
axisColor?: string;
|
||||
axisStrokeWidth?: number;
|
||||
axisLabelFontSize?: number;
|
||||
curveOpacity?: number;
|
||||
curveStrokeWidth?: number;
|
||||
graticuleColor?: string;
|
||||
graticuleOpacity?: number;
|
||||
graticuleStrokeWidth?: number;
|
||||
legendBoxSize?: number;
|
||||
legendFontSize?: number;
|
||||
}
|
||||
|
||||
export interface RadarData {
|
||||
|
@@ -1679,7 +1679,6 @@ Alice->Bob: Hello Bob, how are you?`;
|
||||
|
||||
const diagram = await Diagram.fromText(str);
|
||||
await diagram.renderer.draw(str, 'tst', '1.2.3', diagram);
|
||||
|
||||
const { bounds, models } = diagram.renderer.bounds.getBounds();
|
||||
expect(bounds.startx).toBe(0);
|
||||
expect(bounds.starty).toBe(0);
|
||||
|
Reference in New Issue
Block a user