Fixed some issue related to rendering and space management

This commit is contained in:
Subhash Halder 2023-07-04 19:55:12 +05:30
parent 553be985ae
commit 355263a4fb
9 changed files with 56 additions and 27 deletions

View File

@ -20,8 +20,8 @@
title Basic xychart
x-axis "this is x axis" [category1, "category 2", category3, category4]
y-axis yaxisText 10 --> 150
line [23, 46, 75, 43]
bar "sample bat" [52, 96, 35, 10]
line [23, 46, 75, 43]
</pre>
<hr />
@ -32,11 +32,22 @@
title Basic xychart
x-axis "this is x axis" [category1, "category 2", category3, category4]
y-axis yaxisText 10 --> 150
line [23, 46, 75, 43]
bar "sample bat" [52, 96, 35, 10]
line [23, 46, 75, 43]
</pre>
<hr />
<h1>XY Charts demos</h1>
<pre class="mermaid">
xychart-beta horizontal
title Basic xychart
x-axis "this is x axis" [category1, "category 2", category3, category4]
y-axis yaxisText 10 --> 150
line [23, 46, 75, 43]
</pre>
<hr />
<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.initialize({

View File

@ -26,6 +26,10 @@ export interface BarPlotData {
export type PlotData = LinePlotData | BarPlotData;
export function isBarPlot(data: PlotData): data is BarPlotData {
return data.type === ChartPlotEnum.BAR;
}
export interface BandAxisDataType {
title: string;
categories: string[];

View File

@ -1,5 +1,5 @@
import { log } from '../../../logger.js';
import { DrawableElem, XYChartData } from './Interfaces.js';
import { DrawableElem, XYChartData, isBarPlot } from './Interfaces.js';
import { getChartTitleComponent } from './components/ChartTitle.js';
import { ChartComponent } from './Interfaces.js';
import { IAxis, getAxis } from './components/axis/index.js';
@ -13,7 +13,7 @@ export class Orchestrator {
xAxis: IAxis;
yAxis: IAxis;
};
constructor(private chartConfig: XYChartConfig, chartData: XYChartData) {
constructor(private chartConfig: XYChartConfig, private chartData: XYChartData) {
this.componentStore = {
title: getChartTitleComponent(chartConfig, chartData),
plot: getPlotComponent(chartConfig, chartData),
@ -87,6 +87,9 @@ export class Orchestrator {
this.componentStore.xAxis.setBoundingBoxXY({ x: chartX, y: chartY + chartHeight });
this.componentStore.yAxis.setRange([chartY, chartY + chartHeight]);
this.componentStore.yAxis.setBoundingBoxXY({ x: 0, y: chartY });
if(this.chartData.plots.find(p => isBarPlot(p))) {
this.componentStore.xAxis.recalculateOuterPaddingToDrawBar();
}
}
private calculateHorizonatalSpace() {
@ -156,6 +159,9 @@ export class Orchestrator {
this.componentStore.yAxis.setBoundingBoxXY({ x: chartX, y: titleYEnd });
this.componentStore.xAxis.setRange([chartY, chartY + chartHeight]);
this.componentStore.xAxis.setBoundingBoxXY({ x: 0, y: chartY });
if(this.chartData.plots.find(p => isBarPlot(p))) {
this.componentStore.xAxis.recalculateOuterPaddingToDrawBar();
}
}
private calculateSpace() {

View File

@ -1,15 +1,15 @@
import { ScaleBand, scaleBand } from 'd3';
import { AxisConfig } from '../../Interfaces.js';
import { XYChartAxisConfig } from '../../../../../config.type.js';
import { log } from '../../../../../logger.js';
import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js';
import { BaseAxis } from './BaseAxis.js';
import { log } from '../../../../../logger.js';
export class BandAxis extends BaseAxis {
private scale: ScaleBand<string>;
private categories: string[];
constructor(
axisConfig: AxisConfig,
axisConfig: XYChartAxisConfig,
categories: string[],
title: string,
textDimensionCalculator: ITextDimensionCalculator

View File

@ -1,7 +1,8 @@
import { Dimension, Point, DrawableElem, BoundingRect, AxisConfig } from '../../Interfaces.js';
import { AxisPosition, IAxis } from './index.js';
import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js';
import { XYChartAxisConfig } from '../../../../../config.type.js';
import { log } from '../../../../../logger.js';
import { BoundingRect, Dimension, DrawableElem, Point } from '../../Interfaces.js';
import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js';
import { AxisPosition, IAxis } from './index.js';
export abstract class BaseAxis implements IAxis {
protected boundingRect: BoundingRect = { x: 0, y: 0, width: 0, height: 0 };
@ -10,10 +11,10 @@ export abstract class BaseAxis implements IAxis {
protected showTitle = false;
protected showLabel = false;
protected showTick = false;
protected innerPadding = 0;
protected outerPadding = 0;
constructor(
protected axisConfig: AxisConfig,
protected axisConfig: XYChartAxisConfig,
protected title: string,
protected textDimensionCalculator: ITextDimensionCalculator
) {
@ -28,7 +29,7 @@ export abstract class BaseAxis implements IAxis {
}
getRange(): [number, number] {
return [this.range[0] + this.innerPadding, this.range[1] - this.innerPadding];
return [this.range[0] + this.outerPadding, this.range[1] - this.outerPadding];
}
setAxisPosition(axisPosition: AxisPosition): void {
@ -45,9 +46,8 @@ export abstract class BaseAxis implements IAxis {
return Math.abs(this.range[0] - this.range[1]) / this.getTickValues().length;
}
getTickInnerPadding(): number {
return this.innerPadding * 2;
// return Math.abs(this.range[0] - this.range[1]) / this.getTickValues().length;
getAxisOuterPadding(): number {
return this.outerPadding;
}
private getLabelDimension(): Dimension {
@ -57,11 +57,18 @@ export abstract class BaseAxis implements IAxis {
);
}
recalculateOuterPaddingToDrawBar(): void {
if((0.7 * this.getTickDistance()) > (this.outerPadding * 2) ) {
this.outerPadding = Math.floor((0.7 * this.getTickDistance())/2);
}
this.recalculateScale();
}
private calculateSpaceIfDrawnHorizontally(availableSpace: Dimension) {
let availableHeight = availableSpace.height;
if (this.axisConfig.showLabel) {
const spaceRequired = this.getLabelDimension();
this.innerPadding = spaceRequired.width / 2;
this.outerPadding = spaceRequired.width / 2;
const heightRequired = spaceRequired.height + this.axisConfig.lablePadding * 2;
log.trace('height required for axis label: ', heightRequired);
if (heightRequired <= availableHeight) {
@ -93,7 +100,7 @@ export abstract class BaseAxis implements IAxis {
let availableWidth = availableSpace.width;
if (this.axisConfig.showLabel) {
const spaceRequired = this.getLabelDimension();
this.innerPadding = spaceRequired.height / 2;
this.outerPadding = spaceRequired.height / 2;
const widthRequired = spaceRequired.width + this.axisConfig.lablePadding * 2;
log.trace('width required for axis label: ', widthRequired);
if (widthRequired <= availableWidth) {

View File

@ -1,6 +1,6 @@
import { ScaleLinear, scaleLinear } from 'd3';
import { XYChartAxisConfig } from '../../../../../config.type.js';
import { log } from '../../../../../logger.js';
import { AxisConfig } from '../../Interfaces.js';
import { ITextDimensionCalculator } from '../../TextDimensionCalculator.js';
import { BaseAxis } from './BaseAxis.js';
@ -9,7 +9,7 @@ export class LinearAxis extends BaseAxis {
private domain: [number, number];
constructor(
axisConfig: AxisConfig,
axisConfig: XYChartAxisConfig,
domain: [number, number],
title: string,
textDimensionCalculator: ITextDimensionCalculator

View File

@ -13,8 +13,9 @@ export type AxisPosition = 'left' | 'right' | 'top' | 'bottom';
export interface IAxis extends ChartComponent {
getScaleValue(value: string | number): number;
setAxisPosition(axisPosition: AxisPosition): void;
getTickInnerPadding(): number;
getAxisOuterPadding(): number;
getTickDistance(): number;
recalculateOuterPaddingToDrawBar(): void;
setRange(range: [number, number]): void;
}

View File

@ -24,7 +24,7 @@ export class BarPlot {
const barPaddingPercent = 5;
const barWidth =
Math.min(this.xAxis.getTickInnerPadding(), this.xAxis.getTickDistance()) *
Math.min(this.xAxis.getAxisOuterPadding() * 2, this.xAxis.getTickDistance()) *
(1 - barPaddingPercent / 100);
const barWidthHalf = barWidth / 2;

View File

@ -125,8 +125,9 @@ function setYAxisRangeData(min: number, max: number) {
function setLineData(title: string, data: number[]) {
if (isBandAxisData(xyChartData.xAxis)) {
xyChartData.plots.push({
type: ChartPlotEnum.BAR,
fill: '#0000bb',
type: ChartPlotEnum.LINE,
strokeFill: '#00ff00',
strokeWidth: 2,
data: xyChartData.xAxis.categories.map((c, i) => [c, data[i]]),
});
}
@ -134,9 +135,8 @@ function setLineData(title: string, data: number[]) {
function setBarData(title: string, data: number[]) {
if (isBandAxisData(xyChartData.xAxis)) {
xyChartData.plots.push({
type: ChartPlotEnum.LINE,
strokeFill: '#00ff00',
strokeWidth: 2,
type: ChartPlotEnum.BAR,
fill: '#0000bb',
data: xyChartData.xAxis.categories.map((c, i) => [c, data[i]]),
});
}