diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/Interfaces.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/Interfaces.ts index 767a98262..569a5d11c 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/Interfaces.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/Interfaces.ts @@ -31,6 +31,17 @@ export type VisibilityOption = { yAxisLabel: boolean; }; +export interface AxisConfig { + showLabel: boolean; + labelFontSize: number; + lablePadding: number; + labelColor: string; + showTitle: boolean; + titleFontSize: number; + titlePadding: number; + titleColor: string; +} + export interface XYChartConfig { width: number; height: number; @@ -38,16 +49,9 @@ export interface XYChartConfig { titleFontSize: number; titleFill: string; titlePadding: number; - xAxisFontSize: number; - xAxisTitleFontSize: number; - yAxisFontSize: number; - yAxisTitleFontSize: number; - yAxisPosition: XYChartYAxisPosition; - showChartTitle: boolean; - showXAxisLable: boolean; - showXAxisTitle: boolean; - showYAxisLabel: boolean; - showYAxisTitle: boolean; + showtitle: boolean; + xAxis: AxisConfig; + yAxis: AxisConfig; chartOrientation: OrientationEnum; plotReservedSpacePercent: number; } diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/Orchestrator.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/Orchestrator.ts index d59756921..fdd60d634 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/Orchestrator.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/Orchestrator.ts @@ -1,22 +1,23 @@ +import { log } from '../../../logger.js'; import { DrawableElem, XYChartConfig, XYChartData } from './Interfaces.js'; import { getChartTitleComponent } from './components/ChartTitle.js'; import { ChartComponent } from './components/Interfaces.js'; import { IAxis, getAxis } from './components/axis/index.js'; -import { IPlot, getPlotComponent, isTypeIPlot } from './components/plot/index.js'; +import { IPlot, getPlotComponent } from './components/plot/index.js'; export class Orchestrator { private componentStore: { - title: ChartComponent, - plot: IPlot, - xAxis: IAxis, - yAxis: IAxis, + title: ChartComponent; + plot: IPlot; + xAxis: IAxis; + yAxis: IAxis; }; constructor(private chartConfig: XYChartConfig, chartData: XYChartData) { this.componentStore = { title: getChartTitleComponent(chartConfig, chartData), plot: getPlotComponent(chartConfig, chartData), - xAxis: getAxis(chartData.xAxis, chartConfig), - yAxis: getAxis(chartData.yAxis, chartConfig), + xAxis: getAxis(chartData.xAxis, chartConfig.xAxis), + yAxis: getAxis(chartData.yAxis, chartConfig.yAxis), }; } @@ -25,9 +26,10 @@ export class Orchestrator { let availableHeight = this.chartConfig.height; let chartX = 0; let chartY = 0; - const chartWidth = Math.floor((availableWidth * this.chartConfig.plotReservedSpacePercent) / 100); - const chartHeight = Math.floor((availableHeight * this.chartConfig.plotReservedSpacePercent) / 100); - + let chartWidth = Math.floor((availableWidth * this.chartConfig.plotReservedSpacePercent) / 100); + let chartHeight = Math.floor( + (availableHeight * this.chartConfig.plotReservedSpacePercent) / 100 + ); let spaceUsed = this.componentStore.plot.calculateSpace({ width: chartWidth, height: chartHeight, @@ -39,19 +41,42 @@ export class Orchestrator { width: this.chartConfig.width, height: availableHeight, }); + log.trace('space used by title: ', spaceUsed); chartY = spaceUsed.height; - availableWidth -= spaceUsed.width; availableHeight -= spaceUsed.height; - // - // spaceUsed = this.componentStore.xAxis.calculateSpace({ - // width: availableWidth, - // height: availableHeight, - // }); - // availableWidth -= spaceUsed.width; - // availableHeight -= spaceUsed.height; - this.componentStore.plot.setBoundingBoxXY({x: chartX, y: chartY}); + this.componentStore.xAxis.setAxisPosition('bottom'); + spaceUsed = this.componentStore.xAxis.calculateSpace({ + width: availableWidth, + height: availableHeight, + }); + log.trace('space used by xaxis: ', spaceUsed); + availableHeight -= spaceUsed.height; + this.componentStore.yAxis.setAxisPosition('left'); + spaceUsed = this.componentStore.yAxis.calculateSpace({ + width: availableWidth, + height: availableHeight, + }); + log.trace('space used by yaxis: ', spaceUsed); + chartX = spaceUsed.width; + availableWidth -= spaceUsed.width; + if (availableWidth > 0) { + chartWidth += availableWidth; + availableWidth = 0; + } + if (availableHeight > 0) { + chartHeight += availableHeight; + availableHeight = 0; + } + + log.trace( + `Final chart dimansion: x = ${chartX}, y = ${chartY}, width = ${chartWidth}, height = ${chartHeight}` + ); + + this.componentStore.plot.setBoundingBoxXY({ x: chartX, y: chartY }); this.componentStore.xAxis.setRange([chartX, chartX + chartWidth]); + this.componentStore.xAxis.setBoundingBoxXY({ x: chartX, y: chartY + chartHeight }); this.componentStore.yAxis.setRange([chartY, chartY + chartHeight]); + this.componentStore.yAxis.setBoundingBoxXY({ x: 0, y: chartY }); } getDrawableElement() { diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/TextDimensionCalculator.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/TextDimensionCalculator.ts index e83badc35..c7a252609 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/TextDimensionCalculator.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/TextDimensionCalculator.ts @@ -1,15 +1,15 @@ import { Dimension } from './Interfaces.js'; export interface ITextDimensionCalculator { - getDimension(text: string): Dimension; + getDimension(texts: string[], fontSize: number, fontFamily?: string ): Dimension; } export class TextDimensionCalculator implements ITextDimensionCalculator { - constructor(private fontSize: number, private fontFamily: string) {} - getDimension(text: string): Dimension { + constructor() {} + getDimension(texts: string[], fontSize: number): Dimension { return { - width: text.length * this.fontSize, - height: this.fontSize, + width: texts.reduce((acc, cur) => Math.max(cur.length, acc), 0) * fontSize, + height: fontSize, }; } } diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/ChartTitle.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/ChartTitle.ts index de43859c7..51e27b0cd 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/ChartTitle.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/ChartTitle.ts @@ -25,7 +25,7 @@ export class ChartTitle implements ChartComponent { width: 0, height: 0, }; - this.showChartTitle = !!(this.chartData.title && this.chartConfig.showChartTitle); + this.showChartTitle = !!(this.chartData.title && this.chartConfig.showtitle); this.orientation = OrientationEnum.VERTICAL; } setOrientation(orientation: OrientationEnum): void { @@ -36,7 +36,7 @@ export class ChartTitle implements ChartComponent { this.boundingRect.y = point.y; } calculateSpace(availableSpace: Dimension): Dimension { - const titleDimension = this.textDimensionCalculator.getDimension(this.chartData.title); + const titleDimension = this.textDimensionCalculator.getDimension([this.chartData.title], this.chartConfig.titleFontSize); const widthRequired = Math.max(titleDimension.width, availableSpace.width); const heightRequired = titleDimension.height + 2 * this.chartConfig.titlePadding; if ( @@ -81,9 +81,6 @@ export function getChartTitleComponent( chartConfig: XYChartConfig, chartData: XYChartData ): ChartComponent { - const textDimensionCalculator = new TextDimensionCalculator( - chartConfig.titleFontSize, - chartConfig.fontFamily - ); + const textDimensionCalculator = new TextDimensionCalculator(); return new ChartTitle(textDimensionCalculator, chartConfig, chartData); } diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/Interfaces.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/Interfaces.ts index d9644d6af..92f27986b 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/Interfaces.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/Interfaces.ts @@ -1,7 +1,6 @@ import { Dimension, DrawableElem, OrientationEnum, Point } from '../Interfaces.js'; export interface ChartComponent { - setOrientation(orientation: OrientationEnum): void; calculateSpace(availableSpace: Dimension): Dimension; setBoundingBoxXY(point: Point): void; getDrawableElements(): DrawableElem[]; diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BandAxis.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BandAxis.ts index dd908e283..75a9ab643 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BandAxis.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BandAxis.ts @@ -1,54 +1,43 @@ import { ScaleBand, scaleBand } from 'd3'; -import { - Dimension, - Point, - DrawableElem, - BoundingRect, - OrientationEnum, - XYChartConfig, -} from '../../Interfaces.js'; -import { IAxis } from './index.js'; +import { AxisConfig } from '../../Interfaces.js'; +import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js'; +import { BaseAxis } from './BaseAxis.js'; +import { log } from '../../../../../logger.js'; -export class BandAxis implements IAxis { +export class BandAxis extends BaseAxis { private scale: ScaleBand; - private range: [number, number]; - private boundingRect: BoundingRect; - private orientation: OrientationEnum; private categories: string[]; - constructor(private chartConfig: XYChartConfig, categories: string[]) { - this.range = [0, 10]; + constructor( + axisConfig: AxisConfig, + categories: string[], + title: string, + textDimensionCalculator: ITextDimensionCalculator + ) { + super(axisConfig, title, textDimensionCalculator); this.categories = categories; - this.scale = scaleBand().domain(this.categories).range(this.range); - this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; - this.orientation = OrientationEnum.VERTICAL; + this.scale = scaleBand().domain(this.categories).range(this.getRange()); } setRange(range: [number, number]): void { - this.range = range; - this.scale = scaleBand().domain(this.categories).range(this.range); + super.setRange(range); } - setOrientation(orientation: OrientationEnum): void { - this.orientation = orientation; + + recalculateScale(): void { + this.scale = scaleBand() + .domain(this.categories) + .range(this.getRange()) + .paddingInner(1) + .paddingOuter(0) + .align(0.5); + log.trace('BandAxis axis final categories, range: ', this.categories, this.getRange()); + } + + getTickValues(): (string | number)[] { + return this.categories; } getScaleValue(value: string): number { - return this.scale(value) || this.range[0]; - } - - calculateSpace(availableSpace: Dimension): Dimension { - return { - width: availableSpace.width, - height: availableSpace.height, - }; - } - - setBoundingBoxXY(point: Point): void { - this.boundingRect.x = point.x; - this.boundingRect.y = point.y; - } - - getDrawableElements(): DrawableElem[] { - return []; + return this.scale(value) || this.getRange()[0]; } } diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BaseAxis.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BaseAxis.ts new file mode 100644 index 000000000..14107da52 --- /dev/null +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/BaseAxis.ts @@ -0,0 +1,217 @@ +import { + Dimension, + Point, + DrawableElem, + BoundingRect, + AxisConfig, +} from '../../Interfaces.js'; +import { AxisPosition, IAxis } from './index.js'; +import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js'; +import { log } from '../../../../../logger.js'; + +export abstract class BaseAxis implements IAxis { + protected boundingRect: BoundingRect = {x: 0, y: 0, width: 0, height: 0}; + protected axisPosition: AxisPosition = 'left'; + private range: [number, number]; + protected showTitle = false; + protected showLabel = false; + protected innerPadding = 0; + + constructor( + protected axisConfig: AxisConfig, + protected title: string, + protected textDimensionCalculator: ITextDimensionCalculator + ) { + this.range = [0, 10]; + this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; + this.axisPosition = 'left'; + + } + + setRange(range: [number, number]): void { + this.range = range; + this.recalculateScale(); + } + + getRange(): [number, number] { + return [this.range[0] + this.innerPadding, this.range[1] - this.innerPadding]; + } + + setAxisPosition(axisPosition: AxisPosition): void { + this.axisPosition = axisPosition; + } + + abstract getScaleValue(value: number | string): number; + + abstract recalculateScale(): void; + + abstract getTickValues(): Array; + + private getLabelDimension(): Dimension { + return this.textDimensionCalculator.getDimension( + this.getTickValues().map((tick) => tick.toString()), + this.axisConfig.labelFontSize + ); + } + + private calculateSpaceIfDrawnVertical(availableSpace: Dimension) { + let availableHeight = availableSpace.height; + if (this.axisConfig.showLabel) { + const spaceRequired = this.getLabelDimension(); + this.innerPadding = spaceRequired.width / 2; + const heightRequired = spaceRequired.height + this.axisConfig.lablePadding * 2; + log.trace('height required for axis label: ', heightRequired); + if (heightRequired <= availableHeight) { + availableHeight -= heightRequired; + this.showLabel = true; + } + } + if (this.axisConfig.showTitle) { + const spaceRequired = this.textDimensionCalculator.getDimension( + [this.title], + this.axisConfig.labelFontSize + ); + const heightRequired = spaceRequired.height + this.axisConfig.titlePadding * 2; + log.trace('height required for axis title: ', heightRequired); + if (heightRequired <= availableHeight) { + availableHeight -= heightRequired; + this.showTitle = true; + } + } + this.boundingRect.width = availableSpace.width; + this.boundingRect.height = availableSpace.height - availableHeight; + } + + private calculateSpaceIfDrawnHorizontally(availableSpace: Dimension) { + let availableWidth = availableSpace.width; + if (this.axisConfig.showLabel) { + const spaceRequired = this.getLabelDimension(); + this.innerPadding = spaceRequired.width / 2; + const widthRequired = spaceRequired.width + this.axisConfig.lablePadding * 2; + log.trace('width required for axis label: ', widthRequired); + if (widthRequired <= availableWidth) { + availableWidth -= widthRequired; + this.showLabel = true; + } + } + if (this.axisConfig.showTitle) { + const spaceRequired = this.textDimensionCalculator.getDimension( + [this.title], + this.axisConfig.labelFontSize + ); + const widthRequired = spaceRequired.height + this.axisConfig.lablePadding * 2; + log.trace('width required for axis title: ', widthRequired); + if (widthRequired <= availableWidth) { + availableWidth -= widthRequired; + this.showTitle = true; + } + } + this.boundingRect.width = availableSpace.width - availableWidth; + this.boundingRect.height = availableSpace.height; + } + + calculateSpace(availableSpace: Dimension): Dimension { + if (!(this.axisConfig.showLabel || this.axisConfig.showTitle)) { + this.recalculateScale(); + return { width: 0, height: 0 }; + } + if (this.axisPosition === 'left') { + this.calculateSpaceIfDrawnHorizontally(availableSpace); + } else { + this.calculateSpaceIfDrawnVertical(availableSpace); + } + this.recalculateScale(); + return { + width: this.boundingRect.width, + height: this.boundingRect.height, + }; + } + + setBoundingBoxXY(point: Point): void { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + + private getDrawaableElementsForLeftAxis(): DrawableElem[] { + const drawableElement: DrawableElem[] = []; + if (this.showLabel) { + drawableElement.push({ + type: 'text', + groupText: 'left-axis-label', + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.boundingRect.x + this.boundingRect.width - this.axisConfig.lablePadding, + y: this.getScaleValue(tick), + fill: this.axisConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: 'right', + horizontalPos: 'middle', + })), + }); + } + if (this.showTitle) { + drawableElement.push({ + type: 'text', + groupText: 'right-axis-label', + data: [{ + text: this.title, + x: this.boundingRect.x + this.axisConfig.titlePadding, + y: this.range[0] + (this.range[1] - this.range[0])/2, + fill: this.axisConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 270, + verticalPos: 'center', + horizontalPos: 'top', + }] + }) + } + return drawableElement; + } + private getDrawaableElementsForBottomAxis(): DrawableElem[] { + const drawableElement: DrawableElem[] = []; + if (this.showLabel) { + drawableElement.push({ + type: 'text', + groupText: 'right-axis-lable', + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.getScaleValue(tick), + y: this.boundingRect.y + this.axisConfig.lablePadding, + fill: this.axisConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: 'center', + horizontalPos: 'top', + })), + }); + } + if (this.showTitle) { + drawableElement.push({ + type: 'text', + groupText: 'right-axis-label', + data: [{ + text: this.title, + x: this.range[0] + (this.range[1] - this.range[0])/2, + y: this.boundingRect.y + this.boundingRect.height - this.axisConfig.titlePadding, + fill: this.axisConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 0, + verticalPos: 'center', + horizontalPos: 'bottom', + }] + }) + } + return drawableElement; + } + + getDrawableElements(): DrawableElem[] { + if (this.axisPosition === 'left') { + return this.getDrawaableElementsForLeftAxis(); + } + if (this.axisPosition === 'bottom') { + return this.getDrawaableElementsForBottomAxis(); + } + return []; + } +} diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/LinearAxis.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/LinearAxis.ts index 02c0bd644..9bf7c33b0 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/LinearAxis.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/LinearAxis.ts @@ -1,55 +1,37 @@ -import { scaleLinear, ScaleLinear } from 'd3'; -import { - Dimension, - Point, - DrawableElem, - BoundingRect, - OrientationEnum, - XYChartConfig, -} from '../../Interfaces.js'; -import { IAxis } from './index.js'; +import { ScaleLinear, scaleLinear } from 'd3'; +import { AxisConfig, Dimension } from '../../Interfaces.js'; +import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js'; +import { BaseAxis } from './BaseAxis.js'; +import { log } from '../../../../../logger.js'; -export class LinearAxis implements IAxis { +export class LinearAxis extends BaseAxis { private scale: ScaleLinear; - private boundingRect: BoundingRect; - private orientation: OrientationEnum; private domain: [number, number]; - private range: [number, number]; - constructor(private chartConfig: XYChartConfig, domain: [number, number]) { + constructor( + axisConfig: AxisConfig, + domain: [number, number], + title: string, + textDimensionCalculator: ITextDimensionCalculator + ) { + super(axisConfig, title, textDimensionCalculator); this.domain = domain; - this.range = [0, 10]; - this.scale = scaleLinear().domain(this.domain).range(this.range); - this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; - this.orientation = OrientationEnum.VERTICAL; + this.scale = scaleLinear().domain(this.domain).range(this.getRange()); } - setRange(range: [number, number]): void { - this.range = range; - this.scale = scaleLinear().domain(this.domain).range(this.range); + getTickValues(): (string | number)[] { + return this.scale.ticks(); } - setOrientation(orientation: OrientationEnum): void { - this.orientation = orientation; + recalculateScale(): void { + if (this.axisPosition === 'left') { + this.domain.reverse(); // since yaxis in svg start from top + } + this.scale = scaleLinear().domain(this.domain).range(this.getRange()); + log.trace('Linear axis final domain, range: ', this.domain, this.getRange()); } getScaleValue(value: number): number { return this.scale(value); } - - calculateSpace(availableSpace: Dimension): Dimension { - return { - width: availableSpace.width, - height: availableSpace.height, - }; - } - - setBoundingBoxXY(point: Point): void { - this.boundingRect.x = point.x; - this.boundingRect.y = point.y; - } - - getDrawableElements(): DrawableElem[] { - return []; - } } diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/index.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/index.ts index f7ff5cc69..1972ef2c5 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/index.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/index.ts @@ -1,17 +1,19 @@ import { - AxisDataType, - BandAxisDataType, - BoundingRect, - LinearAxisDataType, - XYChartConfig, - XYChartData, + AxisConfig, + AxisDataType, + BandAxisDataType, + LinearAxisDataType } from '../../Interfaces.js'; +import { TextDimensionCalculator } from '../../TextDimensionCalculator.js'; import { ChartComponent } from '../Interfaces.js'; import { BandAxis } from './BandAxis.js'; import { LinearAxis } from './LinearAxis.js'; +export type AxisPosition = 'left' | 'bottom'; + export interface IAxis extends ChartComponent { getScaleValue(value: string | number): number; + setAxisPosition(axisPosition: AxisPosition): void; setRange(range: [number, number]): void; } @@ -23,9 +25,10 @@ function isBandAxisData(data: any): data is BandAxisDataType { return data.categories && Array.isArray(data.categories); } -export function getAxis(data: AxisDataType, chartConfig: XYChartConfig): IAxis { +export function getAxis(data: AxisDataType, axisConfig: AxisConfig): IAxis { + const textDimansionCalculator = new TextDimensionCalculator(); if (isBandAxisData(data)) { - return new BandAxis(chartConfig, data.categories); + return new BandAxis(axisConfig, data.categories, data.title, textDimansionCalculator); } - return new LinearAxis(chartConfig, [data.min, data.max]); + return new LinearAxis(axisConfig, [data.min, data.max], data.title, textDimansionCalculator); } diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/index.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/index.ts index d307b2957..a47074e73 100644 --- a/packages/mermaid/src/diagrams/xychart/chartBuilder/index.ts +++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/index.ts @@ -2,12 +2,11 @@ import { defaultConfig } from '../../../config.js'; import { log } from '../../../logger.js'; import { - ChartPlotEnum, - DrawableElem, - XYChartConfig, - XYChartData, - OrientationEnum, - XYChartYAxisPosition, + ChartPlotEnum, + DrawableElem, + OrientationEnum, + XYChartConfig, + XYChartData } from './Interfaces.js'; import { Orchestrator } from './Orchestrator.js'; @@ -17,22 +16,33 @@ export class XYChartBuilder { constructor() { this.config = { - width: 500, + width: 700, height: 500, fontFamily: defaultConfig.fontFamily || 'Sans', titleFontSize: 16, titleFill: '#000000', titlePadding: 5, - xAxisFontSize: 14, - xAxisTitleFontSize: 16, - yAxisFontSize: 14, - yAxisTitleFontSize: 16, - yAxisPosition: XYChartYAxisPosition.LEFT, - showChartTitle: true, - showXAxisLable: true, - showXAxisTitle: true, - showYAxisLabel: true, - showYAxisTitle: true, + showtitle: true, + yAxis: { + showLabel: true, + labelFontSize: 14, + lablePadding: 5, + labelColor: '#000000', + showTitle: true, + titleFontSize: 16, + titlePadding: 5, + titleColor: '#000000', + }, + xAxis: { + showLabel: true, + labelFontSize: 14, + lablePadding: 5, + labelColor: '#000000', + showTitle: true, + titleFontSize: 16, + titlePadding: 5, + titleColor: '#000000', + }, chartOrientation: OrientationEnum.HORIZONTAL, plotReservedSpacePercent: 50, }; diff --git a/packages/mermaid/src/diagrams/xychart/xychartRenderer.ts b/packages/mermaid/src/diagrams/xychart/xychartRenderer.ts index ee696377e..a871177ce 100644 --- a/packages/mermaid/src/diagrams/xychart/xychartRenderer.ts +++ b/packages/mermaid/src/diagrams/xychart/xychartRenderer.ts @@ -1,13 +1,13 @@ -import { select, scaleOrdinal, scaleLinear, axisBottom, line } from 'd3'; +import { select } from 'd3'; +import { Diagram } from '../../Diagram.js'; import * as configApi from '../../config.js'; import { log } from '../../logger.js'; import { configureSvgSize } from '../../setupGraphViewbox.js'; -import { Diagram } from '../../Diagram.js'; import { - DrawableElem, - TextElem, - TextHorizontalPos, - TextVerticalPos, + DrawableElem, + TextElem, + TextHorizontalPos, + TextVerticalPos, } from './chartBuilder/Interfaces.js'; export const draw = (txt: string, id: string, _version: string, diagObj: Diagram) => { @@ -16,7 +16,7 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram } function getTextAnchor(verticalPos: TextVerticalPos) { - return verticalPos === 'left' ? 'start' : 'middle'; + return verticalPos === 'left' ? 'start' : verticalPos === 'right' ? 'end' : 'middle'; } function getTextTransformation(data: TextElem) { @@ -32,16 +32,13 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram if (securityLevel === 'sandbox') { sandboxElement = select('#i' + id); } - const root = - sandboxElement - ? sandboxElement - : select('body'); + const root = sandboxElement ? sandboxElement : select('body'); const svg = root.select(`[id="${id}"]`); const group = svg.append('g').attr('class', 'main'); - const width = 500; + const width = 700; const height = 500; // @ts-ignore: TODO Fix ts errors @@ -74,7 +71,6 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram const shapeGroup = group.append('g').attr('class', shape.groupText); - switch (shape.type) { case 'rect': shapeGroup @@ -82,13 +78,13 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram .data(shape.data) .enter() .append('rect') - .attr('x', data => data.x) - .attr('y', data => data.y) - .attr('width', data => data.width) - .attr('height', data => data.height) - .attr('fill', data => data.fill) - .attr('stroke', data => data.strokeFill) - .attr('stroke-width', data => data.strokeWidth); + .attr('x', (data) => data.x) + .attr('y', (data) => data.y) + .attr('width', (data) => data.width) + .attr('height', (data) => data.height) + .attr('fill', (data) => data.fill) + .attr('stroke', (data) => data.strokeFill) + .attr('stroke-width', (data) => data.strokeWidth); break; case 'text': shapeGroup @@ -98,12 +94,12 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram .append('text') .attr('x', 0) .attr('y', 0) - .attr('fill', data => data.fill) - .attr('font-size', data => data.fontSize) - .attr('dominant-baseline', data => getDominantBaseLine(data.horizontalPos)) - .attr('text-anchor', data => getTextAnchor(data.verticalPos)) - .attr('transform', data => getTextTransformation(data)) - .text(data => data.text); + .attr('fill', (data) => data.fill) + .attr('font-size', (data) => data.fontSize) + .attr('dominant-baseline', (data) => getDominantBaseLine(data.horizontalPos)) + .attr('text-anchor', (data) => getTextAnchor(data.verticalPos)) + .attr('transform', (data) => getTextTransformation(data)) + .text((data) => data.text); break; case 'path': shapeGroup @@ -111,10 +107,10 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram .data(shape.data) .enter() .append('path') - .attr('d', data => data.path) - .attr('fill', data => data.fill? data.fill: "none") - .attr('stroke', data => data.strokeFill) - .attr('stroke-width', data => data.strokeWidth) + .attr('d', (data) => data.path) + .attr('fill', (data) => (data.fill ? data.fill : 'none')) + .attr('stroke', (data) => data.strokeFill) + .attr('stroke-width', (data) => data.strokeWidth); break; } }