@gravity-ui/charts 1.35.1 → 1.36.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/AxisX/AxisX.js +18 -8
- package/dist/cjs/components/AxisX/prepare-axis-data.js +12 -0
- package/dist/cjs/components/AxisX/styles.css +7 -2
- package/dist/cjs/components/AxisX/types.d.ts +5 -0
- package/dist/cjs/components/AxisY/AxisY.js +16 -8
- package/dist/cjs/components/AxisY/prepare-axis-data.js +14 -0
- package/dist/cjs/components/AxisY/styles.css +7 -2
- package/dist/cjs/components/AxisY/types.d.ts +5 -0
- package/dist/cjs/components/ChartInner/index.js +2 -0
- package/dist/cjs/components/ChartInner/styles.css +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +3 -0
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +26 -3
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +3 -1
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +2 -2
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.js +1 -1
- package/dist/cjs/components/Tooltip/index.js +5 -2
- package/dist/cjs/components/Tooltip/styles.css +7 -0
- package/dist/cjs/constants/datetime.d.ts +8 -0
- package/dist/cjs/constants/datetime.js +8 -0
- package/dist/cjs/constants/defaults/axis.d.ts +4 -0
- package/dist/cjs/constants/defaults/axis.js +4 -0
- package/dist/cjs/constants/index.d.ts +1 -1
- package/dist/cjs/constants/index.js +1 -1
- package/dist/cjs/hooks/useAxis/types.d.ts +8 -1
- package/dist/cjs/hooks/useAxis/utils.d.ts +1 -1
- package/dist/cjs/hooks/useAxis/x-axis.js +9 -3
- package/dist/cjs/hooks/useAxis/y-axis.js +7 -1
- package/dist/cjs/hooks/useAxisScales/x-scale.d.ts +1 -1
- package/dist/cjs/hooks/useAxisScales/y-scale.d.ts +1 -1
- package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +1 -0
- package/dist/cjs/hooks/useTooltip/index.d.ts +3 -1
- package/dist/cjs/hooks/useTooltip/index.js +7 -3
- package/dist/cjs/types/chart/axis.d.ts +17 -3
- package/dist/cjs/types/chart/base.d.ts +1 -1
- package/dist/cjs/types/chart/tooltip.d.ts +5 -1
- package/dist/cjs/utils/chart/axis/common.d.ts +1 -3
- package/dist/cjs/utils/chart/axis/common.js +2 -10
- package/dist/cjs/utils/chart/axis/x-axis.js +3 -2
- package/dist/cjs/utils/chart/format.js +17 -2
- package/dist/cjs/utils/chart/get-hovered-plots.d.ts +14 -0
- package/dist/cjs/utils/chart/get-hovered-plots.js +67 -0
- package/dist/cjs/utils/chart/ticks/datetime.d.ts +8 -0
- package/dist/cjs/utils/chart/ticks/datetime.js +50 -0
- package/dist/cjs/utils/chart/ticks/index.d.ts +6 -0
- package/dist/cjs/utils/chart/ticks/index.js +17 -0
- package/dist/cjs/utils/chart/time.d.ts +1 -0
- package/dist/cjs/utils/chart/time.js +9 -0
- package/dist/esm/components/AxisX/AxisX.js +18 -8
- package/dist/esm/components/AxisX/prepare-axis-data.js +12 -0
- package/dist/esm/components/AxisX/styles.css +7 -2
- package/dist/esm/components/AxisX/types.d.ts +5 -0
- package/dist/esm/components/AxisY/AxisY.js +16 -8
- package/dist/esm/components/AxisY/prepare-axis-data.js +14 -0
- package/dist/esm/components/AxisY/styles.css +7 -2
- package/dist/esm/components/AxisY/types.d.ts +5 -0
- package/dist/esm/components/ChartInner/index.js +2 -0
- package/dist/esm/components/ChartInner/styles.css +1 -0
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +3 -0
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +26 -3
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +3 -1
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +2 -2
- package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.js +1 -1
- package/dist/esm/components/Tooltip/index.js +5 -2
- package/dist/esm/components/Tooltip/styles.css +7 -0
- package/dist/esm/constants/datetime.d.ts +8 -0
- package/dist/esm/constants/datetime.js +8 -0
- package/dist/esm/constants/defaults/axis.d.ts +4 -0
- package/dist/esm/constants/defaults/axis.js +4 -0
- package/dist/esm/constants/index.d.ts +1 -1
- package/dist/esm/constants/index.js +1 -1
- package/dist/esm/hooks/useAxis/types.d.ts +8 -1
- package/dist/esm/hooks/useAxis/utils.d.ts +1 -1
- package/dist/esm/hooks/useAxis/x-axis.js +9 -3
- package/dist/esm/hooks/useAxis/y-axis.js +7 -1
- package/dist/esm/hooks/useAxisScales/x-scale.d.ts +1 -1
- package/dist/esm/hooks/useAxisScales/y-scale.d.ts +1 -1
- package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +1 -0
- package/dist/esm/hooks/useTooltip/index.d.ts +3 -1
- package/dist/esm/hooks/useTooltip/index.js +7 -3
- package/dist/esm/types/chart/axis.d.ts +17 -3
- package/dist/esm/types/chart/base.d.ts +1 -1
- package/dist/esm/types/chart/tooltip.d.ts +5 -1
- package/dist/esm/utils/chart/axis/common.d.ts +1 -3
- package/dist/esm/utils/chart/axis/common.js +2 -10
- package/dist/esm/utils/chart/axis/x-axis.js +3 -2
- package/dist/esm/utils/chart/format.js +17 -2
- package/dist/esm/utils/chart/get-hovered-plots.d.ts +14 -0
- package/dist/esm/utils/chart/get-hovered-plots.js +67 -0
- package/dist/esm/utils/chart/ticks/datetime.d.ts +8 -0
- package/dist/esm/utils/chart/ticks/datetime.js +50 -0
- package/dist/esm/utils/chart/ticks/index.d.ts +6 -0
- package/dist/esm/utils/chart/ticks/index.js +17 -0
- package/dist/esm/utils/chart/time.d.ts +1 -0
- package/dist/esm/utils/chart/time.js +9 -0
- package/package.json +1 -1
- package/dist/cjs/constants/date.d.ts +0 -1
- package/dist/cjs/constants/date.js +0 -1
- package/dist/esm/constants/date.d.ts +0 -1
- package/dist/esm/constants/date.js +0 -1
|
@@ -16,8 +16,12 @@ export type AxisSvgLabelData = {
|
|
|
16
16
|
export type AxisTickLine = {
|
|
17
17
|
points: PointPosition[];
|
|
18
18
|
};
|
|
19
|
+
export type AxisTickMarkData = {
|
|
20
|
+
points: PointPosition[];
|
|
21
|
+
};
|
|
19
22
|
export type AxisTickData = {
|
|
20
23
|
line: AxisTickLine | null;
|
|
24
|
+
mark: AxisTickMarkData | null;
|
|
21
25
|
svgLabel: AxisSvgLabelData | null;
|
|
22
26
|
htmlLabel: HtmlItem | null;
|
|
23
27
|
};
|
|
@@ -70,6 +74,7 @@ export type AxisDomainData = {
|
|
|
70
74
|
};
|
|
71
75
|
export type AxisXData = {
|
|
72
76
|
id: string;
|
|
77
|
+
gridEnabled: boolean;
|
|
73
78
|
title: AxisTitleData | null;
|
|
74
79
|
domain: AxisDomainData | null;
|
|
75
80
|
ticks: AxisTickData[];
|
|
@@ -15,7 +15,7 @@ export const AxisY = (props) => {
|
|
|
15
15
|
htmlElements.push(preparedAxisData.title);
|
|
16
16
|
}
|
|
17
17
|
React.useEffect(() => {
|
|
18
|
-
var _a;
|
|
18
|
+
var _a, _b, _c;
|
|
19
19
|
if (!ref.current) {
|
|
20
20
|
return () => { };
|
|
21
21
|
}
|
|
@@ -38,15 +38,17 @@ export const AxisY = (props) => {
|
|
|
38
38
|
.attr('class', b('title'))
|
|
39
39
|
.append('text')
|
|
40
40
|
.attr('text-anchor', 'start')
|
|
41
|
-
.
|
|
42
|
-
.style('transform', `translate(${preparedAxisData.title.x}px, ${preparedAxisData.title.y}px) rotate(${preparedAxisData.title.rotate}deg) translate(0px, ${preparedAxisData.title.offset}px)`)
|
|
41
|
+
.attr('transform', `translate(${preparedAxisData.title.x}, ${preparedAxisData.title.y}) rotate(${preparedAxisData.title.rotate}) translate(0, ${preparedAxisData.title.offset})`)
|
|
43
42
|
.attr('font-size', preparedAxisData.title.style.fontSize)
|
|
43
|
+
.attr('font-weight', (_b = preparedAxisData.title.style.fontWeight) !== null && _b !== void 0 ? _b : null)
|
|
44
|
+
.attr('fill', (_c = preparedAxisData.title.style.fontColor) !== null && _c !== void 0 ? _c : null)
|
|
44
45
|
.selectAll('tspan')
|
|
45
46
|
.data(preparedAxisData.title.content)
|
|
46
47
|
.join('tspan')
|
|
47
48
|
.html((d) => d.text)
|
|
48
49
|
.attr('x', (d) => d.x)
|
|
49
50
|
.attr('y', (d) => d.y)
|
|
51
|
+
.attr('dominant-baseline', 'text-after-edge')
|
|
50
52
|
.attr('text-anchor', 'start');
|
|
51
53
|
}
|
|
52
54
|
if (preparedAxisData.domain) {
|
|
@@ -71,13 +73,19 @@ export const AxisY = (props) => {
|
|
|
71
73
|
if (tickData.line) {
|
|
72
74
|
tickSelection.append('path').attr('d', lineGenerator(tickData.line.points));
|
|
73
75
|
}
|
|
76
|
+
if (tickData.mark) {
|
|
77
|
+
tickSelection
|
|
78
|
+
.append('path')
|
|
79
|
+
.attr('class', b('mark', { grid: preparedAxisData.gridEnabled }))
|
|
80
|
+
.attr('d', lineGenerator(tickData.mark.points));
|
|
81
|
+
}
|
|
74
82
|
if (tickData.svgLabel) {
|
|
75
83
|
const label = tickData.svgLabel;
|
|
76
84
|
const textSelection = tickSelection
|
|
77
85
|
.append('text')
|
|
78
|
-
.
|
|
79
|
-
`translate(${label.x}
|
|
80
|
-
label.angle ? `rotate(${label.angle}
|
|
86
|
+
.attr('transform', [
|
|
87
|
+
`translate(${label.x}, ${label.y})`,
|
|
88
|
+
label.angle ? `rotate(${label.angle})` : '',
|
|
81
89
|
]
|
|
82
90
|
.filter(Boolean)
|
|
83
91
|
.join(' '));
|
|
@@ -110,7 +118,7 @@ export const AxisY = (props) => {
|
|
|
110
118
|
.join('g')
|
|
111
119
|
.attr(plotDataAttr, 1)
|
|
112
120
|
.attr(plotBandDataAttr, 1)
|
|
113
|
-
.
|
|
121
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
114
122
|
plotBandsSelection
|
|
115
123
|
.append('rect')
|
|
116
124
|
.attr('width', (d) => d.width)
|
|
@@ -151,7 +159,7 @@ export const AxisY = (props) => {
|
|
|
151
159
|
.join('g')
|
|
152
160
|
.attr(plotDataAttr, 1)
|
|
153
161
|
.attr(plotLineDataAttr, 1)
|
|
154
|
-
.
|
|
162
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
155
163
|
plotLinesSelection
|
|
156
164
|
.append('path')
|
|
157
165
|
.attr('d', (d) => lineGenerator(d.points))
|
|
@@ -175,8 +175,21 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
175
175
|
],
|
|
176
176
|
}
|
|
177
177
|
: null;
|
|
178
|
+
let mark = null;
|
|
179
|
+
if (axis.tickMarks.enabled) {
|
|
180
|
+
const isLeft = axis.position === 'left';
|
|
181
|
+
const markX = isLeft ? 0 : width;
|
|
182
|
+
const dir = isLeft ? -1 : 1;
|
|
183
|
+
mark = {
|
|
184
|
+
points: [
|
|
185
|
+
[markX, y],
|
|
186
|
+
[markX + dir * axis.tickMarks.length, y],
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
178
190
|
ticks.push({
|
|
179
191
|
line: tickLine,
|
|
192
|
+
mark,
|
|
180
193
|
svgLabel,
|
|
181
194
|
htmlLabel,
|
|
182
195
|
});
|
|
@@ -273,6 +286,7 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
273
286
|
}
|
|
274
287
|
return {
|
|
275
288
|
id: getUniqId(),
|
|
289
|
+
gridEnabled: axis.grid.enabled,
|
|
276
290
|
title,
|
|
277
291
|
ticks,
|
|
278
292
|
domain,
|
|
@@ -7,9 +7,14 @@
|
|
|
7
7
|
dominant-baseline: text-after-edge;
|
|
8
8
|
}
|
|
9
9
|
.gcharts-y-axis__tick {
|
|
10
|
-
stroke: var(--
|
|
10
|
+
stroke: var(--gcharts-axis-tick-color);
|
|
11
|
+
}
|
|
12
|
+
.gcharts-y-axis__mark {
|
|
13
|
+
stroke: var(--gcharts-axis-tick-mark-color, var(--g-color-line-generic-active));
|
|
14
|
+
}
|
|
15
|
+
.gcharts-y-axis__mark_grid {
|
|
16
|
+
stroke: var(--gcharts-axis-tick-mark-color, var(--gcharts-axis-tick-color));
|
|
11
17
|
}
|
|
12
18
|
.gcharts-y-axis__title {
|
|
13
|
-
dominant-baseline: text-after-edge;
|
|
14
19
|
fill: var(--g-color-text-secondary);
|
|
15
20
|
}
|
|
@@ -16,8 +16,12 @@ export type AxisSvgLabelData = {
|
|
|
16
16
|
export type AxisTickLine = {
|
|
17
17
|
points: PointPosition[];
|
|
18
18
|
};
|
|
19
|
+
export type AxisTickMarkData = {
|
|
20
|
+
points: PointPosition[];
|
|
21
|
+
};
|
|
19
22
|
export type AxisTickData = {
|
|
20
23
|
line: AxisTickLine | null;
|
|
24
|
+
mark: AxisTickMarkData | null;
|
|
21
25
|
svgLabel: AxisSvgLabelData | null;
|
|
22
26
|
htmlLabel: HtmlItem | null;
|
|
23
27
|
};
|
|
@@ -81,6 +85,7 @@ export type AxisDomainData = {
|
|
|
81
85
|
};
|
|
82
86
|
export type AxisYData = {
|
|
83
87
|
id: string;
|
|
88
|
+
gridEnabled: boolean;
|
|
84
89
|
title: HtmlAxisTitleData | SvgAxisTitleData | null;
|
|
85
90
|
domain: AxisDomainData | null;
|
|
86
91
|
ticks: AxisTickData[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
3
|
import type { PreparedXAxis, PreparedYAxis, ShapeData } from '../../hooks';
|
|
4
|
+
import type { ChartScale } from '../../hooks/useAxisScales/types';
|
|
4
5
|
import type { useChartInnerState } from './useChartInnerState';
|
|
5
6
|
type ChartInnerState = ReturnType<typeof useChartInnerState>;
|
|
6
7
|
type Props = {
|
|
@@ -16,6 +17,8 @@ type Props = {
|
|
|
16
17
|
unpinTooltip: ChartInnerState['unpinTooltip'];
|
|
17
18
|
xAxis: PreparedXAxis | null;
|
|
18
19
|
yAxis: PreparedYAxis[];
|
|
20
|
+
xScale?: ChartScale;
|
|
21
|
+
yScale?: (ChartScale | undefined)[];
|
|
19
22
|
tooltipThrottle: number;
|
|
20
23
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
21
24
|
};
|
|
@@ -4,8 +4,9 @@ import throttle from 'lodash/throttle';
|
|
|
4
4
|
import { IS_TOUCH_ENABLED } from '../../constants';
|
|
5
5
|
import { EventType } from '../../utils';
|
|
6
6
|
import { getClosestPoints } from '../../utils/chart/get-closest-data';
|
|
7
|
+
import { getHoveredPlots } from '../../utils/chart/get-hovered-plots';
|
|
7
8
|
export function useChartInnerHandlers(props) {
|
|
8
|
-
const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, dispatcher, shapesData, svgContainer, togglePinTooltip, tooltipPinned, unpinTooltip, xAxis, yAxis, tooltipThrottle, isOutsideBounds, } = props;
|
|
9
|
+
const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, dispatcher, shapesData, svgContainer, togglePinTooltip, tooltipPinned, unpinTooltip, xAxis, yAxis, xScale, yScale, tooltipThrottle, isOutsideBounds, } = props;
|
|
9
10
|
const handleMove = ([pointerX, pointerY], event) => {
|
|
10
11
|
if (tooltipPinned) {
|
|
11
12
|
return;
|
|
@@ -24,11 +25,22 @@ export function useChartInnerHandlers(props) {
|
|
|
24
25
|
boundsHeight,
|
|
25
26
|
boundsWidth,
|
|
26
27
|
});
|
|
27
|
-
|
|
28
|
+
const { plotLines, plotBands } = getHoveredPlots({
|
|
29
|
+
pointerX: x,
|
|
30
|
+
pointerY: y,
|
|
31
|
+
xAxis,
|
|
32
|
+
yAxis,
|
|
33
|
+
xScale,
|
|
34
|
+
yScale,
|
|
35
|
+
});
|
|
36
|
+
const hoveredPlotsArg = { lines: plotLines, bands: plotBands };
|
|
37
|
+
dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY], hoveredPlotsArg);
|
|
28
38
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
29
39
|
hovered: closest,
|
|
30
40
|
xAxis,
|
|
31
41
|
yAxis: yAxis[0],
|
|
42
|
+
hoveredPlotLines: plotLines,
|
|
43
|
+
hoveredPlotBands: plotBands,
|
|
32
44
|
}, event);
|
|
33
45
|
};
|
|
34
46
|
const handleMouseMove = (event) => {
|
|
@@ -77,11 +89,22 @@ export function useChartInnerHandlers(props) {
|
|
|
77
89
|
dispatcher.call(EventType.CLICK_CHART, undefined, { point: selected.data, series: selected.series }, event);
|
|
78
90
|
const nextTooltipFixed = !tooltipPinned;
|
|
79
91
|
if (!nextTooltipFixed) {
|
|
80
|
-
|
|
92
|
+
const { plotLines, plotBands } = getHoveredPlots({
|
|
93
|
+
pointerX: x,
|
|
94
|
+
pointerY: y,
|
|
95
|
+
xAxis,
|
|
96
|
+
yAxis,
|
|
97
|
+
xScale,
|
|
98
|
+
yScale,
|
|
99
|
+
});
|
|
100
|
+
const hoveredPlotsArg = { lines: plotLines, bands: plotBands };
|
|
101
|
+
dispatcher.call(EventType.HOVER_SHAPE, event.target, items, [pointerX, pointerY], hoveredPlotsArg);
|
|
81
102
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
82
103
|
hovered: items,
|
|
83
104
|
xAxis,
|
|
84
105
|
yAxis: yAxis[0],
|
|
106
|
+
hoveredPlotLines: plotLines,
|
|
107
|
+
hoveredPlotBands: plotBands,
|
|
85
108
|
}, event);
|
|
86
109
|
}
|
|
87
110
|
togglePinTooltip === null || togglePinTooltip === void 0 ? void 0 : togglePinTooltip(nextTooltipFixed, event);
|
|
@@ -77,6 +77,7 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
77
77
|
ticks: {
|
|
78
78
|
pixelInterval?: number;
|
|
79
79
|
};
|
|
80
|
+
tickMarks: import("../../hooks").PreparedAxisTickMarks;
|
|
80
81
|
position: "left" | "right" | "top" | "bottom";
|
|
81
82
|
plotIndex: number;
|
|
82
83
|
plotLines: import("../../hooks").PreparedAxisPlotLine[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ChartTooltip, ChartXAxis, ChartYAxis, TooltipDataChunk } from '../../types';
|
|
2
|
+
import type { ChartTooltip, ChartTooltipRendererArgs, ChartXAxis, ChartYAxis, TooltipDataChunk } from '../../types';
|
|
3
3
|
export interface ChartTooltipContentProps {
|
|
4
4
|
hovered?: TooltipDataChunk[];
|
|
5
5
|
pinned?: boolean;
|
|
@@ -7,6 +7,8 @@ export interface ChartTooltipContentProps {
|
|
|
7
7
|
rowRenderer?: ChartTooltip['rowRenderer'];
|
|
8
8
|
valueFormat?: ChartTooltip['valueFormat'];
|
|
9
9
|
headerFormat?: ChartTooltip['headerFormat'];
|
|
10
|
+
hoveredPlotLines?: ChartTooltipRendererArgs['hoveredPlotLines'];
|
|
11
|
+
hoveredPlotBands?: ChartTooltipRendererArgs['hoveredPlotBands'];
|
|
10
12
|
totals?: ChartTooltip['totals'];
|
|
11
13
|
xAxis?: ChartXAxis | null;
|
|
12
14
|
yAxis?: ChartYAxis;
|
|
@@ -2,11 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import isNil from 'lodash/isNil';
|
|
3
3
|
import { DefaultTooltipContent } from './DefaultTooltipContent';
|
|
4
4
|
export const ChartTooltipContent = React.memo((props) => {
|
|
5
|
-
const { hovered, xAxis, yAxis, renderer, rowRenderer, valueFormat, headerFormat, totals, pinned, qa, } = props;
|
|
5
|
+
const { hovered, hoveredPlotLines, hoveredPlotBands, xAxis, yAxis, renderer, rowRenderer, valueFormat, headerFormat, totals, pinned, qa, } = props;
|
|
6
6
|
if (!hovered) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
|
-
const customTooltip = renderer === null || renderer === void 0 ? void 0 : renderer({ hovered, xAxis, yAxis });
|
|
9
|
+
const customTooltip = renderer === null || renderer === void 0 ? void 0 : renderer({ hovered, hoveredPlotLines, hoveredPlotBands, xAxis, yAxis });
|
|
10
10
|
return isNil(customTooltip) ? (React.createElement(DefaultTooltipContent, { hovered: hovered, pinned: pinned, rowRenderer: rowRenderer, totals: totals, valueFormat: valueFormat, headerFormat: headerFormat, xAxis: xAxis, yAxis: yAxis, qa: qa })) : (customTooltip);
|
|
11
11
|
});
|
|
12
12
|
ChartTooltipContent.displayName = 'ChartTooltipContent';
|
|
@@ -14,6 +14,6 @@ export function Row(props) {
|
|
|
14
14
|
}, [color, colorSymbol]);
|
|
15
15
|
return (React.createElement("div", { className: b('content-row', { active, striped }, className), style: style },
|
|
16
16
|
colorItem,
|
|
17
|
-
label,
|
|
17
|
+
React.createElement("span", { className: b('content-row-label') }, label),
|
|
18
18
|
value && React.createElement("span", { className: b('content-row-value') }, value)));
|
|
19
19
|
}
|
|
@@ -7,7 +7,10 @@ import './styles.css';
|
|
|
7
7
|
const b = block('tooltip');
|
|
8
8
|
export const Tooltip = (props) => {
|
|
9
9
|
const { tooltip, xAxis, yAxis, svgContainer, dispatcher, tooltipPinned, onOutsideClick } = props;
|
|
10
|
-
const { hovered, pointerPosition } = useTooltip({
|
|
10
|
+
const { hovered, hoveredPlotLines, hoveredPlotBands, pointerPosition } = useTooltip({
|
|
11
|
+
dispatcher,
|
|
12
|
+
tooltip,
|
|
13
|
+
});
|
|
11
14
|
const containerRect = (svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) || { left: 0, top: 0 };
|
|
12
15
|
const left = ((pointerPosition === null || pointerPosition === void 0 ? void 0 : pointerPosition[0]) || 0) + containerRect.left;
|
|
13
16
|
const top = ((pointerPosition === null || pointerPosition === void 0 ? void 0 : pointerPosition[1]) || 0) + containerRect.top;
|
|
@@ -23,5 +26,5 @@ export const Tooltip = (props) => {
|
|
|
23
26
|
}, [left, top]);
|
|
24
27
|
return (hovered === null || hovered === void 0 ? void 0 : hovered.length) ? (React.createElement(Popup, { anchorElement: anchor, className: b({ pinned: tooltipPinned }), disableTransition: true, floatingStyles: tooltipPinned ? undefined : { pointerEvents: 'none' }, offset: { mainAxis: 20 }, onOpenChange: tooltipPinned ? handleOnOpenChange : undefined, open: true, placement: ['right', 'left', 'top', 'bottom'] },
|
|
25
28
|
React.createElement("div", { className: b('popup-content') },
|
|
26
|
-
React.createElement(ChartTooltipContent, { hovered: hovered, pinned: tooltipPinned, renderer: tooltip.renderer, rowRenderer: tooltip.rowRenderer, totals: tooltip.totals, valueFormat: tooltip.valueFormat, headerFormat: tooltip.headerFormat, xAxis: xAxis, yAxis: yAxis, qa: tooltip.qa })))) : null;
|
|
29
|
+
React.createElement(ChartTooltipContent, { hovered: hovered, hoveredPlotLines: hoveredPlotLines, hoveredPlotBands: hoveredPlotBands, pinned: tooltipPinned, renderer: tooltip.renderer, rowRenderer: tooltip.rowRenderer, totals: tooltip.totals, valueFormat: tooltip.valueFormat, headerFormat: tooltip.headerFormat, xAxis: xAxis, yAxis: yAxis, qa: tooltip.qa })))) : null;
|
|
27
30
|
};
|
|
@@ -45,14 +45,21 @@
|
|
|
45
45
|
font-weight: 600;
|
|
46
46
|
background-color: var(--g-color-base-info-medium);
|
|
47
47
|
}
|
|
48
|
+
.gcharts-tooltip__content-row-label {
|
|
49
|
+
overflow: hidden;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
text-overflow: ellipsis;
|
|
52
|
+
}
|
|
48
53
|
.gcharts-tooltip__content-row-color {
|
|
49
54
|
display: inline-block;
|
|
55
|
+
flex-shrink: 0;
|
|
50
56
|
width: 16px;
|
|
51
57
|
height: 8px;
|
|
52
58
|
border-radius: 2px;
|
|
53
59
|
background-color: #dddddd;
|
|
54
60
|
}
|
|
55
61
|
.gcharts-tooltip__content-row-value {
|
|
62
|
+
flex-shrink: 0;
|
|
56
63
|
margin-inline-start: auto;
|
|
57
64
|
}
|
|
58
65
|
.gcharts-tooltip__content-row-totals {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DEFAULT_DATE_FORMAT = "DD.MM.YY";
|
|
2
|
+
export declare const SECOND = 1000;
|
|
3
|
+
export declare const MINUTE: number;
|
|
4
|
+
export declare const HOUR: number;
|
|
5
|
+
export declare const DAY: number;
|
|
6
|
+
export declare const WEEK: number;
|
|
7
|
+
export declare const MONTH: number;
|
|
8
|
+
export declare const YEAR: number;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const DEFAULT_DATE_FORMAT = 'DD.MM.YY';
|
|
2
|
+
export const SECOND = 1000;
|
|
3
|
+
export const MINUTE = SECOND * 60;
|
|
4
|
+
export const HOUR = MINUTE * 60;
|
|
5
|
+
export const DAY = HOUR * 24;
|
|
6
|
+
export const WEEK = DAY * 7;
|
|
7
|
+
export const MONTH = DAY * 30;
|
|
8
|
+
export const YEAR = DAY * 365;
|
|
@@ -12,5 +12,9 @@ type AxisCrosshairDefaults = Required<AxisCrosshair>;
|
|
|
12
12
|
export declare const axisCrosshairDefaults: AxisCrosshairDefaults;
|
|
13
13
|
export declare const xAxisTitleDefaults: AxisTitleDefaults;
|
|
14
14
|
export declare const yAxisTitleDefaults: AxisTitleDefaults;
|
|
15
|
+
export declare const axisTickMarksDefaults: {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
length: number;
|
|
18
|
+
};
|
|
15
19
|
export declare const DEFAULT_AXIS_TYPE: ChartAxisType;
|
|
16
20
|
export {};
|
|
@@ -25,4 +25,8 @@ export const axisCrosshairDefaults = {
|
|
|
25
25
|
};
|
|
26
26
|
export const xAxisTitleDefaults = Object.assign(Object.assign({}, axisTitleDefaults), { margin: 4 });
|
|
27
27
|
export const yAxisTitleDefaults = Object.assign(Object.assign({}, axisTitleDefaults), { margin: 8 });
|
|
28
|
+
export const axisTickMarksDefaults = {
|
|
29
|
+
enabled: false,
|
|
30
|
+
length: 6,
|
|
31
|
+
};
|
|
28
32
|
export const DEFAULT_AXIS_TYPE = 'linear';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { DashStyle } from '../../constants';
|
|
3
|
-
import type { AxisCrosshair, AxisPlotBand, BaseTextStyle, ChartAxis, ChartAxisLabels, ChartAxisRangeSlider, ChartAxisTitleAlignment, ChartAxisType, DeepRequired, PlotLayerPlacement } from '../../types';
|
|
3
|
+
import type { AxisCrosshair, AxisPlotBand, BaseTextStyle, ChartAxis, ChartAxisLabels, ChartAxisRangeSlider, ChartAxisTitleAlignment, ChartAxisType, DeepRequired, MeaningfulAny, PlotLayerPlacement } from '../../types';
|
|
4
4
|
type PreparedAxisLabels = Omit<ChartAxisLabels, 'enabled' | 'padding' | 'style' | 'autoRotation'> & Required<Pick<ChartAxisLabels, 'enabled' | 'padding' | 'margin' | 'rotation' | 'html'>> & {
|
|
5
5
|
style: BaseTextStyle;
|
|
6
6
|
rotation: number;
|
|
@@ -10,6 +10,7 @@ type PreparedAxisLabels = Omit<ChartAxisLabels, 'enabled' | 'padding' | 'style'
|
|
|
10
10
|
maxWidth: number;
|
|
11
11
|
};
|
|
12
12
|
export type PreparedAxisPlotBand = Required<AxisPlotBand> & {
|
|
13
|
+
custom?: MeaningfulAny;
|
|
13
14
|
label: {
|
|
14
15
|
text: string;
|
|
15
16
|
style: BaseTextStyle;
|
|
@@ -25,6 +26,7 @@ export type PreparedAxisPlotLine = {
|
|
|
25
26
|
dashStyle: DashStyle;
|
|
26
27
|
opacity: number;
|
|
27
28
|
layerPlacement: PlotLayerPlacement;
|
|
29
|
+
custom?: MeaningfulAny;
|
|
28
30
|
label: {
|
|
29
31
|
text: string;
|
|
30
32
|
style: BaseTextStyle;
|
|
@@ -35,6 +37,10 @@ export type PreparedAxisPlotLine = {
|
|
|
35
37
|
export type PreparedRangeSlider = DeepRequired<Omit<ChartAxisRangeSlider, 'defaultRange'>> & {
|
|
36
38
|
defaultRange?: ChartAxisRangeSlider['defaultRange'];
|
|
37
39
|
};
|
|
40
|
+
export type PreparedAxisTickMarks = {
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
length: number;
|
|
43
|
+
};
|
|
38
44
|
type PreparedBaseAxis = Omit<ChartAxis, 'type' | 'labels' | 'plotLines' | 'plotBands'> & {
|
|
39
45
|
type: ChartAxisType;
|
|
40
46
|
labels: PreparedAxisLabels;
|
|
@@ -58,6 +64,7 @@ type PreparedBaseAxis = Omit<ChartAxis, 'type' | 'labels' | 'plotLines' | 'plotB
|
|
|
58
64
|
ticks: {
|
|
59
65
|
pixelInterval?: number;
|
|
60
66
|
};
|
|
67
|
+
tickMarks: PreparedAxisTickMarks;
|
|
61
68
|
position: 'left' | 'right' | 'top' | 'bottom';
|
|
62
69
|
plotIndex: number;
|
|
63
70
|
plotLines: PreparedAxisPlotLine[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, xAxisTitleDefaults, } from '../../constants';
|
|
3
|
-
import { calculateCos, calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getHorizontalHtmlTextHeight, getHorizontalSvgTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, wrapText, } from '../../utils';
|
|
2
|
+
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, xAxisTitleDefaults, } from '../../constants';
|
|
3
|
+
import { TIME_UNITS, calculateCos, calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getHorizontalHtmlTextHeight, getHorizontalSvgTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, wrapText, } from '../../utils';
|
|
4
4
|
import { getXAxisTickValues } from '../../utils/chart/axis/x-axis';
|
|
5
5
|
import { createXScale } from '../useAxisScales';
|
|
6
6
|
import { getPreparedRangeSlider } from './range-slider';
|
|
@@ -17,7 +17,7 @@ async function setLabelSettings({ axis, seriesData, width, axisLabels, }) {
|
|
|
17
17
|
const labelLineHeight = (await getTextSize('Tmp')).height;
|
|
18
18
|
const tickValues = getXAxisTickValues({ axis, scale, labelLineHeight, series: seriesData });
|
|
19
19
|
const tickStep = getMinSpaceBetween(tickValues, (d) => Number(d.value));
|
|
20
|
-
if (axis.type === 'datetime' && !(axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.dateFormat)) {
|
|
20
|
+
if (axis.type === 'datetime' && !(axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.dateFormat) && tickStep >= TIME_UNITS.day) {
|
|
21
21
|
axis.labels.dateFormat = getDefaultDateFormat(tickStep);
|
|
22
22
|
}
|
|
23
23
|
const labels = tickValues.map((tick) => formatAxisTickLabel({
|
|
@@ -141,6 +141,10 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
141
141
|
})
|
|
142
142
|
: (_j = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _j === void 0 ? void 0 : _j.pixelInterval,
|
|
143
143
|
},
|
|
144
|
+
tickMarks: {
|
|
145
|
+
enabled: get(xAxis, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
146
|
+
length: get(xAxis, 'tickMarks.length', axisTickMarksDefaults.length),
|
|
147
|
+
},
|
|
144
148
|
position: 'bottom',
|
|
145
149
|
plotIndex: 0,
|
|
146
150
|
plotLines: get(xAxis, 'plotLines', []).map((d) => ({
|
|
@@ -150,6 +154,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
150
154
|
dashStyle: get(d, 'dashStyle', DASH_STYLE.Solid),
|
|
151
155
|
opacity: get(d, 'opacity', 1),
|
|
152
156
|
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
157
|
+
custom: d.custom,
|
|
153
158
|
label: prepareAxisPlotLabel(d),
|
|
154
159
|
})),
|
|
155
160
|
plotBands: get(xAxis, 'plotBands', []).map((d) => ({
|
|
@@ -158,6 +163,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
158
163
|
from: get(d, 'from', 0),
|
|
159
164
|
to: get(d, 'to', 0),
|
|
160
165
|
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
166
|
+
custom: d.custom,
|
|
161
167
|
label: prepareAxisPlotLabel(d),
|
|
162
168
|
})),
|
|
163
169
|
crosshair: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import { getTickValues } from '../../components/AxisY/utils';
|
|
3
|
-
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, yAxisTitleDefaults, } from '../../constants';
|
|
3
|
+
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, yAxisTitleDefaults, } from '../../constants';
|
|
4
4
|
import { calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getDefaultMinYAxisValue, getHorizontalHtmlTextHeight, getHorizontalSvgTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, shouldSyncAxisWithPrimary, wrapText, } from '../../utils';
|
|
5
5
|
import { createYScale } from '../useAxisScales';
|
|
6
6
|
import { prepareAxisPlotLabel } from './utils';
|
|
@@ -160,6 +160,10 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
160
160
|
})
|
|
161
161
|
: (_q = axisItem.ticks) === null || _q === void 0 ? void 0 : _q.pixelInterval,
|
|
162
162
|
},
|
|
163
|
+
tickMarks: {
|
|
164
|
+
enabled: get(axisItem, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
165
|
+
length: get(axisItem, 'tickMarks.length', axisTickMarksDefaults.length),
|
|
166
|
+
},
|
|
163
167
|
position: axisPosition,
|
|
164
168
|
plotIndex: get(axisItem, 'plotIndex', 0),
|
|
165
169
|
plotLines: get(axisItem, 'plotLines', []).map((d) => ({
|
|
@@ -169,6 +173,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
169
173
|
dashStyle: get(d, 'dashStyle', DASH_STYLE.Solid),
|
|
170
174
|
opacity: get(d, 'opacity', 1),
|
|
171
175
|
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
176
|
+
custom: d.custom,
|
|
172
177
|
label: prepareAxisPlotLabel(d),
|
|
173
178
|
})),
|
|
174
179
|
plotBands: get(axisItem, 'plotBands', []).map((d) => ({
|
|
@@ -177,6 +182,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
177
182
|
from: get(d, 'from', 0),
|
|
178
183
|
to: get(d, 'to', 0),
|
|
179
184
|
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
185
|
+
custom: d.custom,
|
|
180
186
|
label: prepareAxisPlotLabel(d),
|
|
181
187
|
})),
|
|
182
188
|
crosshair: {
|
|
@@ -6,4 +6,4 @@ export declare function createXScale(args: {
|
|
|
6
6
|
series: (PreparedSeries | ChartSeries)[];
|
|
7
7
|
rangeSliderState?: RangeSliderState;
|
|
8
8
|
zoomStateX?: [number, number];
|
|
9
|
-
}): import("d3-scale").
|
|
9
|
+
}): import("d3-scale").ScaleLinear<number, number, never> | import("d3-scale").ScaleBand<string> | import("d3-scale").ScaleTime<number, number, never> | undefined;
|
|
@@ -7,4 +7,4 @@ export declare function createYScale(args: {
|
|
|
7
7
|
primaryAxis?: PreparedAxis;
|
|
8
8
|
primaryTicksCount?: number;
|
|
9
9
|
zoomStateY?: [number, number];
|
|
10
|
-
}): import("d3-scale").
|
|
10
|
+
}): import("d3-scale").ScaleLinear<number, number, never> | import("d3-scale").ScaleBand<string> | import("d3-scale").ScaleTime<number, number, never> | undefined;
|
|
@@ -27,6 +27,7 @@ export declare function useNormalizedOriginalData(props: UseOriginalDataProps):
|
|
|
27
27
|
maxPadding?: number;
|
|
28
28
|
plotLines?: import("../..").AxisPlotLine[];
|
|
29
29
|
plotBands?: import("../..").AxisPlotBand[];
|
|
30
|
+
tickMarks?: import("../..").ChartAxisTickMarks;
|
|
30
31
|
visible?: boolean;
|
|
31
32
|
order?: "sortAsc" | "sortDesc" | "reverse";
|
|
32
33
|
startOnTick?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Dispatch } from 'd3';
|
|
2
|
-
import type { PointPosition, TooltipDataChunk } from '../../types';
|
|
2
|
+
import type { AxisPlotBand, AxisPlotLine, PointPosition, TooltipDataChunk } from '../../types';
|
|
3
3
|
import type { PreparedTooltip } from '../useChartOptions/types';
|
|
4
4
|
type Args = {
|
|
5
5
|
dispatcher: Dispatch<object>;
|
|
@@ -7,6 +7,8 @@ type Args = {
|
|
|
7
7
|
};
|
|
8
8
|
export declare const useTooltip: ({ dispatcher, tooltip }: Args) => {
|
|
9
9
|
hovered: TooltipDataChunk[] | undefined;
|
|
10
|
+
hoveredPlotLines: AxisPlotLine[] | undefined;
|
|
11
|
+
hoveredPlotBands: AxisPlotBand[] | undefined;
|
|
10
12
|
pointerPosition: PointPosition | undefined;
|
|
11
13
|
};
|
|
12
14
|
export {};
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import isEqual from 'lodash/isEqual';
|
|
3
3
|
export const useTooltip = ({ dispatcher, tooltip }) => {
|
|
4
|
-
const [{ hovered, pointerPosition }, setTooltipState] = React.useState({});
|
|
4
|
+
const [{ hovered, hoveredPlotLines, hoveredPlotBands, pointerPosition }, setTooltipState] = React.useState({});
|
|
5
5
|
const prevHovered = React.useRef(hovered);
|
|
6
6
|
React.useEffect(() => {
|
|
7
7
|
if (tooltip === null || tooltip === void 0 ? void 0 : tooltip.enabled) {
|
|
8
|
-
dispatcher.on('hover-shape.tooltip', (nextHovered, nextPointerPosition) => {
|
|
8
|
+
dispatcher.on('hover-shape.tooltip', (nextHovered, nextPointerPosition, nextHoveredPlots) => {
|
|
9
9
|
const filteredNextHovered = nextHovered === null || nextHovered === void 0 ? void 0 : nextHovered.filter((item) => 'y' in item.data ? item.data.y !== null : true);
|
|
10
10
|
const isHoveredChanged = !isEqual(prevHovered.current, filteredNextHovered);
|
|
11
11
|
const newTooltipState = {
|
|
12
|
-
pointerPosition: nextPointerPosition,
|
|
13
12
|
hovered: isHoveredChanged ? filteredNextHovered : prevHovered.current,
|
|
13
|
+
hoveredPlotLines: nextHoveredPlots === null || nextHoveredPlots === void 0 ? void 0 : nextHoveredPlots.lines,
|
|
14
|
+
hoveredPlotBands: nextHoveredPlots === null || nextHoveredPlots === void 0 ? void 0 : nextHoveredPlots.bands,
|
|
15
|
+
pointerPosition: nextPointerPosition,
|
|
14
16
|
};
|
|
15
17
|
if (isHoveredChanged) {
|
|
16
18
|
prevHovered.current = filteredNextHovered;
|
|
@@ -26,6 +28,8 @@ export const useTooltip = ({ dispatcher, tooltip }) => {
|
|
|
26
28
|
}, [dispatcher, tooltip]);
|
|
27
29
|
return {
|
|
28
30
|
hovered,
|
|
31
|
+
hoveredPlotLines,
|
|
32
|
+
hoveredPlotBands,
|
|
29
33
|
pointerPosition,
|
|
30
34
|
};
|
|
31
35
|
};
|