Added support for bar plot

This commit is contained in:
Subhash Halder 2023-06-15 00:04:48 +05:30
parent cc1d6af232
commit 547a22edef
9 changed files with 77 additions and 37 deletions

View File

@ -1,19 +1,12 @@
export enum ChartPlotEnum {
LINE = 'line',
BAR = 'bar',
}
export enum ChartLayoutElem {
NULL = 'null',
CHART = 'chart',
TITLE = 'title',
XAXISLABEL = 'xaxislabel',
XAXISTITLE = 'xaxistitle',
YAXISLABEL = 'yaxislabel',
YAXISTITLE = 'yaxistitle',
}
export enum XYChartYAxisPosition {
LEFT = 'left',
RIGHT = 'right',
export interface ChartComponent {
calculateSpace(availableSpace: Dimension): Dimension;
setBoundingBoxXY(point: Point): void;
getDrawableElements(): DrawableElem[];
}
export enum OrientationEnum {
@ -21,16 +14,6 @@ export enum OrientationEnum {
HORIZONTAL = 'horizontal',
}
export type ChartLayout = ChartLayoutElem[][];
export type VisibilityOption = {
chartTitle: boolean;
xAxisTitle: boolean;
xAxisLabel: boolean;
yAxisTitle: boolean;
yAxisLabel: boolean;
};
export interface AxisConfig {
showLabel: boolean;
labelFontSize: number;
@ -64,7 +47,7 @@ export interface XYChartConfig {
export type SimplePlotDataType = [string | number, number][];
export interface LinePlotData {
type: ChartPlotEnum.LINE;
type: ChartPlotEnum.LINE | ChartPlotEnum.BAR;
data: SimplePlotDataType;
}

View File

@ -1,7 +1,7 @@
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 { ChartComponent } from './Interfaces.js';
import { IAxis, getAxis } from './components/axis/index.js';
import { IPlot, getPlotComponent } from './components/plot/index.js';

View File

@ -8,7 +8,7 @@ import {
Point,
OrientationEnum,
} from '../Interfaces.js';
import { ChartComponent } from './Interfaces.js';
import { ChartComponent } from '../Interfaces.js';
export class ChartTitle implements ChartComponent {
private boundingRect: BoundingRect;

View File

@ -1,7 +0,0 @@
import { Dimension, DrawableElem, OrientationEnum, Point } from '../Interfaces.js';
export interface ChartComponent {
calculateSpace(availableSpace: Dimension): Dimension;
setBoundingBoxXY(point: Point): void;
getDrawableElements(): DrawableElem[];
}

View File

@ -41,6 +41,11 @@ export abstract class BaseAxis implements IAxis {
abstract getTickValues(): Array<string | number>;
getTickInnerPadding(): number {
return this.innerPadding * 2;
// return Math.abs(this.range[0] - this.range[1]) / this.getTickValues().length;
}
private getLabelDimension(): Dimension {
return this.textDimensionCalculator.getDimension(
this.getTickValues().map((tick) => tick.toString()),
@ -162,7 +167,9 @@ export abstract class BaseAxis implements IAxis {
type: 'path',
groupTexts: ['left-axis', 'ticks'],
data: this.getTickValues().map((tick) => ({
path: `M ${x},${this.getScaleValue(tick)} L ${x - this.axisConfig.tickLength},${this.getScaleValue(tick)}`,
path: `M ${x},${this.getScaleValue(tick)} L ${
x - this.axisConfig.tickLength
},${this.getScaleValue(tick)}`,
strokeFill: this.axisConfig.tickFill,
strokeWidth: this.axisConfig.tickWidth,
})),
@ -212,7 +219,9 @@ export abstract class BaseAxis implements IAxis {
type: 'path',
groupTexts: ['bottom-axis', 'ticks'],
data: this.getTickValues().map((tick) => ({
path: `M ${this.getScaleValue(tick)},${y} L ${this.getScaleValue(tick)},${y + this.axisConfig.tickLength}`,
path: `M ${this.getScaleValue(tick)},${y} L ${this.getScaleValue(tick)},${
y + this.axisConfig.tickLength
}`,
strokeFill: this.axisConfig.tickFill,
strokeWidth: this.axisConfig.tickWidth,
})),

View File

@ -5,15 +5,16 @@ import {
LinearAxisDataType
} from '../../Interfaces.js';
import { TextDimensionCalculator } from '../../TextDimensionCalculator.js';
import { ChartComponent } from '../Interfaces.js';
import { ChartComponent } from '../../Interfaces.js';
import { BandAxis } from './BandAxis.js';
import { LinearAxis } from './LinearAxis.js';
export type AxisPosition = 'left' | 'bottom';
export type AxisPosition = 'left' | 'bottom' | 'top' | 'bottom';
export interface IAxis extends ChartComponent {
getScaleValue(value: string | number): number;
setAxisPosition(axisPosition: AxisPosition): void;
getTickInnerPadding(): number;
setRange(range: [number, number]): void;
}

View File

@ -0,0 +1,40 @@
import { line } from 'd3';
import { BoundingRect, DrawableElem, SimplePlotDataType } from '../../Interfaces.js';
import { IAxis } from '../axis/index.js';
export class BarPlot {
constructor(
private data: SimplePlotDataType,
private boundingRect: BoundingRect,
private xAxis: IAxis,
private yAxis: IAxis
) {}
getDrawableElement(): DrawableElem[] {
const finalData: [number, number][] = this.data.map((d) => [
this.xAxis.getScaleValue(d[0]),
this.yAxis.getScaleValue(d[1]),
]);
const barPaddingPercent = 5;
const barWidth = this.xAxis.getTickInnerPadding() * (1 - barPaddingPercent / 100);
const barWidthHalf = barWidth / 2;
return [
{
groupTexts: ['plot', 'bar-plot'],
type: 'rect',
data: finalData.map((data) => ({
x: data[0] - barWidthHalf,
y: data[1],
width: barWidth,
height: this.boundingRect.y + this.boundingRect.height - data[1],
fill: '#ff0000',
strokeWidth: 0,
strokeFill: '#0000ff',
})),
},
];
}
}

View File

@ -9,9 +9,10 @@ import {
ChartPlotEnum,
} from '../../Interfaces.js';
import { IAxis } from '../axis/index.js';
import { ChartComponent } from './../Interfaces.js';
import { ChartComponent } from '../../Interfaces.js';
import { LinePlot } from './LinePlot.js';
import { PlotBorder } from './PlotBorder.js';
import { BarPlot } from './BarPlot.js';
export interface IPlot extends ChartComponent {
@ -70,6 +71,11 @@ export class Plot implements IPlot {
drawableElem.push(...linePlot.getDrawableElement())
}
break;
case ChartPlotEnum.BAR: {
const barPlot = new BarPlot(plot.data, this.boundingRect, this.xAxis, this.yAxis)
drawableElem.push(...barPlot.getDrawableElement());
}
break;
}
}
return drawableElem;

View File

@ -67,6 +67,14 @@ export class XYChartBuilder {
},
title: 'this is a sample task',
plots: [
{
type: ChartPlotEnum.BAR,
data: [
['category1', 23],
['category2', 56],
['category3', 34],
],
},
{
type: ChartPlotEnum.LINE,
data: [