diff --git a/src/__stories__/__data__/area/playground.ts b/src/__stories__/__data__/area/playground.ts
index 6913d1898..fe369cd96 100644
--- a/src/__stories__/__data__/area/playground.ts
+++ b/src/__stories__/__data__/area/playground.ts
@@ -22,7 +22,8 @@ function prepareData(): ChartData {
stacking: 'normal',
dataLabels: {
enabled: true,
- numberFormat: {
+ format: {
+ type: 'number',
precision: 2,
},
},
diff --git a/src/__stories__/__data__/bar-x/playground.ts b/src/__stories__/__data__/bar-x/playground.ts
index 387698d9a..211a39cbf 100644
--- a/src/__stories__/__data__/bar-x/playground.ts
+++ b/src/__stories__/__data__/bar-x/playground.ts
@@ -21,7 +21,7 @@ function prepareData(): ChartData {
borderRadius: 8,
dataLabels: {
enabled: true,
- numberFormat: {precision: 1},
+ format: {type: 'number', precision: 1},
},
},
],
diff --git a/src/__stories__/__data__/pie/continuous-legend.ts b/src/__stories__/__data__/pie/continuous-legend.ts
index 8a7e9ee19..2d8914d59 100644
--- a/src/__stories__/__data__/pie/continuous-legend.ts
+++ b/src/__stories__/__data__/pie/continuous-legend.ts
@@ -22,7 +22,7 @@ function prepareData(): ChartData {
type: 'pie',
data,
dataLabels: {
- numberFormat: {unit: 'auto'},
+ format: {type: 'number', unit: 'auto'},
},
},
],
@@ -37,6 +37,12 @@ function prepareData(): ChartData {
stops,
},
},
+ tooltip: {
+ valueFormat: {
+ type: 'number',
+ unit: 'k',
+ },
+ },
};
}
diff --git a/src/__stories__/__data__/radar/basic.ts b/src/__stories__/__data__/radar/basic.ts
index 1097b708c..d9ceb5d4c 100644
--- a/src/__stories__/__data__/radar/basic.ts
+++ b/src/__stories__/__data__/radar/basic.ts
@@ -33,6 +33,9 @@ function prepareData(): ChartData {
title: {
text: 'Heroes of Might and Magic 3 Units (dragons)',
},
+ tooltip: {
+ valueFormat: {type: 'number'},
+ },
};
}
diff --git a/src/__stories__/__data__/treemap/playground.ts b/src/__stories__/__data__/treemap/playground.ts
index 152c21cfc..0dc0a273d 100644
--- a/src/__stories__/__data__/treemap/playground.ts
+++ b/src/__stories__/__data__/treemap/playground.ts
@@ -8,7 +8,7 @@ const prepareData = (): ChartData => {
name: 'Example',
dataLabels: {
enabled: true,
- numberFormat: {precision: 1},
+ format: {type: 'number', precision: 1},
},
layoutAlgorithm: 'binary',
levels: [
diff --git a/src/__stories__/__data__/waterfall/playground.ts b/src/__stories__/__data__/waterfall/playground.ts
index 87d2955a5..441eb7685 100644
--- a/src/__stories__/__data__/waterfall/playground.ts
+++ b/src/__stories__/__data__/waterfall/playground.ts
@@ -24,7 +24,7 @@ function prepareData(): ChartData {
{total: true, x: 12},
],
name: 'Profit',
- dataLabels: {enabled: true, numberFormat: {precision: 2}},
+ dataLabels: {enabled: true, format: {type: 'number', precision: 2}},
},
],
},
diff --git a/src/components/Tooltip/ChartTooltipContent.tsx b/src/components/Tooltip/ChartTooltipContent.tsx
index ade52ddd3..fac3a5579 100644
--- a/src/components/Tooltip/ChartTooltipContent.tsx
+++ b/src/components/Tooltip/ChartTooltipContent.tsx
@@ -11,10 +11,11 @@ export interface ChartTooltipContentProps {
xAxis?: ChartXAxis;
yAxis?: ChartYAxis;
renderer?: ChartTooltip['renderer'];
+ valueFormat?: ChartTooltip['valueFormat'];
}
export const ChartTooltipContent = (props: ChartTooltipContentProps) => {
- const {hovered, xAxis, yAxis, renderer} = props;
+ const {hovered, xAxis, yAxis, renderer, valueFormat} = props;
if (!hovered) {
return null;
@@ -23,7 +24,7 @@ export const ChartTooltipContent = (props: ChartTooltipContentProps) => {
const customTooltip = renderer?.({hovered, xAxis, yAxis});
return isNil(customTooltip) ? (
-
+
) : (
customTooltip
);
diff --git a/src/components/Tooltip/DefaultContent.tsx b/src/components/Tooltip/DefaultContent.tsx
index ce26a5e88..d82422db5 100644
--- a/src/components/Tooltip/DefaultContent.tsx
+++ b/src/components/Tooltip/DefaultContent.tsx
@@ -14,9 +14,11 @@ import type {
TooltipDataChunkRadar,
TooltipDataChunkSankey,
TreemapSeriesData,
+ ValueFormat,
WaterfallSeriesData,
} from '../../types';
import {block, getDataCategoryValue, getWaterfallPointSubtotal} from '../../utils';
+import {getFormattedValue} from '../../utils/chart/format';
const b = block('tooltip');
@@ -24,6 +26,7 @@ type Props = {
hovered: TooltipDataChunk[];
xAxis?: ChartXAxis;
yAxis?: ChartYAxis;
+ valueFormat?: ValueFormat;
};
const DEFAULT_DATE_FORMAT = 'DD.MM.YY';
@@ -75,7 +78,7 @@ const getMeasureValue = (data: TooltipDataChunk[], xAxis?: ChartXAxis, yAxis?: C
return getXRowData(data[0]?.data, xAxis);
};
-export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
+export const DefaultContent = ({hovered, xAxis, yAxis, valueFormat}: Props) => {
const measureValue = getMeasureValue(hovered, xAxis, yAxis);
return (
@@ -91,9 +94,13 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
case 'line':
case 'area':
case 'bar-x': {
+ const formattedValue = getFormattedValue({
+ value: getYRowData(data, yAxis),
+ format: valueFormat,
+ });
const value = (
- {series.name}: {getYRowData(data, yAxis)}
+ {series.name}: {formattedValue}
);
return (
@@ -105,10 +112,18 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
}
case 'waterfall': {
const isTotal = get(data, 'total', false);
- const subTotal = getWaterfallPointSubtotal(
+ const subTotalValue = getWaterfallPointSubtotal(
data as WaterfallSeriesData,
series as PreparedWaterfallSeries,
);
+ const subTotal = getFormattedValue({
+ value: subTotalValue,
+ format: valueFormat,
+ });
+ const formattedValue = getFormattedValue({
+ value: getYRowData(data, yAxis),
+ format: valueFormat,
+ });
return (
@@ -119,7 +134,7 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
{series.name}
- {getYRowData(data, yAxis)}
+ {formattedValue}
)}
@@ -130,9 +145,13 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
);
}
case 'bar-y': {
+ const formattedValue = getFormattedValue({
+ value: getXRowData(data, xAxis),
+ format: valueFormat,
+ });
const value = (
- {series.name}: {getXRowData(data, xAxis)}
+ {series.name}: {formattedValue}
);
return (
@@ -145,18 +164,26 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
case 'pie':
case 'treemap': {
const seriesData = data as PreparedPieSeries | TreemapSeriesData;
+ const formattedValue = getFormattedValue({
+ value: seriesData.value,
+ format: valueFormat,
+ });
return (
{seriesData.name || seriesData.id}
-
{seriesData.value}
+
{formattedValue}
);
}
case 'sankey': {
const {target, data: source} = seriesItem as TooltipDataChunkSankey;
const value = source.links.find((d) => d.name === target?.name)?.value;
+ const formattedValue = getFormattedValue({
+ value,
+ format: valueFormat,
+ });
return (
@@ -165,7 +192,7 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
style={{backgroundColor: source.color}}
/>
- {source.name} → {target?.name}: {value}
+ {source.name} → {target?.name}: {formattedValue}
);
@@ -173,11 +200,15 @@ export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => {
case 'radar': {
const radarSeries = series as PreparedRadarSeries;
const seriesData = data as RadarSeriesData;
+ const formattedValue = getFormattedValue({
+ value: seriesData.value,
+ format: valueFormat,
+ });
const value = (
{radarSeries.name || radarSeries.id}
- {seriesData.value}
+ {formattedValue}
);
diff --git a/src/components/Tooltip/index.tsx b/src/components/Tooltip/index.tsx
index d82f5f189..83e062f1f 100644
--- a/src/components/Tooltip/index.tsx
+++ b/src/components/Tooltip/index.tsx
@@ -61,6 +61,7 @@ export const Tooltip = (props: TooltipProps) => {
xAxis={xAxis}
yAxis={yAxis as ChartYAxis}
renderer={tooltip.renderer}
+ valueFormat={tooltip.valueFormat}
/>
diff --git a/src/hooks/useSeries/prepare-area.ts b/src/hooks/useSeries/prepare-area.ts
index 331080368..30817c764 100644
--- a/src/hooks/useSeries/prepare-area.ts
+++ b/src/hooks/useSeries/prepare-area.ts
@@ -84,8 +84,7 @@ export function prepareArea(args: PrepareAreaSeriesArgs) {
padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
allowOverlap: get(series, 'dataLabels.allowOverlap', false),
html: get(series, 'dataLabels.html', false),
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
},
marker: prepareMarker(series, seriesOptions),
cursor: get(series, 'cursor', null),
diff --git a/src/hooks/useSeries/prepare-bar-x.ts b/src/hooks/useSeries/prepare-bar-x.ts
index 33c8b8729..816204937 100644
--- a/src/hooks/useSeries/prepare-bar-x.ts
+++ b/src/hooks/useSeries/prepare-bar-x.ts
@@ -45,8 +45,7 @@ export function prepareBarXSeries(args: PrepareBarXSeriesArgs): PreparedSeries[]
allowOverlap: series.dataLabels?.allowOverlap || false,
padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
html: get(series, 'dataLabels.html', false),
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
},
cursor: get(series, 'cursor', null),
yAxis: get(series, 'yAxis', 0),
diff --git a/src/hooks/useSeries/prepare-bar-y.ts b/src/hooks/useSeries/prepare-bar-y.ts
index dcc7256e0..02fef6db3 100644
--- a/src/hooks/useSeries/prepare-bar-y.ts
+++ b/src/hooks/useSeries/prepare-bar-y.ts
@@ -3,7 +3,7 @@ import get from 'lodash/get';
import type {BarYSeries, ChartSeriesOptions} from '../../types';
import {getLabelsSize, getUniqId} from '../../utils';
-import {getFormattedDataLabel} from '../useShapes/data-labels';
+import {getFormattedValue} from '../../utils/chart/format';
import {DEFAULT_DATALABELS_STYLE} from './constants';
import type {PreparedBarYSeries, PreparedLegend, PreparedSeries} from './types';
@@ -21,9 +21,7 @@ function prepareDataLabels(series: BarYSeries) {
const style = Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style);
const html = get(series, 'dataLabels.html', false);
const labels = enabled
- ? series.data.map((d) =>
- getFormattedDataLabel({value: d.x || d.label, ...series.dataLabels}),
- )
+ ? series.data.map((d) => getFormattedValue({value: d.x || d.label, ...series.dataLabels}))
: [];
const {maxHeight = 0, maxWidth = 0} = getLabelsSize({
labels,
@@ -39,8 +37,7 @@ function prepareDataLabels(series: BarYSeries) {
maxHeight,
maxWidth,
html,
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
};
}
diff --git a/src/hooks/useSeries/prepare-line.ts b/src/hooks/useSeries/prepare-line.ts
index f78cd2adf..7126c5616 100644
--- a/src/hooks/useSeries/prepare-line.ts
+++ b/src/hooks/useSeries/prepare-line.ts
@@ -116,8 +116,7 @@ export function prepareLineSeries(args: PrepareLineSeriesArgs) {
padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
allowOverlap: get(series, 'dataLabels.allowOverlap', false),
html: get(series, 'dataLabels.html', false),
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
},
marker: prepareMarker(series, seriesOptions),
dashStyle: dashStyle as DashStyle,
diff --git a/src/hooks/useSeries/prepare-pie.ts b/src/hooks/useSeries/prepare-pie.ts
index acc3973d1..d80f103cb 100644
--- a/src/hooks/useSeries/prepare-pie.ts
+++ b/src/hooks/useSeries/prepare-pie.ts
@@ -36,8 +36,7 @@ export function preparePieSeries(args: PreparePieSeriesArgs) {
distance: get(series, 'dataLabels.distance', 25),
connectorCurve: get(series, 'dataLabels.connectorCurve', 'basic'),
html: get(series, 'dataLabels.html', false),
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
},
label: dataItem.label,
value: dataItem.value,
diff --git a/src/hooks/useSeries/prepare-radar.ts b/src/hooks/useSeries/prepare-radar.ts
index dcbf37e98..391f45401 100644
--- a/src/hooks/useSeries/prepare-radar.ts
+++ b/src/hooks/useSeries/prepare-radar.ts
@@ -84,8 +84,7 @@ export function prepareRadarSeries(args: PrepareRadarSeriesArgs) {
padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
allowOverlap: get(series, 'dataLabels.allowOverlap', false),
html: get(series, 'dataLabels.html', false),
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
},
cursor: get(series, 'cursor', null),
marker: prepareMarker(series, seriesOptions),
diff --git a/src/hooks/useSeries/prepare-sankey.ts b/src/hooks/useSeries/prepare-sankey.ts
index 5969c83a5..9acadc39e 100644
--- a/src/hooks/useSeries/prepare-sankey.ts
+++ b/src/hooks/useSeries/prepare-sankey.ts
@@ -33,8 +33,7 @@ export function prepareSankeySeries(args: PrepareSankeySeriesArgs) {
dataLabels: {
enabled: get(s, 'dataLabels.enabled', true),
style: Object.assign({}, DEFAULT_DATALABELS_STYLE, s.dataLabels?.style),
- numberFormat: s.dataLabels?.numberFormat,
- dateFormat: s.dataLabels?.dateFormat,
+ format: s.dataLabels?.format,
},
id,
type: s.type,
diff --git a/src/hooks/useSeries/prepare-treemap.ts b/src/hooks/useSeries/prepare-treemap.ts
index 704e105c2..9272a6abd 100644
--- a/src/hooks/useSeries/prepare-treemap.ts
+++ b/src/hooks/useSeries/prepare-treemap.ts
@@ -34,8 +34,7 @@ export function prepareTreemap(args: PrepareTreemapSeriesArgs) {
allowOverlap: get(s, 'dataLabels.allowOverlap', false),
html: get(s, 'dataLabels.html', false),
align: get(s, 'dataLabels.align', 'left'),
- numberFormat: s.dataLabels?.numberFormat,
- dateFormat: s.dataLabels?.dateFormat,
+ format: s.dataLabels?.format,
},
id,
type: s.type,
diff --git a/src/hooks/useSeries/prepare-waterfall.ts b/src/hooks/useSeries/prepare-waterfall.ts
index 798415790..f18289d4a 100644
--- a/src/hooks/useSeries/prepare-waterfall.ts
+++ b/src/hooks/useSeries/prepare-waterfall.ts
@@ -42,8 +42,7 @@ export function prepareWaterfallSeries(args: PrepareWaterfallSeriesArgs): Prepar
allowOverlap: series.dataLabels?.allowOverlap || false,
padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
html: get(series, 'dataLabels.html', false),
- numberFormat: series.dataLabels?.numberFormat,
- dateFormat: series.dataLabels?.dateFormat,
+ format: series.dataLabels?.format,
},
cursor: get(series, 'cursor', null),
};
diff --git a/src/hooks/useSeries/types.ts b/src/hooks/useSeries/types.ts
index 0ec65cdf7..e15038839 100644
--- a/src/hooks/useSeries/types.ts
+++ b/src/hooks/useSeries/types.ts
@@ -32,10 +32,10 @@ import type {
SymbolLegendSymbolOptions,
TreemapSeries,
TreemapSeriesData,
+ ValueFormat,
WaterfallSeries,
WaterfallSeriesData,
} from '../../types';
-import type {FormatNumberOptions} from '../../types/formatter';
export type RectLegendSymbol = {
shape: 'rect';
@@ -151,8 +151,7 @@ export type PreparedBarXSeries = {
allowOverlap: boolean;
padding: number;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
borderRadius: number;
yAxis: number;
@@ -170,8 +169,7 @@ export type PreparedBarYSeries = {
maxHeight: number;
maxWidth: number;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
borderRadius: number;
} & BasePreparedSeries;
@@ -198,8 +196,7 @@ export type PreparedPieSeries = {
distance: number;
connectorCurve: ConnectorCurve;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
states: {
hover: {
@@ -220,8 +217,7 @@ export type PreparedLineSeries = {
padding: number;
allowOverlap: boolean;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
marker: {
states: {
@@ -260,8 +256,7 @@ export type PreparedAreaSeries = {
padding: number;
allowOverlap: boolean;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
marker: {
states: {
@@ -294,8 +289,7 @@ export type PreparedTreemapSeries = {
allowOverlap: boolean;
html: boolean;
align: Required['dataLabels']>['align'];
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
layoutAlgorithm: `${LayoutAlgorithm}`;
} & BasePreparedSeries &
@@ -310,8 +304,7 @@ export type PreparedWaterfallSeries = {
allowOverlap: boolean;
padding: number;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
positiveColor: string;
negativeColor: string;
@@ -323,8 +316,7 @@ export type PreparedSankeySeries = {
dataLabels: {
enabled: boolean;
style: BaseTextStyle;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
} & BasePreparedSeries &
Omit;
@@ -342,8 +334,7 @@ export type PreparedRadarSeries = {
padding: number;
allowOverlap: boolean;
html: boolean;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
+ format?: ValueFormat;
};
marker: {
states: {
diff --git a/src/hooks/useShapes/area/prepare-data.ts b/src/hooks/useShapes/area/prepare-data.ts
index 5f9b1999e..2613174f1 100644
--- a/src/hooks/useShapes/area/prepare-data.ts
+++ b/src/hooks/useShapes/area/prepare-data.ts
@@ -2,16 +2,16 @@ import {group, sort} from 'd3';
import type {AreaSeriesData, HtmlItem, LabelData} from '../../../types';
import {getDataCategoryValue, getLabelsSize, getLeftPosition} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {ChartScale} from '../../useAxisScales';
import type {PreparedAxis} from '../../useChartOptions/types';
import type {PreparedAreaSeries} from '../../useSeries/types';
-import {getFormattedDataLabel} from '../data-labels';
import {getXValue, getYValue} from '../utils';
import type {MarkerData, PointData, PreparedAreaData} from './types';
function getLabelData(point: PointData, series: PreparedAreaSeries, xMax: number) {
- const text = getFormattedDataLabel({
+ const text = getFormattedValue({
value: point.data.label || point.data.y,
...series.dataLabels,
});
diff --git a/src/hooks/useShapes/bar-x/prepare-data.ts b/src/hooks/useShapes/bar-x/prepare-data.ts
index 6833f60b3..ba4282698 100644
--- a/src/hooks/useShapes/bar-x/prepare-data.ts
+++ b/src/hooks/useShapes/bar-x/prepare-data.ts
@@ -4,11 +4,11 @@ import get from 'lodash/get';
import type {BarXSeriesData, LabelData} from '../../../types';
import {getDataCategoryValue, getLabelsSize} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {ChartScale} from '../../useAxisScales';
import type {PreparedAxis} from '../../useChartOptions/types';
import type {PreparedBarXSeries, PreparedSeriesOptions} from '../../useSeries/types';
import {MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH} from '../constants';
-import {getFormattedDataLabel} from '../data-labels';
import type {PreparedBarXData} from './types';
@@ -17,7 +17,7 @@ function getLabelData(d: PreparedBarXData): LabelData | undefined {
return undefined;
}
- const text = getFormattedDataLabel({
+ const text = getFormattedValue({
value: d.data.label || d.data.y,
...d.series.dataLabels,
});
diff --git a/src/hooks/useShapes/bar-y/prepare-data.ts b/src/hooks/useShapes/bar-y/prepare-data.ts
index 9db1a51df..4ca50a565 100644
--- a/src/hooks/useShapes/bar-y/prepare-data.ts
+++ b/src/hooks/useShapes/bar-y/prepare-data.ts
@@ -4,11 +4,11 @@ import get from 'lodash/get';
import type {BarYSeriesData, LabelData} from '../../../types';
import {getDataCategoryValue, getLabelsSize} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {ChartScale} from '../../useAxisScales';
import type {PreparedAxis} from '../../useChartOptions/types';
import type {PreparedBarYSeries, PreparedSeriesOptions} from '../../useSeries/types';
import {MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH} from '../constants';
-import {getFormattedDataLabel} from '../data-labels';
import type {PreparedBarYData} from './types';
@@ -78,7 +78,7 @@ function setLabel(prepared: PreparedBarYData) {
}
const data = prepared.data;
- const content = getFormattedDataLabel({value: data.label || data.x, ...dataLabels});
+ const content = getFormattedValue({value: data.label || data.x, ...dataLabels});
const {maxHeight: height, maxWidth: width} = getLabelsSize({
labels: [content],
style: dataLabels.style,
diff --git a/src/hooks/useShapes/data-labels.ts b/src/hooks/useShapes/data-labels.ts
deleted file mode 100644
index df1fc84e5..000000000
--- a/src/hooks/useShapes/data-labels.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import {dateTime} from '@gravity-ui/date-utils';
-
-import {formatNumber} from '../../libs';
-import type {FormatNumberOptions} from '../../types/formatter';
-
-export function getFormattedDataLabel(args: {
- value: string | number | undefined | null;
- dateFormat?: string;
- numberFormat?: FormatNumberOptions;
-}) {
- const {value, numberFormat, dateFormat} = args;
-
- const valueAsNumber = Number(value);
-
- if (dateFormat) {
- const date = dateTime({input: value});
- if (date?.isValid()) {
- return date.format(dateFormat);
- }
- }
-
- if (!Number.isNaN(valueAsNumber) && numberFormat) {
- return formatNumber(valueAsNumber, numberFormat);
- }
-
- return String(value);
-}
diff --git a/src/hooks/useShapes/line/prepare-data.ts b/src/hooks/useShapes/line/prepare-data.ts
index d9ae6a6d1..010dbea09 100644
--- a/src/hooks/useShapes/line/prepare-data.ts
+++ b/src/hooks/useShapes/line/prepare-data.ts
@@ -1,16 +1,16 @@
import type {HtmlItem, LabelData} from '../../../types';
import {getLabelsSize, getLeftPosition} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {ChartScale} from '../../useAxisScales';
import type {PreparedAxis} from '../../useChartOptions/types';
import type {PreparedLineSeries} from '../../useSeries/types';
import type {PreparedSplit} from '../../useSplit/types';
-import {getFormattedDataLabel} from '../data-labels';
import {getXValue, getYValue} from '../utils';
import type {MarkerData, PointData, PreparedLineData} from './types';
function getLabelData(point: PointData, series: PreparedLineSeries, xMax: number) {
- const text = getFormattedDataLabel({
+ const text = getFormattedValue({
value: point.data.label || point.data.y,
...series.dataLabels,
});
diff --git a/src/hooks/useShapes/pie/prepare-data.ts b/src/hooks/useShapes/pie/prepare-data.ts
index 8dd834265..dfd0a3516 100644
--- a/src/hooks/useShapes/pie/prepare-data.ts
+++ b/src/hooks/useShapes/pie/prepare-data.ts
@@ -8,8 +8,8 @@ import {
getLeftPosition,
isLabelsOverlapping,
} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {PreparedPieSeries} from '../../useSeries/types';
-import {getFormattedDataLabel} from '../data-labels';
import type {PieConnectorData, PieLabelData, PreparedPieData, SegmentData} from './types';
import {getCurveFactory, pieGenerator} from './utils';
@@ -149,7 +149,7 @@ export function preparePieData(args: Args): PreparedPieData[] {
series.forEach((d, index) => {
const prevLabel = labels[labels.length - 1];
- const text = getFormattedDataLabel({
+ const text = getFormattedValue({
value: d.data.label || d.data.value,
...d.dataLabels,
});
diff --git a/src/hooks/useShapes/radar/prepare-data.ts b/src/hooks/useShapes/radar/prepare-data.ts
index 022117efd..28c67928e 100644
--- a/src/hooks/useShapes/radar/prepare-data.ts
+++ b/src/hooks/useShapes/radar/prepare-data.ts
@@ -2,8 +2,8 @@ import {curveLinearClosed, line, range, scaleLinear} from 'd3';
import type {HtmlItem} from '../../../types';
import {getLabelsSize} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {PreparedRadarSeries} from '../../useSeries/types';
-import {getFormattedDataLabel} from '../data-labels';
import type {PreparedRadarData, RadarGridData, RadarMarkerData} from './types';
@@ -137,7 +137,7 @@ export function prepareRadarData(args: Args): PreparedRadarData[] {
const {style} = dataLabels;
const shouldUseHtml = dataLabels.html;
data.labels = categories.map((category, index) => {
- const text = getFormattedDataLabel({
+ const text = getFormattedValue({
value: category.key,
...dataLabels,
});
diff --git a/src/hooks/useShapes/sankey/prepare-data.ts b/src/hooks/useShapes/sankey/prepare-data.ts
index 30131c9e9..244bcae87 100644
--- a/src/hooks/useShapes/sankey/prepare-data.ts
+++ b/src/hooks/useShapes/sankey/prepare-data.ts
@@ -1,8 +1,8 @@
import {sankey, sankeyLinkHorizontal} from 'd3-sankey';
import type {HtmlItem, SankeySeriesData} from '../../../types';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {PreparedSankeySeries} from '../../useSeries/types';
-import {getFormattedDataLabel} from '../data-labels';
import type {PreparedSankeyData, SankeyDataLabel} from './types';
@@ -77,7 +77,7 @@ export function prepareSankeyData(args: {
const x1 = d.x1 ?? 0;
const y0 = d.y0 ?? 0;
const y1 = d.y1 ?? 0;
- const text = getFormattedDataLabel({value: d.name, ...dataLabels});
+ const text = getFormattedValue({value: d.name, ...dataLabels});
return {
text,
diff --git a/src/hooks/useShapes/treemap/prepare-data.ts b/src/hooks/useShapes/treemap/prepare-data.ts
index 20145157c..c950207d6 100644
--- a/src/hooks/useShapes/treemap/prepare-data.ts
+++ b/src/hooks/useShapes/treemap/prepare-data.ts
@@ -12,8 +12,8 @@ import type {HierarchyRectangularNode} from 'd3';
import {LayoutAlgorithm} from '../../../constants';
import type {HtmlItem, TreemapSeriesData} from '../../../types';
import {getLabelsSize} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {PreparedTreemapSeries} from '../../useSeries/types';
-import {getFormattedDataLabel} from '../data-labels';
import type {PreparedTreemapData, TreemapLabelData} from './types';
@@ -34,7 +34,7 @@ function getLabels(args: {
const texts = Array.isArray(d.data.name) ? d.data.name : [d.data.name];
texts.forEach((text, index) => {
- const label = getFormattedDataLabel({value: text, ...args.options});
+ const label = getFormattedValue({value: text, ...args.options});
const {maxHeight: lineHeight, maxWidth: labelWidth} =
getLabelsSize({labels: [label], html}) ?? {};
const left = d.x0 + padding;
diff --git a/src/hooks/useShapes/waterfall/prepare-data.ts b/src/hooks/useShapes/waterfall/prepare-data.ts
index 967fa7888..b845228b4 100644
--- a/src/hooks/useShapes/waterfall/prepare-data.ts
+++ b/src/hooks/useShapes/waterfall/prepare-data.ts
@@ -4,11 +4,11 @@ import sortBy from 'lodash/sortBy';
import type {LabelData, WaterfallSeriesData} from '../../../types';
import {getLabelsSize} from '../../../utils';
+import {getFormattedValue} from '../../../utils/chart/format';
import type {ChartScale} from '../../useAxisScales';
import type {PreparedAxis} from '../../useChartOptions/types';
import type {PreparedSeriesOptions, PreparedWaterfallSeries} from '../../useSeries/types';
import {MIN_BAR_GAP, MIN_BAR_WIDTH} from '../constants';
-import {getFormattedDataLabel} from '../data-labels';
import {getXValue, getYValue} from '../utils';
import type {PreparedWaterfallData} from './types';
@@ -18,7 +18,7 @@ function getLabelData(d: PreparedWaterfallData, plotHeight: number): LabelData |
return undefined;
}
- const text = getFormattedDataLabel({value: d.data.label || d.subTotal, ...d.series.dataLabels});
+ const text = getFormattedValue({value: d.data.label || d.subTotal, ...d.series.dataLabels});
const style = d.series.dataLabels.style;
const {maxHeight: height, maxWidth: width} = getLabelsSize({labels: [text], style});
diff --git a/src/types/chart/base.ts b/src/types/chart/base.ts
index 1233a1988..2cc5b8237 100644
--- a/src/types/chart/base.ts
+++ b/src/types/chart/base.ts
@@ -1,6 +1,15 @@
import type {FormatNumberOptions} from '../formatter';
import type {MeaningfulAny} from '../misc';
+type NumberFormat = {
+ type: 'number';
+} & FormatNumberOptions;
+type DateFormat = {
+ type: 'date';
+ format?: string;
+};
+export type ValueFormat = NumberFormat | DateFormat;
+
export interface BaseSeries {
/** Initial visibility of the series */
visible?: boolean;
@@ -29,10 +38,8 @@ export interface BaseSeries {
* @default false
* */
html?: boolean;
- /** If specified, label formatting is applied with the selected date format. */
- dateFormat?: string;
- /** Formatting settings for numeric values */
- numberFormat?: FormatNumberOptions;
+ /** Formatting settings for labels. */
+ format?: ValueFormat;
};
/** You can set the cursor to "pointer" if you have click events attached to the series, to signal to the user that the points and lines can be clicked. */
cursor?: string;
diff --git a/src/types/chart/tooltip.ts b/src/types/chart/tooltip.ts
index 8587b0c35..71e92f2d7 100644
--- a/src/types/chart/tooltip.ts
+++ b/src/types/chart/tooltip.ts
@@ -4,6 +4,7 @@ import type {AreaSeries, AreaSeriesData} from './area';
import type {ChartXAxis, ChartYAxis} from './axis';
import type {BarXSeries, BarXSeriesData} from './bar-x';
import type {BarYSeries, BarYSeriesData} from './bar-y';
+import type {ValueFormat} from './base';
import type {LineSeries, LineSeriesData} from './line';
import type {PieSeries, PieSeriesData} from './pie';
import type {RadarSeries, RadarSeriesCategory, RadarSeriesData} from './radar';
@@ -110,4 +111,6 @@ export interface ChartTooltip {
};
/** Show tooltip at most once per every ```throttle``` milliseconds */
throttle?: number;
+ /** Formatting settings for tooltip value. */
+ valueFormat?: ValueFormat;
}
diff --git a/src/utils/chart/format.ts b/src/utils/chart/format.ts
new file mode 100644
index 000000000..e0469a9de
--- /dev/null
+++ b/src/utils/chart/format.ts
@@ -0,0 +1,25 @@
+import {dateTime} from '@gravity-ui/date-utils';
+
+import {formatNumber} from '../../libs';
+import type {ValueFormat} from '../../types';
+
+export function getFormattedValue(args: {
+ value: string | number | undefined | null;
+ format?: ValueFormat;
+}) {
+ const {value, format} = args;
+
+ switch (format?.type) {
+ case 'number': {
+ return formatNumber(Number(value), format);
+ }
+ case 'date': {
+ const date = dateTime({input: value});
+ if (date?.isValid()) {
+ return date.format(format.format);
+ }
+ }
+ }
+
+ return String(value);
+}