diff --git a/docs/pages/x/api/charts/axis-config.json b/docs/pages/x/api/charts/axis-config.json index 8f826848b2868..a3b887bf9d81d 100644 --- a/docs/pages/x/api/charts/axis-config.json +++ b/docs/pages/x/api/charts/axis-config.json @@ -3,8 +3,10 @@ "imports": ["import { AxisConfig } from '@mui/x-charts'"], "properties": { "id": { "type": { "description": "AxisId" }, "required": true }, - "scaleType": { "type": { "description": "'linear'" }, "required": true }, - "colorMap": { "type": { "description": "ContinuousColorConfig | PiecewiseColorConfig" } }, + "scaleType": { "type": { "description": "'band'" }, "required": true }, + "colorMap": { + "type": { "description": "OrdinalColorConfig | ContinuousColorConfig | PiecewiseColorConfig" } + }, "data": { "type": { "description": "V[]" } }, "dataKey": { "type": { "description": "string" } }, "hideTooltip": { "type": { "description": "boolean" } }, diff --git a/packages/x-charts/src/context/CartesianProvider/computeValue.ts b/packages/x-charts/src/context/CartesianProvider/computeValue.ts index 053b51cf1afd6..b9125a212ffef 100644 --- a/packages/x-charts/src/context/CartesianProvider/computeValue.ts +++ b/packages/x-charts/src/context/CartesianProvider/computeValue.ts @@ -1,4 +1,4 @@ -import { scaleBand, scalePoint } from 'd3-scale'; +import { scaleBand, scalePoint, scaleTime } from 'd3-scale'; import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../../constants'; import { AxisConfig, ScaleName } from '../../models'; import { @@ -27,6 +27,18 @@ const getRange = (drawingArea: DrawingArea, axisName: 'x' | 'y', isReverse?: boo return isReverse ? range.reverse() : range; }; +const isDateData = (data?: any[]): data is Date[] => data?.[0] instanceof Date; + +function createDateFormatter( + axis: AxisConfig<'band' | 'point', any, ChartsAxisProps>, + range: number[], +): AxisConfig<'band' | 'point', any, ChartsAxisProps>['valueFormatter'] { + const timeScale = scaleTime(axis.data!, range); + + return (v, { location }) => + location === 'tick' ? timeScale.tickFormat(axis.tickNumber)(v) : `${v.toLocaleString()}`; +} + const DEFAULT_CATEGORY_GAP_RATIO = 0.2; const DEFAULT_BAR_GAP_RATIO = 0.1; @@ -99,6 +111,11 @@ export function computeValue( ? getOrdinalColorScale({ values: axis.data, ...axis.colorMap }) : getColorScale(axis.colorMap)), }; + + if (isDateData(axis.data)) { + const dateFormatter = createDateFormatter(axis, scaleRange); + completeAxis[axis.id].valueFormatter = axis.valueFormatter ?? dateFormatter; + } } if (isPointScaleConfig(axis)) { const scaleRange = axisName === 'x' ? range : [...range].reverse(); @@ -113,6 +130,11 @@ export function computeValue( ? getOrdinalColorScale({ values: axis.data, ...axis.colorMap }) : getColorScale(axis.colorMap)), }; + + if (isDateData(axis.data)) { + const dateFormatter = createDateFormatter(axis, scaleRange); + completeAxis[axis.id].valueFormatter = axis.valueFormatter ?? dateFormatter; + } } if (axis.scaleType === 'band' || axis.scaleType === 'point') { // Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`. diff --git a/packages/x-charts/src/hooks/useTicks.ts b/packages/x-charts/src/hooks/useTicks.ts index 8049ebe780d16..ecc42b5727fea 100644 --- a/packages/x-charts/src/hooks/useTicks.ts +++ b/packages/x-charts/src/hooks/useTicks.ts @@ -101,8 +101,12 @@ export function useTicks( if (scale.bandwidth() > 0) { // scale type = 'band' + const filteredDomain = + (typeof tickInterval === 'function' && domain.filter(tickInterval)) || + (typeof tickInterval === 'object' && tickInterval) || + domain; return [ - ...domain.map((value) => ({ + ...filteredDomain.map((value) => ({ value, formattedValue: valueFormatter?.(value, { location: 'tick' }) ?? `${value}`, offset: diff --git a/packages/x-charts/src/models/axis.ts b/packages/x-charts/src/models/axis.ts index 2ca13a4836ffb..651612e1ec52b 100644 --- a/packages/x-charts/src/models/axis.ts +++ b/packages/x-charts/src/models/axis.ts @@ -156,7 +156,7 @@ export interface ChartsXAxisProps extends ChartsAxisProps { position?: 'top' | 'bottom'; } -export type ScaleName = 'linear' | 'band' | 'point' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'; +export type ScaleName = keyof AxisScaleConfig; export type ContinuousScaleName = 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'; export interface AxisScaleConfig {