mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-09 10:36:43 +02:00
some fixes
This commit is contained in:
@@ -239,12 +239,12 @@ describe('Quadrant Chart', () => {
|
|||||||
quadrant-3 Re-evaluate
|
quadrant-3 Re-evaluate
|
||||||
quadrant-4 May be improved
|
quadrant-4 May be improved
|
||||||
Campaign A: [0.3, 0.6] radius: 20
|
Campaign A: [0.3, 0.6] radius: 20
|
||||||
Campaign B: [0.45, 0.23] color: #ff0000
|
Campaign B: [0.45, 0.23] color: #ff0000
|
||||||
Campaign C: [0.57, 0.69] stroke-color: #ff00ff
|
Campaign C: [0.57, 0.69] stroke-color: #ff00ff
|
||||||
Campaign D: [0.78, 0.34] stroke-width: 3px
|
Campaign D: [0.78, 0.34] stroke-width: 3px
|
||||||
Campaign E: [0.40, 0.34] radius: 20, color: #ff0000, stroke-color: #ff00ff, stroke-width: 3px
|
Campaign E: [0.40, 0.34] radius: 20, color: #ff0000 , stroke-color : #ff00ff, stroke-width : 3px
|
||||||
Campaign F: [0.35, 0.78] stroke-width: 3px, color: #ff0000, radius: 20, stroke-color: #ff00ff
|
Campaign F: [0.35, 0.78] stroke-width: 3px , color: #ff0000, radius: 20, stroke-color: #ff00ff
|
||||||
Campaign G: [0.22, 0.22] stroke-width: 3px, color: #309708, radius: 20, stroke-color: #5060ff
|
Campaign G: [0.22, 0.22] stroke-width: 3px , color: #309708 , radius : 20 , stroke-color: #5060ff
|
||||||
Campaign H: [0.22, 0.44]
|
Campaign H: [0.22, 0.44]
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
|
@@ -18,13 +18,8 @@ export interface StylesObject {
|
|||||||
strokeWidth?: string;
|
strokeWidth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuadrantPointInputType extends Point {
|
export interface QuadrantPointInputType extends Point, StylesObject {
|
||||||
text: string;
|
text: string;
|
||||||
className?: string;
|
|
||||||
radius?: number;
|
|
||||||
color?: string;
|
|
||||||
strokeColor?: string;
|
|
||||||
strokeWidth?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuadrantTextType extends Point {
|
export interface QuadrantTextType extends Point {
|
||||||
@@ -36,12 +31,12 @@ export interface QuadrantTextType extends Point {
|
|||||||
rotation: number;
|
rotation: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuadrantPointType extends Point {
|
export interface QuadrantPointType
|
||||||
|
extends Point,
|
||||||
|
Pick<StylesObject, 'strokeColor' | 'strokeWidth'> {
|
||||||
fill: string;
|
fill: string;
|
||||||
radius: number;
|
radius: number;
|
||||||
text: QuadrantTextType;
|
text: QuadrantTextType;
|
||||||
strokeColor: string;
|
|
||||||
strokeWidth: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuadrantQuadrantsType extends Point {
|
export interface QuadrantQuadrantsType extends Point {
|
||||||
@@ -132,7 +127,7 @@ export class QuadrantBuilder {
|
|||||||
private config: QuadrantBuilderConfig;
|
private config: QuadrantBuilderConfig;
|
||||||
private themeConfig: QuadrantBuilderThemeConfig;
|
private themeConfig: QuadrantBuilderThemeConfig;
|
||||||
private data: QuadrantBuilderData;
|
private data: QuadrantBuilderData;
|
||||||
private classes: StylesObject[] = [];
|
private classes: Record<string, StylesObject> = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.config = this.getDefaultConfig();
|
this.config = this.getDefaultConfig();
|
||||||
@@ -219,10 +214,7 @@ export class QuadrantBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addClass(className: string, styles: StylesObject) {
|
addClass(className: string, styles: StylesObject) {
|
||||||
this.classes.push({
|
this.classes[className] = styles;
|
||||||
className,
|
|
||||||
...styles,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setConfig(config: Partial<QuadrantBuilderConfig>) {
|
setConfig(config: Partial<QuadrantBuilderConfig>) {
|
||||||
@@ -493,7 +485,7 @@ export class QuadrantBuilder {
|
|||||||
.range([quadrantHeight + quadrantTop, quadrantTop]);
|
.range([quadrantHeight + quadrantTop, quadrantTop]);
|
||||||
|
|
||||||
const points: QuadrantPointType[] = this.data.points.map((point) => {
|
const points: QuadrantPointType[] = this.data.points.map((point) => {
|
||||||
const classStyles = this.classes.find((obj) => obj.className === point.className);
|
const classStyles = this.classes[point.className as keyof typeof this.classes];
|
||||||
if (classStyles !== undefined) {
|
if (classStyles !== undefined) {
|
||||||
if (classStyles.color !== undefined) {
|
if (classStyles.color !== undefined) {
|
||||||
point.color = classStyles.color;
|
point.color = classStyles.color;
|
||||||
@@ -511,11 +503,8 @@ export class QuadrantBuilder {
|
|||||||
const props: QuadrantPointType = {
|
const props: QuadrantPointType = {
|
||||||
x: xAxis(point.x),
|
x: xAxis(point.x),
|
||||||
y: yAxis(point.y),
|
y: yAxis(point.y),
|
||||||
fill:
|
fill: point.color || this.themeConfig.quadrantPointFill,
|
||||||
point.color !== undefined && point.color !== ''
|
radius: point.radius || this.config.pointRadius,
|
||||||
? point.color
|
|
||||||
: this.themeConfig.quadrantPointFill,
|
|
||||||
radius: point.radius !== undefined && point.radius ? point.radius : this.config.pointRadius,
|
|
||||||
text: {
|
text: {
|
||||||
text: point.text,
|
text: point.text,
|
||||||
fill: this.themeConfig.quadrantPointTextFill,
|
fill: this.themeConfig.quadrantPointTextFill,
|
||||||
|
@@ -29,22 +29,22 @@ describe('quadrant unit tests', () => {
|
|||||||
it('should throw an error for unacceptable style value', () => {
|
it('should throw an error for unacceptable style value', () => {
|
||||||
let styles: string[] = ['radius: f'];
|
let styles: string[] = ['radius: f'];
|
||||||
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
||||||
'value for radius f is unvalid, requires a number'
|
'value for radius f is invalid, please use a valid number'
|
||||||
);
|
);
|
||||||
|
|
||||||
styles = ['color: ffaa'];
|
styles = ['color: ffaa'];
|
||||||
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
||||||
'value for color ffaa is unvalid, requires a valid hex code'
|
'value for color ffaa is invalid, please use a valid hex code'
|
||||||
);
|
);
|
||||||
|
|
||||||
styles = ['stroke-color: #f677779'];
|
styles = ['stroke-color: #f677779'];
|
||||||
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
||||||
'value for stroke-color #f677779 is unvalid, requires a valid hex code'
|
'value for stroke-color #f677779 is invalid, please use a valid hex code'
|
||||||
);
|
);
|
||||||
|
|
||||||
styles = ['stroke-width: 30'];
|
styles = ['stroke-width: 30'];
|
||||||
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
|
||||||
'value for stroke-width 30 is unvalid, requires a valid number of pixels (eg. 10px)'
|
'value for stroke-width 30 is invalid, please use a valid number of pixels (eg. 10px)'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -11,6 +11,12 @@ import {
|
|||||||
} from '../common/commonDb.js';
|
} from '../common/commonDb.js';
|
||||||
import type { StylesObject } from './quadrantBuilder.js';
|
import type { StylesObject } from './quadrantBuilder.js';
|
||||||
import { QuadrantBuilder } from './quadrantBuilder.js';
|
import { QuadrantBuilder } from './quadrantBuilder.js';
|
||||||
|
import {
|
||||||
|
validateHexCode,
|
||||||
|
validateSizeInPixels,
|
||||||
|
validateNumber,
|
||||||
|
InvalidStyleError,
|
||||||
|
} from './utils.js';
|
||||||
|
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
|
||||||
@@ -56,36 +62,30 @@ function setYAxisBottomText(textObj: LexTextObj) {
|
|||||||
|
|
||||||
function parseStyles(styles: string[]): StylesObject {
|
function parseStyles(styles: string[]): StylesObject {
|
||||||
const stylesObject: StylesObject = {};
|
const stylesObject: StylesObject = {};
|
||||||
if (styles.length !== 0) {
|
for (const style of styles) {
|
||||||
for (const item of styles) {
|
const [key, value] = style.trim().split(/\s*:\s*/);
|
||||||
const style = item.trim().split(/\s*:\s*/);
|
if (key == 'radius') {
|
||||||
if (style[0] == 'radius') {
|
if (validateNumber(value)) {
|
||||||
if (!/^\d+$/.test(style[1])) {
|
throw new InvalidStyleError(key, value, 'number');
|
||||||
throw new Error(`value for radius ${style[1]} is unvalid, requires a number`);
|
|
||||||
}
|
|
||||||
stylesObject.radius = parseInt(style[1]);
|
|
||||||
} else if (style[0] == 'color') {
|
|
||||||
if (!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(style[1])) {
|
|
||||||
throw new Error(`value for color ${style[1]} is unvalid, requires a valid hex code`);
|
|
||||||
}
|
|
||||||
stylesObject.color = style[1];
|
|
||||||
} else if (style[0] == 'stroke-color') {
|
|
||||||
if (!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(style[1])) {
|
|
||||||
throw new Error(
|
|
||||||
`value for stroke-color ${style[1]} is unvalid, requires a valid hex code`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
stylesObject.strokeColor = style[1];
|
|
||||||
} else if (style[0] == 'stroke-width') {
|
|
||||||
if (!/^\d+px$/.test(style[1])) {
|
|
||||||
throw new Error(
|
|
||||||
`value for stroke-width ${style[1]} is unvalid, requires a valid number of pixels (eg. 10px)`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
stylesObject.strokeWidth = style[1];
|
|
||||||
} else {
|
|
||||||
throw new Error(`stlye named ${style[0]} is unacceptable`);
|
|
||||||
}
|
}
|
||||||
|
stylesObject.radius = parseInt(value);
|
||||||
|
} else if (key == 'color') {
|
||||||
|
if (validateHexCode(value)) {
|
||||||
|
throw new InvalidStyleError(key, value, 'hex code');
|
||||||
|
}
|
||||||
|
stylesObject.color = value;
|
||||||
|
} else if (key == 'stroke-color') {
|
||||||
|
if (validateHexCode(value)) {
|
||||||
|
throw new InvalidStyleError(key, value, 'hex code');
|
||||||
|
}
|
||||||
|
stylesObject.strokeColor = value;
|
||||||
|
} else if (key == 'stroke-width') {
|
||||||
|
if (validateSizeInPixels(value)) {
|
||||||
|
throw new InvalidStyleError(key, value, 'number of pixels (eg. 10px)');
|
||||||
|
}
|
||||||
|
stylesObject.strokeWidth = value;
|
||||||
|
} else {
|
||||||
|
throw new Error(`stlye named ${key} is unacceptable`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stylesObject;
|
return stylesObject;
|
||||||
@@ -97,12 +97,9 @@ function addPoint(textObj: LexTextObj, className: string, x: number, y: number,
|
|||||||
{
|
{
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
className: className,
|
|
||||||
text: textSanitizer(textObj.text),
|
text: textSanitizer(textObj.text),
|
||||||
radius: stylesObject.radius,
|
className,
|
||||||
color: stylesObject.color,
|
...stylesObject,
|
||||||
strokeColor: stylesObject.strokeColor,
|
|
||||||
strokeWidth: stylesObject.strokeWidth,
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
20
packages/mermaid/src/diagrams/quadrant-chart/utils.ts
Normal file
20
packages/mermaid/src/diagrams/quadrant-chart/utils.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
class InvalidStyleError extends Error {
|
||||||
|
constructor(style: string, value: string, type: string) {
|
||||||
|
super(`value for ${style} ${value} is invalid, please use a valid ${type}`);
|
||||||
|
this.name = 'InvalidStyleError';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateHexCode(value: string): boolean {
|
||||||
|
return !/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateNumber(value: string): boolean {
|
||||||
|
return !/^\d+$/.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateSizeInPixels(value: string): boolean {
|
||||||
|
return !/^\d+px$/.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { validateHexCode, validateNumber, validateSizeInPixels, InvalidStyleError };
|
Reference in New Issue
Block a user