Fixed review comment

This commit is contained in:
Subhash Halder
2023-05-11 12:10:58 +05:30
parent 4cbcfa054e
commit 1253733962
13 changed files with 446 additions and 258 deletions

View File

@@ -27,9 +27,10 @@
</pre> </pre>
<pre class="mermaid"> <pre class="mermaid">
%%{init: {"quadrantChart": {"xAxisPosition": "bottom", "chartWidth": 600, "chartHeight": 600} } }%% %%{init: {"quadrantChart": {"chartWidth": 600, "chartHeight": 600} } }%%
quadrantChart quadrantChart
x-axis "Completeness of Vision ❤" title Analytics and Business Intelligence Platforms
x-axis "Completeness of Vision ❤" -->
y-axis Ability to Execute y-axis Ability to Execute
quadrant-1 Leaders quadrant-1 Leaders
quadrant-2 Challengers quadrant-2 Challengers
@@ -46,7 +47,7 @@
import mermaid from './mermaid.esm.mjs'; import mermaid from './mermaid.esm.mjs';
mermaid.initialize({ mermaid.initialize({
theme: 'default', theme: 'default',
logLevel: 1, logLevel: 3,
securityLevel: 'loose', securityLevel: 'loose',
}); });
</script> </script>

View File

@@ -14,7 +14,7 @@
#### Defined in #### Defined in
[defaultConfig.ts:2257](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2257) [defaultConfig.ts:2293](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2293)
--- ---

View File

@@ -230,6 +230,8 @@ export interface PieDiagramConfig extends BaseDiagramConfig {
export interface QuadrantChartConfig extends BaseDiagramConfig { export interface QuadrantChartConfig extends BaseDiagramConfig {
chartWidth: number; chartWidth: number;
chartHeight: number; chartHeight: number;
titleFontSize: number;
titlePadding: number;
quadrantPadding: number; quadrantPadding: number;
xAxisLabelPadding: number; xAxisLabelPadding: number;
yAxisLabelPadding: number; yAxisLabelPadding: number;
@@ -242,6 +244,8 @@ export interface QuadrantChartConfig extends BaseDiagramConfig {
pointRadius: number; pointRadius: number;
xAxisPosition: 'top' | 'bottom'; xAxisPosition: 'top' | 'bottom';
yAxisPosition: 'left' | 'right'; yAxisPosition: 'left' | 'right';
quadrantInternalBorderStrokeWidth: number;
quadrantExternalBorderStrokeWidth: number;
} }
export interface ErDiagramConfig extends BaseDiagramConfig { export interface ErDiagramConfig extends BaseDiagramConfig {

View File

@@ -1326,6 +1326,24 @@ const config: Partial<MermaidConfig> = {
* Default value: 5 * Default value: 5
*/ */
yAxisLabelPadding: 5, yAxisLabelPadding: 5,
/**
* | Parameter | Description | Type | Required | Values |
* | ------------------ | ---------------------------------- | ------- | -------- | ------------------- |
* | titlePadding | Chart title top and bottom padding | number | Optional | Any positive number |
*
* **Notes:**
* Default value: 5
*/
titlePadding: 5,
/**
* | Parameter | Description | Type | Required | Values |
* | ------------------ | ---------------------------------- | ------- | -------- | ------------------- |
* | titleFontSize | Chart title font size | number | Optional | Any positive number |
*
* **Notes:**
* Default value: 20
*/
titleFontSize: 20,
/** /**
* | Parameter | Description | Type | Required | Values | * | Parameter | Description | Type | Required | Values |
* | ------------------ | ---------------------------------- | ------- | -------- | ------------------- | * | ------------------ | ---------------------------------- | ------- | -------- | ------------------- |
@@ -1407,6 +1425,24 @@ const config: Partial<MermaidConfig> = {
* Default value: left * Default value: left
*/ */
yAxisPosition: 'left', yAxisPosition: 'left',
/**
* | Parameter | Description | Type | Required | Values |
* | --------------------------------- | ------------------------------------------------------------- | ------- | -------- | ------------------- |
* | quadrantInternalBorderStrokeWidth | stroke width of edges of the box that are inside the quadrant | number | Optional | Any positive number |
*
* **Notes:**
* Default value: 1
*/
quadrantInternalBorderStrokeWidth: 1,
/**
* | Parameter | Description | Type | Required | Values |
* | --------------------------------- | -------------------------------------------------------------- | ------- | -------- | ------------------- |
* | quadrantExternalBorderStrokeWidth | stroke width of edges of the box that are outside the quadrant | number | Optional | Any positive number |
*
* **Notes:**
* Default value: 2
*/
quadrantExternalBorderStrokeWidth: 2,
/** /**
* | Parameter | Description | Type | Required | Values | * | Parameter | Description | Type | Required | Values |
* | ----------- | ----------- | ------- | -------- | ----------- | * | ----------- | ----------- | ------- | -------- | ----------- |

View File

@@ -44,7 +44,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
\s*"x-axis"\s* return 'X-AXIS'; \s*"x-axis"\s* return 'X-AXIS';
\s*"y-axis"\s* return 'Y-AXIS'; \s*"y-axis"\s* return 'Y-AXIS';
\s*\-\-\>\s* return 'AXIS-TEXT-DELIMITER' \s*\-\-+\>[^(\r?\n)\s]* return 'AXIS-TEXT-DELIMITER'
\s*"quadrant-1"\s* return 'QUADRANT_1'; \s*"quadrant-1"\s* return 'QUADRANT_1';
\s*"quadrant-2"\s* return 'QUADRANT_2'; \s*"quadrant-2"\s* return 'QUADRANT_2';
\s*"quadrant-3"\s* return 'QUADRANT_3'; \s*"quadrant-3"\s* return 'QUADRANT_3';
@@ -118,12 +118,14 @@ statement
; ;
points points
: text point_start point_x point_y {yy.addPoints($1, $3, $4);}; : text point_start point_x point_y {yy.addPoint($1, $3, $4);};
axisDetails axisDetails
: X-AXIS text AXIS-TEXT-DELIMITER text {yy.setXAxisLeftText($2); yy.setXAxisRightText($4);} : X-AXIS text AXIS-TEXT-DELIMITER text {yy.setXAxisLeftText($2); yy.setXAxisRightText($4);}
| X-AXIS text AXIS-TEXT-DELIMITER {$2.text += $3; yy.setXAxisLeftText($2);}
| X-AXIS text {yy.setXAxisLeftText($2);} | X-AXIS text {yy.setXAxisLeftText($2);}
| Y-AXIS text AXIS-TEXT-DELIMITER text {yy.setYAxisBottomText($2); yy.setYAxisTopText($4);} | Y-AXIS text AXIS-TEXT-DELIMITER text {yy.setYAxisBottomText($2); yy.setYAxisTopText($4);}
| Y-AXIS text AXIS-TEXT-DELIMITER {$2.text += $3; yy.setYAxisBottomText($2);}
| Y-AXIS text {yy.setYAxisBottomText($2);} | Y-AXIS text {yy.setYAxisBottomText($2);}
; ;

View File

@@ -1,12 +1,18 @@
// @ts-ignore: TODO Fix ts errors // @ts-ignore: TODO Fix ts errors
import { scaleLinear } from 'd3'; import { scaleLinear } from 'd3';
import { log } from '../../logger.js';
import { QuadrantChartConfig } from '../../config.type.js';
export type QuadrantPointInputType = { x: number; y: number; text: string }; export interface QuadrantPointInputType {
x: number;
y: number;
text: string;
}
export type TextVerticalPos = 'left' | 'center' | 'right'; export type TextVerticalPos = 'left' | 'center' | 'right';
export type TextHorizontalPos = 'top' | 'middle' | 'bottom'; export type TextHorizontalPos = 'top' | 'middle' | 'bottom';
export type QuadrantTextType = { export interface QuadrantTextType {
text: string; text: string;
fill: string; fill: string;
x: number; x: number;
@@ -15,250 +21,267 @@ export type QuadrantTextType = {
horizontalPos: TextHorizontalPos; horizontalPos: TextHorizontalPos;
fontSize: number; fontSize: number;
rotation: number; rotation: number;
}; }
export type QuadrantPointType = { export interface QuadrantPointType {
x: number; x: number;
y: number; y: number;
fill: string; fill: string;
radius: number; radius: number;
text: QuadrantTextType; text: QuadrantTextType;
}; }
export type QuadrantQuadrantsType = { export interface QuadrantLineType {
strokeWidth: number;
strokeFill: string;
x1: number;
y1: number;
x2: number;
y2: number;
}
export interface QuadrantQuadrantsType {
text: QuadrantTextType; text: QuadrantTextType;
x: number; x: number;
y: number; y: number;
width: number; width: number;
height: number; height: number;
fill: string; fill: string;
}; }
export type QuadrantBuildType = { export interface QuadrantBuildType {
points: QuadrantPointType[]; points: QuadrantPointType[];
quadrants: QuadrantQuadrantsType[]; quadrants: QuadrantQuadrantsType[];
axisLabels: QuadrantTextType[]; axisLabels: QuadrantTextType[];
}; title?: QuadrantTextType;
borderLines?: QuadrantLineType[];
}
export interface QuadrantBuilderConfig extends QuadrantChartConfig {
titleText: string;
quadrant1Text: string;
quadrant2Text: string;
quadrant3Text: string;
quadrant4Text: string;
xAxisLeftText: string;
xAxisRightText: string;
yAxisBottomText: string;
yAxisTopText: string;
points: QuadrantPointInputType[];
showXAxis: boolean;
showYAxis: boolean;
showTitle: boolean;
}
export interface QuadrantBuilderThemeConfig {
quadrantTitleFill: string;
quadrant1Fill: string;
quadrant2Fill: string;
quadrant3Fill: string;
quadrant4Fill: string;
quadrant1TextFill: string;
quadrant2TextFill: string;
quadrant3TextFill: string;
quadrant4TextFill: string;
quadrantPointFill: string;
quadrantPointTextFill: string;
quadrantXAxisTextFill: string;
quadrantYAxisTextFill: string;
quadrantInternalBorderStrokeFill: string;
quadrantExternalBorderStrokeFill: string;
}
export class QuadrantBuilder { export class QuadrantBuilder {
private _quadrant1Text = ''; private config: QuadrantBuilderConfig;
private _quadrant2Text = ''; private themeConfig: QuadrantBuilderThemeConfig;
private _quadrant3Text = '';
private _quadrant4Text = ''; constructor() {
private _xAxisLeftText = ''; this.config = this.getDefaultConfig();
private _xAxisRightText = ''; this.themeConfig = this.getDefaultThemeConfig();
private _yAxisBottomText = ''; }
private _yAxisTopText = '';
private _totalHeight = 500; getDefaultConfig(): QuadrantBuilderConfig {
private _totalWidth = 500; return {
public quadrantPadding = 5; titleText: '',
public xAxisLabelPadding = 5; quadrant1Text: '',
public yAxisLabelPadding = 5; quadrant2Text: '',
public xAxisLabelFontSize = 16; quadrant3Text: '',
public yAxisLabelFontSize = 16; quadrant4Text: '',
public quadrantLabelFontSize = 16; xAxisLeftText: '',
public quadrantTextTopPadding = 5; xAxisRightText: '',
public pointTextPadding = 5; yAxisBottomText: '',
public pointLabelFontSize = 12; yAxisTopText: '',
public pointRadius = 5; points: [],
public points: QuadrantPointInputType[] = []; showXAxis: true,
public xAxisPosition = 'top'; showYAxis: true,
public yAxisPosition = 'left'; showTitle: true,
public quadrant1Fill = '#8bc2f3'; chartHeight: 500,
public quadrant2Fill = '#faebd7'; chartWidth: 500,
public quadrant3Fill = '#00ffff'; titlePadding: 5,
public quadrant4Fill = '#f0ffff'; titleFontSize: 20,
public quadrant1TextFill = '#93690e'; quadrantPadding: 5,
public quadrant2TextFill = '#8644ff'; xAxisLabelPadding: 5,
public quadrant3TextFill = '#e3004d'; yAxisLabelPadding: 5,
public quadrant4TextFill = '#000000'; xAxisLabelFontSize: 16,
public pointFill = '#60B19C'; yAxisLabelFontSize: 16,
public pointTextFill = '#0000ff'; quadrantLabelFontSize: 16,
public xAxisTextFill = '#000000'; quadrantTextTopPadding: 5,
public yAxisTextFill = '#000000'; pointTextPadding: 5,
public showXAxis = true; pointLabelFontSize: 12,
public showYAxis = true; pointRadius: 5,
xAxisPosition: 'top',
yAxisPosition: 'left',
quadrantInternalBorderStrokeWidth: 2,
quadrantExternalBorderStrokeWidth: 3,
};
}
getDefaultThemeConfig(): QuadrantBuilderThemeConfig {
return {
quadrant1Fill: '#8bc2f3',
quadrant2Fill: '#faebd7',
quadrant3Fill: '#00ffff',
quadrant4Fill: '#f0ffff',
quadrant1TextFill: '#93690e',
quadrant2TextFill: '#8644ff',
quadrant3TextFill: '#e3004d',
quadrant4TextFill: '#000000',
quadrantPointFill: '#60B19C',
quadrantPointTextFill: '#0000ff',
quadrantXAxisTextFill: '#000000',
quadrantYAxisTextFill: '#000000',
quadrantTitleFill: '#000000',
quadrantInternalBorderStrokeFill: '#000000',
quadrantExternalBorderStrokeFill: '#000000',
};
}
clear() { clear() {
this.points = []; this.config = this.getDefaultConfig();
this.quadrant1Text = ''; this.themeConfig = this.getDefaultThemeConfig();
this.quadrant2Text = ''; log.info('clear called');
this.quadrant3Text = '';
this.quadrant4Text = '';
this.xAxisLeftText = '';
this.xAxisRightText = '';
this.yAxisBottomText = '';
this.yAxisTopText = '';
} }
addPoints(points: QuadrantPointInputType[]) { addPoints(points: QuadrantPointInputType[]) {
this.points = [...points, ...this.points]; this.config.points = [...points, ...this.config.points];
} }
set quadrant1Text(text: string) { setConfig(config: Partial<QuadrantBuilderConfig>) {
this._quadrant1Text = text; log.trace('setConfig called with: ', config);
this.config = { ...this.config, ...config };
} }
get quadrant1Text() { setThemeConfig(themeConfig: Partial<QuadrantBuilderThemeConfig>) {
return this._quadrant1Text; log.trace('setThemeConfig called with: ', themeConfig);
} this.themeConfig = { ...this.themeConfig, ...themeConfig };
set quadrant2Text(text: string) {
this._quadrant2Text = text;
}
get quadrant2Text() {
return this._quadrant2Text;
}
set quadrant3Text(text: string) {
this._quadrant3Text = text;
}
get quadrant3Text() {
return this._quadrant3Text;
}
set quadrant4Text(text: string) {
this._quadrant4Text = text;
}
get quadrant4Text() {
return this._quadrant4Text;
}
set xAxisLeftText(text: string) {
this._xAxisLeftText = text;
}
get xAxisLeftText() {
return this._xAxisLeftText;
}
set xAxisRightText(text: string) {
this._xAxisRightText = text;
}
get xAxisRightText() {
return this._xAxisRightText;
}
set yAxisTopText(text: string) {
this._yAxisTopText = text;
}
get yAxisTopText() {
return this._yAxisTopText;
}
set yAxisBottomText(text: string) {
this._yAxisBottomText = text;
}
get yAxisBottomText() {
return this._yAxisBottomText;
}
set totalWidth(width: number) {
this._totalWidth = width;
}
get totalWidth() {
return this._totalWidth;
}
set totalHeight(height: number) {
this._totalHeight = height;
}
get totalHeight() {
return this._totalHeight;
} }
build(): QuadrantBuildType { build(): QuadrantBuildType {
const showXAxis = !this.xAxisLeftText && !this.xAxisRightText ? false : this.showXAxis; const showXAxis =
const showYAxis = !this.yAxisTopText && !this.yAxisBottomText ? false : this.showYAxis; this.config.showXAxis && (this.config.xAxisLeftText || this.config.xAxisRightText);
const quadrantLeft = const showYAxis =
this.quadrantPadding + this.config.showYAxis && (this.config.yAxisTopText || this.config.yAxisBottomText);
(this.yAxisPosition === 'left' && showYAxis const showTitle = this.config.showTitle && this.config.titleText;
? this.yAxisLabelPadding * 2 + this.yAxisLabelFontSize
: 0); const halfExternalBorderWidth = this.config.quadrantExternalBorderStrokeWidth / 2;
const quadrantTop = const halfInternalBorderWidth = this.config.quadrantInternalBorderStrokeWidth / 2;
this.quadrantPadding +
(this.xAxisPosition === 'top' && showXAxis const xAxisPosition = this.config.points.length > 0 ? 'bottom' : this.config.xAxisPosition;
? this.xAxisLabelPadding * 2 + this.xAxisLabelFontSize
: 0); const drawAxisLabelInMiddle = this.config.points.length === 0;
const xAxisSpaceCalculation =
this.config.xAxisLabelPadding * 2 + this.config.xAxisLabelFontSize;
const xAxisSpace = {
top: xAxisPosition === 'top' && showXAxis ? xAxisSpaceCalculation : 0,
bottom: xAxisPosition === 'bottom' && showXAxis ? xAxisSpaceCalculation : 0,
};
const yAxisSpaceCalculation =
this.config.yAxisLabelPadding * 2 + this.config.yAxisLabelFontSize;
const yAxisSpace = {
left: this.config.yAxisPosition === 'left' && showYAxis ? yAxisSpaceCalculation : 0,
right: this.config.yAxisPosition === 'right' && showYAxis ? yAxisSpaceCalculation : 0,
};
const titleSpaceCalculation = this.config.titleFontSize + this.config.titlePadding * 2;
const titleSpace = {
top: showTitle ? titleSpaceCalculation : 0,
};
const quadrantLeft = this.config.quadrantPadding + yAxisSpace.left;
const quadrantTop = this.config.quadrantPadding + xAxisSpace.top + titleSpace.top;
const quadrantWidth = const quadrantWidth =
this.totalWidth - this.config.chartWidth - this.config.quadrantPadding * 2 - yAxisSpace.left - yAxisSpace.right;
(this.quadrantPadding * 2 +
(showYAxis ? this.yAxisLabelPadding * 2 + this.yAxisLabelFontSize : 0));
const quadrantHeight = const quadrantHeight =
this.totalHeight - this.config.chartHeight -
(this.quadrantPadding * 2 + this.config.quadrantPadding * 2 -
(showXAxis ? this.xAxisLabelPadding * 2 + this.xAxisLabelFontSize : 0)); xAxisSpace.top -
xAxisSpace.bottom -
titleSpace.top;
const quadrantHalfWidth = quadrantWidth / 2; const quadrantHalfWidth = quadrantWidth / 2;
const quadrantHalfHeight = quadrantHeight / 2; const quadrantHalfHeight = quadrantHeight / 2;
const axisLabels: QuadrantTextType[] = []; const axisLabels: QuadrantTextType[] = [];
if (this.xAxisLeftText && showXAxis) { if (this.config.xAxisLeftText && showXAxis) {
axisLabels.push({ axisLabels.push({
text: this.xAxisLeftText, text: this.config.xAxisLeftText,
fill: this.xAxisTextFill, fill: this.themeConfig.quadrantXAxisTextFill,
x: quadrantLeft, x: quadrantLeft + (drawAxisLabelInMiddle ? quadrantHalfWidth / 2 : 0),
y: y:
this.xAxisPosition === 'top' xAxisPosition === 'top'
? this.xAxisLabelPadding ? this.config.xAxisLabelPadding + titleSpace.top
: this.xAxisLabelPadding + quadrantTop + quadrantHeight, : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight,
fontSize: this.xAxisLabelFontSize, fontSize: this.config.xAxisLabelFontSize,
verticalPos: 'left', verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top', horizontalPos: 'top',
rotation: 0, rotation: 0,
}); });
} }
if (this.xAxisRightText && showXAxis) { if (this.config.xAxisRightText && showXAxis) {
axisLabels.push({ axisLabels.push({
text: this.xAxisRightText, text: this.config.xAxisRightText,
fill: this.xAxisTextFill, fill: this.themeConfig.quadrantXAxisTextFill,
x: quadrantLeft + quadrantHalfWidth, x: quadrantLeft + quadrantHalfWidth + (drawAxisLabelInMiddle ? quadrantHalfWidth / 2 : 0),
y: y:
this.xAxisPosition === 'top' xAxisPosition === 'top'
? this.xAxisLabelPadding ? this.config.xAxisLabelPadding + titleSpace.top
: this.xAxisLabelPadding + quadrantTop + quadrantHeight, : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight,
fontSize: this.xAxisLabelFontSize, fontSize: this.config.xAxisLabelFontSize,
verticalPos: 'left', verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top', horizontalPos: 'top',
rotation: 0, rotation: 0,
}); });
} }
if (this.yAxisBottomText && showYAxis) { if (this.config.yAxisBottomText && showYAxis) {
axisLabels.push({ axisLabels.push({
text: this.yAxisBottomText, text: this.config.yAxisBottomText,
fill: this.yAxisTextFill, fill: this.themeConfig.quadrantYAxisTextFill,
x: x:
this.yAxisPosition === 'left' this.config.yAxisPosition === 'left'
? this.yAxisLabelPadding ? this.config.yAxisLabelPadding
: this.yAxisLabelPadding + quadrantLeft + quadrantWidth, : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth,
y: quadrantTop + quadrantHeight, y: quadrantTop + quadrantHeight - (drawAxisLabelInMiddle ? quadrantHalfHeight / 2 : 0),
fontSize: this.yAxisLabelFontSize, fontSize: this.config.yAxisLabelFontSize,
verticalPos: 'left', verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top', horizontalPos: 'top',
rotation: -90, rotation: -90,
}); });
} }
if (this.yAxisTopText && showYAxis) { if (this.config.yAxisTopText && showYAxis) {
axisLabels.push({ axisLabels.push({
text: this.yAxisTopText, text: this.config.yAxisTopText,
fill: this.yAxisTextFill, fill: this.themeConfig.quadrantYAxisTextFill,
x: x:
this.yAxisPosition === 'left' this.config.yAxisPosition === 'left'
? this.yAxisLabelPadding ? this.config.yAxisLabelPadding
: this.yAxisLabelPadding + quadrantLeft + quadrantWidth, : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth,
y: quadrantTop + quadrantHalfHeight, y: quadrantTop + quadrantHalfHeight - (drawAxisLabelInMiddle ? quadrantHalfHeight / 2 : 0),
fontSize: this.yAxisLabelFontSize, fontSize: this.config.yAxisLabelFontSize,
verticalPos: 'left', verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top', horizontalPos: 'top',
rotation: -90, rotation: -90,
}); });
@@ -267,11 +290,11 @@ export class QuadrantBuilder {
const quadrants: QuadrantQuadrantsType[] = [ const quadrants: QuadrantQuadrantsType[] = [
{ {
text: { text: {
text: this.quadrant1Text, text: this.config.quadrant1Text,
fill: this.quadrant1TextFill, fill: this.themeConfig.quadrant1TextFill,
x: 0, x: 0,
y: 0, y: 0,
fontSize: this.quadrantLabelFontSize, fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center', verticalPos: 'center',
horizontalPos: 'middle', horizontalPos: 'middle',
rotation: 0, rotation: 0,
@@ -280,15 +303,15 @@ export class QuadrantBuilder {
y: quadrantTop, y: quadrantTop,
width: quadrantHalfWidth, width: quadrantHalfWidth,
height: quadrantHalfHeight, height: quadrantHalfHeight,
fill: this.quadrant1Fill, fill: this.themeConfig.quadrant1Fill,
}, },
{ {
text: { text: {
text: this.quadrant2Text, text: this.config.quadrant2Text,
fill: this.quadrant2TextFill, fill: this.themeConfig.quadrant2TextFill,
x: 0, x: 0,
y: 0, y: 0,
fontSize: this.quadrantLabelFontSize, fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center', verticalPos: 'center',
horizontalPos: 'middle', horizontalPos: 'middle',
rotation: 0, rotation: 0,
@@ -297,15 +320,15 @@ export class QuadrantBuilder {
y: quadrantTop, y: quadrantTop,
width: quadrantHalfWidth, width: quadrantHalfWidth,
height: quadrantHalfHeight, height: quadrantHalfHeight,
fill: this.quadrant2Fill, fill: this.themeConfig.quadrant2Fill,
}, },
{ {
text: { text: {
text: this.quadrant3Text, text: this.config.quadrant3Text,
fill: this.quadrant3TextFill, fill: this.themeConfig.quadrant3TextFill,
x: 0, x: 0,
y: 0, y: 0,
fontSize: this.quadrantLabelFontSize, fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center', verticalPos: 'center',
horizontalPos: 'middle', horizontalPos: 'middle',
rotation: 0, rotation: 0,
@@ -314,15 +337,15 @@ export class QuadrantBuilder {
y: quadrantTop + quadrantHalfHeight, y: quadrantTop + quadrantHalfHeight,
width: quadrantHalfWidth, width: quadrantHalfWidth,
height: quadrantHalfHeight, height: quadrantHalfHeight,
fill: this.quadrant3Fill, fill: this.themeConfig.quadrant3Fill,
}, },
{ {
text: { text: {
text: this.quadrant4Text, text: this.config.quadrant4Text,
fill: this.quadrant4TextFill, fill: this.themeConfig.quadrant4TextFill,
x: 0, x: 0,
y: 0, y: 0,
fontSize: this.quadrantLabelFontSize, fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center', verticalPos: 'center',
horizontalPos: 'middle', horizontalPos: 'middle',
rotation: 0, rotation: 0,
@@ -331,22 +354,21 @@ export class QuadrantBuilder {
y: quadrantTop + quadrantHalfHeight, y: quadrantTop + quadrantHalfHeight,
width: quadrantHalfWidth, width: quadrantHalfWidth,
height: quadrantHalfHeight, height: quadrantHalfHeight,
fill: this.quadrant4Fill, fill: this.themeConfig.quadrant4Fill,
}, },
]; ];
quadrants.forEach((quadrant, i) => { for (const quadrant of quadrants) {
// place the text in the center of the box
if (this.points.length === 0) {
quadrant.text.x = quadrant.x + quadrant.width / 2; quadrant.text.x = quadrant.x + quadrant.width / 2;
// place the text in the center of the box
if (this.config.points.length === 0) {
quadrant.text.y = quadrant.y + quadrant.height / 2; quadrant.text.y = quadrant.y + quadrant.height / 2;
quadrant.text.horizontalPos = 'middle'; quadrant.text.horizontalPos = 'middle';
// place the text top of the quadrant square // place the text top of the quadrant square
} else { } else {
quadrant.text.x = quadrant.x + quadrant.width / 2; quadrant.text.y = quadrant.y + this.config.quadrantTextTopPadding;
quadrant.text.y = quadrant.y + this.quadrantTextTopPadding;
quadrant.text.horizontalPos = 'top'; quadrant.text.horizontalPos = 'top';
} }
}); }
const xAxis = scaleLinear() const xAxis = scaleLinear()
.domain([0, 1]) .domain([0, 1])
@@ -356,30 +378,103 @@ export class QuadrantBuilder {
.domain([0, 1]) .domain([0, 1])
.range([quadrantHeight + quadrantTop, quadrantTop]); .range([quadrantHeight + quadrantTop, quadrantTop]);
const points: QuadrantPointType[] = this.points.map((point) => { const points: QuadrantPointType[] = this.config.points.map((point) => {
const props: QuadrantPointType = { const props: QuadrantPointType = {
x: xAxis(point.x), x: xAxis(point.x),
y: yAxis(point.y), y: yAxis(point.y),
fill: this.pointFill, fill: this.themeConfig.quadrantPointFill,
radius: this.pointRadius, radius: this.config.pointRadius,
text: { text: {
text: point.text, text: point.text,
fill: this.pointTextFill, fill: this.themeConfig.quadrantPointTextFill,
x: xAxis(point.x), x: xAxis(point.x),
y: yAxis(point.y) + this.pointTextPadding, y: yAxis(point.y) + this.config.pointTextPadding,
verticalPos: 'center', verticalPos: 'center',
horizontalPos: 'top', horizontalPos: 'top',
fontSize: this.pointLabelFontSize, fontSize: this.config.pointLabelFontSize,
rotation: 0, rotation: 0,
}, },
}; };
return props; return props;
}); });
return { const borderLines: QuadrantLineType[] = [
// top border
{
strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,
strokeWidth: this.config.quadrantExternalBorderStrokeWidth,
x1: quadrantLeft - halfExternalBorderWidth,
y1: quadrantTop,
x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth,
y2: quadrantTop,
},
// right border
{
strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,
strokeWidth: this.config.quadrantExternalBorderStrokeWidth,
x1: quadrantLeft + quadrantWidth,
y1: quadrantTop + halfExternalBorderWidth,
x2: quadrantLeft + quadrantWidth,
y2: quadrantTop + quadrantHeight - halfExternalBorderWidth,
},
// bottom border
{
strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,
strokeWidth: this.config.quadrantExternalBorderStrokeWidth,
x1: quadrantLeft - halfExternalBorderWidth,
y1: quadrantTop + quadrantHeight,
x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth,
y2: quadrantTop + quadrantHeight,
},
// left border
{
strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,
strokeWidth: this.config.quadrantExternalBorderStrokeWidth,
x1: quadrantLeft,
y1: quadrantTop + halfExternalBorderWidth,
x2: quadrantLeft,
y2: quadrantTop + quadrantHeight - halfExternalBorderWidth,
},
// vertical inner border
{
strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill,
strokeWidth: this.config.quadrantInternalBorderStrokeWidth,
x1: quadrantLeft + quadrantHalfWidth,
y1: quadrantTop + halfExternalBorderWidth,
x2: quadrantLeft + quadrantHalfWidth,
y2: quadrantTop + quadrantHeight - halfExternalBorderWidth,
},
// horizontal inner border
{
strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill,
strokeWidth: this.config.quadrantInternalBorderStrokeWidth,
x1: quadrantLeft + halfExternalBorderWidth,
y1: quadrantTop + quadrantHalfHeight,
x2: quadrantLeft + quadrantWidth - halfExternalBorderWidth,
y2: quadrantTop + quadrantHalfHeight,
},
];
const retVal: QuadrantBuildType = {
points, points,
quadrants, quadrants,
axisLabels, axisLabels,
borderLines,
};
if (showTitle) {
retVal.title = {
text: this.config.titleText,
fill: this.themeConfig.quadrantTitleFill,
fontSize: this.config.titleFontSize,
horizontalPos: 'top',
verticalPos: 'center',
rotation: 0,
y: this.config.titlePadding,
x: this.config.chartWidth / 2,
}; };
} }
return retVal;
}
} }

View File

@@ -24,78 +24,73 @@ type LexTextObj = { text: string; type: 'text' | 'markdown' };
const quadrantBuilder = new QuadrantBuilder(); const quadrantBuilder = new QuadrantBuilder();
function setQuadrant1Text(textObj: LexTextObj) { function setQuadrant1Text(textObj: LexTextObj) {
quadrantBuilder.quadrant1Text = textSanitizer(textObj.text); quadrantBuilder.setConfig({ quadrant1Text: textSanitizer(textObj.text) });
} }
function setQuadrant2Text(textObj: LexTextObj) { function setQuadrant2Text(textObj: LexTextObj) {
quadrantBuilder.quadrant2Text = textSanitizer(textObj.text); quadrantBuilder.setConfig({ quadrant2Text: textSanitizer(textObj.text) });
} }
function setQuadrant3Text(textObj: LexTextObj) { function setQuadrant3Text(textObj: LexTextObj) {
quadrantBuilder.quadrant3Text = textSanitizer(textObj.text); quadrantBuilder.setConfig({ quadrant3Text: textSanitizer(textObj.text) });
} }
function setQuadrant4Text(textObj: LexTextObj) { function setQuadrant4Text(textObj: LexTextObj) {
quadrantBuilder.quadrant4Text = textSanitizer(textObj.text); quadrantBuilder.setConfig({ quadrant4Text: textSanitizer(textObj.text) });
} }
function setXAxisLeftText(textObj: LexTextObj) { function setXAxisLeftText(textObj: LexTextObj) {
quadrantBuilder.xAxisLeftText = textSanitizer(textObj.text); quadrantBuilder.setConfig({ xAxisLeftText: textSanitizer(textObj.text) });
} }
function setXAxisRightText(textObj: LexTextObj) { function setXAxisRightText(textObj: LexTextObj) {
quadrantBuilder.xAxisRightText = textSanitizer(textObj.text); quadrantBuilder.setConfig({ xAxisRightText: textSanitizer(textObj.text) });
} }
function setYAxisTopText(textObj: LexTextObj) { function setYAxisTopText(textObj: LexTextObj) {
quadrantBuilder.yAxisTopText = textSanitizer(textObj.text); quadrantBuilder.setConfig({ yAxisTopText: textSanitizer(textObj.text) });
} }
function setYAxisBottomText(textObj: LexTextObj) { function setYAxisBottomText(textObj: LexTextObj) {
quadrantBuilder.yAxisBottomText = textSanitizer(textObj.text); quadrantBuilder.setConfig({ yAxisBottomText: textSanitizer(textObj.text) });
} }
function addPoints(textObj: LexTextObj, x: number, y: number) { function addPoint(textObj: LexTextObj, x: number, y: number) {
quadrantBuilder.addPoints([{ x, y, text: textSanitizer(textObj.text) }]); quadrantBuilder.addPoints([{ x, y, text: textSanitizer(textObj.text) }]);
} }
function setWidth(width: number) { function setWidth(width: number) {
quadrantBuilder.totalWidth = width; quadrantBuilder.setConfig({ chartWidth: width });
} }
function setHeight(height: number) { function setHeight(height: number) {
quadrantBuilder.totalHeight = height; quadrantBuilder.setConfig({ chartHeight: height });
} }
function getQuadrantData() { function getQuadrantData() {
const config = configApi.getConfig(); const config = configApi.getConfig();
const { themeVariables, quadrantChart: quadrantChartConfig } = config; const { themeVariables, quadrantChart: quadrantChartConfig } = config;
quadrantBuilder.quadrant1Fill = themeVariables.quadrant1Fill;
quadrantBuilder.quadrant2Fill = themeVariables.quadrant2Fill;
quadrantBuilder.quadrant3Fill = themeVariables.quadrant3Fill;
quadrantBuilder.quadrant4Fill = themeVariables.quadrant4Fill;
quadrantBuilder.quadrant1TextFill = themeVariables.quadrant1TextFill;
quadrantBuilder.quadrant2TextFill = themeVariables.quadrant2TextFill;
quadrantBuilder.quadrant3TextFill = themeVariables.quadrant3TextFill;
quadrantBuilder.quadrant4TextFill = themeVariables.quadrant4TextFill;
quadrantBuilder.pointFill = themeVariables.quadrantPointFill;
quadrantBuilder.pointTextFill = themeVariables.quadrantPointTextFill;
quadrantBuilder.xAxisTextFill = themeVariables.quadrantXAxisTextFill;
quadrantBuilder.yAxisTextFill = themeVariables.quadrantYAxisTextFill;
if (quadrantChartConfig) { if (quadrantChartConfig) {
quadrantBuilder.quadrantPadding = quadrantChartConfig.quadrantPadding; quadrantBuilder.setConfig(quadrantChartConfig);
quadrantBuilder.xAxisLabelPadding = quadrantChartConfig.xAxisLabelPadding;
quadrantBuilder.yAxisLabelPadding = quadrantChartConfig.yAxisLabelPadding;
quadrantBuilder.xAxisLabelFontSize = quadrantChartConfig.xAxisLabelFontSize;
quadrantBuilder.yAxisLabelFontSize = quadrantChartConfig.yAxisLabelFontSize;
quadrantBuilder.quadrantLabelFontSize = quadrantChartConfig.quadrantLabelFontSize;
quadrantBuilder.quadrantTextTopPadding = quadrantChartConfig.quadrantTextTopPadding;
quadrantBuilder.pointTextPadding = quadrantChartConfig.pointTextPadding;
quadrantBuilder.pointLabelFontSize = quadrantChartConfig.pointLabelFontSize;
quadrantBuilder.pointRadius = quadrantChartConfig.pointRadius;
quadrantBuilder.xAxisPosition = quadrantChartConfig.xAxisPosition;
quadrantBuilder.yAxisPosition = quadrantChartConfig.yAxisPosition;
} }
quadrantBuilder.setThemeConfig({
quadrant1Fill: themeVariables.quadrant1Fill,
quadrant2Fill: themeVariables.quadrant2Fill,
quadrant3Fill: themeVariables.quadrant3Fill,
quadrant4Fill: themeVariables.quadrant4Fill,
quadrant1TextFill: themeVariables.quadrant1TextFill,
quadrant2TextFill: themeVariables.quadrant2TextFill,
quadrant3TextFill: themeVariables.quadrant3TextFill,
quadrant4TextFill: themeVariables.quadrant4TextFill,
quadrantPointFill: themeVariables.quadrantPointFill,
quadrantPointTextFill: themeVariables.quadrantPointTextFill,
quadrantXAxisTextFill: themeVariables.quadrantXAxisTextFill,
quadrantYAxisTextFill: themeVariables.quadrantYAxisTextFill,
quadrantExternalBorderStrokeFill: themeVariables.quadrantExternalBorderStrokeFill,
quadrantInternalBorderStrokeFill: themeVariables.quadrantInternalBorderStrokeFill,
quadrantTitleFill: themeVariables.quadrantTitleFill,
});
quadrantBuilder.setConfig({ titleText: getDiagramTitle() });
return quadrantBuilder.build(); return quadrantBuilder.build();
} }
@@ -120,7 +115,7 @@ export default {
setXAxisRightText, setXAxisRightText,
setYAxisTopText, setYAxisTopText,
setYAxisBottomText, setYAxisBottomText,
addPoints, addPoint,
getQuadrantData, getQuadrantData,
parseDirective, parseDirective,
clear, clear,

View File

@@ -7,6 +7,7 @@ import { configureSvgSize } from '../../setupGraphViewbox.js';
import { Diagram } from '../../Diagram.js'; import { Diagram } from '../../Diagram.js';
import { import {
QuadrantBuildType, QuadrantBuildType,
QuadrantLineType,
QuadrantPointType, QuadrantPointType,
QuadrantQuadrantsType, QuadrantQuadrantsType,
QuadrantTextType, QuadrantTextType,
@@ -29,7 +30,7 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram
const conf = configApi.getConfig(); const conf = configApi.getConfig();
log.debug('Rendering info diagram\n' + txt); log.debug('Rendering quadrant chart\n' + txt);
const securityLevel = conf.securityLevel; const securityLevel = conf.securityLevel;
// Handle root and Document for when rendering in sandbox mode // Handle root and Document for when rendering in sandbox mode
@@ -62,8 +63,37 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram
const quadrantData: QuadrantBuildType = diagObj.db.getQuadrantData(); const quadrantData: QuadrantBuildType = diagObj.db.getQuadrantData();
const quadrantsGroup = group.append('g').attr('class', 'quadrants'); const quadrantsGroup = group.append('g').attr('class', 'quadrants');
const borderGroup = group.append('g').attr('class', 'border');
const dataPointGroup = group.append('g').attr('class', 'data-points'); const dataPointGroup = group.append('g').attr('class', 'data-points');
const labelGroup = group.append('g').attr('class', 'labels'); const labelGroup = group.append('g').attr('class', 'labels');
const titleGroup = group.append('g').attr('class', 'title');
if (quadrantData.title) {
titleGroup
.append('text')
.attr('x', 0)
.attr('y', 0)
.attr('fill', quadrantData.title.fill)
.attr('font-size', quadrantData.title.fontSize)
.attr('dominant-baseline', getDominantBaseLine(quadrantData.title.horizontalPos))
.attr('text-anchor', getTextAnchor(quadrantData.title.verticalPos))
.attr('transform', getTransformation(quadrantData.title))
.text(quadrantData.title.text);
}
if (quadrantData.borderLines) {
borderGroup
.selectAll('line')
.data(quadrantData.borderLines)
.enter()
.append('line')
.attr('x1', (data: QuadrantLineType) => data.x1)
.attr('y1', (data: QuadrantLineType) => data.y1)
.attr('x2', (data: QuadrantLineType) => data.x2)
.attr('y2', (data: QuadrantLineType) => data.y2)
.style('stroke', (data: QuadrantLineType) => data.strokeFill)
.style('stroke-width', (data: QuadrantLineType) => data.strokeWidth);
}
const quadrants = quadrantsGroup const quadrants = quadrantsGroup
.selectAll('g.quadrant') .selectAll('g.quadrant')

View File

@@ -239,6 +239,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor; this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor; this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor;
this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor; this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor;
this.quadrantInternalBorderStrokeFill =
this.quadrantInternalBorderStrokeFill || this.primaryBorderColor;
this.quadrantExternalBorderStrokeFill =
this.quadrantExternalBorderStrokeFill || this.secondaryBorderColor;
this.quadrantTitleFill = this.quadrantTitleFill || this.primaryTextColor;
/* requirement-diagram */ /* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor; this.requirementBackground = this.requirementBackground || this.primaryColor;

View File

@@ -245,6 +245,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor; this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor; this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor;
this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor; this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor;
this.quadrantInternalBorderStrokeFill =
this.quadrantInternalBorderStrokeFill || this.primaryBorderColor;
this.quadrantExternalBorderStrokeFill =
this.quadrantExternalBorderStrokeFill || this.secondaryBorderColor;
this.quadrantTitleFill = this.quadrantTitleFill || this.primaryTextColor;
/* class */ /* class */
this.classText = this.primaryTextColor; this.classText = this.primaryTextColor;

View File

@@ -266,6 +266,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor; this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor; this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor;
this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor; this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor;
this.quadrantInternalBorderStrokeFill =
this.quadrantInternalBorderStrokeFill || this.primaryBorderColor;
this.quadrantExternalBorderStrokeFill =
this.quadrantExternalBorderStrokeFill || this.secondaryBorderColor;
this.quadrantTitleFill = this.quadrantTitleFill || this.primaryTextColor;
/* requirement-diagram */ /* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor; this.requirementBackground = this.requirementBackground || this.primaryColor;

View File

@@ -234,6 +234,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor; this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor; this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor;
this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor; this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor;
this.quadrantInternalBorderStrokeFill =
this.quadrantInternalBorderStrokeFill || this.primaryBorderColor;
this.quadrantExternalBorderStrokeFill =
this.quadrantExternalBorderStrokeFill || this.secondaryBorderColor;
this.quadrantTitleFill = this.quadrantTitleFill || this.primaryTextColor;
/* requirement-diagram */ /* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor; this.requirementBackground = this.requirementBackground || this.primaryColor;

View File

@@ -265,6 +265,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor; this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor; this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || this.primaryTextColor;
this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor; this.quadrantYAxisTextFill = this.quadrantYAxisTextFill || this.primaryTextColor;
this.quadrantInternalBorderStrokeFill =
this.quadrantInternalBorderStrokeFill || this.primaryBorderColor;
this.quadrantExternalBorderStrokeFill =
this.quadrantExternalBorderStrokeFill || this.secondaryBorderColor;
this.quadrantTitleFill = this.quadrantTitleFill || this.primaryTextColor;
/* requirement-diagram */ /* requirement-diagram */
this.requirementBackground = this.requirementBackground || this.primaryColor; this.requirementBackground = this.requirementBackground || this.primaryColor;