@@ -23,6 +23,7 @@ import {
2323 MAX_BAR_THICKNESS ,
2424} from './constants'
2525import {
26+ AxisConfig ,
2627 ChartColorKey ,
2728 ChartProps ,
2829 ChartType ,
@@ -173,6 +174,66 @@ const getScaleTickTitleConfig = (title: string, appTheme: AppThemeType): ScaleOp
173174 color : CHART_AXIS_LABELS_COLOR [ appTheme ] ,
174175} )
175176
177+ /**
178+ * Formats a value with unit based on axis configuration
179+ */
180+ const formatValueWithUnit = ( value : number | string , axisConfig ?: AxisConfig ) : string => {
181+ if ( ! axisConfig ?. unit ) {
182+ return String ( value )
183+ }
184+
185+ const { unit, unitPosition = 'suffix' } = axisConfig
186+ const valueStr = String ( value )
187+
188+ return unitPosition === 'prefix' ? `${ unit } ${ valueStr } ` : `${ valueStr } ${ unit } `
189+ }
190+
191+ /**
192+ * Creates a comprehensive axis configuration with enhanced customization
193+ */
194+ const getEnhancedAxisConfig = (
195+ axisConfig : AxisConfig | undefined ,
196+ legacyTitle : string | undefined ,
197+ legacyMax : number | undefined ,
198+ appTheme : AppThemeType ,
199+ isHidden : boolean ,
200+ hideLabels : boolean = false ,
201+ ) : ScaleOptions < 'linear' > => {
202+ // Merge legacy props with new axis config (new config takes priority)
203+ const title = axisConfig ?. title || legacyTitle
204+ const max = axisConfig ?. max !== undefined ? axisConfig . max : legacyMax
205+ const hide = axisConfig ?. hide !== undefined ? axisConfig . hide : isHidden
206+
207+ return {
208+ display : ! hide ,
209+ min : axisConfig ?. min ,
210+ max,
211+ border : {
212+ color : CHART_AXIS_COLORS [ appTheme ] ,
213+ } ,
214+ grid : {
215+ color : CHART_GRID_LINES_COLORS [ appTheme ] ,
216+ } ,
217+ title : getScaleTickTitleConfig ( title || '' , appTheme ) ,
218+ ticks : {
219+ display : ! hideLabels && ! hide ,
220+ color : CHART_AXIS_LABELS_COLOR [ appTheme ] ,
221+ font : {
222+ family : "'IBM Plex Sans', 'Open Sans', 'Roboto'" ,
223+ size : 12 ,
224+ lineHeight : '150%' ,
225+ weight : 400 ,
226+ } ,
227+ stepSize : axisConfig ?. stepSize ,
228+ callback :
229+ axisConfig ?. labelFormatter ||
230+ ( ( value ) =>
231+ // Apply unit formatting if specified
232+ formatValueWithUnit ( value , axisConfig ) ) ,
233+ } ,
234+ }
235+ }
236+
176237// Get default options based on chart type
177238export const getDefaultOptions = ( {
178239 chartProps,
@@ -189,6 +250,8 @@ export const getDefaultOptions = ({
189250 yAxisMax,
190251 xScaleTitle,
191252 yScaleTitle,
253+ xAxisConfig,
254+ yAxisConfig,
192255 yScaleTickFormat,
193256 xScaleTickFormat,
194257 xAxisLabels,
@@ -249,54 +312,44 @@ export const getDefaultOptions = ({
249312 : { } ) ,
250313 }
251314
252- const commonScaleConfig = {
253- display : ! hideAxis ,
254- border : {
255- color : CHART_AXIS_COLORS [ appTheme ] ,
256- } ,
257- grid : {
258- color : CHART_GRID_LINES_COLORS [ appTheme ] ,
259- } ,
260- ticks : {
261- display : ! hideXAxisLabels ,
262- color : CHART_AXIS_LABELS_COLOR [ appTheme ] ,
263- font : {
264- family : "'IBM Plex Sans', 'Open Sans', 'Roboto'" ,
265- size : 12 ,
266- lineHeight : '150%' ,
267- weight : 400 ,
268- } ,
269- } ,
270- } satisfies ScaleOptions < 'linear' >
315+ // Create enhanced axis configurations
316+ const enhancedXAxisConfig = getEnhancedAxisConfig (
317+ xAxisConfig ,
318+ xScaleTitle ,
319+ xAxisMax ,
320+ appTheme ,
321+ hideAxis ,
322+ hideXAxisLabels ,
323+ )
271324
325+ const enhancedYAxisConfig = getEnhancedAxisConfig ( yAxisConfig , yScaleTitle , yAxisMax , appTheme , hideAxis , false )
326+
327+ // Apply legacy tick formatters if no custom formatter is provided in axis config
272328 const commonXScaleConfig = {
273- ...commonScaleConfig ,
274- max : xAxisMax ,
275- title : getScaleTickTitleConfig ( xScaleTitle , appTheme ) ,
329+ ...enhancedXAxisConfig ,
276330 ticks : {
277- ...commonScaleConfig . ticks ,
278- ...( ( type !== 'stackedBarHorizontal' && typeof xScaleTickFormat === 'function' ) ||
279- ( type === 'stackedBarHorizontal' && typeof yScaleTickFormat === 'function' )
331+ ...enhancedXAxisConfig . ticks ,
332+ autoSkip : false ,
333+ ...( ! xAxisConfig ?. labelFormatter &&
334+ ( ( type !== 'stackedBarHorizontal' && typeof xScaleTickFormat === 'function' ) ||
335+ ( type === 'stackedBarHorizontal' && typeof yScaleTickFormat === 'function' ) )
280336 ? {
281337 callback :
282338 type === 'stackedBarHorizontal'
283339 ? ( value , index ) => yScaleTickFormat ( Number ( value ) , index )
284340 : ( _ , index ) => xScaleTickFormat ( xAxisLabels [ index ] , index ) ,
285341 }
286342 : { } ) ,
287- autoSkip : false ,
288343 } ,
289344 } satisfies ScaleOptions < 'linear' >
290345
291346 const commonYScaleConfig = {
292- ...commonScaleConfig ,
293- max : yAxisMax ,
294- title : getScaleTickTitleConfig ( yScaleTitle , appTheme ) ,
295- // for stackedBarHorizon
347+ ...enhancedYAxisConfig ,
296348 ticks : {
297- ...commonScaleConfig . ticks ,
298- ...( ( type === 'stackedBarHorizontal' && typeof xScaleTickFormat === 'function' ) ||
299- ( type !== 'stackedBarHorizontal' && typeof yScaleTickFormat === 'function' )
349+ ...enhancedYAxisConfig . ticks ,
350+ ...( ! yAxisConfig ?. labelFormatter &&
351+ ( ( type === 'stackedBarHorizontal' && typeof xScaleTickFormat === 'function' ) ||
352+ ( type !== 'stackedBarHorizontal' && typeof yScaleTickFormat === 'function' ) )
300353 ? {
301354 callback :
302355 type !== 'stackedBarHorizontal'
0 commit comments