@gravity-ui/charts 1.35.2 → 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 +15 -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 +13 -7
- 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/defaults/axis.d.ts +4 -0
- package/dist/cjs/constants/defaults/axis.js +4 -0
- package/dist/cjs/hooks/useAxis/types.d.ts +8 -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/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 +16 -1
- package/dist/cjs/types/chart/tooltip.d.ts +5 -1
- 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/time.d.ts +1 -0
- package/dist/cjs/utils/chart/time.js +9 -0
- package/dist/esm/components/AxisX/AxisX.js +15 -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 +13 -7
- 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/defaults/axis.d.ts +4 -0
- package/dist/esm/constants/defaults/axis.js +4 -0
- package/dist/esm/hooks/useAxis/types.d.ts +8 -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/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 +16 -1
- package/dist/esm/types/chart/tooltip.d.ts +5 -1
- 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/time.d.ts +1 -0
- package/dist/esm/utils/chart/time.js +9 -0
- package/package.json +1 -1
|
@@ -33,7 +33,7 @@ export const AxisX = (props) => {
|
|
|
33
33
|
.attr('class', b('title'))
|
|
34
34
|
.append('text')
|
|
35
35
|
.attr('text-anchor', 'start')
|
|
36
|
-
.
|
|
36
|
+
.attr('transform', `translate(${preparedAxisData.title.x},${preparedAxisData.title.y}) rotate(${preparedAxisData.title.rotate}) translate(0,${preparedAxisData.title.offset})`)
|
|
37
37
|
.attr('font-size', preparedAxisData.title.style.fontSize)
|
|
38
38
|
.attr('font-weight', (_a = preparedAxisData.title.style.fontWeight) !== null && _a !== void 0 ? _a : null)
|
|
39
39
|
.attr('fill', (_b = preparedAxisData.title.style.fontColor) !== null && _b !== void 0 ? _b : null)
|
|
@@ -43,6 +43,7 @@ export const AxisX = (props) => {
|
|
|
43
43
|
.html((d) => d.text)
|
|
44
44
|
.attr('x', (d) => d.x)
|
|
45
45
|
.attr('y', (d) => d.y)
|
|
46
|
+
.attr('dominant-baseline', 'text-before-edge')
|
|
46
47
|
.attr('text-anchor', 'start');
|
|
47
48
|
}
|
|
48
49
|
if (preparedAxisData.domain) {
|
|
@@ -67,13 +68,19 @@ export const AxisX = (props) => {
|
|
|
67
68
|
if (tickData.line) {
|
|
68
69
|
tickSelection.append('path').attr('d', lineGenerator(tickData.line.points));
|
|
69
70
|
}
|
|
71
|
+
if (tickData.mark) {
|
|
72
|
+
tickSelection
|
|
73
|
+
.append('path')
|
|
74
|
+
.attr('class', b('mark', { grid: preparedAxisData.gridEnabled }))
|
|
75
|
+
.attr('d', lineGenerator(tickData.mark.points));
|
|
76
|
+
}
|
|
70
77
|
if (tickData.svgLabel) {
|
|
71
78
|
const label = tickData.svgLabel;
|
|
72
79
|
const textSelection = tickSelection
|
|
73
80
|
.append('text')
|
|
74
|
-
.
|
|
75
|
-
`translate(${label.x}
|
|
76
|
-
label.angle ? `rotate(${label.angle}
|
|
81
|
+
.attr('transform', [
|
|
82
|
+
`translate(${label.x}, ${label.y})`,
|
|
83
|
+
label.angle ? `rotate(${label.angle})` : '',
|
|
77
84
|
]
|
|
78
85
|
.filter(Boolean)
|
|
79
86
|
.join(' '));
|
|
@@ -106,7 +113,7 @@ export const AxisX = (props) => {
|
|
|
106
113
|
.join('g')
|
|
107
114
|
.attr(plotDataAttr, 1)
|
|
108
115
|
.attr(plotBandDataAttr, 1)
|
|
109
|
-
.
|
|
116
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
110
117
|
plotBandsSelection
|
|
111
118
|
.append('rect')
|
|
112
119
|
.attr('width', (d) => d.width)
|
|
@@ -127,7 +134,7 @@ export const AxisX = (props) => {
|
|
|
127
134
|
.style('font-weight', (_b = label.style.fontWeight) !== null && _b !== void 0 ? _b : '')
|
|
128
135
|
.style('dominant-baseline', 'text-before-edge')
|
|
129
136
|
.style('text-anchor', 'start')
|
|
130
|
-
.
|
|
137
|
+
.attr('transform', `translate(${label.x}, ${label.y}) rotate(${label.rotate})`)
|
|
131
138
|
.attr('data-qa', (_c = label.qa) !== null && _c !== void 0 ? _c : null);
|
|
132
139
|
}
|
|
133
140
|
});
|
|
@@ -147,7 +154,7 @@ export const AxisX = (props) => {
|
|
|
147
154
|
.join('g')
|
|
148
155
|
.attr(plotDataAttr, 1)
|
|
149
156
|
.attr(plotLineDataAttr, 1)
|
|
150
|
-
.
|
|
157
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
151
158
|
plotLinesSelection
|
|
152
159
|
.append('path')
|
|
153
160
|
.attr('d', (d) => lineGenerator(d.points))
|
|
@@ -169,7 +176,7 @@ export const AxisX = (props) => {
|
|
|
169
176
|
.style('font-weight', (_b = label.style.fontWeight) !== null && _b !== void 0 ? _b : '')
|
|
170
177
|
.style('dominant-baseline', 'text-before-edge')
|
|
171
178
|
.style('text-anchor', 'start')
|
|
172
|
-
.
|
|
179
|
+
.attr('transform', `translate(${label.x}, ${label.y}) rotate(${label.rotate})`)
|
|
173
180
|
.attr('data-qa', (_c = label.qa) !== null && _c !== void 0 ? _c : null);
|
|
174
181
|
}
|
|
175
182
|
});
|
|
@@ -178,8 +178,19 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
178
178
|
],
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
|
+
let mark = null;
|
|
182
|
+
if (isBottomPlot && axis.tickMarks.enabled) {
|
|
183
|
+
const axisBottom = axisTop + axisHeight;
|
|
184
|
+
mark = {
|
|
185
|
+
points: [
|
|
186
|
+
[tickValue.x, axisBottom],
|
|
187
|
+
[tickValue.x, axisBottom + axis.tickMarks.length],
|
|
188
|
+
],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
181
191
|
ticks.push({
|
|
182
192
|
line: tickLine,
|
|
193
|
+
mark,
|
|
183
194
|
svgLabel,
|
|
184
195
|
htmlLabel,
|
|
185
196
|
});
|
|
@@ -315,6 +326,7 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
315
326
|
}
|
|
316
327
|
xAxisItems.push({
|
|
317
328
|
id: getUniqId(),
|
|
329
|
+
gridEnabled: axis.grid.enabled,
|
|
318
330
|
title,
|
|
319
331
|
ticks,
|
|
320
332
|
domain,
|
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
stroke: none;
|
|
7
7
|
}
|
|
8
8
|
.gcharts-x-axis__tick {
|
|
9
|
-
stroke: var(--
|
|
9
|
+
stroke: var(--gcharts-axis-tick-color);
|
|
10
|
+
}
|
|
11
|
+
.gcharts-x-axis__mark {
|
|
12
|
+
stroke: var(--gcharts-axis-tick-mark-color, var(--g-color-line-generic-active));
|
|
13
|
+
}
|
|
14
|
+
.gcharts-x-axis__mark_grid {
|
|
15
|
+
stroke: var(--gcharts-axis-tick-mark-color, var(--gcharts-axis-tick-color));
|
|
10
16
|
}
|
|
11
17
|
.gcharts-x-axis__title {
|
|
12
|
-
dominant-baseline: text-before-edge;
|
|
13
18
|
fill: var(--g-color-text-secondary);
|
|
14
19
|
}
|
|
@@ -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[];
|
|
@@ -38,8 +38,7 @@ 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)
|
|
44
43
|
.attr('font-weight', (_b = preparedAxisData.title.style.fontWeight) !== null && _b !== void 0 ? _b : null)
|
|
45
44
|
.attr('fill', (_c = preparedAxisData.title.style.fontColor) !== null && _c !== void 0 ? _c : null)
|
|
@@ -49,6 +48,7 @@ export const AxisY = (props) => {
|
|
|
49
48
|
.html((d) => d.text)
|
|
50
49
|
.attr('x', (d) => d.x)
|
|
51
50
|
.attr('y', (d) => d.y)
|
|
51
|
+
.attr('dominant-baseline', 'text-after-edge')
|
|
52
52
|
.attr('text-anchor', 'start');
|
|
53
53
|
}
|
|
54
54
|
if (preparedAxisData.domain) {
|
|
@@ -73,13 +73,19 @@ export const AxisY = (props) => {
|
|
|
73
73
|
if (tickData.line) {
|
|
74
74
|
tickSelection.append('path').attr('d', lineGenerator(tickData.line.points));
|
|
75
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
|
+
}
|
|
76
82
|
if (tickData.svgLabel) {
|
|
77
83
|
const label = tickData.svgLabel;
|
|
78
84
|
const textSelection = tickSelection
|
|
79
85
|
.append('text')
|
|
80
|
-
.
|
|
81
|
-
`translate(${label.x}
|
|
82
|
-
label.angle ? `rotate(${label.angle}
|
|
86
|
+
.attr('transform', [
|
|
87
|
+
`translate(${label.x}, ${label.y})`,
|
|
88
|
+
label.angle ? `rotate(${label.angle})` : '',
|
|
83
89
|
]
|
|
84
90
|
.filter(Boolean)
|
|
85
91
|
.join(' '));
|
|
@@ -112,7 +118,7 @@ export const AxisY = (props) => {
|
|
|
112
118
|
.join('g')
|
|
113
119
|
.attr(plotDataAttr, 1)
|
|
114
120
|
.attr(plotBandDataAttr, 1)
|
|
115
|
-
.
|
|
121
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
116
122
|
plotBandsSelection
|
|
117
123
|
.append('rect')
|
|
118
124
|
.attr('width', (d) => d.width)
|
|
@@ -153,7 +159,7 @@ export const AxisY = (props) => {
|
|
|
153
159
|
.join('g')
|
|
154
160
|
.attr(plotDataAttr, 1)
|
|
155
161
|
.attr(plotLineDataAttr, 1)
|
|
156
|
-
.
|
|
162
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
157
163
|
plotLinesSelection
|
|
158
164
|
.append('path')
|
|
159
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 {
|
|
@@ -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: {
|
|
@@ -27,6 +27,7 @@ export declare function useNormalizedOriginalData(props: UseOriginalDataProps):
|
|
|
27
27
|
maxPadding?: number;
|
|
28
28
|
plotLines?: import("../../types").AxisPlotLine[];
|
|
29
29
|
plotBands?: import("../../types").AxisPlotBand[];
|
|
30
|
+
tickMarks?: import("../../types").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 {};
|