@gravity-ui/charts 1.11.4 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/Axis/AxisX.js +62 -36
- package/dist/cjs/components/Axis/AxisY.js +67 -31
- package/dist/cjs/components/ChartInner/styles.css +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +15 -9
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +1 -0
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +3 -3
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.d.ts +9 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.js +10 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/RowTotals.d.ts +9 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/RowTotals.js +23 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.d.ts +11 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +102 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.d.ts +30 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +126 -0
- package/dist/cjs/components/Tooltip/index.js +1 -1
- package/dist/cjs/components/Tooltip/styles.css +14 -2
- package/dist/cjs/components/Tooltip/utils.d.ts +30 -0
- package/dist/cjs/components/Tooltip/utils.js +126 -0
- package/dist/cjs/constants/axis.d.ts +6 -0
- package/dist/cjs/constants/axis.js +6 -0
- package/dist/cjs/constants/index.d.ts +6 -4
- package/dist/cjs/constants/index.js +6 -4
- package/dist/cjs/constants/tooltip.d.ts +3 -0
- package/dist/cjs/constants/tooltip.js +3 -0
- package/dist/cjs/hooks/useAxisScales/index.d.ts +14 -3
- package/dist/cjs/hooks/useAxisScales/index.js +86 -22
- package/dist/cjs/hooks/useChartOptions/types.d.ts +5 -0
- package/dist/cjs/hooks/useChartOptions/utils.d.ts +11 -0
- package/dist/cjs/hooks/useChartOptions/utils.js +27 -0
- package/dist/cjs/hooks/useChartOptions/x-axis.js +6 -2
- package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +4 -2
- package/dist/cjs/hooks/useChartOptions/y-axis.js +14 -4
- package/dist/cjs/hooks/useSeries/prepare-area.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +3 -0
- package/dist/cjs/hooks/useSeries/prepare-bar-y.js +5 -2
- package/dist/cjs/hooks/useSeries/prepare-line.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-radar.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/types.d.ts +3 -0
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +16 -13
- package/dist/cjs/hooks/useShapes/bar-y/index.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-y/index.js +5 -9
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +80 -107
- package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +7 -2
- package/dist/cjs/hooks/useShapes/index.js +1 -1
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +1 -1
- package/dist/cjs/hooks/utils/bar-y.d.ts +27 -0
- package/dist/cjs/hooks/utils/bar-y.js +55 -0
- package/dist/cjs/hooks/utils/index.d.ts +1 -0
- package/dist/cjs/hooks/utils/index.js +1 -0
- package/dist/cjs/i18n/keysets/en.json +7 -1
- package/dist/cjs/i18n/keysets/ru.json +7 -1
- package/dist/cjs/types/chart/axis.d.ts +15 -3
- package/dist/cjs/types/chart/bar-y.d.ts +10 -0
- package/dist/cjs/types/chart/series.d.ts +10 -0
- package/dist/cjs/types/chart/tooltip.d.ts +21 -0
- package/dist/cjs/utils/chart/axis-generators/bottom.js +26 -13
- package/dist/cjs/utils/chart/get-closest-data.js +13 -12
- package/dist/cjs/utils/chart/index.js +1 -1
- package/dist/cjs/utils/chart/series/sorting.d.ts +6 -2
- package/dist/cjs/utils/chart/series/sorting.js +29 -4
- package/dist/cjs/utils/chart/zoom.js +2 -1
- package/dist/cjs/validation/index.js +55 -1
- package/dist/esm/components/Axis/AxisX.js +62 -36
- package/dist/esm/components/Axis/AxisY.js +67 -31
- package/dist/esm/components/ChartInner/styles.css +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +15 -9
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +1 -0
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +3 -3
- package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.d.ts +9 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.js +10 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/RowTotals.d.ts +9 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/RowTotals.js +23 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.d.ts +11 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +102 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.d.ts +30 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +126 -0
- package/dist/esm/components/Tooltip/index.js +1 -1
- package/dist/esm/components/Tooltip/styles.css +14 -2
- package/dist/esm/components/Tooltip/utils.d.ts +30 -0
- package/dist/esm/components/Tooltip/utils.js +126 -0
- package/dist/esm/constants/axis.d.ts +6 -0
- package/dist/esm/constants/axis.js +6 -0
- package/dist/esm/constants/index.d.ts +6 -4
- package/dist/esm/constants/index.js +6 -4
- package/dist/esm/constants/tooltip.d.ts +3 -0
- package/dist/esm/constants/tooltip.js +3 -0
- package/dist/esm/hooks/useAxisScales/index.d.ts +14 -3
- package/dist/esm/hooks/useAxisScales/index.js +86 -22
- package/dist/esm/hooks/useChartOptions/types.d.ts +5 -0
- package/dist/esm/hooks/useChartOptions/utils.d.ts +11 -0
- package/dist/esm/hooks/useChartOptions/utils.js +27 -0
- package/dist/esm/hooks/useChartOptions/x-axis.js +6 -2
- package/dist/esm/hooks/useChartOptions/y-axis.d.ts +4 -2
- package/dist/esm/hooks/useChartOptions/y-axis.js +14 -4
- package/dist/esm/hooks/useSeries/prepare-area.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +3 -0
- package/dist/esm/hooks/useSeries/prepare-bar-y.js +5 -2
- package/dist/esm/hooks/useSeries/prepare-line.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-radar.d.ts +1 -1
- package/dist/esm/hooks/useSeries/types.d.ts +3 -0
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +16 -13
- package/dist/esm/hooks/useShapes/bar-y/index.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-y/index.js +5 -9
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +80 -107
- package/dist/esm/hooks/useShapes/bar-y/types.d.ts +7 -2
- package/dist/esm/hooks/useShapes/index.js +1 -1
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +1 -1
- package/dist/esm/hooks/utils/bar-y.d.ts +27 -0
- package/dist/esm/hooks/utils/bar-y.js +55 -0
- package/dist/esm/hooks/utils/index.d.ts +1 -0
- package/dist/esm/hooks/utils/index.js +1 -0
- package/dist/esm/i18n/keysets/en.json +7 -1
- package/dist/esm/i18n/keysets/ru.json +7 -1
- package/dist/esm/types/chart/axis.d.ts +15 -3
- package/dist/esm/types/chart/bar-y.d.ts +10 -0
- package/dist/esm/types/chart/series.d.ts +10 -0
- package/dist/esm/types/chart/tooltip.d.ts +21 -0
- package/dist/esm/utils/chart/axis-generators/bottom.js +26 -13
- package/dist/esm/utils/chart/get-closest-data.js +13 -12
- package/dist/esm/utils/chart/index.js +1 -1
- package/dist/esm/utils/chart/series/sorting.d.ts +6 -2
- package/dist/esm/utils/chart/series/sorting.js +29 -4
- package/dist/esm/utils/chart/zoom.js +2 -1
- package/dist/esm/validation/index.js +55 -1
- package/package.json +1 -1
- package/dist/cjs/components/Tooltip/DefaultContent.d.ts +0 -10
- package/dist/cjs/components/Tooltip/DefaultContent.js +0 -187
- package/dist/esm/components/Tooltip/DefaultContent.d.ts +0 -10
- package/dist/esm/components/Tooltip/DefaultContent.js +0 -187
- /package/dist/cjs/hooks/{useShapes/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/cjs/hooks/{useShapes/constants.js → constants.js} +0 -0
- /package/dist/esm/hooks/{useShapes/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/esm/hooks/{useShapes/constants.js → constants.js} +0 -0
|
@@ -2,7 +2,7 @@ import get from 'lodash/get';
|
|
|
2
2
|
import sortBy from 'lodash/sortBy';
|
|
3
3
|
import { getLabelsSize } from '../../../utils';
|
|
4
4
|
import { getFormattedValue } from '../../../utils/chart/format';
|
|
5
|
-
import { MIN_BAR_GAP, MIN_BAR_WIDTH } from '
|
|
5
|
+
import { MIN_BAR_GAP, MIN_BAR_WIDTH } from '../../constants';
|
|
6
6
|
import { getXValue, getYValue } from '../utils';
|
|
7
7
|
async function getLabelData(d, plotHeight) {
|
|
8
8
|
var _a, _b;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BarYSeries, BarYSeriesData } from '../../types';
|
|
2
|
+
import type { ChartScale } from '../useAxisScales';
|
|
3
|
+
import type { PreparedAxis } from '../useChartOptions/types';
|
|
4
|
+
import type { PreparedBarYSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
5
|
+
export declare function groupBarYDataByYValue<T extends BarYSeries | PreparedBarYSeries>(series: T[], yAxis: PreparedAxis[]): Record<string | number, Record<string, {
|
|
6
|
+
data: BarYSeriesData;
|
|
7
|
+
series: T;
|
|
8
|
+
}[]>>;
|
|
9
|
+
export declare function getBarYLayoutForNumericScale(args: {
|
|
10
|
+
plotHeight: number;
|
|
11
|
+
seriesOptions: PreparedSeriesOptions;
|
|
12
|
+
groupedData: ReturnType<typeof groupBarYDataByYValue>;
|
|
13
|
+
}): {
|
|
14
|
+
bandSize: number;
|
|
15
|
+
barGap: number;
|
|
16
|
+
barSize: number;
|
|
17
|
+
dataLength: number;
|
|
18
|
+
};
|
|
19
|
+
export declare function getBarYLayoutForCategoryScale(args: {
|
|
20
|
+
groupedData: ReturnType<typeof groupBarYDataByYValue>;
|
|
21
|
+
seriesOptions: PreparedSeriesOptions;
|
|
22
|
+
yScale: ChartScale;
|
|
23
|
+
}): {
|
|
24
|
+
bandSize: number;
|
|
25
|
+
barGap: number;
|
|
26
|
+
barSize: number;
|
|
27
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { max } from 'd3';
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import { getDataCategoryValue } from '../../utils';
|
|
4
|
+
import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../constants';
|
|
5
|
+
import { getSeriesStackId } from '../useSeries/utils';
|
|
6
|
+
export function groupBarYDataByYValue(series, yAxis) {
|
|
7
|
+
const data = {};
|
|
8
|
+
series.forEach((s) => {
|
|
9
|
+
s.data.forEach((d) => {
|
|
10
|
+
const axisIndex = get(s, 'yAxis', 0);
|
|
11
|
+
const seriesYAxis = yAxis[axisIndex];
|
|
12
|
+
const categories = get(seriesYAxis, 'categories', []);
|
|
13
|
+
const key = seriesYAxis.type === 'category'
|
|
14
|
+
? getDataCategoryValue({ axisDirection: 'y', categories, data: d })
|
|
15
|
+
: d.y;
|
|
16
|
+
if (key) {
|
|
17
|
+
if (!data[key]) {
|
|
18
|
+
data[key] = {};
|
|
19
|
+
}
|
|
20
|
+
const stackId = getSeriesStackId(s);
|
|
21
|
+
if (!data[key][stackId]) {
|
|
22
|
+
data[key][stackId] = [];
|
|
23
|
+
}
|
|
24
|
+
data[key][stackId].push({ data: d, series: s });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return data;
|
|
29
|
+
}
|
|
30
|
+
export function getBarYLayoutForNumericScale(args) {
|
|
31
|
+
const { plotHeight, groupedData, seriesOptions } = args;
|
|
32
|
+
const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth');
|
|
33
|
+
const barPadding = get(seriesOptions, 'bar-y.barPadding');
|
|
34
|
+
const groupPadding = get(seriesOptions, 'bar-y.groupPadding');
|
|
35
|
+
const dataLength = Object.values(groupedData).reduce((sum, items) => sum + Object.keys(items).length, 0);
|
|
36
|
+
const bandSize = plotHeight / dataLength;
|
|
37
|
+
const groupGap = Math.max(bandSize * groupPadding, MIN_BAR_GROUP_GAP);
|
|
38
|
+
const groupSize = bandSize - groupGap;
|
|
39
|
+
const barGap = Math.max(bandSize * barPadding, MIN_BAR_GAP);
|
|
40
|
+
const barSize = Math.max(MIN_BAR_WIDTH, Math.min(groupSize - barGap, barMaxWidth));
|
|
41
|
+
return { bandSize, barGap, barSize, dataLength };
|
|
42
|
+
}
|
|
43
|
+
export function getBarYLayoutForCategoryScale(args) {
|
|
44
|
+
const { groupedData, seriesOptions, yScale } = args;
|
|
45
|
+
const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth');
|
|
46
|
+
const barPadding = get(seriesOptions, 'bar-y.barPadding');
|
|
47
|
+
const groupPadding = get(seriesOptions, 'bar-y.groupPadding');
|
|
48
|
+
const bandSize = yScale.bandwidth();
|
|
49
|
+
const maxGroupSize = max(Object.values(groupedData), (d) => Object.values(d).length) || 1;
|
|
50
|
+
const groupGap = Math.max(bandSize * groupPadding, MIN_BAR_GROUP_GAP);
|
|
51
|
+
const groupSize = bandSize - groupGap;
|
|
52
|
+
const barGap = Math.max(bandSize * barPadding, MIN_BAR_GAP);
|
|
53
|
+
const barSize = Math.max(MIN_BAR_WIDTH, Math.min(groupSize / maxGroupSize - barGap, barMaxWidth));
|
|
54
|
+
return { bandSize, barGap, barSize };
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './bar-y';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './bar-y';
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
"label_invalid-treemap-missing-value": "It seems you are trying to use node without \"value\". Check node with this properties: { id: \"{{id}}\", name: \"{{name}}\" }",
|
|
14
14
|
"label_invalid-y-axis-index": "It seems you are trying to use inappropriate index for Y axis: \"{{index}}\"",
|
|
15
15
|
"label_invalid-axis-plot-band-option": "It seems you are trying to use inappropriate type for \"{{axis}}\" axis plot band option: \"{{option}}\"",
|
|
16
|
-
"label_axis-plot-band-options-not-equal": "It seems you are trying to use different type for \"{{axis}}\" axis plot band options"
|
|
16
|
+
"label_axis-plot-band-options-not-equal": "It seems you are trying to use different type for \"{{axis}}\" axis plot band options",
|
|
17
|
+
"label_invalid-tooltip-totals-aggregation-type": "It seems you are trying to use inappropriate data type for \"tooltip.totals.aggregation\". Available types: string, function.",
|
|
18
|
+
"label_invalid-tooltip-totals-aggregation-type-str": "It seems you are trying to use inappropriate value for built-in \"tooltip.totals.aggregation\". Available values: [{{values}}].",
|
|
19
|
+
"label_invalid-axis-type": "It seems you are trying to use inappropriate type for \"{{key}}\" axis. Available types: [{{values}}]."
|
|
20
|
+
},
|
|
21
|
+
"tooltip": {
|
|
22
|
+
"label_totals_sum": "Sum"
|
|
17
23
|
}
|
|
18
24
|
}
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
"label_invalid-treemap-missing-value": "Похоже, что вы пытаетесь использовать узел без значения \"value\". Проверьте узел с этими свойствами: { id: \"{{id}}\", name: \"{{name}}\" }",
|
|
14
14
|
"label_invalid-y-axis-index": "Похоже, что вы пытаетесь использовать некорректный индекс для оси Y: \"{{index}}\"",
|
|
15
15
|
"label_invalid-axis-plot-band-option": "Похоже, что вы пытаетесь использовать некорректный тип для параметра полосы: \"{{option}}\" для оси \"{{axis}}\"",
|
|
16
|
-
"label_axis-plot-band-options-not-equal": "Похоже, что вы пытаетесь использовать разные типы для для параметра полосы для оси \"{{axis}}\""
|
|
16
|
+
"label_axis-plot-band-options-not-equal": "Похоже, что вы пытаетесь использовать разные типы для для параметра полосы для оси \"{{axis}}\"",
|
|
17
|
+
"label_invalid-tooltip-totals-aggregation-type": "Похоже, что вы пытаетесь использовать некорректный тип данных для \"tooltip.totals.aggregation\". Доступные типы: string, function.",
|
|
18
|
+
"label_invalid-tooltip-totals-aggregation-type-str": "Похоже, что вы пытаетесь использовать некорректное значение для встроенной агрегации \"tooltip.totals.aggregation\". Доступные значения: [{{values}}].",
|
|
19
|
+
"label_invalid-axis-type": "Похоже, что вы пытаетесь использовать некорректный тип для оси \"{{key}}\". Доступные типы: [{{values}}]."
|
|
20
|
+
},
|
|
21
|
+
"tooltip": {
|
|
22
|
+
"label_totals_sum": "Сумма"
|
|
17
23
|
}
|
|
18
24
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { DashStyle } from '../../constants';
|
|
1
|
+
import type { AXIS_TYPE, DashStyle } from '../../constants';
|
|
2
2
|
import type { FormatNumberOptions } from '../formatter';
|
|
3
3
|
import type { BaseTextStyle } from './base';
|
|
4
|
-
export type ChartAxisType =
|
|
4
|
+
export type ChartAxisType = (typeof AXIS_TYPE)[keyof typeof AXIS_TYPE];
|
|
5
5
|
export type ChartAxisTitleAlignment = 'left' | 'center' | 'right';
|
|
6
6
|
export interface ChartAxisLabels {
|
|
7
7
|
/** Enable or disable the axis labels. */
|
|
@@ -78,6 +78,10 @@ export interface ChartAxis {
|
|
|
78
78
|
plotBands?: AxisPlotBand[];
|
|
79
79
|
/** Whether axis, including axis title, line, ticks and labels, should be visible. */
|
|
80
80
|
visible?: boolean;
|
|
81
|
+
/** Setting the order of the axis values. It is not applied by default.
|
|
82
|
+
* the "reverse" value is needed to use the reverse order without sorting
|
|
83
|
+
*/
|
|
84
|
+
order?: 'sortAsc' | 'sortDesc' | 'reverse';
|
|
81
85
|
}
|
|
82
86
|
export interface ChartXAxis extends ChartAxis {
|
|
83
87
|
}
|
|
@@ -92,6 +96,14 @@ export interface AxisPlot {
|
|
|
92
96
|
* @default 1
|
|
93
97
|
* */
|
|
94
98
|
opacity?: number;
|
|
99
|
+
label?: {
|
|
100
|
+
text: string;
|
|
101
|
+
style?: Partial<BaseTextStyle>;
|
|
102
|
+
/** The pixel padding for label.
|
|
103
|
+
* @default 5
|
|
104
|
+
*/
|
|
105
|
+
padding?: number;
|
|
106
|
+
};
|
|
95
107
|
}
|
|
96
108
|
export interface AxisPlotLine extends AxisPlot {
|
|
97
109
|
/** The position of the line in axis units. */
|
|
@@ -121,7 +133,7 @@ export interface AxisPlotBand extends AxisPlot {
|
|
|
121
133
|
*/
|
|
122
134
|
to: number | string;
|
|
123
135
|
}
|
|
124
|
-
export interface AxisCrosshair extends Omit<AxisPlotLine, 'value'> {
|
|
136
|
+
export interface AxisCrosshair extends Omit<AxisPlotLine, 'value' | 'label'> {
|
|
125
137
|
/** Whether the crosshair should snap to the point or follow the pointer independent of points.
|
|
126
138
|
* @default true
|
|
127
139
|
*/
|
|
@@ -29,6 +29,16 @@ export interface BarYSeries<T = MeaningfulAny> extends BaseSeries {
|
|
|
29
29
|
name: string;
|
|
30
30
|
/** The main color of the series (hex, rgba) */
|
|
31
31
|
color?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The width of the border surrounding each bar.
|
|
34
|
+
*
|
|
35
|
+
* @default 0
|
|
36
|
+
*/
|
|
37
|
+
borderWidth?: number;
|
|
38
|
+
/**
|
|
39
|
+
* The color of the border surrounding each bar.
|
|
40
|
+
*/
|
|
41
|
+
borderColor?: string;
|
|
32
42
|
/**
|
|
33
43
|
* The corner radius of the border surrounding each bar.
|
|
34
44
|
* @default 0
|
|
@@ -115,6 +115,16 @@ export interface ChartSeriesOptions {
|
|
|
115
115
|
* @default 0.2
|
|
116
116
|
*/
|
|
117
117
|
groupPadding?: number;
|
|
118
|
+
/**
|
|
119
|
+
* The width of the border surrounding each bar.
|
|
120
|
+
*
|
|
121
|
+
* @default 0
|
|
122
|
+
*/
|
|
123
|
+
borderWidth?: number;
|
|
124
|
+
/**
|
|
125
|
+
* The color of the border surrounding each bar.
|
|
126
|
+
*/
|
|
127
|
+
borderColor?: string;
|
|
118
128
|
/**
|
|
119
129
|
* The corner radius of the border surrounding each bar.
|
|
120
130
|
* @default 0
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TOOLTIP_TOTALS_BUILT_IN_AGGREGATION } from '../../constants';
|
|
1
2
|
import type { MeaningfulAny } from '../misc';
|
|
2
3
|
import type { AreaSeries, AreaSeriesData } from './area';
|
|
3
4
|
import type { ChartXAxis, ChartYAxis } from './axis';
|
|
@@ -79,6 +80,10 @@ export interface ChartTooltipRendererArgs<T = MeaningfulAny> {
|
|
|
79
80
|
xAxis?: ChartXAxis | null;
|
|
80
81
|
yAxis?: ChartYAxis;
|
|
81
82
|
}
|
|
83
|
+
export interface ChartTooltipTotalsAggregationArgs<T = MeaningfulAny> extends ChartTooltipRendererArgs<T> {
|
|
84
|
+
}
|
|
85
|
+
export type ChartTooltipTotalsBuiltInAggregation = (typeof TOOLTIP_TOTALS_BUILT_IN_AGGREGATION)[keyof typeof TOOLTIP_TOTALS_BUILT_IN_AGGREGATION];
|
|
86
|
+
export type ChartTooltipTotalsAggregationValue = number | string | undefined;
|
|
82
87
|
export interface ChartTooltip<T = MeaningfulAny> {
|
|
83
88
|
enabled?: boolean;
|
|
84
89
|
/** Specifies the renderer for the tooltip. If returned null default tooltip renderer will be used. */
|
|
@@ -91,4 +96,20 @@ export interface ChartTooltip<T = MeaningfulAny> {
|
|
|
91
96
|
throttle?: number;
|
|
92
97
|
/** Formatting settings for tooltip value. */
|
|
93
98
|
valueFormat?: ValueFormat;
|
|
99
|
+
/** Settings for totals block in tooltip */
|
|
100
|
+
totals?: {
|
|
101
|
+
/**
|
|
102
|
+
* The aggregation method for calculating totals.
|
|
103
|
+
* It can be a built-in function (e.g., 'sum') or a custom function.
|
|
104
|
+
* @default 'sum'
|
|
105
|
+
*/
|
|
106
|
+
aggregation?: ChartTooltipTotalsBuiltInAggregation | ((args: ChartTooltipTotalsAggregationArgs) => ChartTooltipTotalsAggregationValue);
|
|
107
|
+
/**
|
|
108
|
+
* Enables/disables the display of totals
|
|
109
|
+
* @default false
|
|
110
|
+
*/
|
|
111
|
+
enabled?: boolean;
|
|
112
|
+
/** The label text for the totals. For built-in aggregations, the label can be omitted. */
|
|
113
|
+
label?: string;
|
|
114
|
+
};
|
|
94
115
|
}
|
|
@@ -93,18 +93,31 @@ export async function axisBottom(args) {
|
|
|
93
93
|
let elementX = 0;
|
|
94
94
|
// add an ellipsis to the labels that go beyond the boundaries of the chart
|
|
95
95
|
// and remove overlapping labels
|
|
96
|
-
labels
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
96
|
+
labels
|
|
97
|
+
.nodes()
|
|
98
|
+
.map((element) => {
|
|
99
|
+
const r = element.getBoundingClientRect();
|
|
100
|
+
return {
|
|
101
|
+
left: r.left,
|
|
102
|
+
right: r.right,
|
|
103
|
+
node: element,
|
|
104
|
+
};
|
|
105
|
+
}, {})
|
|
106
|
+
.sort((a, b) => {
|
|
107
|
+
return a.left - b.left;
|
|
108
|
+
})
|
|
109
|
+
.forEach(function (item, i, nodes) {
|
|
110
|
+
var _a, _b, _c, _d;
|
|
111
|
+
const { node, left, right: currentElementPositionRigth } = item;
|
|
112
|
+
const currentElement = node;
|
|
100
113
|
if (i === 0) {
|
|
101
114
|
const text = select(currentElement);
|
|
102
|
-
const nextElement = nodes[i + 1];
|
|
115
|
+
const nextElement = (_a = nodes[i + 1]) === null || _a === void 0 ? void 0 : _a.node;
|
|
103
116
|
const nextElementPosition = nextElement === null || nextElement === void 0 ? void 0 : nextElement.getBoundingClientRect();
|
|
104
|
-
if (
|
|
105
|
-
const rightmostPossiblePoint = (
|
|
117
|
+
if (left < leftmostLimit) {
|
|
118
|
+
const rightmostPossiblePoint = (_b = nextElementPosition === null || nextElementPosition === void 0 ? void 0 : nextElementPosition.left) !== null && _b !== void 0 ? _b : right;
|
|
106
119
|
const remainSpace = rightmostPossiblePoint -
|
|
107
|
-
|
|
120
|
+
currentElementPositionRigth +
|
|
108
121
|
x -
|
|
109
122
|
labelsMargin;
|
|
110
123
|
text.attr('text-anchor', 'start');
|
|
@@ -112,16 +125,16 @@ export async function axisBottom(args) {
|
|
|
112
125
|
}
|
|
113
126
|
}
|
|
114
127
|
else {
|
|
115
|
-
if (
|
|
116
|
-
(
|
|
128
|
+
if (left < elementX) {
|
|
129
|
+
(_c = currentElement.closest('.tick')) === null || _c === void 0 ? void 0 : _c.remove();
|
|
117
130
|
return;
|
|
118
131
|
}
|
|
119
|
-
elementX =
|
|
132
|
+
elementX = currentElementPositionRigth + labelsPaddings;
|
|
120
133
|
if (i === nodes.length - 1) {
|
|
121
|
-
const prevElement = nodes[i - 1];
|
|
134
|
+
const prevElement = (_d = nodes[i - 1]) === null || _d === void 0 ? void 0 : _d.node;
|
|
122
135
|
const text = select(currentElement);
|
|
123
136
|
const prevElementPosition = prevElement === null || prevElement === void 0 ? void 0 : prevElement.getBoundingClientRect();
|
|
124
|
-
const lackingSpace = Math.max(0,
|
|
137
|
+
const lackingSpace = Math.max(0, currentElementPositionRigth - right);
|
|
125
138
|
if (lackingSpace) {
|
|
126
139
|
const remainSpace = right - ((prevElementPosition === null || prevElementPosition === void 0 ? void 0 : prevElementPosition.right) || 0) - labelsPaddings;
|
|
127
140
|
const translateX = -lackingSpace;
|
|
@@ -49,7 +49,7 @@ export function getClosestPoints(args) {
|
|
|
49
49
|
const groups = groupBy(shapesData, getSeriesType);
|
|
50
50
|
// eslint-disable-next-line complexity
|
|
51
51
|
Object.entries(groups).forEach(([seriesType, list]) => {
|
|
52
|
-
var _a, _b;
|
|
52
|
+
var _a, _b, _c;
|
|
53
53
|
switch (seriesType) {
|
|
54
54
|
case 'bar-x': {
|
|
55
55
|
const points = list.map((d) => ({
|
|
@@ -106,26 +106,27 @@ export function getClosestPoints(args) {
|
|
|
106
106
|
const points = list;
|
|
107
107
|
const sorted = sort(points, (p) => p.y);
|
|
108
108
|
const closestYIndex = bisector((p) => p.y).center(sorted, pointerY);
|
|
109
|
-
|
|
110
|
-
let
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
const closestYPoint = sorted[closestYIndex];
|
|
110
|
+
let selectedPoints = [];
|
|
111
|
+
let closestPointXValue = -1;
|
|
112
|
+
if (closestYPoint) {
|
|
113
|
+
selectedPoints = points.filter((p) => p.data.y === closestYPoint.data.y);
|
|
114
|
+
const closestPoints = sort(selectedPoints.filter((p) => p.y === closestYPoint.y), (p) => p.x);
|
|
114
115
|
const lastPoint = closestPoints[closestPoints.length - 1];
|
|
115
116
|
if (pointerX < ((_a = closestPoints[0]) === null || _a === void 0 ? void 0 : _a.x)) {
|
|
116
|
-
|
|
117
|
+
closestPointXValue = closestPoints[0].x;
|
|
117
118
|
}
|
|
118
119
|
else if (lastPoint && pointerX > lastPoint.x + lastPoint.width) {
|
|
119
|
-
|
|
120
|
+
closestPointXValue = lastPoint.x;
|
|
120
121
|
}
|
|
121
122
|
else {
|
|
122
|
-
|
|
123
|
+
closestPointXValue = (_b = closestPoints.find((p) => pointerX > p.x && pointerX < p.x + p.width)) === null || _b === void 0 ? void 0 : _b.x;
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
|
-
result.push(...
|
|
126
|
+
result.push(...selectedPoints.map((p) => ({
|
|
126
127
|
data: p.data,
|
|
127
128
|
series: p.series,
|
|
128
|
-
closest:
|
|
129
|
+
closest: p.x === closestPointXValue && p.y === closestYPoint.y,
|
|
129
130
|
})));
|
|
130
131
|
break;
|
|
131
132
|
}
|
|
@@ -164,7 +165,7 @@ export function getClosestPoints(args) {
|
|
|
164
165
|
}
|
|
165
166
|
case 'treemap': {
|
|
166
167
|
const data = list;
|
|
167
|
-
const closestPoint = (
|
|
168
|
+
const closestPoint = (_c = data[0]) === null || _c === void 0 ? void 0 : _c.leaves.find((l) => {
|
|
168
169
|
return (pointerX >= l.x0 && pointerX <= l.x1 && pointerY >= l.y0 && pointerY <= l.y1);
|
|
169
170
|
});
|
|
170
171
|
if (closestPoint) {
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import type { ChartSeries } from '../../../types';
|
|
2
|
-
export declare function getSortedSeriesData(seriesData
|
|
1
|
+
import type { ChartAxis, ChartSeries } from '../../../types';
|
|
2
|
+
export declare function getSortedSeriesData({ seriesData, yAxes, xAxis, }: {
|
|
3
|
+
seriesData: ChartSeries[];
|
|
4
|
+
yAxes?: ChartAxis[];
|
|
5
|
+
xAxis?: ChartAxis;
|
|
6
|
+
}): ChartSeries[];
|
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
import { sort } from 'd3';
|
|
2
|
+
import { isEmpty } from 'lodash';
|
|
3
|
+
import get from 'lodash/get';
|
|
2
4
|
import { SeriesType } from '../../../constants';
|
|
3
|
-
|
|
5
|
+
import { getAxisCategories } from '../../../hooks/useChartOptions/utils';
|
|
6
|
+
function applyAxisCategoriesOrder({ series, axis, key, }) {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
const originalCategories = (_a = axis === null || axis === void 0 ? void 0 : axis.categories) !== null && _a !== void 0 ? _a : [];
|
|
9
|
+
if (isEmpty(originalCategories)) {
|
|
10
|
+
return series;
|
|
11
|
+
}
|
|
12
|
+
const axisCategories = (_b = getAxisCategories(axis)) !== null && _b !== void 0 ? _b : [];
|
|
13
|
+
const order = Object.fromEntries(axisCategories.map((value, index) => [value, index]));
|
|
14
|
+
const newSeriesData = series.data.map((d) => {
|
|
15
|
+
const value = get(d, key);
|
|
16
|
+
if (typeof value === 'number') {
|
|
17
|
+
return Object.assign(Object.assign({}, d), { [key]: order[originalCategories[value]] });
|
|
18
|
+
}
|
|
19
|
+
return d;
|
|
20
|
+
});
|
|
21
|
+
return Object.assign(Object.assign({}, series), { data: newSeriesData });
|
|
22
|
+
}
|
|
23
|
+
export function getSortedSeriesData({ seriesData, yAxes, xAxis, }) {
|
|
4
24
|
return seriesData.map((s) => {
|
|
5
|
-
|
|
25
|
+
const yAxis = yAxes === null || yAxes === void 0 ? void 0 : yAxes[0];
|
|
26
|
+
let sortedSeries = s;
|
|
27
|
+
sortedSeries = applyAxisCategoriesOrder({ series: sortedSeries, axis: yAxis, key: 'y' });
|
|
28
|
+
sortedSeries = applyAxisCategoriesOrder({ series: sortedSeries, axis: xAxis, key: 'x' });
|
|
29
|
+
switch (sortedSeries.type) {
|
|
6
30
|
case SeriesType.Area: {
|
|
7
|
-
|
|
31
|
+
sortedSeries = Object.assign(Object.assign({}, sortedSeries), { data: sort(sortedSeries.data, (d) => d.x) });
|
|
32
|
+
break;
|
|
8
33
|
}
|
|
9
34
|
}
|
|
10
|
-
return
|
|
35
|
+
return sortedSeries;
|
|
11
36
|
});
|
|
12
37
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SeriesType } from '../../constants';
|
|
2
|
+
import { getAxisCategories } from '../../hooks/useChartOptions/utils';
|
|
2
3
|
const SERIES_TYPE_WITH_HIDDEN_POINTS = [SeriesType.Area, SeriesType.Line];
|
|
3
4
|
// eslint-disable-next-line complexity
|
|
4
5
|
function isValueInRange(args) {
|
|
@@ -20,7 +21,7 @@ function isValueInRange(args) {
|
|
|
20
21
|
return numValue >= numMin && numValue <= numMax;
|
|
21
22
|
}
|
|
22
23
|
case 'category': {
|
|
23
|
-
const categories = (axis
|
|
24
|
+
const categories = getAxisCategories(axis) || [];
|
|
24
25
|
if (typeof value === 'string' && typeof min === 'number' && typeof max === 'number') {
|
|
25
26
|
const valueIndex = categories.indexOf(value);
|
|
26
27
|
if (min === -1 || max === -1 || valueIndex === -1) {
|
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
|
-
import { DEFAULT_AXIS_TYPE, SeriesType } from '../constants';
|
|
3
|
+
import { AXIS_TYPE, DEFAULT_AXIS_TYPE, SeriesType, TOOLTIP_TOTALS_BUILT_IN_AGGREGATION, } from '../constants';
|
|
4
4
|
import { i18n } from '../i18n';
|
|
5
5
|
import { CHART_ERROR_CODE, ChartError } from '../libs';
|
|
6
|
+
function getTypeOf(value) {
|
|
7
|
+
return typeof value;
|
|
8
|
+
}
|
|
6
9
|
const AVAILABLE_SERIES_TYPES = Object.values(SeriesType);
|
|
10
|
+
const AVAILABLE_TOOLTIP_TOTALS_BUILT_IN_AGGREGATIONS = Object.values(TOOLTIP_TOTALS_BUILT_IN_AGGREGATION);
|
|
11
|
+
const AVAILABLE_TOOLTIP_TOTALS_AGGREGATION_TYPES = ['function', 'string'];
|
|
12
|
+
const AVAILABLE_AXIS_TYPES = Object.values(AXIS_TYPE);
|
|
13
|
+
function validateAxisType({ axis, key }) {
|
|
14
|
+
if (axis.type && !AVAILABLE_AXIS_TYPES.includes(axis.type)) {
|
|
15
|
+
throw new ChartError({
|
|
16
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
17
|
+
message: i18n('error', 'label_invalid-axis-type', {
|
|
18
|
+
key,
|
|
19
|
+
values: AVAILABLE_AXIS_TYPES,
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function validateAxes(args) {
|
|
25
|
+
const { xAxis, yAxis = [] } = args;
|
|
26
|
+
if (xAxis) {
|
|
27
|
+
validateAxisType({ axis: xAxis, key: 'x' });
|
|
28
|
+
}
|
|
29
|
+
yAxis.forEach((axis) => {
|
|
30
|
+
validateAxisType({ axis, key: 'y' });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
7
33
|
function validateXYSeries(args) {
|
|
8
34
|
const { series, xAxis, yAxis = [] } = args;
|
|
9
35
|
const yAxisIndex = get(series, 'yAxis', 0);
|
|
@@ -335,6 +361,32 @@ function countSeriesByType(args) {
|
|
|
335
361
|
});
|
|
336
362
|
return count;
|
|
337
363
|
}
|
|
364
|
+
function validateTooltip({ tooltip }) {
|
|
365
|
+
if (!tooltip) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (tooltip.totals) {
|
|
369
|
+
const aggregation = tooltip.totals.aggregation;
|
|
370
|
+
if (aggregation) {
|
|
371
|
+
const aggregationType = getTypeOf(aggregation);
|
|
372
|
+
if (!AVAILABLE_TOOLTIP_TOTALS_AGGREGATION_TYPES.includes(aggregationType)) {
|
|
373
|
+
throw new ChartError({
|
|
374
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
375
|
+
message: i18n('error', 'label_invalid-tooltip-totals-aggregation-type'),
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
if (typeof aggregation === 'string' &&
|
|
379
|
+
!AVAILABLE_TOOLTIP_TOTALS_BUILT_IN_AGGREGATIONS.includes(aggregation)) {
|
|
380
|
+
throw new ChartError({
|
|
381
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
382
|
+
message: i18n('error', 'label_invalid-tooltip-totals-aggregation-type-str', {
|
|
383
|
+
values: AVAILABLE_TOOLTIP_TOTALS_BUILT_IN_AGGREGATIONS,
|
|
384
|
+
}),
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
338
390
|
export function validateData(data) {
|
|
339
391
|
if (isEmpty(data) || isEmpty(data.series) || isEmpty(data.series.data)) {
|
|
340
392
|
throw new ChartError({
|
|
@@ -342,6 +394,8 @@ export function validateData(data) {
|
|
|
342
394
|
message: i18n('error', 'label_no-data'),
|
|
343
395
|
});
|
|
344
396
|
}
|
|
397
|
+
validateAxes({ xAxis: data.xAxis, yAxis: data.yAxis });
|
|
398
|
+
validateTooltip({ tooltip: data.tooltip });
|
|
345
399
|
if (data.series.data.some((s) => isEmpty(s.data))) {
|
|
346
400
|
throw new ChartError({
|
|
347
401
|
code: CHART_ERROR_CODE.INVALID_DATA,
|