mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 12:54:08 +01:00 
			
		
		
		
	Improved space management for text
This commit is contained in:
		@@ -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),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user