@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
|
@@ -10,6 +10,7 @@ export const AxisX = (props) => {
|
|
|
10
10
|
const lineGenerator = line();
|
|
11
11
|
const htmlLabels = preparedAxisData.ticks.map((d) => d.htmlLabel).filter(Boolean);
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
+
var _a, _b;
|
|
13
14
|
if (!ref.current) {
|
|
14
15
|
return () => { };
|
|
15
16
|
}
|
|
@@ -32,14 +33,17 @@ export const AxisX = (props) => {
|
|
|
32
33
|
.attr('class', b('title'))
|
|
33
34
|
.append('text')
|
|
34
35
|
.attr('text-anchor', 'start')
|
|
35
|
-
.
|
|
36
|
+
.attr('transform', `translate(${preparedAxisData.title.x},${preparedAxisData.title.y}) rotate(${preparedAxisData.title.rotate}) translate(0,${preparedAxisData.title.offset})`)
|
|
36
37
|
.attr('font-size', preparedAxisData.title.style.fontSize)
|
|
38
|
+
.attr('font-weight', (_a = preparedAxisData.title.style.fontWeight) !== null && _a !== void 0 ? _a : null)
|
|
39
|
+
.attr('fill', (_b = preparedAxisData.title.style.fontColor) !== null && _b !== void 0 ? _b : null)
|
|
37
40
|
.selectAll('tspan')
|
|
38
41
|
.data(preparedAxisData.title.content)
|
|
39
42
|
.join('tspan')
|
|
40
43
|
.html((d) => d.text)
|
|
41
44
|
.attr('x', (d) => d.x)
|
|
42
45
|
.attr('y', (d) => d.y)
|
|
46
|
+
.attr('dominant-baseline', 'text-before-edge')
|
|
43
47
|
.attr('text-anchor', 'start');
|
|
44
48
|
}
|
|
45
49
|
if (preparedAxisData.domain) {
|
|
@@ -64,13 +68,19 @@ export const AxisX = (props) => {
|
|
|
64
68
|
if (tickData.line) {
|
|
65
69
|
tickSelection.append('path').attr('d', lineGenerator(tickData.line.points));
|
|
66
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
|
+
}
|
|
67
77
|
if (tickData.svgLabel) {
|
|
68
78
|
const label = tickData.svgLabel;
|
|
69
79
|
const textSelection = tickSelection
|
|
70
80
|
.append('text')
|
|
71
|
-
.
|
|
72
|
-
`translate(${label.x}
|
|
73
|
-
label.angle ? `rotate(${label.angle}
|
|
81
|
+
.attr('transform', [
|
|
82
|
+
`translate(${label.x}, ${label.y})`,
|
|
83
|
+
label.angle ? `rotate(${label.angle})` : '',
|
|
74
84
|
]
|
|
75
85
|
.filter(Boolean)
|
|
76
86
|
.join(' '));
|
|
@@ -103,7 +113,7 @@ export const AxisX = (props) => {
|
|
|
103
113
|
.join('g')
|
|
104
114
|
.attr(plotDataAttr, 1)
|
|
105
115
|
.attr(plotBandDataAttr, 1)
|
|
106
|
-
.
|
|
116
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
107
117
|
plotBandsSelection
|
|
108
118
|
.append('rect')
|
|
109
119
|
.attr('width', (d) => d.width)
|
|
@@ -124,7 +134,7 @@ export const AxisX = (props) => {
|
|
|
124
134
|
.style('font-weight', (_b = label.style.fontWeight) !== null && _b !== void 0 ? _b : '')
|
|
125
135
|
.style('dominant-baseline', 'text-before-edge')
|
|
126
136
|
.style('text-anchor', 'start')
|
|
127
|
-
.
|
|
137
|
+
.attr('transform', `translate(${label.x}, ${label.y}) rotate(${label.rotate})`)
|
|
128
138
|
.attr('data-qa', (_c = label.qa) !== null && _c !== void 0 ? _c : null);
|
|
129
139
|
}
|
|
130
140
|
});
|
|
@@ -144,7 +154,7 @@ export const AxisX = (props) => {
|
|
|
144
154
|
.join('g')
|
|
145
155
|
.attr(plotDataAttr, 1)
|
|
146
156
|
.attr(plotLineDataAttr, 1)
|
|
147
|
-
.
|
|
157
|
+
.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
|
|
148
158
|
plotLinesSelection
|
|
149
159
|
.append('path')
|
|
150
160
|
.attr('d', (d) => lineGenerator(d.points))
|
|
@@ -166,7 +176,7 @@ export const AxisX = (props) => {
|
|
|
166
176
|
.style('font-weight', (_b = label.style.fontWeight) !== null && _b !== void 0 ? _b : '')
|
|
167
177
|
.style('dominant-baseline', 'text-before-edge')
|
|
168
178
|
.style('text-anchor', 'start')
|
|
169
|
-
.
|
|
179
|
+
.attr('transform', `translate(${label.x}, ${label.y}) rotate(${label.rotate})`)
|
|
170
180
|
.attr('data-qa', (_c = label.qa) !== null && _c !== void 0 ? _c : null);
|
|
171
181
|
}
|
|
172
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[];
|
|
@@ -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: {
|