Skip to content

Commit

Permalink
[charts] Add dataIndex to series valueFormatter (#12745)
Browse files Browse the repository at this point in the history
Signed-off-by: Jose C Quintas Jr <juniorquintas@gmail.com>
Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com>
  • Loading branch information
JCQuintas and alexfauquette authored Apr 15, 2024
1 parent b540a36 commit 5c54c78
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 21 deletions.
6 changes: 3 additions & 3 deletions docs/data/charts/tooltip/Formatting.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export default function Formatting() {
<LineChart
{...lineChartsParams}
xAxis={[{ data: years, scaleType: 'time', valueFormatter: yearFormatter }]}
series={lineChartsParams.series.map((serie) => ({
...serie,
valueFormatter: currencyFormatter,
series={lineChartsParams.series.map((series) => ({
...series,
valueFormatter: (v) => (v === null ? '' : currencyFormatter(v)),
}))}
/>
);
Expand Down
6 changes: 3 additions & 3 deletions docs/data/charts/tooltip/Formatting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export default function Formatting() {
<LineChart
{...lineChartsParams}
xAxis={[{ data: years, scaleType: 'time', valueFormatter: yearFormatter }]}
series={lineChartsParams.series.map((serie) => ({
...serie,
valueFormatter: currencyFormatter,
series={lineChartsParams.series.map((series) => ({
...series,
valueFormatter: (v) => (v === null ? '' : currencyFormatter(v)),
}))}
/>
);
Expand Down
6 changes: 3 additions & 3 deletions docs/data/charts/tooltip/Formatting.tsx.preview
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<LineChart
{...lineChartsParams}
xAxis={[{ data: years, scaleType: 'time', valueFormatter: yearFormatter }]}
series={lineChartsParams.series.map((serie) => ({
...serie,
valueFormatter: currencyFormatter,
series={lineChartsParams.series.map((series) => ({
...series,
valueFormatter: (v) => (v === null ? '' : currencyFormatter(v)),
}))}
/>
38 changes: 38 additions & 0 deletions docs/data/charts/tooltip/SeriesFormatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from 'react';
import { PieChart } from '@mui/x-charts/PieChart';
import { legendClasses } from '@mui/x-charts';

const otherProps = {
width: 400,
height: 200,
sx: {
[`.${legendClasses.root}`]: {
transform: 'translate(20px, 0)',
},
},
};

const data = [
{ team: 'Amber Ants', rank: 3, points: 31 },
{ team: 'Eagle Warriors', rank: 1, points: 50 },
{ team: 'Elephant Trunk', rank: 4, points: 18 },
{ team: 'Jaguars', rank: 2, points: 37 },
{ team: 'Smooth Pandas', rank: 5, points: 6 },
];

export default function SeriesFormatter() {
return (
<PieChart
series={[
{
data: data.map((d) => ({ label: d.team, id: d.team, value: d.points })),
valueFormatter: (v, { dataIndex }) => {
const { rank } = data[dataIndex];
return `has ${v.value} points and is ranked ${rank}.`;
},
},
]}
{...otherProps}
/>
);
}
38 changes: 38 additions & 0 deletions docs/data/charts/tooltip/SeriesFormatter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from 'react';
import { PieChart, PieChartProps } from '@mui/x-charts/PieChart';
import { legendClasses } from '@mui/x-charts';

const otherProps: Partial<PieChartProps> = {
width: 400,
height: 200,
sx: {
[`.${legendClasses.root}`]: {
transform: 'translate(20px, 0)',
},
},
};

const data = [
{ team: 'Amber Ants', rank: 3, points: 31 },
{ team: 'Eagle Warriors', rank: 1, points: 50 },
{ team: 'Elephant Trunk', rank: 4, points: 18 },
{ team: 'Jaguars', rank: 2, points: 37 },
{ team: 'Smooth Pandas', rank: 5, points: 6 },
];

export default function SeriesFormatter() {
return (
<PieChart
series={[
{
data: data.map((d) => ({ label: d.team, id: d.team, value: d.points })),
valueFormatter: (v, { dataIndex }) => {
const { rank } = data[dataIndex];
return `has ${v.value} points and is ranked ${rank}.`;
},
},
]}
{...otherProps}
/>
);
}
12 changes: 12 additions & 0 deletions docs/data/charts/tooltip/SeriesFormatter.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<PieChart
series={[
{
data: data.map((d) => ({ label: d.team, id: d.team, value: d.points })),
valueFormatter: (v, { dataIndex }) => {
const { rank } = data[dataIndex];
return `has ${v.value} points and is ranked ${rank}.`;
},
},
]}
{...otherProps}
/>
8 changes: 8 additions & 0 deletions docs/data/charts/tooltip/tooltip.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ Here is a demo with:

{{"demo": "Formatting.js"}}

### Advanced formatting

The series `valueFormatter` provides a context as its second argument containing a `dataIndex` property which you can use to calculate other data-related values.

In the demo below you can notice we use `dataIndex` to add each team's rank in the tooltip.

{{"demo": "SeriesFormatter.js"}}

### Axis formatter

To modify how data is displayed in the axis use the `valueFormatter` property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function DefaultChartsAxisTooltipContent(props: ChartsAxisContentProps) {
.filter(isCartesianSeries)
.map(({ color, id, label, valueFormatter, data, getColor }) => {
// @ts-ignore
const formattedValue = valueFormatter(data[dataIndex] ?? null);
const formattedValue = valueFormatter(data[dataIndex] ?? null, { dataIndex });
if (formattedValue == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function DefaultChartsItemTooltipContent<T extends ChartSeriesType = ChartSeries
const value = series.data[itemData.dataIndex];
const formattedValue = (
series.valueFormatter as CommonSeriesType<typeof value>['valueFormatter']
)?.(value);
)?.(value, { dataIndex: itemData.dataIndex });
return (
<ChartsTooltipPaper sx={sx} className={classes.root}>
<ChartsTooltipTable className={classes.table}>
Expand Down
6 changes: 4 additions & 2 deletions packages/x-charts/src/PieChart/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ const formatter: Formatter<'pie'> = (params) => {
id: item.id ?? `auto-generated-pie-id-${seriesId}-${index}`,
...arcs[index],
}))
.map((item) => ({
.map((item, index) => ({
...item,
formattedValue: series[seriesId].valueFormatter?.(item) ?? item.value.toLocaleString(),
formattedValue:
series[seriesId].valueFormatter?.(item, { dataIndex: index }) ??
item.value.toLocaleString(),
})),
};
});
Expand Down
15 changes: 9 additions & 6 deletions packages/x-charts/src/internals/defaultizeValueFormatter.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { SeriesId } from '../models/seriesType/common';
import { SeriesId, SeriesValueFormatter } from '../models/seriesType/common';

function defaultizeValueFormatter<
ISeries extends { valueFormatter?: IFormatter },
IFormatter extends (v: any) => string,
TValue,
ISeries extends { valueFormatter?: SeriesValueFormatter<TValue> },
>(
series: Record<SeriesId, ISeries>,
defaultValueFormatter: IFormatter,
): Record<SeriesId, ISeries & { valueFormatter: IFormatter }> {
const defaultizedSeries: Record<SeriesId, ISeries & { valueFormatter: IFormatter }> = {};
defaultValueFormatter: SeriesValueFormatter<TValue>,
): Record<SeriesId, ISeries & { valueFormatter: SeriesValueFormatter<TValue> }> {
const defaultizedSeries: Record<
SeriesId,
ISeries & { valueFormatter: SeriesValueFormatter<TValue> }
> = {};
Object.keys(series).forEach((seriesId) => {
defaultizedSeries[seriesId] = {
...series[seriesId],
Expand Down
5 changes: 5 additions & 0 deletions packages/x-charts/src/models/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ interface AxisScaleComputedConfig {
};
}
export type AxisValueFormatterContext = {
/**
* Location indicates where the value will be displayed.
* - `'tick'` The value is displayed on the axis ticks.
* - `'tooltip'` The value is displayed in the tooltip when hovering the chart.
*/
location: 'tick' | 'tooltip';
};

Expand Down
17 changes: 15 additions & 2 deletions packages/x-charts/src/models/seriesType/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,28 @@ import type { StackOffsetType, StackOrderType } from '../stacking';

export type SeriesId = number | string;

export type SeriesValueFormatterContext = {
/**
* The index of the value in the data array.
*/
dataIndex: number;
};

export type SeriesValueFormatter<TValue> = (
value: TValue,
context: SeriesValueFormatterContext,
) => string;

export type CommonSeriesType<TValue> = {
id?: SeriesId;
color?: string;
/**
* Formatter used to render values in tooltip or other data display.
* @param {TValue} value The series' value to render.
* @returns {string} The string to dispaly.
* @param {SeriesValueFormatterContext} context The rendering context of the value.
* @returns {string} The string to display.
*/
valueFormatter?: <Value extends TValue>(value: Value) => string;
valueFormatter?: SeriesValueFormatter<TValue>;
highlightScope?: Partial<HighlightScope>;
};

Expand Down

0 comments on commit 5c54c78

Please sign in to comment.