Fixed review comment

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

View File

@ -14,7 +14,7 @@
#### 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 {
chartWidth: number;
chartHeight: number;
titleFontSize: number;
titlePadding: number;
quadrantPadding: number;
xAxisLabelPadding: number;
yAxisLabelPadding: number;
@ -242,6 +244,8 @@ export interface QuadrantChartConfig extends BaseDiagramConfig {
pointRadius: number;
xAxisPosition: 'top' | 'bottom';
yAxisPosition: 'left' | 'right';
quadrantInternalBorderStrokeWidth: number;
quadrantExternalBorderStrokeWidth: number;
}
export interface ErDiagramConfig extends BaseDiagramConfig {

View File

@ -1326,6 +1326,24 @@ const config: Partial<MermaidConfig> = {
* Default value: 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 |
* | ------------------ | ---------------------------------- | ------- | -------- | ------------------- |
@ -1407,6 +1425,24 @@ const config: Partial<MermaidConfig> = {
* Default value: 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 |
* | ----------- | ----------- | ------- | -------- | ----------- |

View File

@ -44,7 +44,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
\s*"x-axis"\s* return 'X-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-2"\s* return 'QUADRANT_2';
\s*"quadrant-3"\s* return 'QUADRANT_3';
@ -118,12 +118,14 @@ statement
;
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
: 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);}
| 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);}
;

View File

@ -1,12 +1,18 @@
// @ts-ignore: TODO Fix ts errors
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 TextHorizontalPos = 'top' | 'middle' | 'bottom';
export type QuadrantTextType = {
export interface QuadrantTextType {
text: string;
fill: string;
x: number;
@ -15,250 +21,267 @@ export type QuadrantTextType = {
horizontalPos: TextHorizontalPos;
fontSize: number;
rotation: number;
};
}
export type QuadrantPointType = {
export interface QuadrantPointType {
x: number;
y: number;
fill: string;
radius: number;
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;
x: number;
y: number;
width: number;
height: number;
fill: string;
};
}
export type QuadrantBuildType = {
export interface QuadrantBuildType {
points: QuadrantPointType[];
quadrants: QuadrantQuadrantsType[];
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 {
private _quadrant1Text = '';
private _quadrant2Text = '';
private _quadrant3Text = '';
private _quadrant4Text = '';
private _xAxisLeftText = '';
private _xAxisRightText = '';
private _yAxisBottomText = '';
private _yAxisTopText = '';
private _totalHeight = 500;
private _totalWidth = 500;
public quadrantPadding = 5;
public xAxisLabelPadding = 5;
public yAxisLabelPadding = 5;
public xAxisLabelFontSize = 16;
public yAxisLabelFontSize = 16;
public quadrantLabelFontSize = 16;
public quadrantTextTopPadding = 5;
public pointTextPadding = 5;
public pointLabelFontSize = 12;
public pointRadius = 5;
public points: QuadrantPointInputType[] = [];
public xAxisPosition = 'top';
public yAxisPosition = 'left';
public quadrant1Fill = '#8bc2f3';
public quadrant2Fill = '#faebd7';
public quadrant3Fill = '#00ffff';
public quadrant4Fill = '#f0ffff';
public quadrant1TextFill = '#93690e';
public quadrant2TextFill = '#8644ff';
public quadrant3TextFill = '#e3004d';
public quadrant4TextFill = '#000000';
public pointFill = '#60B19C';
public pointTextFill = '#0000ff';
public xAxisTextFill = '#000000';
public yAxisTextFill = '#000000';
public showXAxis = true;
public showYAxis = true;
private config: QuadrantBuilderConfig;
private themeConfig: QuadrantBuilderThemeConfig;
constructor() {
this.config = this.getDefaultConfig();
this.themeConfig = this.getDefaultThemeConfig();
}
getDefaultConfig(): QuadrantBuilderConfig {
return {
titleText: '',
quadrant1Text: '',
quadrant2Text: '',
quadrant3Text: '',
quadrant4Text: '',
xAxisLeftText: '',
xAxisRightText: '',
yAxisBottomText: '',
yAxisTopText: '',
points: [],
showXAxis: true,
showYAxis: true,
showTitle: true,
chartHeight: 500,
chartWidth: 500,
titlePadding: 5,
titleFontSize: 20,
quadrantPadding: 5,
xAxisLabelPadding: 5,
yAxisLabelPadding: 5,
xAxisLabelFontSize: 16,
yAxisLabelFontSize: 16,
quadrantLabelFontSize: 16,
quadrantTextTopPadding: 5,
pointTextPadding: 5,
pointLabelFontSize: 12,
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() {
this.points = [];
this.quadrant1Text = '';
this.quadrant2Text = '';
this.quadrant3Text = '';
this.quadrant4Text = '';
this.xAxisLeftText = '';
this.xAxisRightText = '';
this.yAxisBottomText = '';
this.yAxisTopText = '';
this.config = this.getDefaultConfig();
this.themeConfig = this.getDefaultThemeConfig();
log.info('clear called');
}
addPoints(points: QuadrantPointInputType[]) {
this.points = [...points, ...this.points];
this.config.points = [...points, ...this.config.points];
}
set quadrant1Text(text: string) {
this._quadrant1Text = text;
setConfig(config: Partial<QuadrantBuilderConfig>) {
log.trace('setConfig called with: ', config);
this.config = { ...this.config, ...config };
}
get quadrant1Text() {
return this._quadrant1Text;
}
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;
setThemeConfig(themeConfig: Partial<QuadrantBuilderThemeConfig>) {
log.trace('setThemeConfig called with: ', themeConfig);
this.themeConfig = { ...this.themeConfig, ...themeConfig };
}
build(): QuadrantBuildType {
const showXAxis = !this.xAxisLeftText && !this.xAxisRightText ? false : this.showXAxis;
const showYAxis = !this.yAxisTopText && !this.yAxisBottomText ? false : this.showYAxis;
const quadrantLeft =
this.quadrantPadding +
(this.yAxisPosition === 'left' && showYAxis
? this.yAxisLabelPadding * 2 + this.yAxisLabelFontSize
: 0);
const quadrantTop =
this.quadrantPadding +
(this.xAxisPosition === 'top' && showXAxis
? this.xAxisLabelPadding * 2 + this.xAxisLabelFontSize
: 0);
const showXAxis =
this.config.showXAxis && (this.config.xAxisLeftText || this.config.xAxisRightText);
const showYAxis =
this.config.showYAxis && (this.config.yAxisTopText || this.config.yAxisBottomText);
const showTitle = this.config.showTitle && this.config.titleText;
const halfExternalBorderWidth = this.config.quadrantExternalBorderStrokeWidth / 2;
const halfInternalBorderWidth = this.config.quadrantInternalBorderStrokeWidth / 2;
const xAxisPosition = this.config.points.length > 0 ? 'bottom' : this.config.xAxisPosition;
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 =
this.totalWidth -
(this.quadrantPadding * 2 +
(showYAxis ? this.yAxisLabelPadding * 2 + this.yAxisLabelFontSize : 0));
this.config.chartWidth - this.config.quadrantPadding * 2 - yAxisSpace.left - yAxisSpace.right;
const quadrantHeight =
this.totalHeight -
(this.quadrantPadding * 2 +
(showXAxis ? this.xAxisLabelPadding * 2 + this.xAxisLabelFontSize : 0));
this.config.chartHeight -
this.config.quadrantPadding * 2 -
xAxisSpace.top -
xAxisSpace.bottom -
titleSpace.top;
const quadrantHalfWidth = quadrantWidth / 2;
const quadrantHalfHeight = quadrantHeight / 2;
const axisLabels: QuadrantTextType[] = [];
if (this.xAxisLeftText && showXAxis) {
if (this.config.xAxisLeftText && showXAxis) {
axisLabels.push({
text: this.xAxisLeftText,
fill: this.xAxisTextFill,
x: quadrantLeft,
text: this.config.xAxisLeftText,
fill: this.themeConfig.quadrantXAxisTextFill,
x: quadrantLeft + (drawAxisLabelInMiddle ? quadrantHalfWidth / 2 : 0),
y:
this.xAxisPosition === 'top'
? this.xAxisLabelPadding
: this.xAxisLabelPadding + quadrantTop + quadrantHeight,
fontSize: this.xAxisLabelFontSize,
verticalPos: 'left',
xAxisPosition === 'top'
? this.config.xAxisLabelPadding + titleSpace.top
: this.config.xAxisLabelPadding + quadrantTop + quadrantHeight,
fontSize: this.config.xAxisLabelFontSize,
verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top',
rotation: 0,
});
}
if (this.xAxisRightText && showXAxis) {
if (this.config.xAxisRightText && showXAxis) {
axisLabels.push({
text: this.xAxisRightText,
fill: this.xAxisTextFill,
x: quadrantLeft + quadrantHalfWidth,
text: this.config.xAxisRightText,
fill: this.themeConfig.quadrantXAxisTextFill,
x: quadrantLeft + quadrantHalfWidth + (drawAxisLabelInMiddle ? quadrantHalfWidth / 2 : 0),
y:
this.xAxisPosition === 'top'
? this.xAxisLabelPadding
: this.xAxisLabelPadding + quadrantTop + quadrantHeight,
fontSize: this.xAxisLabelFontSize,
verticalPos: 'left',
xAxisPosition === 'top'
? this.config.xAxisLabelPadding + titleSpace.top
: this.config.xAxisLabelPadding + quadrantTop + quadrantHeight,
fontSize: this.config.xAxisLabelFontSize,
verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top',
rotation: 0,
});
}
if (this.yAxisBottomText && showYAxis) {
if (this.config.yAxisBottomText && showYAxis) {
axisLabels.push({
text: this.yAxisBottomText,
fill: this.yAxisTextFill,
text: this.config.yAxisBottomText,
fill: this.themeConfig.quadrantYAxisTextFill,
x:
this.yAxisPosition === 'left'
? this.yAxisLabelPadding
: this.yAxisLabelPadding + quadrantLeft + quadrantWidth,
y: quadrantTop + quadrantHeight,
fontSize: this.yAxisLabelFontSize,
verticalPos: 'left',
this.config.yAxisPosition === 'left'
? this.config.yAxisLabelPadding
: this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth,
y: quadrantTop + quadrantHeight - (drawAxisLabelInMiddle ? quadrantHalfHeight / 2 : 0),
fontSize: this.config.yAxisLabelFontSize,
verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top',
rotation: -90,
});
}
if (this.yAxisTopText && showYAxis) {
if (this.config.yAxisTopText && showYAxis) {
axisLabels.push({
text: this.yAxisTopText,
fill: this.yAxisTextFill,
text: this.config.yAxisTopText,
fill: this.themeConfig.quadrantYAxisTextFill,
x:
this.yAxisPosition === 'left'
? this.yAxisLabelPadding
: this.yAxisLabelPadding + quadrantLeft + quadrantWidth,
y: quadrantTop + quadrantHalfHeight,
fontSize: this.yAxisLabelFontSize,
verticalPos: 'left',
this.config.yAxisPosition === 'left'
? this.config.yAxisLabelPadding
: this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth,
y: quadrantTop + quadrantHalfHeight - (drawAxisLabelInMiddle ? quadrantHalfHeight / 2 : 0),
fontSize: this.config.yAxisLabelFontSize,
verticalPos: drawAxisLabelInMiddle ? 'center' : 'left',
horizontalPos: 'top',
rotation: -90,
});
@ -267,11 +290,11 @@ export class QuadrantBuilder {
const quadrants: QuadrantQuadrantsType[] = [
{
text: {
text: this.quadrant1Text,
fill: this.quadrant1TextFill,
text: this.config.quadrant1Text,
fill: this.themeConfig.quadrant1TextFill,
x: 0,
y: 0,
fontSize: this.quadrantLabelFontSize,
fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center',
horizontalPos: 'middle',
rotation: 0,
@ -280,15 +303,15 @@ export class QuadrantBuilder {
y: quadrantTop,
width: quadrantHalfWidth,
height: quadrantHalfHeight,
fill: this.quadrant1Fill,
fill: this.themeConfig.quadrant1Fill,
},
{
text: {
text: this.quadrant2Text,
fill: this.quadrant2TextFill,
text: this.config.quadrant2Text,
fill: this.themeConfig.quadrant2TextFill,
x: 0,
y: 0,
fontSize: this.quadrantLabelFontSize,
fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center',
horizontalPos: 'middle',
rotation: 0,
@ -297,15 +320,15 @@ export class QuadrantBuilder {
y: quadrantTop,
width: quadrantHalfWidth,
height: quadrantHalfHeight,
fill: this.quadrant2Fill,
fill: this.themeConfig.quadrant2Fill,
},
{
text: {
text: this.quadrant3Text,
fill: this.quadrant3TextFill,
text: this.config.quadrant3Text,
fill: this.themeConfig.quadrant3TextFill,
x: 0,
y: 0,
fontSize: this.quadrantLabelFontSize,
fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center',
horizontalPos: 'middle',
rotation: 0,
@ -314,15 +337,15 @@ export class QuadrantBuilder {
y: quadrantTop + quadrantHalfHeight,
width: quadrantHalfWidth,
height: quadrantHalfHeight,
fill: this.quadrant3Fill,
fill: this.themeConfig.quadrant3Fill,
},
{
text: {
text: this.quadrant4Text,
fill: this.quadrant4TextFill,
text: this.config.quadrant4Text,
fill: this.themeConfig.quadrant4TextFill,
x: 0,
y: 0,
fontSize: this.quadrantLabelFontSize,
fontSize: this.config.quadrantLabelFontSize,
verticalPos: 'center',
horizontalPos: 'middle',
rotation: 0,
@ -331,22 +354,21 @@ export class QuadrantBuilder {
y: quadrantTop + quadrantHalfHeight,
width: quadrantHalfWidth,
height: quadrantHalfHeight,
fill: this.quadrant4Fill,
fill: this.themeConfig.quadrant4Fill,
},
];
quadrants.forEach((quadrant, i) => {
for (const quadrant of quadrants) {
quadrant.text.x = quadrant.x + quadrant.width / 2;
// place the text in the center of the box
if (this.points.length === 0) {
quadrant.text.x = quadrant.x + quadrant.width / 2;
if (this.config.points.length === 0) {
quadrant.text.y = quadrant.y + quadrant.height / 2;
quadrant.text.horizontalPos = 'middle';
// place the text top of the quadrant square
} else {
quadrant.text.x = quadrant.x + quadrant.width / 2;
quadrant.text.y = quadrant.y + this.quadrantTextTopPadding;
quadrant.text.y = quadrant.y + this.config.quadrantTextTopPadding;
quadrant.text.horizontalPos = 'top';
}
});
}
const xAxis = scaleLinear()
.domain([0, 1])
@ -356,30 +378,103 @@ export class QuadrantBuilder {
.domain([0, 1])
.range([quadrantHeight + quadrantTop, quadrantTop]);
const points: QuadrantPointType[] = this.points.map((point) => {
const points: QuadrantPointType[] = this.config.points.map((point) => {
const props: QuadrantPointType = {
x: xAxis(point.x),
y: yAxis(point.y),
fill: this.pointFill,
radius: this.pointRadius,
fill: this.themeConfig.quadrantPointFill,
radius: this.config.pointRadius,
text: {
text: point.text,
fill: this.pointTextFill,
fill: this.themeConfig.quadrantPointTextFill,
x: xAxis(point.x),
y: yAxis(point.y) + this.pointTextPadding,
y: yAxis(point.y) + this.config.pointTextPadding,
verticalPos: 'center',
horizontalPos: 'top',
fontSize: this.pointLabelFontSize,
fontSize: this.config.pointLabelFontSize,
rotation: 0,
},
};
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,
quadrants,
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();
function setQuadrant1Text(textObj: LexTextObj) {
quadrantBuilder.quadrant1Text = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ quadrant1Text: textSanitizer(textObj.text) });
}
function setQuadrant2Text(textObj: LexTextObj) {
quadrantBuilder.quadrant2Text = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ quadrant2Text: textSanitizer(textObj.text) });
}
function setQuadrant3Text(textObj: LexTextObj) {
quadrantBuilder.quadrant3Text = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ quadrant3Text: textSanitizer(textObj.text) });
}
function setQuadrant4Text(textObj: LexTextObj) {
quadrantBuilder.quadrant4Text = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ quadrant4Text: textSanitizer(textObj.text) });
}
function setXAxisLeftText(textObj: LexTextObj) {
quadrantBuilder.xAxisLeftText = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ xAxisLeftText: textSanitizer(textObj.text) });
}
function setXAxisRightText(textObj: LexTextObj) {
quadrantBuilder.xAxisRightText = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ xAxisRightText: textSanitizer(textObj.text) });
}
function setYAxisTopText(textObj: LexTextObj) {
quadrantBuilder.yAxisTopText = textSanitizer(textObj.text);
quadrantBuilder.setConfig({ yAxisTopText: textSanitizer(textObj.text) });
}
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) }]);
}
function setWidth(width: number) {
quadrantBuilder.totalWidth = width;
quadrantBuilder.setConfig({ chartWidth: width });
}
function setHeight(height: number) {
quadrantBuilder.totalHeight = height;
quadrantBuilder.setConfig({ chartHeight: height });
}
function getQuadrantData() {
const config = configApi.getConfig();
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) {
quadrantBuilder.quadrantPadding = quadrantChartConfig.quadrantPadding;
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.setConfig(quadrantChartConfig);
}
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();
}
@ -120,7 +115,7 @@ export default {
setXAxisRightText,
setYAxisTopText,
setYAxisBottomText,
addPoints,
addPoint,
getQuadrantData,
parseDirective,
clear,

View File

@ -7,6 +7,7 @@ import { configureSvgSize } from '../../setupGraphViewbox.js';
import { Diagram } from '../../Diagram.js';
import {
QuadrantBuildType,
QuadrantLineType,
QuadrantPointType,
QuadrantQuadrantsType,
QuadrantTextType,
@ -29,7 +30,7 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram
const conf = configApi.getConfig();
log.debug('Rendering info diagram\n' + txt);
log.debug('Rendering quadrant chart\n' + txt);
const securityLevel = conf.securityLevel;
// 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 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 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
.selectAll('g.quadrant')

View File

@ -239,6 +239,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || 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 */
this.requirementBackground = this.requirementBackground || this.primaryColor;

View File

@ -245,6 +245,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || 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 */
this.classText = this.primaryTextColor;

View File

@ -266,6 +266,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || 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 */
this.requirementBackground = this.requirementBackground || this.primaryColor;

View File

@ -234,6 +234,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || 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 */
this.requirementBackground = this.requirementBackground || this.primaryColor;

View File

@ -265,6 +265,11 @@ class Theme {
this.quadrantPointTextFill = this.quadrantPointTextFill || this.primaryTextColor;
this.quadrantXAxisTextFill = this.quadrantXAxisTextFill || 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 */
this.requirementBackground = this.requirementBackground || this.primaryColor;