Improved space management for text

This commit is contained in:
Subhash Halder
2023-07-04 10:00:13 +05:30
parent 597f7a8e87
commit 553be985ae
4 changed files with 72 additions and 18 deletions

View File

@@ -17,8 +17,8 @@ export class Orchestrator {
this.componentStore = {
title: getChartTitleComponent(chartConfig, chartData),
plot: getPlotComponent(chartConfig, chartData),
xAxis: getAxis(chartData.xAxis, chartConfig.xAxis),
yAxis: getAxis(chartData.yAxis, chartConfig.yAxis),
xAxis: getAxis(chartData.xAxis, chartConfig.xAxis, chartConfig.fontFamily),
yAxis: getAxis(chartData.yAxis, chartConfig.yAxis, chartConfig.fontFamily),
};
}

View File

@@ -1,7 +1,7 @@
import { Dimension } from './Interfaces.js';
export interface ITextDimensionCalculator {
getDimension(texts: string[], fontSize: number, fontFamily?: string ): Dimension;
getDimension(texts: string[], fontSize: number, fontFamily?: string): Dimension;
}
export class TextDimensionCalculator implements ITextDimensionCalculator {
@@ -13,3 +13,57 @@ export class TextDimensionCalculator implements ITextDimensionCalculator {
};
}
}
export class TextDimensionCalculatorWithFont implements ITextDimensionCalculator {
private container: HTMLSpanElement | null = null;
private hiddenElementId = 'mermaid-text-dimension-calculator';
constructor(fontFamily?: string) {
if (document) {
let parentContainer = document.getElementById(this.hiddenElementId);
if (!parentContainer) {
parentContainer = document.createElement('div');
parentContainer.id = this.hiddenElementId;
parentContainer.style.position = 'absolute';
parentContainer.style.top = '-100px';
parentContainer.style.left = '0px';
parentContainer.style.visibility = 'hidden';
document.body.append(parentContainer);
}
const fontClassName = `font-${fontFamily}`;
const prevContainerAvailable = parentContainer.getElementsByClassName(fontClassName);
if (prevContainerAvailable.length > 0) {
this.container = prevContainerAvailable.item(0) as HTMLSpanElement;
} else {
this.container = document.createElement('div');
this.container.className = fontClassName;
if (fontFamily) {
this.container.style.fontFamily = fontFamily;
}
parentContainer.append(this.container);
}
}
}
getDimension(texts: string[], fontSize: number): Dimension {
if (!this.container) {
return {
width: texts.reduce((acc, cur) => Math.max(cur.length, acc), 0) * fontSize,
height: fontSize,
};
}
const dimension: Dimension = {
width: 0,
height: 0,
};
this.container.style.fontSize = `${fontSize}px`;
for (let t of texts) {
this.container.innerHTML = t;
const bbox = this.container.getBoundingClientRect();
dimension.width = Math.max(dimension.width, bbox.width);
dimension.height = Math.max(dimension.height, bbox.height);
}
return dimension;
}
}

View File

@@ -1,13 +1,13 @@
import { ITextDimensionCalculator, TextDimensionCalculator } from '../TextDimensionCalculator.js';
import {
XYChartData,
Dimension,
BoundingRect,
DrawableElem,
Point,
} from '../Interfaces.js';
import { ChartComponent } from '../Interfaces.js';
import { XYChartConfig } from '../../../../config.type.js';
import {
BoundingRect,
ChartComponent,
Dimension,
DrawableElem,
Point,
XYChartData,
} from '../Interfaces.js';
import { ITextDimensionCalculator, TextDimensionCalculatorWithFont } from '../TextDimensionCalculator.js';
export class ChartTitle implements ChartComponent {
private boundingRect: BoundingRect;
@@ -75,6 +75,6 @@ export function getChartTitleComponent(
chartConfig: XYChartConfig,
chartData: XYChartData
): ChartComponent {
const textDimensionCalculator = new TextDimensionCalculator();
const textDimensionCalculator = new TextDimensionCalculatorWithFont(chartConfig.fontFamily);
return new ChartTitle(textDimensionCalculator, chartConfig, chartData);
}

View File

@@ -1,12 +1,12 @@
import { XYChartAxisConfig } from '../../../../../config.type.js';
import {
AxisDataType,
ChartComponent,
isBandAxisData,
} from '../../Interfaces.js';
import { TextDimensionCalculator } from '../../TextDimensionCalculator.js';
import { ChartComponent } from '../../Interfaces.js';
import { TextDimensionCalculatorWithFont } from '../../TextDimensionCalculator.js';
import { BandAxis } from './BandAxis.js';
import { LinearAxis } from './LinearAxis.js';
import { XYChartAxisConfig } from '../../../../../config.type.js';
export type AxisPosition = 'left' | 'right' | 'top' | 'bottom';
@@ -18,8 +18,8 @@ export interface IAxis extends ChartComponent {
setRange(range: [number, number]): void;
}
export function getAxis(data: AxisDataType, axisConfig: XYChartAxisConfig): IAxis {
const textDimansionCalculator = new TextDimensionCalculator();
export function getAxis(data: AxisDataType, axisConfig: XYChartAxisConfig, fontFamily?: string): IAxis {
const textDimansionCalculator = new TextDimensionCalculatorWithFont(fontFamily);
if (isBandAxisData(data)) {
return new BandAxis(axisConfig, data.categories, data.title, textDimansionCalculator);
}