@gravity-ui/charts 1.11.3 → 1.12.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/ChartInner/index.js +1 -1
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +19 -12
- package/dist/cjs/components/Legend/index.d.ts +0 -1
- package/dist/cjs/components/Legend/index.js +13 -23
- 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 +73 -22
- package/dist/cjs/hooks/useChartOptions/x-axis.js +1 -1
- package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +4 -2
- package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -3
- package/dist/cjs/hooks/useSeries/index.d.ts +9 -0
- package/dist/cjs/hooks/useSeries/index.js +59 -29
- package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +2 -2
- package/dist/cjs/hooks/useSeries/prepare-legend.js +4 -6
- package/dist/cjs/hooks/useSeries/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +17 -62
- 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 +69 -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 +2 -2
- package/dist/cjs/types/chart/tooltip.d.ts +21 -0
- package/dist/cjs/validation/index.js +55 -1
- package/dist/esm/components/ChartInner/index.js +1 -1
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +19 -12
- package/dist/esm/components/Legend/index.d.ts +0 -1
- package/dist/esm/components/Legend/index.js +13 -23
- 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 +73 -22
- package/dist/esm/hooks/useChartOptions/x-axis.js +1 -1
- package/dist/esm/hooks/useChartOptions/y-axis.d.ts +4 -2
- package/dist/esm/hooks/useChartOptions/y-axis.js +9 -3
- package/dist/esm/hooks/useSeries/index.d.ts +9 -0
- package/dist/esm/hooks/useSeries/index.js +59 -29
- package/dist/esm/hooks/useSeries/prepare-legend.d.ts +2 -2
- package/dist/esm/hooks/useSeries/prepare-legend.js +4 -6
- package/dist/esm/hooks/useSeries/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +1 -1
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +17 -62
- 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 +69 -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 +2 -2
- package/dist/esm/types/chart/tooltip.d.ts +21 -0
- 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
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
export function groupBarYDataByYValue(series, yAxis) {
|
|
6
|
+
const data = {};
|
|
7
|
+
series.forEach((s) => {
|
|
8
|
+
s.data.forEach((d) => {
|
|
9
|
+
const axisIndex = get(s, 'yAxis', 0);
|
|
10
|
+
const seriesYAxis = yAxis[axisIndex];
|
|
11
|
+
const categories = get(seriesYAxis, 'categories', []);
|
|
12
|
+
const key = seriesYAxis.type === 'category'
|
|
13
|
+
? getDataCategoryValue({ axisDirection: 'y', categories, data: d })
|
|
14
|
+
: d.y;
|
|
15
|
+
if (key) {
|
|
16
|
+
if (!data[key]) {
|
|
17
|
+
data[key] = {};
|
|
18
|
+
}
|
|
19
|
+
if (!data[key][s.stackId]) {
|
|
20
|
+
data[key][s.stackId] = [];
|
|
21
|
+
}
|
|
22
|
+
data[key][s.stackId].push({ data: d, series: s });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
export function getBarYLayoutForNumericScale(args) {
|
|
29
|
+
const { plotHeight, series, seriesOptions } = args;
|
|
30
|
+
const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth');
|
|
31
|
+
const barPadding = get(seriesOptions, 'bar-y.barPadding');
|
|
32
|
+
const groupPadding = get(seriesOptions, 'bar-y.groupPadding');
|
|
33
|
+
let yValuesWithoutStacking = 0;
|
|
34
|
+
const yValuesByStackingIdMap = {};
|
|
35
|
+
series.forEach((s) => {
|
|
36
|
+
s.data.forEach((d) => {
|
|
37
|
+
if (s.stackId) {
|
|
38
|
+
if (!yValuesByStackingIdMap[s.stackId]) {
|
|
39
|
+
yValuesByStackingIdMap[s.stackId] = new Set();
|
|
40
|
+
}
|
|
41
|
+
yValuesByStackingIdMap[s.stackId].add(Number(d.y));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
yValuesWithoutStacking += 1;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
const stackedSeriesLength = Object.values(yValuesByStackingIdMap).reduce((acc, set) => acc + set.size, 0);
|
|
49
|
+
const dataLength = yValuesWithoutStacking + stackedSeriesLength;
|
|
50
|
+
const bandSize = plotHeight / dataLength;
|
|
51
|
+
const groupGap = Math.max(bandSize * groupPadding, MIN_BAR_GROUP_GAP);
|
|
52
|
+
const groupSize = bandSize - groupGap;
|
|
53
|
+
const barGap = Math.max(bandSize * barPadding, MIN_BAR_GAP);
|
|
54
|
+
const barSize = Math.max(MIN_BAR_WIDTH, Math.min(groupSize - barGap, barMaxWidth));
|
|
55
|
+
return { bandSize, barGap, barSize, dataLength };
|
|
56
|
+
}
|
|
57
|
+
export function getBarYLayoutForCategoryScale(args) {
|
|
58
|
+
const { groupedData, seriesOptions, yScale } = args;
|
|
59
|
+
const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth');
|
|
60
|
+
const barPadding = get(seriesOptions, 'bar-y.barPadding');
|
|
61
|
+
const groupPadding = get(seriesOptions, 'bar-y.groupPadding');
|
|
62
|
+
const bandSize = yScale.bandwidth();
|
|
63
|
+
const maxGroupSize = max(Object.values(groupedData), (d) => Object.values(d).length) || 1;
|
|
64
|
+
const groupGap = Math.max(bandSize * groupPadding, MIN_BAR_GROUP_GAP);
|
|
65
|
+
const groupSize = bandSize - groupGap;
|
|
66
|
+
const barGap = Math.max(bandSize * barPadding, MIN_BAR_GAP);
|
|
67
|
+
const barSize = Math.max(MIN_BAR_WIDTH, Math.min(groupSize / maxGroupSize - barGap, barMaxWidth));
|
|
68
|
+
return { bandSize, barGap, barSize };
|
|
69
|
+
}
|
|
@@ -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. */
|
|
@@ -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
|
}
|
|
@@ -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,
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ChartXAxis, ChartYAxis, TooltipDataChunk, ValueFormat } from '../../types';
|
|
3
|
-
type Props = {
|
|
4
|
-
hovered: TooltipDataChunk[];
|
|
5
|
-
xAxis?: ChartXAxis | null;
|
|
6
|
-
yAxis?: ChartYAxis;
|
|
7
|
-
valueFormat?: ValueFormat;
|
|
8
|
-
};
|
|
9
|
-
export declare const DefaultContent: ({ hovered, xAxis, yAxis, valueFormat }: Props) => React.JSX.Element;
|
|
10
|
-
export {};
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import get from 'lodash/get';
|
|
3
|
-
import { block, getDataCategoryValue } from '../../utils';
|
|
4
|
-
import { getFormattedValue } from '../../utils/chart/format';
|
|
5
|
-
const b = block('tooltip');
|
|
6
|
-
const DEFAULT_DATE_FORMAT = 'DD.MM.YY';
|
|
7
|
-
const getRowData = (fieldName, data, axis) => {
|
|
8
|
-
switch (axis === null || axis === void 0 ? void 0 : axis.type) {
|
|
9
|
-
case 'category': {
|
|
10
|
-
const categories = get(axis, 'categories', []);
|
|
11
|
-
return getDataCategoryValue({ axisDirection: fieldName, categories, data });
|
|
12
|
-
}
|
|
13
|
-
default: {
|
|
14
|
-
return get(data, fieldName);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
const getXRowData = (data, xAxis) => getRowData('x', data, xAxis);
|
|
19
|
-
const getYRowData = (data, yAxis) => getRowData('y', data, yAxis);
|
|
20
|
-
const getMeasureValue = ({ data, xAxis, yAxis, valueFormat, }) => {
|
|
21
|
-
var _a, _b, _c, _d;
|
|
22
|
-
if (data.every((item) => ['pie', 'treemap', 'waterfall', 'sankey'].includes(item.series.type))) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
if (data.some((item) => item.series.type === 'radar')) {
|
|
26
|
-
return (_b = (_a = data[0].category) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : null;
|
|
27
|
-
}
|
|
28
|
-
if (data.some((item) => item.series.type === 'bar-y')) {
|
|
29
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
|
|
30
|
-
return getFormattedValue({
|
|
31
|
-
value: getYRowData((_c = data[0]) === null || _c === void 0 ? void 0 : _c.data, yAxis),
|
|
32
|
-
format,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: xAxis });
|
|
36
|
-
return getFormattedValue({
|
|
37
|
-
value: getXRowData((_d = data[0]) === null || _d === void 0 ? void 0 : _d.data, xAxis),
|
|
38
|
-
format,
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
function getDefaultValueFormat({ axis, }) {
|
|
42
|
-
switch (axis === null || axis === void 0 ? void 0 : axis.type) {
|
|
43
|
-
case 'linear':
|
|
44
|
-
case 'logarithmic': {
|
|
45
|
-
return {
|
|
46
|
-
type: 'number',
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
case 'datetime': {
|
|
50
|
-
return {
|
|
51
|
-
type: 'date',
|
|
52
|
-
format: DEFAULT_DATE_FORMAT,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
default:
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
|
|
60
|
-
const measureValue = getMeasureValue({ data: hovered, xAxis, yAxis });
|
|
61
|
-
return (React.createElement("div", { className: b('content') },
|
|
62
|
-
measureValue && React.createElement("div", { className: b('series-name') }, measureValue),
|
|
63
|
-
// eslint-disable-next-line complexity
|
|
64
|
-
hovered.map((seriesItem, i) => {
|
|
65
|
-
var _a, _b;
|
|
66
|
-
const { data, series, closest } = seriesItem;
|
|
67
|
-
const id = `${get(series, 'id')}_${i}`;
|
|
68
|
-
const color = get(series, 'color');
|
|
69
|
-
switch (series.type) {
|
|
70
|
-
case 'scatter':
|
|
71
|
-
case 'line':
|
|
72
|
-
case 'area':
|
|
73
|
-
case 'bar-x': {
|
|
74
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
|
|
75
|
-
const formattedValue = getFormattedValue({
|
|
76
|
-
value: getYRowData(data, yAxis),
|
|
77
|
-
format,
|
|
78
|
-
});
|
|
79
|
-
const value = (React.createElement(React.Fragment, null,
|
|
80
|
-
series.name,
|
|
81
|
-
": ",
|
|
82
|
-
formattedValue));
|
|
83
|
-
const active = closest && hovered.length > 1;
|
|
84
|
-
return (React.createElement("div", { key: id, className: b('content-row', { active }) },
|
|
85
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
86
|
-
React.createElement("div", null, value)));
|
|
87
|
-
}
|
|
88
|
-
case 'waterfall': {
|
|
89
|
-
const isTotal = get(data, 'total', false);
|
|
90
|
-
const subTotalValue = (_a = seriesItem.subTotal) !== null && _a !== void 0 ? _a : 0;
|
|
91
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
|
|
92
|
-
const subTotal = getFormattedValue({
|
|
93
|
-
value: subTotalValue,
|
|
94
|
-
format,
|
|
95
|
-
});
|
|
96
|
-
const formattedValue = getFormattedValue({
|
|
97
|
-
value: getYRowData(data, yAxis),
|
|
98
|
-
format,
|
|
99
|
-
});
|
|
100
|
-
return (React.createElement("div", { key: `${id}_${get(data, 'x')}` },
|
|
101
|
-
!isTotal && (React.createElement(React.Fragment, null,
|
|
102
|
-
React.createElement("div", { key: id, className: b('content-row') },
|
|
103
|
-
React.createElement("b", null, getXRowData(data, xAxis))),
|
|
104
|
-
React.createElement("div", { className: b('content-row') },
|
|
105
|
-
React.createElement("span", null,
|
|
106
|
-
series.name,
|
|
107
|
-
"\u00A0"),
|
|
108
|
-
React.createElement("span", null, formattedValue)))),
|
|
109
|
-
React.createElement("div", { key: id, className: b('content-row') },
|
|
110
|
-
isTotal ? 'Total' : 'Subtotal',
|
|
111
|
-
": ",
|
|
112
|
-
subTotal)));
|
|
113
|
-
}
|
|
114
|
-
case 'bar-y': {
|
|
115
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: xAxis });
|
|
116
|
-
const formattedValue = getFormattedValue({
|
|
117
|
-
value: getXRowData(data, xAxis),
|
|
118
|
-
format,
|
|
119
|
-
});
|
|
120
|
-
const value = (React.createElement(React.Fragment, null,
|
|
121
|
-
series.name,
|
|
122
|
-
": ",
|
|
123
|
-
formattedValue));
|
|
124
|
-
const active = closest && hovered.length > 1;
|
|
125
|
-
return (React.createElement("div", { key: id, className: b('content-row', { active }) },
|
|
126
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
127
|
-
React.createElement("div", null, value)));
|
|
128
|
-
}
|
|
129
|
-
case 'pie':
|
|
130
|
-
case 'treemap': {
|
|
131
|
-
const seriesData = data;
|
|
132
|
-
const formattedValue = getFormattedValue({
|
|
133
|
-
value: seriesData.value,
|
|
134
|
-
format: valueFormat !== null && valueFormat !== void 0 ? valueFormat : { type: 'number' },
|
|
135
|
-
});
|
|
136
|
-
return (React.createElement("div", { key: id, className: b('content-row') },
|
|
137
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
138
|
-
React.createElement("span", { dangerouslySetInnerHTML: {
|
|
139
|
-
__html: [seriesData.name || seriesData.id]
|
|
140
|
-
.flat()
|
|
141
|
-
.join('\n'),
|
|
142
|
-
} }),
|
|
143
|
-
"\u00A0",
|
|
144
|
-
React.createElement("span", null, formattedValue)));
|
|
145
|
-
}
|
|
146
|
-
case 'sankey': {
|
|
147
|
-
const { target, data: source } = seriesItem;
|
|
148
|
-
const value = (_b = source.links.find((d) => d.name === (target === null || target === void 0 ? void 0 : target.name))) === null || _b === void 0 ? void 0 : _b.value;
|
|
149
|
-
const formattedValue = getFormattedValue({
|
|
150
|
-
value,
|
|
151
|
-
format: valueFormat !== null && valueFormat !== void 0 ? valueFormat : { type: 'number' },
|
|
152
|
-
});
|
|
153
|
-
return (React.createElement("div", { key: id, className: b('content-row') },
|
|
154
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: source.color } }),
|
|
155
|
-
React.createElement("div", { style: { display: 'flex', gap: 8, verticalAlign: 'center' } },
|
|
156
|
-
source.name,
|
|
157
|
-
" ",
|
|
158
|
-
React.createElement("span", null, "\u2192"),
|
|
159
|
-
" ", target === null || target === void 0 ? void 0 :
|
|
160
|
-
target.name,
|
|
161
|
-
":",
|
|
162
|
-
' ',
|
|
163
|
-
formattedValue)));
|
|
164
|
-
}
|
|
165
|
-
case 'radar': {
|
|
166
|
-
const radarSeries = series;
|
|
167
|
-
const seriesData = data;
|
|
168
|
-
const formattedValue = getFormattedValue({
|
|
169
|
-
value: seriesData.value,
|
|
170
|
-
format: valueFormat !== null && valueFormat !== void 0 ? valueFormat : { type: 'number' },
|
|
171
|
-
});
|
|
172
|
-
const value = (React.createElement(React.Fragment, null,
|
|
173
|
-
React.createElement("span", null,
|
|
174
|
-
radarSeries.name || radarSeries.id,
|
|
175
|
-
"\u00A0"),
|
|
176
|
-
React.createElement("span", null, formattedValue)));
|
|
177
|
-
const active = closest && hovered.length > 1;
|
|
178
|
-
return (React.createElement("div", { key: id, className: b('content-row', { active }) },
|
|
179
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
180
|
-
React.createElement("div", null, value)));
|
|
181
|
-
}
|
|
182
|
-
default: {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
})));
|
|
187
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ChartXAxis, ChartYAxis, TooltipDataChunk, ValueFormat } from '../../types';
|
|
3
|
-
type Props = {
|
|
4
|
-
hovered: TooltipDataChunk[];
|
|
5
|
-
xAxis?: ChartXAxis | null;
|
|
6
|
-
yAxis?: ChartYAxis;
|
|
7
|
-
valueFormat?: ValueFormat;
|
|
8
|
-
};
|
|
9
|
-
export declare const DefaultContent: ({ hovered, xAxis, yAxis, valueFormat }: Props) => React.JSX.Element;
|
|
10
|
-
export {};
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import get from 'lodash/get';
|
|
3
|
-
import { block, getDataCategoryValue } from '../../utils';
|
|
4
|
-
import { getFormattedValue } from '../../utils/chart/format';
|
|
5
|
-
const b = block('tooltip');
|
|
6
|
-
const DEFAULT_DATE_FORMAT = 'DD.MM.YY';
|
|
7
|
-
const getRowData = (fieldName, data, axis) => {
|
|
8
|
-
switch (axis === null || axis === void 0 ? void 0 : axis.type) {
|
|
9
|
-
case 'category': {
|
|
10
|
-
const categories = get(axis, 'categories', []);
|
|
11
|
-
return getDataCategoryValue({ axisDirection: fieldName, categories, data });
|
|
12
|
-
}
|
|
13
|
-
default: {
|
|
14
|
-
return get(data, fieldName);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
const getXRowData = (data, xAxis) => getRowData('x', data, xAxis);
|
|
19
|
-
const getYRowData = (data, yAxis) => getRowData('y', data, yAxis);
|
|
20
|
-
const getMeasureValue = ({ data, xAxis, yAxis, valueFormat, }) => {
|
|
21
|
-
var _a, _b, _c, _d;
|
|
22
|
-
if (data.every((item) => ['pie', 'treemap', 'waterfall', 'sankey'].includes(item.series.type))) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
if (data.some((item) => item.series.type === 'radar')) {
|
|
26
|
-
return (_b = (_a = data[0].category) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : null;
|
|
27
|
-
}
|
|
28
|
-
if (data.some((item) => item.series.type === 'bar-y')) {
|
|
29
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
|
|
30
|
-
return getFormattedValue({
|
|
31
|
-
value: getYRowData((_c = data[0]) === null || _c === void 0 ? void 0 : _c.data, yAxis),
|
|
32
|
-
format,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: xAxis });
|
|
36
|
-
return getFormattedValue({
|
|
37
|
-
value: getXRowData((_d = data[0]) === null || _d === void 0 ? void 0 : _d.data, xAxis),
|
|
38
|
-
format,
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
function getDefaultValueFormat({ axis, }) {
|
|
42
|
-
switch (axis === null || axis === void 0 ? void 0 : axis.type) {
|
|
43
|
-
case 'linear':
|
|
44
|
-
case 'logarithmic': {
|
|
45
|
-
return {
|
|
46
|
-
type: 'number',
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
case 'datetime': {
|
|
50
|
-
return {
|
|
51
|
-
type: 'date',
|
|
52
|
-
format: DEFAULT_DATE_FORMAT,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
default:
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
|
|
60
|
-
const measureValue = getMeasureValue({ data: hovered, xAxis, yAxis });
|
|
61
|
-
return (React.createElement("div", { className: b('content') },
|
|
62
|
-
measureValue && React.createElement("div", { className: b('series-name') }, measureValue),
|
|
63
|
-
// eslint-disable-next-line complexity
|
|
64
|
-
hovered.map((seriesItem, i) => {
|
|
65
|
-
var _a, _b;
|
|
66
|
-
const { data, series, closest } = seriesItem;
|
|
67
|
-
const id = `${get(series, 'id')}_${i}`;
|
|
68
|
-
const color = get(series, 'color');
|
|
69
|
-
switch (series.type) {
|
|
70
|
-
case 'scatter':
|
|
71
|
-
case 'line':
|
|
72
|
-
case 'area':
|
|
73
|
-
case 'bar-x': {
|
|
74
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
|
|
75
|
-
const formattedValue = getFormattedValue({
|
|
76
|
-
value: getYRowData(data, yAxis),
|
|
77
|
-
format,
|
|
78
|
-
});
|
|
79
|
-
const value = (React.createElement(React.Fragment, null,
|
|
80
|
-
series.name,
|
|
81
|
-
": ",
|
|
82
|
-
formattedValue));
|
|
83
|
-
const active = closest && hovered.length > 1;
|
|
84
|
-
return (React.createElement("div", { key: id, className: b('content-row', { active }) },
|
|
85
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
86
|
-
React.createElement("div", null, value)));
|
|
87
|
-
}
|
|
88
|
-
case 'waterfall': {
|
|
89
|
-
const isTotal = get(data, 'total', false);
|
|
90
|
-
const subTotalValue = (_a = seriesItem.subTotal) !== null && _a !== void 0 ? _a : 0;
|
|
91
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
|
|
92
|
-
const subTotal = getFormattedValue({
|
|
93
|
-
value: subTotalValue,
|
|
94
|
-
format,
|
|
95
|
-
});
|
|
96
|
-
const formattedValue = getFormattedValue({
|
|
97
|
-
value: getYRowData(data, yAxis),
|
|
98
|
-
format,
|
|
99
|
-
});
|
|
100
|
-
return (React.createElement("div", { key: `${id}_${get(data, 'x')}` },
|
|
101
|
-
!isTotal && (React.createElement(React.Fragment, null,
|
|
102
|
-
React.createElement("div", { key: id, className: b('content-row') },
|
|
103
|
-
React.createElement("b", null, getXRowData(data, xAxis))),
|
|
104
|
-
React.createElement("div", { className: b('content-row') },
|
|
105
|
-
React.createElement("span", null,
|
|
106
|
-
series.name,
|
|
107
|
-
"\u00A0"),
|
|
108
|
-
React.createElement("span", null, formattedValue)))),
|
|
109
|
-
React.createElement("div", { key: id, className: b('content-row') },
|
|
110
|
-
isTotal ? 'Total' : 'Subtotal',
|
|
111
|
-
": ",
|
|
112
|
-
subTotal)));
|
|
113
|
-
}
|
|
114
|
-
case 'bar-y': {
|
|
115
|
-
const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: xAxis });
|
|
116
|
-
const formattedValue = getFormattedValue({
|
|
117
|
-
value: getXRowData(data, xAxis),
|
|
118
|
-
format,
|
|
119
|
-
});
|
|
120
|
-
const value = (React.createElement(React.Fragment, null,
|
|
121
|
-
series.name,
|
|
122
|
-
": ",
|
|
123
|
-
formattedValue));
|
|
124
|
-
const active = closest && hovered.length > 1;
|
|
125
|
-
return (React.createElement("div", { key: id, className: b('content-row', { active }) },
|
|
126
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
127
|
-
React.createElement("div", null, value)));
|
|
128
|
-
}
|
|
129
|
-
case 'pie':
|
|
130
|
-
case 'treemap': {
|
|
131
|
-
const seriesData = data;
|
|
132
|
-
const formattedValue = getFormattedValue({
|
|
133
|
-
value: seriesData.value,
|
|
134
|
-
format: valueFormat !== null && valueFormat !== void 0 ? valueFormat : { type: 'number' },
|
|
135
|
-
});
|
|
136
|
-
return (React.createElement("div", { key: id, className: b('content-row') },
|
|
137
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
138
|
-
React.createElement("span", { dangerouslySetInnerHTML: {
|
|
139
|
-
__html: [seriesData.name || seriesData.id]
|
|
140
|
-
.flat()
|
|
141
|
-
.join('\n'),
|
|
142
|
-
} }),
|
|
143
|
-
"\u00A0",
|
|
144
|
-
React.createElement("span", null, formattedValue)));
|
|
145
|
-
}
|
|
146
|
-
case 'sankey': {
|
|
147
|
-
const { target, data: source } = seriesItem;
|
|
148
|
-
const value = (_b = source.links.find((d) => d.name === (target === null || target === void 0 ? void 0 : target.name))) === null || _b === void 0 ? void 0 : _b.value;
|
|
149
|
-
const formattedValue = getFormattedValue({
|
|
150
|
-
value,
|
|
151
|
-
format: valueFormat !== null && valueFormat !== void 0 ? valueFormat : { type: 'number' },
|
|
152
|
-
});
|
|
153
|
-
return (React.createElement("div", { key: id, className: b('content-row') },
|
|
154
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: source.color } }),
|
|
155
|
-
React.createElement("div", { style: { display: 'flex', gap: 8, verticalAlign: 'center' } },
|
|
156
|
-
source.name,
|
|
157
|
-
" ",
|
|
158
|
-
React.createElement("span", null, "\u2192"),
|
|
159
|
-
" ", target === null || target === void 0 ? void 0 :
|
|
160
|
-
target.name,
|
|
161
|
-
":",
|
|
162
|
-
' ',
|
|
163
|
-
formattedValue)));
|
|
164
|
-
}
|
|
165
|
-
case 'radar': {
|
|
166
|
-
const radarSeries = series;
|
|
167
|
-
const seriesData = data;
|
|
168
|
-
const formattedValue = getFormattedValue({
|
|
169
|
-
value: seriesData.value,
|
|
170
|
-
format: valueFormat !== null && valueFormat !== void 0 ? valueFormat : { type: 'number' },
|
|
171
|
-
});
|
|
172
|
-
const value = (React.createElement(React.Fragment, null,
|
|
173
|
-
React.createElement("span", null,
|
|
174
|
-
radarSeries.name || radarSeries.id,
|
|
175
|
-
"\u00A0"),
|
|
176
|
-
React.createElement("span", null, formattedValue)));
|
|
177
|
-
const active = closest && hovered.length > 1;
|
|
178
|
-
return (React.createElement("div", { key: id, className: b('content-row', { active }) },
|
|
179
|
-
React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
|
|
180
|
-
React.createElement("div", null, value)));
|
|
181
|
-
}
|
|
182
|
-
default: {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
})));
|
|
187
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|