import { DEFAULT_CHART_OPTIONS } from "./options";
import type { BarChartMetrics } from "./types/BarChartMetrics";
import type {
BarChartOptions,
ResolvedBarChartOptions,
} from "./types/BarChartOptions";
import {
getItemNames,
resolveBarChartOptions,
validateBarChartMetrics,
} from "./utils/BarChartUtil";
import { createLegend, createTitle, createYAxis } from "./utils/ChartUtil";
/**
* Default bar chart options
*/
export const DEFAULT_BAR_CHART_OPTIONS: BarChartOptions = {
...DEFAULT_CHART_OPTIONS,
barPadding: 0.2,
barGroupPadding: 0.4,
};
/**
* Creates the SVG bars for the bar chart
* @param metrics - The data for the bar chart
* @param config - Resolved bar chart options
* @returns SVG string for the bars
*/
const createBars = (
metrics: BarChartMetrics,
config: ResolvedBarChartOptions,
): string => {
// Initialize SVG string
let svg = "";
// Pre-compute values
const itemsArray = getItemNames(metrics);
const groupNames = Object.keys(metrics);
const maxValue = config.maxValue;
const chartWidth = config.width - config.margin.left - config.margin.right;
const chartHeight = config.height - config.margin.top - config.margin.bottom;
const groupWidth = chartWidth / groupNames.length;
const barWidth =
(groupWidth * (1 - config.barGroupPadding)) / itemsArray.length;
groupNames.forEach((group, groupIndex) => {
const groupX = groupIndex * groupWidth;
// Add group name below the x-axis
svg += ` ${group}\n`;
itemsArray.forEach((item, itemIndex) => {
const value = metrics[group][item] || 0;
const barHeight = (value / maxValue) * chartHeight;
const barX =
groupX +
(config.barGroupPadding * groupWidth) / 2 +
itemIndex * barWidth;
const barY = chartHeight - barHeight;
const colorIndex = itemIndex % config.colors.length;
// Draw the bar
svg += ` \n`;
// Add the value on top of or inside the bar
if (config.showValues) {
const formattedValue = config.formatValue(value);
if (barHeight > config.fontSize * 2) {
svg += ` ${formattedValue}\n`;
} else {
svg += ` ${formattedValue}\n`;
}
}
});
});
return svg;
};
/**
* Generates an SVG bar chart from given metrics
* @param metrics - The data for the bar chart
* @param options - Optional configuration for the chart
* @returns SVG string representing the bar chart
*/
export const generateBarChart = (
metrics: BarChartMetrics,
options: Partial = {},
): string => {
// Validate input
validateBarChartMetrics(metrics);
// Resolve options
const config = resolveBarChartOptions(options, metrics);
// Create the SVG content
let svg = `";
return svg;
};