Skip to content

Commit

Permalink
[charts] Support BarChart with Date data (#13471)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfauquette authored Jun 26, 2024
1 parent 7128911 commit b285e50
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 5 deletions.
6 changes: 4 additions & 2 deletions docs/pages/x/api/charts/axis-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" } },
Expand Down
24 changes: 23 additions & 1 deletion packages/x-charts/src/context/CartesianProvider/computeValue.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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();
Expand All @@ -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`.
Expand Down
6 changes: 5 additions & 1 deletion packages/x-charts/src/hooks/useTicks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion packages/x-charts/src/models/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit b285e50

Please sign in to comment.