@gravity-ui/charts 1.42.4 → 1.43.1
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 +27 -0
- package/dist/cjs/components/AxisX/prepare-axis-data.js +41 -0
- package/dist/cjs/components/AxisX/types.d.ts +18 -1
- package/dist/cjs/components/AxisY/AxisY.js +27 -0
- package/dist/cjs/components/AxisY/prepare-axis-data.js +41 -0
- package/dist/cjs/components/AxisY/types.d.ts +18 -1
- package/dist/cjs/components/ChartInner/index.js +19 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +16 -17
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +2 -4
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +8 -4
- package/dist/cjs/components/ChartInner/useDefaultState.js +4 -3
- package/dist/cjs/components/ChartInner/utils/chart.js +1 -1
- package/dist/cjs/components/ChartInner/utils/normalized-original-data.d.ts +1 -0
- package/dist/cjs/components/ChartInner/utils/title.d.ts +4 -2
- package/dist/cjs/components/ChartInner/utils/title.js +77 -14
- package/dist/cjs/components/Title/index.d.ts +1 -3
- package/dist/cjs/components/Title/index.js +3 -5
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +2 -1
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +3 -2
- package/dist/cjs/components/Tooltip/index.js +2 -2
- package/dist/cjs/core/axes/types.d.ts +26 -9
- package/dist/cjs/core/axes/x-axis.js +14 -1
- package/dist/cjs/core/axes/y-axis.js +20 -7
- package/dist/cjs/core/constants/defaults/axis.d.ts +1 -0
- package/dist/cjs/core/constants/defaults/axis.js +1 -0
- package/dist/cjs/core/constants/index.d.ts +0 -1
- package/dist/cjs/core/constants/index.js +0 -1
- package/dist/cjs/core/scales/y-scale.js +37 -13
- package/dist/cjs/core/types/chart/axis.d.ts +43 -1
- package/dist/cjs/core/types/chart/title.d.ts +10 -0
- package/dist/cjs/core/types/chart/tooltip.d.ts +3 -1
- package/dist/cjs/core/utils/common.js +1 -1
- package/dist/cjs/core/utils/get-hovered-plots.d.ts +3 -2
- package/dist/cjs/core/utils/get-hovered-plots.js +28 -4
- package/dist/cjs/core/utils/labels.d.ts +1 -1
- package/dist/cjs/core/utils/labels.js +3 -2
- package/dist/cjs/core/utils/text.js +12 -2
- package/dist/cjs/hooks/types.d.ts +5 -2
- package/dist/cjs/hooks/useSeries/index.js +8 -2
- package/dist/cjs/hooks/useShapes/area/index.js +2 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +15 -10
- package/dist/cjs/hooks/useShapes/area/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +27 -16
- package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/index.js +18 -5
- package/dist/cjs/hooks/useShapes/line/index.js +7 -16
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +11 -7
- package/dist/cjs/hooks/useShapes/line/types.d.ts +2 -2
- package/dist/cjs/hooks/useTooltip/index.d.ts +3 -2
- package/dist/cjs/hooks/useTooltip/index.js +5 -3
- package/dist/cjs/types/chart-ui.d.ts +4 -0
- package/dist/esm/components/AxisX/AxisX.js +27 -0
- package/dist/esm/components/AxisX/prepare-axis-data.js +41 -0
- package/dist/esm/components/AxisX/types.d.ts +18 -1
- package/dist/esm/components/AxisY/AxisY.js +27 -0
- package/dist/esm/components/AxisY/prepare-axis-data.js +41 -0
- package/dist/esm/components/AxisY/types.d.ts +18 -1
- package/dist/esm/components/ChartInner/index.js +19 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +16 -17
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +2 -4
- package/dist/esm/components/ChartInner/useChartInnerProps.js +8 -4
- package/dist/esm/components/ChartInner/useDefaultState.js +4 -3
- package/dist/esm/components/ChartInner/utils/chart.js +1 -1
- package/dist/esm/components/ChartInner/utils/normalized-original-data.d.ts +1 -0
- package/dist/esm/components/ChartInner/utils/title.d.ts +4 -2
- package/dist/esm/components/ChartInner/utils/title.js +77 -14
- package/dist/esm/components/Title/index.d.ts +1 -3
- package/dist/esm/components/Title/index.js +3 -5
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +2 -1
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +3 -2
- package/dist/esm/components/Tooltip/index.js +2 -2
- package/dist/esm/core/axes/types.d.ts +26 -9
- package/dist/esm/core/axes/x-axis.js +14 -1
- package/dist/esm/core/axes/y-axis.js +20 -7
- package/dist/esm/core/constants/defaults/axis.d.ts +1 -0
- package/dist/esm/core/constants/defaults/axis.js +1 -0
- package/dist/esm/core/constants/index.d.ts +0 -1
- package/dist/esm/core/constants/index.js +0 -1
- package/dist/esm/core/scales/y-scale.js +37 -13
- package/dist/esm/core/types/chart/axis.d.ts +43 -1
- package/dist/esm/core/types/chart/title.d.ts +10 -0
- package/dist/esm/core/types/chart/tooltip.d.ts +3 -1
- package/dist/esm/core/utils/common.js +1 -1
- package/dist/esm/core/utils/get-hovered-plots.d.ts +3 -2
- package/dist/esm/core/utils/get-hovered-plots.js +28 -4
- package/dist/esm/core/utils/labels.d.ts +1 -1
- package/dist/esm/core/utils/labels.js +3 -2
- package/dist/esm/core/utils/text.js +12 -2
- package/dist/esm/hooks/types.d.ts +5 -2
- package/dist/esm/hooks/useSeries/index.js +8 -2
- package/dist/esm/hooks/useShapes/area/index.js +2 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.js +15 -10
- package/dist/esm/hooks/useShapes/area/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +27 -16
- package/dist/esm/hooks/useShapes/bar-x/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/index.js +18 -5
- package/dist/esm/hooks/useShapes/line/index.js +7 -16
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +2 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +11 -7
- package/dist/esm/hooks/useShapes/line/types.d.ts +2 -2
- package/dist/esm/hooks/useTooltip/index.d.ts +3 -2
- package/dist/esm/hooks/useTooltip/index.js +5 -3
- package/dist/esm/types/chart-ui.d.ts +4 -0
- package/package.json +1 -1
- package/dist/cjs/core/constants/misc.d.ts +0 -1
- package/dist/cjs/core/constants/misc.js +0 -7
- package/dist/esm/core/constants/misc.d.ts +0 -1
- package/dist/esm/core/constants/misc.js +0 -7
|
@@ -1,20 +1,83 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import { getTextSizeFn } from '../../../core/utils';
|
|
2
|
+
import { getTextSizeFn, getTextWithElipsis, wrapText } from '../../../core/utils';
|
|
3
3
|
const DEFAULT_TITLE_FONT_SIZE = '15px';
|
|
4
|
-
const
|
|
5
|
-
export const getPreparedTitle = async ({ title, }) => {
|
|
6
|
-
var _a, _b, _c, _d, _e, _f;
|
|
4
|
+
const DEFAULT_TITLE_MARGIN = 10;
|
|
5
|
+
export const getPreparedTitle = async ({ title, chartWidth, chartMargin, }) => {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
7
|
+
const chartMarginTop = (_a = chartMargin === null || chartMargin === void 0 ? void 0 : chartMargin.top) !== null && _a !== void 0 ? _a : 0;
|
|
8
|
+
const chartMarginLeft = (_b = chartMargin === null || chartMargin === void 0 ? void 0 : chartMargin.left) !== null && _b !== void 0 ? _b : 0;
|
|
9
|
+
const chartMarginRight = (_c = chartMargin === null || chartMargin === void 0 ? void 0 : chartMargin.right) !== null && _c !== void 0 ? _c : 0;
|
|
7
10
|
const titleText = get(title, 'text');
|
|
8
11
|
const titleStyle = {
|
|
9
|
-
fontSize: (
|
|
10
|
-
fontWeight: (
|
|
11
|
-
fontColor: (
|
|
12
|
+
fontSize: (_e = (_d = title === null || title === void 0 ? void 0 : title.style) === null || _d === void 0 ? void 0 : _d.fontSize) !== null && _e !== void 0 ? _e : DEFAULT_TITLE_FONT_SIZE,
|
|
13
|
+
fontWeight: (_g = (_f = title === null || title === void 0 ? void 0 : title.style) === null || _f === void 0 ? void 0 : _f.fontWeight) !== null && _g !== void 0 ? _g : 'var(--g-text-subheader-font-weight)',
|
|
14
|
+
fontColor: (_j = (_h = title === null || title === void 0 ? void 0 : title.style) === null || _h === void 0 ? void 0 : _h.fontColor) !== null && _j !== void 0 ? _j : 'var(--g-color-text-primary)',
|
|
15
|
+
};
|
|
16
|
+
if (!titleText) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
const getTitleTextSize = getTextSizeFn({ style: titleStyle });
|
|
20
|
+
const maxRowCount = (_k = title === null || title === void 0 ? void 0 : title.maxRowCount) !== null && _k !== void 0 ? _k : 1;
|
|
21
|
+
const contentRows = [];
|
|
22
|
+
const usableWidth = chartWidth - chartMarginLeft - chartMarginRight;
|
|
23
|
+
const xCenter = chartMarginLeft + usableWidth / 2;
|
|
24
|
+
if (maxRowCount > 1) {
|
|
25
|
+
let titleTextRows = await wrapText({
|
|
26
|
+
text: titleText,
|
|
27
|
+
style: titleStyle,
|
|
28
|
+
width: usableWidth,
|
|
29
|
+
getTextSize: getTitleTextSize,
|
|
30
|
+
});
|
|
31
|
+
titleTextRows = titleTextRows.reduce((acc, row, index) => {
|
|
32
|
+
if (index < maxRowCount) {
|
|
33
|
+
acc.push(row);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
acc[maxRowCount - 1].text += row.text;
|
|
37
|
+
}
|
|
38
|
+
return acc;
|
|
39
|
+
}, []);
|
|
40
|
+
for (let i = 0; i < titleTextRows.length; i++) {
|
|
41
|
+
const textRow = titleTextRows[i];
|
|
42
|
+
let textRowContent = textRow.text.trim();
|
|
43
|
+
if (i === titleTextRows.length - 1) {
|
|
44
|
+
textRowContent = await getTextWithElipsis({
|
|
45
|
+
text: textRowContent,
|
|
46
|
+
maxWidth: usableWidth,
|
|
47
|
+
getTextWidth: async (s) => (await getTitleTextSize(s)).width,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const textRowSize = await getTitleTextSize(textRowContent);
|
|
51
|
+
contentRows.push({
|
|
52
|
+
text: textRowContent,
|
|
53
|
+
x: xCenter,
|
|
54
|
+
y: textRow.y + textRowSize.hangingOffset + chartMarginTop,
|
|
55
|
+
size: textRowSize,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const truncatedText = await getTextWithElipsis({
|
|
61
|
+
text: titleText,
|
|
62
|
+
maxWidth: usableWidth,
|
|
63
|
+
getTextWidth: async (s) => (await getTitleTextSize(s)).width,
|
|
64
|
+
});
|
|
65
|
+
const textSize = await getTitleTextSize(truncatedText);
|
|
66
|
+
contentRows.push({
|
|
67
|
+
text: truncatedText,
|
|
68
|
+
x: xCenter,
|
|
69
|
+
y: textSize.hangingOffset + chartMarginTop,
|
|
70
|
+
size: textSize,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const totalTextHeight = contentRows.reduce((acc, row) => acc + row.size.height, 0);
|
|
74
|
+
const titleHeight = totalTextHeight;
|
|
75
|
+
return {
|
|
76
|
+
text: titleText,
|
|
77
|
+
style: titleStyle,
|
|
78
|
+
height: titleHeight,
|
|
79
|
+
margin: (_l = title === null || title === void 0 ? void 0 : title.margin) !== null && _l !== void 0 ? _l : DEFAULT_TITLE_MARGIN,
|
|
80
|
+
qa: title === null || title === void 0 ? void 0 : title.qa,
|
|
81
|
+
contentRows,
|
|
12
82
|
};
|
|
13
|
-
const titleHeight = titleText
|
|
14
|
-
? (await getTextSizeFn({ style: titleStyle })(titleText)).height + TITLE_PADDINGS
|
|
15
|
-
: 0;
|
|
16
|
-
const preparedTitle = titleText
|
|
17
|
-
? { text: titleText, style: titleStyle, height: titleHeight, qa: title === null || title === void 0 ? void 0 : title.qa }
|
|
18
|
-
: undefined;
|
|
19
|
-
return preparedTitle;
|
|
20
83
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export const Title = (props) => {
|
|
3
|
-
const {
|
|
4
|
-
return (React.createElement("text", {
|
|
3
|
+
const { style, qa, contentRows } = props;
|
|
4
|
+
return (React.createElement("text", { dominantBaseline: "hanging", textAnchor: "middle", style: {
|
|
5
5
|
fill: style === null || style === void 0 ? void 0 : style.fontColor,
|
|
6
6
|
fontSize: style === null || style === void 0 ? void 0 : style.fontSize,
|
|
7
7
|
fontWeight: style === null || style === void 0 ? void 0 : style.fontWeight,
|
|
8
|
-
|
|
9
|
-
}, "data-qa": qa },
|
|
10
|
-
React.createElement("tspan", { dangerouslySetInnerHTML: { __html: text } })));
|
|
8
|
+
}, "data-qa": qa }, contentRows.map((row, i) => (React.createElement("tspan", { key: i, x: row.x, y: row.y, dominantBaseline: "hanging", dangerouslySetInnerHTML: { __html: row.text } })))));
|
|
11
9
|
};
|
|
@@ -7,8 +7,9 @@ export interface ChartTooltipContentProps {
|
|
|
7
7
|
rowRenderer?: ChartTooltip['rowRenderer'];
|
|
8
8
|
valueFormat?: ChartTooltip['valueFormat'];
|
|
9
9
|
headerFormat?: ChartTooltip['headerFormat'];
|
|
10
|
-
hoveredPlotLines?: ChartTooltipRendererArgs['hoveredPlotLines'];
|
|
11
10
|
hoveredPlotBands?: ChartTooltipRendererArgs['hoveredPlotBands'];
|
|
11
|
+
hoveredPlotLines?: ChartTooltipRendererArgs['hoveredPlotLines'];
|
|
12
|
+
hoveredPlotShapes?: ChartTooltipRendererArgs['hoveredPlotShapes'];
|
|
12
13
|
totals?: ChartTooltip['totals'];
|
|
13
14
|
xAxis?: ChartXAxis | null;
|
|
14
15
|
yAxis?: ChartYAxis;
|
|
@@ -2,15 +2,16 @@ 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, hoveredPlotLines,
|
|
5
|
+
const { hovered, hoveredPlotBands, hoveredPlotLines, hoveredPlotShapes, xAxis, yAxis, renderer, rowRenderer, valueFormat, headerFormat, totals, pinned, qa, } = props;
|
|
6
6
|
if (!hovered) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
const customTooltip = renderer === null || renderer === void 0 ? void 0 : renderer({
|
|
10
10
|
headerFormat,
|
|
11
11
|
hovered,
|
|
12
|
-
hoveredPlotLines,
|
|
13
12
|
hoveredPlotBands,
|
|
13
|
+
hoveredPlotLines,
|
|
14
|
+
hoveredPlotShapes,
|
|
14
15
|
xAxis,
|
|
15
16
|
yAxis,
|
|
16
17
|
});
|
|
@@ -7,7 +7,7 @@ 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, hoveredPlotLines,
|
|
10
|
+
const { hovered, hoveredPlotBands, hoveredPlotLines, hoveredPlotShapes, pointerPosition } = useTooltip({
|
|
11
11
|
dispatcher,
|
|
12
12
|
tooltip,
|
|
13
13
|
xAxis,
|
|
@@ -28,5 +28,5 @@ export const Tooltip = (props) => {
|
|
|
28
28
|
}, [left, top]);
|
|
29
29
|
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'] },
|
|
30
30
|
React.createElement("div", { className: b('popup-content') },
|
|
31
|
-
React.createElement(ChartTooltipContent, { hovered: hovered, hoveredPlotLines: hoveredPlotLines,
|
|
31
|
+
React.createElement(ChartTooltipContent, { hovered: hovered, hoveredPlotBands: hoveredPlotBands, hoveredPlotLines: hoveredPlotLines, hoveredPlotShapes: hoveredPlotShapes, 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;
|
|
32
32
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxisCrosshair, AxisPlotBand, BaseTextStyle, ChartAxis, ChartAxisLabels, ChartAxisRangeSlider, ChartAxisTitleAlignment, ChartAxisTitleRotation, ChartAxisType, DeepRequired, MeaningfulAny, PlotLayerPlacement } from '../../types';
|
|
1
|
+
import type { AxisCrosshair, AxisPlotBand, AxisPlotShape, BaseTextStyle, ChartAxis, ChartAxisLabels, ChartAxisRangeSlider, ChartAxisTitleAlignment, ChartAxisTitleRotation, ChartAxisType, DeepRequired, MeaningfulAny, PlotLayerPlacement } from '../../types';
|
|
2
2
|
import type { DashStyle } from '../constants';
|
|
3
3
|
type PreparedAxisLabels = Omit<ChartAxisLabels, 'enabled' | 'padding' | 'style' | 'autoRotation'> & Required<Pick<ChartAxisLabels, 'enabled' | 'padding' | 'margin' | 'rotation' | 'html'>> & {
|
|
4
4
|
style: BaseTextStyle;
|
|
@@ -19,19 +19,35 @@ export type PreparedAxisPlotBand = Required<AxisPlotBand> & {
|
|
|
19
19
|
};
|
|
20
20
|
type PreparedAxisCrosshair = Required<AxisCrosshair>;
|
|
21
21
|
export type PreparedAxisPlotLine = {
|
|
22
|
-
value: number;
|
|
23
22
|
color: string;
|
|
24
|
-
width: number;
|
|
25
|
-
dashStyle: DashStyle;
|
|
26
|
-
opacity: number;
|
|
27
|
-
layerPlacement: PlotLayerPlacement;
|
|
28
23
|
custom?: MeaningfulAny;
|
|
24
|
+
dashStyle: DashStyle;
|
|
25
|
+
hoverThreshold: number;
|
|
29
26
|
label: {
|
|
30
|
-
text: string;
|
|
31
|
-
style: BaseTextStyle;
|
|
32
27
|
padding: number;
|
|
33
28
|
qa?: string;
|
|
29
|
+
style: BaseTextStyle;
|
|
30
|
+
text: string;
|
|
34
31
|
};
|
|
32
|
+
layerPlacement: PlotLayerPlacement;
|
|
33
|
+
opacity: number;
|
|
34
|
+
value: number;
|
|
35
|
+
width: number;
|
|
36
|
+
};
|
|
37
|
+
export type PreparedAxisPlotShape = {
|
|
38
|
+
custom?: MeaningfulAny;
|
|
39
|
+
hitbox: {
|
|
40
|
+
height: number;
|
|
41
|
+
width: number;
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
};
|
|
45
|
+
layerPlacement: PlotLayerPlacement;
|
|
46
|
+
opacity: number;
|
|
47
|
+
renderer: AxisPlotShape['renderer'];
|
|
48
|
+
value: number | string;
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
35
51
|
};
|
|
36
52
|
export type PreparedRangeSlider = DeepRequired<Omit<ChartAxisRangeSlider, 'defaultRange'>> & {
|
|
37
53
|
defaultRange?: ChartAxisRangeSlider['defaultRange'];
|
|
@@ -40,7 +56,7 @@ export type PreparedAxisTickMarks = {
|
|
|
40
56
|
enabled: boolean;
|
|
41
57
|
length: number;
|
|
42
58
|
};
|
|
43
|
-
type PreparedBaseAxis = Omit<ChartAxis, 'type' | 'labels' | 'plotLines' | 'plotBands'> & {
|
|
59
|
+
type PreparedBaseAxis = Omit<ChartAxis, 'type' | 'labels' | 'plotLines' | 'plotBands' | 'plotShapes'> & {
|
|
44
60
|
type: ChartAxisType;
|
|
45
61
|
labels: PreparedAxisLabels;
|
|
46
62
|
title: {
|
|
@@ -67,6 +83,7 @@ type PreparedBaseAxis = Omit<ChartAxis, 'type' | 'labels' | 'plotLines' | 'plotB
|
|
|
67
83
|
plotIndex: number;
|
|
68
84
|
plotLines: PreparedAxisPlotLine[];
|
|
69
85
|
plotBands: PreparedAxisPlotBand[];
|
|
86
|
+
plotShapes: PreparedAxisPlotShape[];
|
|
70
87
|
crosshair: PreparedAxisCrosshair;
|
|
71
88
|
};
|
|
72
89
|
export type PreparedXAxis = PreparedBaseAxis & {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import { TIME_UNITS, calculateCos, calculateNumericProperty, calculateSin, formatAxisTickLabel, getDefaultDateFormat, getHorizontalHtmlTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, wrapText, } from '../utils';
|
|
3
|
-
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, xAxisTitleDefaults, } from '../constants';
|
|
3
|
+
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, PLOT_LINE_HOVER_THRESHOLD, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, xAxisTitleDefaults, } from '../constants';
|
|
4
4
|
import { createXScale } from '../scales/x-scale';
|
|
5
5
|
import { getXAxisTickValues } from '../utils/axis/x-axis';
|
|
6
6
|
import { getPreparedRangeSlider } from './range-slider';
|
|
@@ -155,6 +155,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
155
155
|
color: get(d, 'color', 'var(--g-color-base-brand)'),
|
|
156
156
|
width: get(d, 'width', 1),
|
|
157
157
|
dashStyle: get(d, 'dashStyle', DASH_STYLE.Solid),
|
|
158
|
+
hoverThreshold: get(d, 'hoverThreshold', PLOT_LINE_HOVER_THRESHOLD),
|
|
158
159
|
opacity: get(d, 'opacity', 1),
|
|
159
160
|
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
160
161
|
custom: d.custom,
|
|
@@ -169,6 +170,18 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
169
170
|
custom: d.custom,
|
|
170
171
|
label: prepareAxisPlotLabel(d),
|
|
171
172
|
})),
|
|
173
|
+
// x, y and hitbox are populated later in prepare-axis-data
|
|
174
|
+
// after pixel coordinates and element dimensions are computed
|
|
175
|
+
plotShapes: get(xAxis, 'plotShapes', []).map((d) => ({
|
|
176
|
+
custom: d.custom,
|
|
177
|
+
hitbox: { x: 0, y: 0, width: 0, height: 0 },
|
|
178
|
+
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
179
|
+
opacity: get(d, 'opacity', 1),
|
|
180
|
+
renderer: d.renderer,
|
|
181
|
+
value: d.value,
|
|
182
|
+
x: 0,
|
|
183
|
+
y: 0,
|
|
184
|
+
})),
|
|
172
185
|
crosshair: {
|
|
173
186
|
enabled: get(xAxis, 'crosshair.enabled', axisCrosshairDefaults.enabled),
|
|
174
187
|
color: get(xAxis, 'crosshair.color', axisCrosshairDefaults.color),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import { calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat,
|
|
2
|
+
import { calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getHorizontalHtmlTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, shouldSyncAxisWithPrimary, wrapText, } from '../utils';
|
|
3
3
|
import { getTickValues } from '../../components/AxisY/utils';
|
|
4
|
-
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, yAxisTitleDefaults, } from '../constants';
|
|
4
|
+
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, PLOT_LINE_HOVER_THRESHOLD, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, yAxisTitleDefaults, } from '../constants';
|
|
5
5
|
import { createYScale } from '../scales/y-scale';
|
|
6
6
|
import { prepareAxisPlotLabel } from './utils';
|
|
7
7
|
export const getYAxisLabelMaxWidth = async (args) => {
|
|
@@ -50,7 +50,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
50
50
|
return Promise.resolve([]);
|
|
51
51
|
}
|
|
52
52
|
return Promise.all(axisItems.map(async (axisItem, axisIndex) => {
|
|
53
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q
|
|
53
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
54
54
|
const plotIndex = get(axisItem, 'plotIndex', 0);
|
|
55
55
|
const firstPlotAxis = !axisByPlot[plotIndex];
|
|
56
56
|
if (firstPlotAxis) {
|
|
@@ -142,7 +142,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
142
142
|
maxWidth: titleMaxWidth !== null && titleMaxWidth !== void 0 ? titleMaxWidth : Infinity,
|
|
143
143
|
rotation: titleRotation,
|
|
144
144
|
},
|
|
145
|
-
min:
|
|
145
|
+
min: get(axisItem, 'min'),
|
|
146
146
|
max: get(axisItem, 'max'),
|
|
147
147
|
startOnTick: get(axisItem, 'startOnTick'),
|
|
148
148
|
endOnTick: get(axisItem, 'endOnTick'),
|
|
@@ -151,12 +151,12 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
151
151
|
enabled: gridEnabled,
|
|
152
152
|
},
|
|
153
153
|
ticks: {
|
|
154
|
-
pixelInterval: ((
|
|
154
|
+
pixelInterval: ((_o = axisItem.ticks) === null || _o === void 0 ? void 0 : _o.interval)
|
|
155
155
|
? calculateNumericProperty({
|
|
156
156
|
base: height,
|
|
157
|
-
value: (
|
|
157
|
+
value: (_p = axisItem.ticks) === null || _p === void 0 ? void 0 : _p.interval,
|
|
158
158
|
})
|
|
159
|
-
: (
|
|
159
|
+
: (_q = axisItem.ticks) === null || _q === void 0 ? void 0 : _q.pixelInterval,
|
|
160
160
|
},
|
|
161
161
|
tickMarks: {
|
|
162
162
|
enabled: isAxisVisible &&
|
|
@@ -170,6 +170,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
170
170
|
color: get(d, 'color', 'var(--g-color-base-brand)'),
|
|
171
171
|
width: get(d, 'width', 1),
|
|
172
172
|
dashStyle: get(d, 'dashStyle', DASH_STYLE.Solid),
|
|
173
|
+
hoverThreshold: get(d, 'hoverThreshold', PLOT_LINE_HOVER_THRESHOLD),
|
|
173
174
|
opacity: get(d, 'opacity', 1),
|
|
174
175
|
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
175
176
|
custom: d.custom,
|
|
@@ -184,6 +185,18 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
184
185
|
custom: d.custom,
|
|
185
186
|
label: prepareAxisPlotLabel(d),
|
|
186
187
|
})),
|
|
188
|
+
// x, y and hitbox are populated later in prepare-axis-data
|
|
189
|
+
// after pixel coordinates and element dimensions are computed
|
|
190
|
+
plotShapes: get(axisItem, 'plotShapes', []).map((d) => ({
|
|
191
|
+
custom: d.custom,
|
|
192
|
+
hitbox: { x: 0, y: 0, width: 0, height: 0 },
|
|
193
|
+
layerPlacement: get(d, 'layerPlacement', 'before'),
|
|
194
|
+
opacity: get(d, 'opacity', 1),
|
|
195
|
+
renderer: d.renderer,
|
|
196
|
+
value: d.value,
|
|
197
|
+
x: 0,
|
|
198
|
+
y: 0,
|
|
199
|
+
})),
|
|
187
200
|
crosshair: {
|
|
188
201
|
enabled: get(axisItem, 'crosshair.enabled', axisCrosshairDefaults.enabled),
|
|
189
202
|
color: get(axisItem, 'crosshair.color', axisCrosshairDefaults.color),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extent, tickStep, ticks } from 'd3-array';
|
|
2
2
|
import { scaleBand, scaleLinear, scaleLog, scaleUtc } from 'd3-scale';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
import { CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, getDomainDataYBySeries, shouldSyncAxisWithPrimary, } from '../utils';
|
|
4
|
+
import { CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, getDefaultMinYAxisValue, getDomainDataYBySeries, shouldSyncAxisWithPrimary, } from '../utils';
|
|
5
5
|
import { getTickValues } from '../../components/AxisY/utils';
|
|
6
6
|
import { getBandSize } from '../../hooks/utils/get-band-size';
|
|
7
7
|
import { SERIES_TYPE } from '../constants';
|
|
@@ -83,14 +83,21 @@ function getDomainMinAlignedToStartTick(args) {
|
|
|
83
83
|
const isStartOnTick = tickValues[0].y === range[0];
|
|
84
84
|
let dNewMin = dMin;
|
|
85
85
|
if (!isStartOnTick) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
if (axis.type === 'logarithmic') {
|
|
87
|
+
const [nicedMin, _nicedMax] = scale.copy().nice().domain();
|
|
88
|
+
dNewMin = nicedMin;
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
|
-
step
|
|
91
|
+
let step;
|
|
92
|
+
if (typeof ((_a = tickValues[0]) === null || _a === void 0 ? void 0 : _a.value) === 'number' &&
|
|
93
|
+
typeof ((_b = tickValues[1]) === null || _b === void 0 ? void 0 : _b.value) === 'number') {
|
|
94
|
+
step = tickValues[1].value - tickValues[0].value;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
step = tickStep(dMin, dMax, 1);
|
|
98
|
+
}
|
|
99
|
+
dNewMin = tickValues[0].value - step;
|
|
92
100
|
}
|
|
93
|
-
dNewMin = tickValues[0].value - step;
|
|
94
101
|
}
|
|
95
102
|
return dNewMin;
|
|
96
103
|
}
|
|
@@ -104,17 +111,24 @@ function getDomainMaxAlignedToEndTick(args) {
|
|
|
104
111
|
labelLineHeight: axis.labels.lineHeight,
|
|
105
112
|
series,
|
|
106
113
|
});
|
|
107
|
-
const isEndOnTick = tickValues[tickValues.length - 1].y === range[1];
|
|
108
114
|
let dNewMax = dMax;
|
|
115
|
+
const isEndOnTick = tickValues[tickValues.length - 1].y === range[1];
|
|
109
116
|
if (!isEndOnTick) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
if (axis.type === 'logarithmic') {
|
|
118
|
+
const [_nicedMin, nicedMax] = scale.copy().nice().domain();
|
|
119
|
+
dNewMax = nicedMax;
|
|
113
120
|
}
|
|
114
121
|
else {
|
|
115
|
-
step
|
|
122
|
+
let step;
|
|
123
|
+
if (typeof ((_a = tickValues[0]) === null || _a === void 0 ? void 0 : _a.value) === 'number' &&
|
|
124
|
+
typeof ((_b = tickValues[1]) === null || _b === void 0 ? void 0 : _b.value) === 'number') {
|
|
125
|
+
step = tickValues[1].value - tickValues[0].value;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
step = tickStep(dMin, dMax, 1);
|
|
129
|
+
}
|
|
130
|
+
dNewMax = tickValues[tickValues.length - 1].value + step;
|
|
116
131
|
}
|
|
117
|
-
dNewMax = tickValues[tickValues.length - 1].value + step;
|
|
118
132
|
}
|
|
119
133
|
return dNewMax;
|
|
120
134
|
}
|
|
@@ -141,7 +155,17 @@ export function createYScale(args) {
|
|
|
141
155
|
}
|
|
142
156
|
if (hasNumberAndNullValues) {
|
|
143
157
|
const [yMinDomain, yMaxDomain] = extent(domain);
|
|
144
|
-
|
|
158
|
+
let yMin;
|
|
159
|
+
if (typeof yMinPropsOrState === 'number') {
|
|
160
|
+
yMin = yMinPropsOrState;
|
|
161
|
+
}
|
|
162
|
+
else if (axis.type === 'logarithmic') {
|
|
163
|
+
yMin = yMinDomain;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const yMinDefault = getDefaultMinYAxisValue(series);
|
|
167
|
+
yMin = typeof yMinDefault === 'number' ? yMinDefault : yMinDomain;
|
|
168
|
+
}
|
|
145
169
|
let yMax;
|
|
146
170
|
if (typeof yMaxPropsOrState === 'number') {
|
|
147
171
|
yMax = yMaxPropsOrState;
|
|
@@ -187,6 +187,8 @@ export interface ChartAxis {
|
|
|
187
187
|
plotLines?: AxisPlotLine[];
|
|
188
188
|
/** An array of colored bands stretching across the plot area marking an interval on the axis. */
|
|
189
189
|
plotBands?: AxisPlotBand[];
|
|
190
|
+
/** An array of custom SVG elements placed at specific axis values. */
|
|
191
|
+
plotShapes?: AxisPlotShape[];
|
|
190
192
|
/**
|
|
191
193
|
* Small perpendicular marks on the axis line at each tick position.
|
|
192
194
|
*
|
|
@@ -275,6 +277,46 @@ export interface AxisPlotLine extends AxisPlot {
|
|
|
275
277
|
width?: number;
|
|
276
278
|
/** Option for line stroke style. */
|
|
277
279
|
dashStyle?: DashStyle;
|
|
280
|
+
/**
|
|
281
|
+
* Extra pixels added to each side of the line for hover detection.
|
|
282
|
+
* The total hoverable area equals `line.width + hoverThreshold * 2`.
|
|
283
|
+
* @default 4
|
|
284
|
+
*/
|
|
285
|
+
hoverThreshold?: number;
|
|
286
|
+
}
|
|
287
|
+
export interface AxisPlotShape extends AxisPlot {
|
|
288
|
+
/**
|
|
289
|
+
* The position of the shape in axis units.
|
|
290
|
+
*
|
|
291
|
+
* Can be a number or a string (e.g., a category).
|
|
292
|
+
* When representing a date, the value **must be a timestamp** (number of milliseconds since Unix epoch).
|
|
293
|
+
*/
|
|
294
|
+
value: number | string;
|
|
295
|
+
/**
|
|
296
|
+
* Custom SVG content renderer.
|
|
297
|
+
*
|
|
298
|
+
* Called with the pixel coordinates of the shape and the plot area dimensions.
|
|
299
|
+
* Must return a string of valid SVG markup that will be inserted inside a `<g>` container
|
|
300
|
+
* positioned at the shape's axis value.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```
|
|
304
|
+
* renderer: ({plotHeight}) =>
|
|
305
|
+
* `<circle cx="0" cy="${plotHeight}" r="4" fill="red"/>
|
|
306
|
+
* <line x1="0" y1="0" x2="0" y2="${plotHeight}" stroke="red" stroke-width="1"/>
|
|
307
|
+
* <text x="4" y="12" font-size="11" fill="currentColor">Label</text>`
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
renderer: (args: {
|
|
311
|
+
/** Pixel X coordinate in the plot area coordinate system */
|
|
312
|
+
x: number;
|
|
313
|
+
/** Pixel Y coordinate in the plot area coordinate system */
|
|
314
|
+
y: number;
|
|
315
|
+
/** Width of the plot area in pixels */
|
|
316
|
+
plotWidth: number;
|
|
317
|
+
/** Height of the plot area in pixels */
|
|
318
|
+
plotHeight: number;
|
|
319
|
+
}) => string;
|
|
278
320
|
}
|
|
279
321
|
export interface AxisPlotBand extends AxisPlot {
|
|
280
322
|
/**
|
|
@@ -296,7 +338,7 @@ export interface AxisPlotBand extends AxisPlot {
|
|
|
296
338
|
*/
|
|
297
339
|
to: number | string | null;
|
|
298
340
|
}
|
|
299
|
-
export interface AxisCrosshair extends
|
|
341
|
+
export interface AxisCrosshair extends Pick<AxisPlotLine, 'color' | 'dashStyle' | 'opacity' | 'layerPlacement' | 'width'> {
|
|
300
342
|
/**
|
|
301
343
|
* Whether the crosshair should snap to the point or follow the pointer independent of points.
|
|
302
344
|
* @default true
|
|
@@ -2,6 +2,16 @@ import type { BaseTextStyle } from './base';
|
|
|
2
2
|
export interface ChartTitle {
|
|
3
3
|
text: string;
|
|
4
4
|
style?: Partial<BaseTextStyle>;
|
|
5
|
+
/**
|
|
6
|
+
* Maximum number of text rows. If the text exceeds this limit, it is truncated with an ellipsis.
|
|
7
|
+
* Default: 1
|
|
8
|
+
*/
|
|
9
|
+
maxRowCount?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Space between the title and the chart area (in pixels).
|
|
12
|
+
* Default: 10
|
|
13
|
+
*/
|
|
14
|
+
margin?: number;
|
|
5
15
|
/**
|
|
6
16
|
* Can be used for the UI automated test.
|
|
7
17
|
* It is assigned as a data-qa attribute to an element.
|
|
@@ -2,7 +2,7 @@ import type { TOOLTIP_TOTALS_BUILT_IN_AGGREGATION } from '../../constants';
|
|
|
2
2
|
import type { DateTimeLabelFormats } from '../../utils/time';
|
|
3
3
|
import type { MeaningfulAny } from '../misc';
|
|
4
4
|
import type { AreaSeries, AreaSeriesData } from './area';
|
|
5
|
-
import type { AxisPlotBand, AxisPlotLine, ChartXAxis, ChartYAxis } from './axis';
|
|
5
|
+
import type { AxisPlotBand, AxisPlotLine, AxisPlotShape, ChartXAxis, ChartYAxis } from './axis';
|
|
6
6
|
import type { BarXSeries, BarXSeriesData } from './bar-x';
|
|
7
7
|
import type { BarYSeries, BarYSeriesData } from './bar-y';
|
|
8
8
|
import type { CustomFormat, ValueFormat } from './base';
|
|
@@ -96,6 +96,8 @@ export interface ChartTooltipRendererArgs<T = MeaningfulAny> {
|
|
|
96
96
|
hoveredPlotLines?: AxisPlotLine[];
|
|
97
97
|
/** Plot bands that contain the current pointer position. */
|
|
98
98
|
hoveredPlotBands?: AxisPlotBand[];
|
|
99
|
+
/** Plot shapes that contain the current pointer position. */
|
|
100
|
+
hoveredPlotShapes?: AxisPlotShape[];
|
|
99
101
|
xAxis?: ChartXAxis | null;
|
|
100
102
|
yAxis?: ChartYAxis;
|
|
101
103
|
/** Formatting settings for tooltip header row (includes computed default). */
|
|
@@ -88,7 +88,7 @@ export const getDomainDataYBySeries = (series) => {
|
|
|
88
88
|
switch (type) {
|
|
89
89
|
case 'area':
|
|
90
90
|
case 'bar-x': {
|
|
91
|
-
acc.push(
|
|
91
|
+
acc.push(...getDomainDataForStackedSeries(seriesList));
|
|
92
92
|
break;
|
|
93
93
|
}
|
|
94
94
|
case 'waterfall': {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxisPlotBand, AxisPlotLine } from '../../types';
|
|
1
|
+
import type { AxisPlotBand, AxisPlotLine, AxisPlotShape } from '../../types';
|
|
2
2
|
import type { PreparedXAxis, PreparedYAxis } from '../axes/types';
|
|
3
3
|
import type { ChartScale } from '../scales/types';
|
|
4
4
|
export declare function getHoveredPlots(args: {
|
|
@@ -9,6 +9,7 @@ export declare function getHoveredPlots(args: {
|
|
|
9
9
|
xScale?: ChartScale;
|
|
10
10
|
yScale?: (ChartScale | undefined)[];
|
|
11
11
|
}): {
|
|
12
|
-
plotLines: AxisPlotLine[];
|
|
13
12
|
plotBands: AxisPlotBand[];
|
|
13
|
+
plotLines: AxisPlotLine[];
|
|
14
|
+
plotShapes: AxisPlotShape[];
|
|
14
15
|
};
|