@gravity-ui/charts 1.38.1 → 1.38.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +4 -15
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +1 -41
- package/dist/cjs/components/ChartInner/useLegend.d.ts +14 -0
- package/dist/cjs/components/ChartInner/useLegend.js +37 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +10 -23
- package/dist/cjs/hooks/useAxis/index.js +8 -3
- package/dist/cjs/hooks/useAxis/x-axis.js +1 -1
- package/dist/cjs/hooks/useAxis/y-axis.js +18 -17
- package/dist/cjs/hooks/useChartDimensions/index.js +3 -0
- package/dist/cjs/hooks/useShapes/index.js +3 -0
- package/dist/cjs/hooks/useYAxisLabelWidth/index.js +2 -2
- package/dist/cjs/types/chart/axis.d.ts +8 -2
- package/dist/cjs/utils/misc.d.ts +0 -1
- package/dist/cjs/utils/misc.js +0 -6
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +4 -15
- package/dist/esm/components/ChartInner/useChartInnerProps.js +1 -41
- package/dist/esm/components/ChartInner/useLegend.d.ts +14 -0
- package/dist/esm/components/ChartInner/useLegend.js +37 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +10 -23
- package/dist/esm/hooks/useAxis/index.js +8 -3
- package/dist/esm/hooks/useAxis/x-axis.js +1 -1
- package/dist/esm/hooks/useAxis/y-axis.js +18 -17
- package/dist/esm/hooks/useChartDimensions/index.js +3 -0
- package/dist/esm/hooks/useShapes/index.js +3 -0
- package/dist/esm/hooks/useYAxisLabelWidth/index.js +2 -2
- package/dist/esm/types/chart/axis.d.ts +8 -2
- package/dist/esm/utils/misc.d.ts +0 -1
- package/dist/esm/utils/misc.js +0 -6
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PreparedChart, PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
|
|
4
4
|
import type { LegendConfig } from '../../types';
|
|
5
5
|
import type { ChartInnerProps } from './types';
|
|
6
6
|
type Props = ChartInnerProps & {
|
|
@@ -13,19 +13,8 @@ type Props = ChartInnerProps & {
|
|
|
13
13
|
zoomState: Partial<ZoomState>;
|
|
14
14
|
rangeSliderState?: RangeSliderState;
|
|
15
15
|
};
|
|
16
|
-
type LegendState = {
|
|
17
|
-
legendConfig?: LegendConfig;
|
|
18
|
-
legendItems: LegendItem[][];
|
|
19
|
-
};
|
|
20
|
-
export declare function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }: {
|
|
21
|
-
preparedLegend: PreparedLegend | null;
|
|
22
|
-
preparedChart: PreparedChart;
|
|
23
|
-
preparedSeries: PreparedSeries[];
|
|
24
|
-
width: number;
|
|
25
|
-
height: number;
|
|
26
|
-
}): LegendState;
|
|
27
16
|
export declare function useChartInnerProps(props: Props): {
|
|
28
|
-
allPreparedSeries: PreparedSeries[];
|
|
17
|
+
allPreparedSeries: import("../../hooks").PreparedSeries[];
|
|
29
18
|
boundsHeight: number;
|
|
30
19
|
boundsOffsetLeft: number;
|
|
31
20
|
boundsOffsetTop: number;
|
|
@@ -33,9 +22,9 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
33
22
|
handleLegendItemClick: import("../../hooks").OnLegendItemClick;
|
|
34
23
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
35
24
|
legendConfig: LegendConfig | undefined;
|
|
36
|
-
legendItems: LegendItem[][];
|
|
25
|
+
legendItems: import("../../hooks").LegendItem[][];
|
|
37
26
|
preparedLegend: PreparedLegend | null;
|
|
38
|
-
preparedSeries: PreparedSeries[];
|
|
27
|
+
preparedSeries: import("../../hooks").PreparedSeries[];
|
|
39
28
|
preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
|
|
40
29
|
preparedSplit: import("../../hooks").PreparedSplit;
|
|
41
30
|
prevHeight: number | undefined;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import isEqual from 'lodash/isEqual';
|
|
3
2
|
import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
|
|
4
3
|
import { useAxis, useAxisScales, useChartDimensions, useNormalizedOriginalData, usePrevious, useSeries, useShapes, useSplit, useYAxisLabelWidth, useZoom, } from '../../hooks';
|
|
5
4
|
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
6
|
-
import { getLegendComponents } from '../../hooks/useSeries/prepare-legend';
|
|
7
5
|
import { getPreparedOptions } from '../../hooks/useSeries/prepare-options';
|
|
8
6
|
import { getEffectiveXRange, getZoomedSeriesData } from '../../utils';
|
|
7
|
+
import { useLegend } from './useLegend';
|
|
9
8
|
import { hasAtLeastOneSeriesDataPerPlot } from './utils';
|
|
10
9
|
const CLIP_PATH_BY_SERIES_TYPE = {
|
|
11
10
|
[SERIES_TYPE.Scatter]: false,
|
|
@@ -35,45 +34,6 @@ function getBoundsOffsetLeft(args) {
|
|
|
35
34
|
}, 0);
|
|
36
35
|
return chartMarginLeft + legendOffset + leftAxisWidth;
|
|
37
36
|
}
|
|
38
|
-
export function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }) {
|
|
39
|
-
const [legendState, setLegend] = React.useState({
|
|
40
|
-
legendConfig: undefined,
|
|
41
|
-
legendItems: [],
|
|
42
|
-
});
|
|
43
|
-
const legendStateRunRef = React.useRef(0);
|
|
44
|
-
const prevLegendStateValue = React.useRef(legendState);
|
|
45
|
-
const legendStateReady = React.useRef(false);
|
|
46
|
-
React.useEffect(() => {
|
|
47
|
-
legendStateRunRef.current++;
|
|
48
|
-
legendStateReady.current = false;
|
|
49
|
-
(async function () {
|
|
50
|
-
const currentRun = legendStateRunRef.current;
|
|
51
|
-
if (!preparedLegend) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const newStateValue = await getLegendComponents({
|
|
55
|
-
chartWidth: width,
|
|
56
|
-
chartHeight: height,
|
|
57
|
-
chartMargin: preparedChart.margin,
|
|
58
|
-
series: preparedSeries,
|
|
59
|
-
preparedLegend,
|
|
60
|
-
});
|
|
61
|
-
if (legendStateRunRef.current === currentRun) {
|
|
62
|
-
if (!isEqual(prevLegendStateValue.current, newStateValue)) {
|
|
63
|
-
setLegend(newStateValue);
|
|
64
|
-
prevLegendStateValue.current = newStateValue;
|
|
65
|
-
}
|
|
66
|
-
legendStateReady.current = true;
|
|
67
|
-
}
|
|
68
|
-
})();
|
|
69
|
-
}, [height, preparedChart.margin, preparedLegend, preparedSeries, width]);
|
|
70
|
-
return legendStateReady.current
|
|
71
|
-
? legendState
|
|
72
|
-
: {
|
|
73
|
-
legendConfig: undefined,
|
|
74
|
-
legendItems: [],
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
37
|
export function useChartInnerProps(props) {
|
|
78
38
|
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
|
|
79
39
|
const prevWidth = usePrevious(width);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LegendItem, PreparedChart, PreparedLegend, PreparedSeries } from '../../hooks';
|
|
2
|
+
import type { LegendConfig } from '../../types';
|
|
3
|
+
type LegendState = {
|
|
4
|
+
legendConfig?: LegendConfig;
|
|
5
|
+
legendItems: LegendItem[][];
|
|
6
|
+
};
|
|
7
|
+
export declare function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }: {
|
|
8
|
+
preparedLegend: PreparedLegend | null;
|
|
9
|
+
preparedChart: PreparedChart;
|
|
10
|
+
preparedSeries: PreparedSeries[];
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
}): LegendState;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
3
|
+
import { getLegendComponents } from '../../hooks/useSeries/prepare-legend';
|
|
4
|
+
export function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }) {
|
|
5
|
+
const [legendState, setLegend] = React.useState({
|
|
6
|
+
legendConfig: undefined,
|
|
7
|
+
legendItems: [],
|
|
8
|
+
});
|
|
9
|
+
const legendStateRunRef = React.useRef(0);
|
|
10
|
+
const prevLegendStateValue = React.useRef(legendState);
|
|
11
|
+
const legendStateReady = React.useRef(false);
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
legendStateRunRef.current++;
|
|
14
|
+
legendStateReady.current = false;
|
|
15
|
+
(async function () {
|
|
16
|
+
const currentRun = legendStateRunRef.current;
|
|
17
|
+
if (!preparedLegend) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const newStateValue = await getLegendComponents({
|
|
21
|
+
chartWidth: width,
|
|
22
|
+
chartHeight: height,
|
|
23
|
+
chartMargin: preparedChart.margin,
|
|
24
|
+
series: preparedSeries,
|
|
25
|
+
preparedLegend,
|
|
26
|
+
});
|
|
27
|
+
if (legendStateRunRef.current === currentRun) {
|
|
28
|
+
if (!isEqual(prevLegendStateValue.current, newStateValue)) {
|
|
29
|
+
setLegend(newStateValue);
|
|
30
|
+
prevLegendStateValue.current = newStateValue;
|
|
31
|
+
}
|
|
32
|
+
legendStateReady.current = true;
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
35
|
+
}, [height, preparedChart.margin, preparedLegend, preparedSeries, width]);
|
|
36
|
+
return legendState;
|
|
37
|
+
}
|
|
@@ -4,7 +4,7 @@ import get from 'lodash/get';
|
|
|
4
4
|
import isEqual from 'lodash/isEqual';
|
|
5
5
|
import { usePrevious } from '../../../hooks';
|
|
6
6
|
import { i18n } from '../../../i18n';
|
|
7
|
-
import { block
|
|
7
|
+
import { block } from '../../../utils';
|
|
8
8
|
import { getFormattedValue } from '../../../utils/chart/format';
|
|
9
9
|
import { Row } from './Row';
|
|
10
10
|
import { RowWithAggregation } from './RowWithAggregation';
|
|
@@ -52,30 +52,17 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
52
52
|
if (!contentRowsRef.current) {
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (isEqual(hoveredValues, prevHoveredValues)) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const rows = contentRowsRef.current.querySelectorAll(`.${b('content-row')}`);
|
|
62
|
-
let nextVisibleRows = 0;
|
|
63
|
-
let nextMaxContentRowsHeight = 0;
|
|
64
|
-
for (let i = 0; i < rows.length; i++) {
|
|
65
|
-
const row = rows[i];
|
|
66
|
-
const { top, height } = row.getBoundingClientRect();
|
|
67
|
-
if (top - containerTop + height <= clientHeight) {
|
|
68
|
-
nextVisibleRows += 1;
|
|
69
|
-
nextMaxContentRowsHeight += height;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
setVisibleRows(nextVisibleRows - 1);
|
|
76
|
-
setMaxContentRowsHeight(nextMaxContentRowsHeight);
|
|
58
|
+
const { scrollHeight, clientHeight } = contentRowsRef.current;
|
|
59
|
+
if (scrollHeight <= clientHeight) {
|
|
60
|
+
return;
|
|
77
61
|
}
|
|
78
|
-
|
|
62
|
+
const nextVisibleRows = Math.floor(hovered.length * (clientHeight / scrollHeight));
|
|
63
|
+
setVisibleRows(Math.max(nextVisibleRows - 1, 1));
|
|
64
|
+
setMaxContentRowsHeight((scrollHeight / hovered.length) * nextVisibleRows);
|
|
65
|
+
}, [hovered.length, hoveredValues, prevHoveredValues]);
|
|
79
66
|
React.useEffect(() => {
|
|
80
67
|
if (!contentRowsRef.current) {
|
|
81
68
|
return;
|
|
@@ -91,7 +78,7 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
91
78
|
return (React.createElement("div", { className: b('content'), "data-qa": qa },
|
|
92
79
|
formattedHeadValue && (React.createElement("div", { className: b('series-name') },
|
|
93
80
|
React.createElement("div", { className: b('series-name-text'), dangerouslySetInnerHTML: { __html: formattedHeadValue } }))),
|
|
94
|
-
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: { maxHeight: maxContentRowsHeight } },
|
|
81
|
+
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: pinned ? { maxHeight: maxContentRowsHeight } : undefined },
|
|
95
82
|
visibleHovered.map((seriesItem, i) => {
|
|
96
83
|
var _a;
|
|
97
84
|
const { data, series, closest } = seriesItem;
|
|
@@ -10,12 +10,12 @@ export function useAxis(props) {
|
|
|
10
10
|
const prevAxesStateValue = React.useRef(axesState);
|
|
11
11
|
const axesStateReady = React.useRef(false);
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
+
axesStateRunRef.current++;
|
|
14
|
+
axesStateReady.current = false;
|
|
13
15
|
const shouldWaitForLegendReady = !preparedLegend || ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && !legendConfig);
|
|
14
16
|
if (shouldWaitForLegendReady) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
|
-
axesStateRunRef.current++;
|
|
18
|
-
axesStateReady.current = false;
|
|
19
19
|
(async function () {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
const currentRun = axesStateRunRef.current;
|
|
@@ -79,5 +79,10 @@ export function useAxis(props) {
|
|
|
79
79
|
xAxis,
|
|
80
80
|
yAxis,
|
|
81
81
|
]);
|
|
82
|
-
|
|
82
|
+
const isAxesReady = axesStateReady.current;
|
|
83
|
+
const result = React.useMemo(() => {
|
|
84
|
+
return isAxesReady ? Object.assign(Object.assign({}, axesState), { setAxes }) : { xAxis: null, yAxis: [], setAxes };
|
|
85
|
+
}, [isAxesReady, axesState]);
|
|
86
|
+
prevAxesStateValue.current = result;
|
|
87
|
+
return result;
|
|
83
88
|
}
|
|
@@ -142,7 +142,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
142
142
|
: (_j = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _j === void 0 ? void 0 : _j.pixelInterval,
|
|
143
143
|
},
|
|
144
144
|
tickMarks: {
|
|
145
|
-
enabled: get(xAxis, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
145
|
+
enabled: isAxisVisible && get(xAxis, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
146
146
|
length: get(xAxis, 'tickMarks.length', axisTickMarksDefaults.length),
|
|
147
147
|
},
|
|
148
148
|
position: 'bottom',
|
|
@@ -52,7 +52,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
52
52
|
return Promise.all(
|
|
53
53
|
// eslint-disable-next-line complexity
|
|
54
54
|
axisItems.map(async (axisItem, axisIndex) => {
|
|
55
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
55
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
56
56
|
const plotIndex = get(axisItem, 'plotIndex', 0);
|
|
57
57
|
const firstPlotAxis = !axisByPlot[plotIndex];
|
|
58
58
|
if (firstPlotAxis) {
|
|
@@ -62,7 +62,8 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
62
62
|
const defaultAxisPosition = firstPlotAxis ? 'left' : 'right';
|
|
63
63
|
const axisPosition = get(axisItem, 'position', defaultAxisPosition);
|
|
64
64
|
const axisSeriesData = seriesData.filter((s) => get(s, 'yAxis', 0) === axisIndex);
|
|
65
|
-
const
|
|
65
|
+
const isAxisVisible = (_a = axisItem.visible) !== null && _a !== void 0 ? _a : true;
|
|
66
|
+
const labelsEnabled = isAxisVisible && get(axisItem, 'labels.enabled', true);
|
|
66
67
|
const labelsStyle = {
|
|
67
68
|
fontSize: get(axisItem, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE),
|
|
68
69
|
};
|
|
@@ -70,7 +71,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
70
71
|
const labelsLineHeight = labelsHtml
|
|
71
72
|
? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
|
|
72
73
|
: getHorizontalSvgTextHeight({ text: 'Tmp', style: labelsStyle });
|
|
73
|
-
const titleText = get(axisItem, 'title.text', '');
|
|
74
|
+
const titleText = isAxisVisible ? get(axisItem, 'title.text', '') : '';
|
|
74
75
|
const titleStyle = Object.assign(Object.assign({}, yAxisTitleDefaults.style), get(axisItem, 'title.style'));
|
|
75
76
|
const titleMaxRowsCount = get(axisItem, 'title.maxRowCount', yAxisTitleDefaults.maxRowCount);
|
|
76
77
|
const estimatedTitleRows = (await wrapText({
|
|
@@ -78,24 +79,23 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
78
79
|
style: titleStyle,
|
|
79
80
|
width: height,
|
|
80
81
|
})).slice(0, titleMaxRowsCount);
|
|
81
|
-
const titleRotation = getAxisTitleRotation((
|
|
82
|
+
const titleRotation = getAxisTitleRotation((_b = axisItem.title) === null || _b === void 0 ? void 0 : _b.rotation, axisPosition);
|
|
82
83
|
const titleMaxWidth = titleRotation === 0
|
|
83
84
|
? calculateNumericProperty({
|
|
84
|
-
value: (
|
|
85
|
+
value: (_d = (_c = axisItem.title) === null || _c === void 0 ? void 0 : _c.maxWidth) !== null && _d !== void 0 ? _d : '20%',
|
|
85
86
|
base: width,
|
|
86
87
|
})
|
|
87
88
|
: calculateNumericProperty({
|
|
88
|
-
value: (
|
|
89
|
+
value: (_f = (_e = axisItem.title) === null || _e === void 0 ? void 0 : _e.maxWidth) !== null && _f !== void 0 ? _f : '100%',
|
|
89
90
|
base: height,
|
|
90
91
|
});
|
|
91
92
|
const titleSize = await getLabelsSize({
|
|
92
93
|
labels: [titleText],
|
|
93
94
|
style: titleStyle,
|
|
94
|
-
html: (
|
|
95
|
+
html: (_g = axisItem.title) === null || _g === void 0 ? void 0 : _g.html,
|
|
95
96
|
});
|
|
96
97
|
const axisType = get(axisItem, 'type', DEFAULT_AXIS_TYPE);
|
|
97
|
-
const shouldHideGrid =
|
|
98
|
-
axisSeriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
|
|
98
|
+
const shouldHideGrid = !isAxisVisible || axisSeriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
|
|
99
99
|
let gridEnabled;
|
|
100
100
|
if (shouldHideGrid) {
|
|
101
101
|
gridEnabled = false;
|
|
@@ -108,7 +108,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
108
108
|
else {
|
|
109
109
|
gridEnabled = shouldSyncAxisWithPrimary(axisItem, axisByPlot[plotIndex][0])
|
|
110
110
|
? false
|
|
111
|
-
: !((
|
|
111
|
+
: !((_h = axisByPlot[plotIndex][0].visible) !== null && _h !== void 0 ? _h : true);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
const preparedAxis = {
|
|
@@ -126,7 +126,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
126
126
|
width: 0,
|
|
127
127
|
height: 0,
|
|
128
128
|
lineHeight: labelsLineHeight,
|
|
129
|
-
maxWidth: (
|
|
129
|
+
maxWidth: (_k = calculateNumericProperty({ base: width, value: (_j = axisItem.labels) === null || _j === void 0 ? void 0 : _j.maxWidth })) !== null && _k !== void 0 ? _k : axisLabelsDefaults.maxWidth,
|
|
130
130
|
html: labelsHtml,
|
|
131
131
|
},
|
|
132
132
|
lineColor: get(axisItem, 'lineColor'),
|
|
@@ -140,11 +140,11 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
140
140
|
height: titleSize.maxHeight * estimatedTitleRows.length,
|
|
141
141
|
align: get(axisItem, 'title.align', yAxisTitleDefaults.align),
|
|
142
142
|
maxRowCount: titleMaxRowsCount,
|
|
143
|
-
html: (
|
|
143
|
+
html: (_m = (_l = axisItem.title) === null || _l === void 0 ? void 0 : _l.html) !== null && _m !== void 0 ? _m : false,
|
|
144
144
|
maxWidth: titleMaxWidth !== null && titleMaxWidth !== void 0 ? titleMaxWidth : Infinity,
|
|
145
145
|
rotation: titleRotation,
|
|
146
146
|
},
|
|
147
|
-
min: (
|
|
147
|
+
min: (_o = get(axisItem, 'min')) !== null && _o !== void 0 ? _o : getDefaultMinYAxisValue(axisSeriesData),
|
|
148
148
|
max: get(axisItem, 'max'),
|
|
149
149
|
startOnTick: get(axisItem, 'startOnTick'),
|
|
150
150
|
endOnTick: get(axisItem, 'endOnTick'),
|
|
@@ -153,15 +153,16 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
153
153
|
enabled: gridEnabled,
|
|
154
154
|
},
|
|
155
155
|
ticks: {
|
|
156
|
-
pixelInterval: ((
|
|
156
|
+
pixelInterval: ((_p = axisItem.ticks) === null || _p === void 0 ? void 0 : _p.interval)
|
|
157
157
|
? calculateNumericProperty({
|
|
158
158
|
base: height,
|
|
159
|
-
value: (
|
|
159
|
+
value: (_q = axisItem.ticks) === null || _q === void 0 ? void 0 : _q.interval,
|
|
160
160
|
})
|
|
161
|
-
: (
|
|
161
|
+
: (_r = axisItem.ticks) === null || _r === void 0 ? void 0 : _r.pixelInterval,
|
|
162
162
|
},
|
|
163
163
|
tickMarks: {
|
|
164
|
-
enabled:
|
|
164
|
+
enabled: isAxisVisible &&
|
|
165
|
+
get(axisItem, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
165
166
|
length: get(axisItem, 'tickMarks.length', axisTickMarksDefaults.length),
|
|
166
167
|
},
|
|
167
168
|
position: axisPosition,
|
|
@@ -49,6 +49,9 @@ const getLeftOffset = ({ preparedLegend, legendConfig, }) => {
|
|
|
49
49
|
export const useChartDimensions = (args) => {
|
|
50
50
|
const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width, legendConfig, } = args;
|
|
51
51
|
return React.useMemo(() => {
|
|
52
|
+
if (!preparedLegend || (!legendConfig && (preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled))) {
|
|
53
|
+
return { boundsWidth: 0, boundsHeight: 0 };
|
|
54
|
+
}
|
|
52
55
|
const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
|
|
53
56
|
const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
|
|
54
57
|
const bottomOffset = getBottomOffset({
|
|
@@ -38,6 +38,9 @@ export const useShapes = (args) => {
|
|
|
38
38
|
const countedRef = React.useRef(0);
|
|
39
39
|
React.useEffect(() => {
|
|
40
40
|
countedRef.current++;
|
|
41
|
+
if (!boundsHeight || !boundsWidth) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
41
44
|
(async () => {
|
|
42
45
|
const currentRun = countedRef.current;
|
|
43
46
|
const visibleSeries = getOnlyVisibleSeries(series);
|
|
@@ -32,7 +32,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
32
32
|
}
|
|
33
33
|
if (runRef.current === currentRun && axisIndexesToRecalculateMap.size > 0) {
|
|
34
34
|
setAxes((prevState) => {
|
|
35
|
-
|
|
35
|
+
const newYAxis = prevState.yAxis.map((axis, i) => {
|
|
36
36
|
const width = axisIndexesToRecalculateMap.get(i);
|
|
37
37
|
if (width) {
|
|
38
38
|
const axisWithRecalculatedLabels = Object.assign(Object.assign({}, axis), { labels: Object.assign(Object.assign({}, axis.labels), { width }) });
|
|
@@ -40,7 +40,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
40
40
|
}
|
|
41
41
|
return axis;
|
|
42
42
|
});
|
|
43
|
-
return prevState;
|
|
43
|
+
return Object.assign(Object.assign({}, prevState), { yAxis: newYAxis });
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
})();
|
|
@@ -97,6 +97,9 @@ export interface ChartAxisTitle {
|
|
|
97
97
|
}
|
|
98
98
|
export interface ChartAxisTickMarks {
|
|
99
99
|
/** Enable or disable the tick marks on the axis.
|
|
100
|
+
*
|
|
101
|
+
* Note: tick marks are always hidden when the axis `visible` is set to `false`.
|
|
102
|
+
*
|
|
100
103
|
* @default false
|
|
101
104
|
*/
|
|
102
105
|
enabled?: boolean;
|
|
@@ -172,9 +175,12 @@ export interface ChartAxis {
|
|
|
172
175
|
plotLines?: AxisPlotLine[];
|
|
173
176
|
/** An array of colored bands stretching across the plot area marking an interval on the axis. */
|
|
174
177
|
plotBands?: AxisPlotBand[];
|
|
175
|
-
/** Small perpendicular marks on the axis line at each tick position.
|
|
178
|
+
/** Small perpendicular marks on the axis line at each tick position.
|
|
179
|
+
*
|
|
180
|
+
* Hidden when the axis `visible` is set to `false`.
|
|
181
|
+
*/
|
|
176
182
|
tickMarks?: ChartAxisTickMarks;
|
|
177
|
-
/** Whether axis, including axis title, line,
|
|
183
|
+
/** Whether axis, including axis title, line, tick marks, and labels, should be visible. */
|
|
178
184
|
visible?: boolean;
|
|
179
185
|
/** Setting the order of the axis values. It is not applied by default.
|
|
180
186
|
* the "reverse" value is needed to use the reverse order without sorting
|
package/dist/cjs/utils/misc.d.ts
CHANGED
package/dist/cjs/utils/misc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PreparedChart, PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
|
|
4
4
|
import type { LegendConfig } from '../../types';
|
|
5
5
|
import type { ChartInnerProps } from './types';
|
|
6
6
|
type Props = ChartInnerProps & {
|
|
@@ -13,19 +13,8 @@ type Props = ChartInnerProps & {
|
|
|
13
13
|
zoomState: Partial<ZoomState>;
|
|
14
14
|
rangeSliderState?: RangeSliderState;
|
|
15
15
|
};
|
|
16
|
-
type LegendState = {
|
|
17
|
-
legendConfig?: LegendConfig;
|
|
18
|
-
legendItems: LegendItem[][];
|
|
19
|
-
};
|
|
20
|
-
export declare function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }: {
|
|
21
|
-
preparedLegend: PreparedLegend | null;
|
|
22
|
-
preparedChart: PreparedChart;
|
|
23
|
-
preparedSeries: PreparedSeries[];
|
|
24
|
-
width: number;
|
|
25
|
-
height: number;
|
|
26
|
-
}): LegendState;
|
|
27
16
|
export declare function useChartInnerProps(props: Props): {
|
|
28
|
-
allPreparedSeries: PreparedSeries[];
|
|
17
|
+
allPreparedSeries: import("../../hooks").PreparedSeries[];
|
|
29
18
|
boundsHeight: number;
|
|
30
19
|
boundsOffsetLeft: number;
|
|
31
20
|
boundsOffsetTop: number;
|
|
@@ -33,9 +22,9 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
33
22
|
handleLegendItemClick: import("../../hooks").OnLegendItemClick;
|
|
34
23
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
35
24
|
legendConfig: LegendConfig | undefined;
|
|
36
|
-
legendItems: LegendItem[][];
|
|
25
|
+
legendItems: import("../../hooks").LegendItem[][];
|
|
37
26
|
preparedLegend: PreparedLegend | null;
|
|
38
|
-
preparedSeries: PreparedSeries[];
|
|
27
|
+
preparedSeries: import("../../hooks").PreparedSeries[];
|
|
39
28
|
preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
|
|
40
29
|
preparedSplit: import("../../hooks").PreparedSplit;
|
|
41
30
|
prevHeight: number | undefined;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import isEqual from 'lodash/isEqual';
|
|
3
2
|
import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
|
|
4
3
|
import { useAxis, useAxisScales, useChartDimensions, useNormalizedOriginalData, usePrevious, useSeries, useShapes, useSplit, useYAxisLabelWidth, useZoom, } from '../../hooks';
|
|
5
4
|
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
6
|
-
import { getLegendComponents } from '../../hooks/useSeries/prepare-legend';
|
|
7
5
|
import { getPreparedOptions } from '../../hooks/useSeries/prepare-options';
|
|
8
6
|
import { getEffectiveXRange, getZoomedSeriesData } from '../../utils';
|
|
7
|
+
import { useLegend } from './useLegend';
|
|
9
8
|
import { hasAtLeastOneSeriesDataPerPlot } from './utils';
|
|
10
9
|
const CLIP_PATH_BY_SERIES_TYPE = {
|
|
11
10
|
[SERIES_TYPE.Scatter]: false,
|
|
@@ -35,45 +34,6 @@ function getBoundsOffsetLeft(args) {
|
|
|
35
34
|
}, 0);
|
|
36
35
|
return chartMarginLeft + legendOffset + leftAxisWidth;
|
|
37
36
|
}
|
|
38
|
-
export function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }) {
|
|
39
|
-
const [legendState, setLegend] = React.useState({
|
|
40
|
-
legendConfig: undefined,
|
|
41
|
-
legendItems: [],
|
|
42
|
-
});
|
|
43
|
-
const legendStateRunRef = React.useRef(0);
|
|
44
|
-
const prevLegendStateValue = React.useRef(legendState);
|
|
45
|
-
const legendStateReady = React.useRef(false);
|
|
46
|
-
React.useEffect(() => {
|
|
47
|
-
legendStateRunRef.current++;
|
|
48
|
-
legendStateReady.current = false;
|
|
49
|
-
(async function () {
|
|
50
|
-
const currentRun = legendStateRunRef.current;
|
|
51
|
-
if (!preparedLegend) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const newStateValue = await getLegendComponents({
|
|
55
|
-
chartWidth: width,
|
|
56
|
-
chartHeight: height,
|
|
57
|
-
chartMargin: preparedChart.margin,
|
|
58
|
-
series: preparedSeries,
|
|
59
|
-
preparedLegend,
|
|
60
|
-
});
|
|
61
|
-
if (legendStateRunRef.current === currentRun) {
|
|
62
|
-
if (!isEqual(prevLegendStateValue.current, newStateValue)) {
|
|
63
|
-
setLegend(newStateValue);
|
|
64
|
-
prevLegendStateValue.current = newStateValue;
|
|
65
|
-
}
|
|
66
|
-
legendStateReady.current = true;
|
|
67
|
-
}
|
|
68
|
-
})();
|
|
69
|
-
}, [height, preparedChart.margin, preparedLegend, preparedSeries, width]);
|
|
70
|
-
return legendStateReady.current
|
|
71
|
-
? legendState
|
|
72
|
-
: {
|
|
73
|
-
legendConfig: undefined,
|
|
74
|
-
legendItems: [],
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
37
|
export function useChartInnerProps(props) {
|
|
78
38
|
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
|
|
79
39
|
const prevWidth = usePrevious(width);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LegendItem, PreparedChart, PreparedLegend, PreparedSeries } from '../../hooks';
|
|
2
|
+
import type { LegendConfig } from '../../types';
|
|
3
|
+
type LegendState = {
|
|
4
|
+
legendConfig?: LegendConfig;
|
|
5
|
+
legendItems: LegendItem[][];
|
|
6
|
+
};
|
|
7
|
+
export declare function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }: {
|
|
8
|
+
preparedLegend: PreparedLegend | null;
|
|
9
|
+
preparedChart: PreparedChart;
|
|
10
|
+
preparedSeries: PreparedSeries[];
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
}): LegendState;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
3
|
+
import { getLegendComponents } from '../../hooks/useSeries/prepare-legend';
|
|
4
|
+
export function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }) {
|
|
5
|
+
const [legendState, setLegend] = React.useState({
|
|
6
|
+
legendConfig: undefined,
|
|
7
|
+
legendItems: [],
|
|
8
|
+
});
|
|
9
|
+
const legendStateRunRef = React.useRef(0);
|
|
10
|
+
const prevLegendStateValue = React.useRef(legendState);
|
|
11
|
+
const legendStateReady = React.useRef(false);
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
legendStateRunRef.current++;
|
|
14
|
+
legendStateReady.current = false;
|
|
15
|
+
(async function () {
|
|
16
|
+
const currentRun = legendStateRunRef.current;
|
|
17
|
+
if (!preparedLegend) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const newStateValue = await getLegendComponents({
|
|
21
|
+
chartWidth: width,
|
|
22
|
+
chartHeight: height,
|
|
23
|
+
chartMargin: preparedChart.margin,
|
|
24
|
+
series: preparedSeries,
|
|
25
|
+
preparedLegend,
|
|
26
|
+
});
|
|
27
|
+
if (legendStateRunRef.current === currentRun) {
|
|
28
|
+
if (!isEqual(prevLegendStateValue.current, newStateValue)) {
|
|
29
|
+
setLegend(newStateValue);
|
|
30
|
+
prevLegendStateValue.current = newStateValue;
|
|
31
|
+
}
|
|
32
|
+
legendStateReady.current = true;
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
35
|
+
}, [height, preparedChart.margin, preparedLegend, preparedSeries, width]);
|
|
36
|
+
return legendState;
|
|
37
|
+
}
|
|
@@ -4,7 +4,7 @@ import get from 'lodash/get';
|
|
|
4
4
|
import isEqual from 'lodash/isEqual';
|
|
5
5
|
import { usePrevious } from '../../../hooks';
|
|
6
6
|
import { i18n } from '../../../i18n';
|
|
7
|
-
import { block
|
|
7
|
+
import { block } from '../../../utils';
|
|
8
8
|
import { getFormattedValue } from '../../../utils/chart/format';
|
|
9
9
|
import { Row } from './Row';
|
|
10
10
|
import { RowWithAggregation } from './RowWithAggregation';
|
|
@@ -52,30 +52,17 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
52
52
|
if (!contentRowsRef.current) {
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (isEqual(hoveredValues, prevHoveredValues)) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const rows = contentRowsRef.current.querySelectorAll(`.${b('content-row')}`);
|
|
62
|
-
let nextVisibleRows = 0;
|
|
63
|
-
let nextMaxContentRowsHeight = 0;
|
|
64
|
-
for (let i = 0; i < rows.length; i++) {
|
|
65
|
-
const row = rows[i];
|
|
66
|
-
const { top, height } = row.getBoundingClientRect();
|
|
67
|
-
if (top - containerTop + height <= clientHeight) {
|
|
68
|
-
nextVisibleRows += 1;
|
|
69
|
-
nextMaxContentRowsHeight += height;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
setVisibleRows(nextVisibleRows - 1);
|
|
76
|
-
setMaxContentRowsHeight(nextMaxContentRowsHeight);
|
|
58
|
+
const { scrollHeight, clientHeight } = contentRowsRef.current;
|
|
59
|
+
if (scrollHeight <= clientHeight) {
|
|
60
|
+
return;
|
|
77
61
|
}
|
|
78
|
-
|
|
62
|
+
const nextVisibleRows = Math.floor(hovered.length * (clientHeight / scrollHeight));
|
|
63
|
+
setVisibleRows(Math.max(nextVisibleRows - 1, 1));
|
|
64
|
+
setMaxContentRowsHeight((scrollHeight / hovered.length) * nextVisibleRows);
|
|
65
|
+
}, [hovered.length, hoveredValues, prevHoveredValues]);
|
|
79
66
|
React.useEffect(() => {
|
|
80
67
|
if (!contentRowsRef.current) {
|
|
81
68
|
return;
|
|
@@ -91,7 +78,7 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
91
78
|
return (React.createElement("div", { className: b('content'), "data-qa": qa },
|
|
92
79
|
formattedHeadValue && (React.createElement("div", { className: b('series-name') },
|
|
93
80
|
React.createElement("div", { className: b('series-name-text'), dangerouslySetInnerHTML: { __html: formattedHeadValue } }))),
|
|
94
|
-
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: { maxHeight: maxContentRowsHeight } },
|
|
81
|
+
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: pinned ? { maxHeight: maxContentRowsHeight } : undefined },
|
|
95
82
|
visibleHovered.map((seriesItem, i) => {
|
|
96
83
|
var _a;
|
|
97
84
|
const { data, series, closest } = seriesItem;
|
|
@@ -10,12 +10,12 @@ export function useAxis(props) {
|
|
|
10
10
|
const prevAxesStateValue = React.useRef(axesState);
|
|
11
11
|
const axesStateReady = React.useRef(false);
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
+
axesStateRunRef.current++;
|
|
14
|
+
axesStateReady.current = false;
|
|
13
15
|
const shouldWaitForLegendReady = !preparedLegend || ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && !legendConfig);
|
|
14
16
|
if (shouldWaitForLegendReady) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
|
-
axesStateRunRef.current++;
|
|
18
|
-
axesStateReady.current = false;
|
|
19
19
|
(async function () {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
const currentRun = axesStateRunRef.current;
|
|
@@ -79,5 +79,10 @@ export function useAxis(props) {
|
|
|
79
79
|
xAxis,
|
|
80
80
|
yAxis,
|
|
81
81
|
]);
|
|
82
|
-
|
|
82
|
+
const isAxesReady = axesStateReady.current;
|
|
83
|
+
const result = React.useMemo(() => {
|
|
84
|
+
return isAxesReady ? Object.assign(Object.assign({}, axesState), { setAxes }) : { xAxis: null, yAxis: [], setAxes };
|
|
85
|
+
}, [isAxesReady, axesState]);
|
|
86
|
+
prevAxesStateValue.current = result;
|
|
87
|
+
return result;
|
|
83
88
|
}
|
|
@@ -142,7 +142,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
142
142
|
: (_j = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _j === void 0 ? void 0 : _j.pixelInterval,
|
|
143
143
|
},
|
|
144
144
|
tickMarks: {
|
|
145
|
-
enabled: get(xAxis, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
145
|
+
enabled: isAxisVisible && get(xAxis, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
146
146
|
length: get(xAxis, 'tickMarks.length', axisTickMarksDefaults.length),
|
|
147
147
|
},
|
|
148
148
|
position: 'bottom',
|
|
@@ -52,7 +52,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
52
52
|
return Promise.all(
|
|
53
53
|
// eslint-disable-next-line complexity
|
|
54
54
|
axisItems.map(async (axisItem, axisIndex) => {
|
|
55
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
55
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
56
56
|
const plotIndex = get(axisItem, 'plotIndex', 0);
|
|
57
57
|
const firstPlotAxis = !axisByPlot[plotIndex];
|
|
58
58
|
if (firstPlotAxis) {
|
|
@@ -62,7 +62,8 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
62
62
|
const defaultAxisPosition = firstPlotAxis ? 'left' : 'right';
|
|
63
63
|
const axisPosition = get(axisItem, 'position', defaultAxisPosition);
|
|
64
64
|
const axisSeriesData = seriesData.filter((s) => get(s, 'yAxis', 0) === axisIndex);
|
|
65
|
-
const
|
|
65
|
+
const isAxisVisible = (_a = axisItem.visible) !== null && _a !== void 0 ? _a : true;
|
|
66
|
+
const labelsEnabled = isAxisVisible && get(axisItem, 'labels.enabled', true);
|
|
66
67
|
const labelsStyle = {
|
|
67
68
|
fontSize: get(axisItem, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE),
|
|
68
69
|
};
|
|
@@ -70,7 +71,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
70
71
|
const labelsLineHeight = labelsHtml
|
|
71
72
|
? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
|
|
72
73
|
: getHorizontalSvgTextHeight({ text: 'Tmp', style: labelsStyle });
|
|
73
|
-
const titleText = get(axisItem, 'title.text', '');
|
|
74
|
+
const titleText = isAxisVisible ? get(axisItem, 'title.text', '') : '';
|
|
74
75
|
const titleStyle = Object.assign(Object.assign({}, yAxisTitleDefaults.style), get(axisItem, 'title.style'));
|
|
75
76
|
const titleMaxRowsCount = get(axisItem, 'title.maxRowCount', yAxisTitleDefaults.maxRowCount);
|
|
76
77
|
const estimatedTitleRows = (await wrapText({
|
|
@@ -78,24 +79,23 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
78
79
|
style: titleStyle,
|
|
79
80
|
width: height,
|
|
80
81
|
})).slice(0, titleMaxRowsCount);
|
|
81
|
-
const titleRotation = getAxisTitleRotation((
|
|
82
|
+
const titleRotation = getAxisTitleRotation((_b = axisItem.title) === null || _b === void 0 ? void 0 : _b.rotation, axisPosition);
|
|
82
83
|
const titleMaxWidth = titleRotation === 0
|
|
83
84
|
? calculateNumericProperty({
|
|
84
|
-
value: (
|
|
85
|
+
value: (_d = (_c = axisItem.title) === null || _c === void 0 ? void 0 : _c.maxWidth) !== null && _d !== void 0 ? _d : '20%',
|
|
85
86
|
base: width,
|
|
86
87
|
})
|
|
87
88
|
: calculateNumericProperty({
|
|
88
|
-
value: (
|
|
89
|
+
value: (_f = (_e = axisItem.title) === null || _e === void 0 ? void 0 : _e.maxWidth) !== null && _f !== void 0 ? _f : '100%',
|
|
89
90
|
base: height,
|
|
90
91
|
});
|
|
91
92
|
const titleSize = await getLabelsSize({
|
|
92
93
|
labels: [titleText],
|
|
93
94
|
style: titleStyle,
|
|
94
|
-
html: (
|
|
95
|
+
html: (_g = axisItem.title) === null || _g === void 0 ? void 0 : _g.html,
|
|
95
96
|
});
|
|
96
97
|
const axisType = get(axisItem, 'type', DEFAULT_AXIS_TYPE);
|
|
97
|
-
const shouldHideGrid =
|
|
98
|
-
axisSeriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
|
|
98
|
+
const shouldHideGrid = !isAxisVisible || axisSeriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
|
|
99
99
|
let gridEnabled;
|
|
100
100
|
if (shouldHideGrid) {
|
|
101
101
|
gridEnabled = false;
|
|
@@ -108,7 +108,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
108
108
|
else {
|
|
109
109
|
gridEnabled = shouldSyncAxisWithPrimary(axisItem, axisByPlot[plotIndex][0])
|
|
110
110
|
? false
|
|
111
|
-
: !((
|
|
111
|
+
: !((_h = axisByPlot[plotIndex][0].visible) !== null && _h !== void 0 ? _h : true);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
const preparedAxis = {
|
|
@@ -126,7 +126,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
126
126
|
width: 0,
|
|
127
127
|
height: 0,
|
|
128
128
|
lineHeight: labelsLineHeight,
|
|
129
|
-
maxWidth: (
|
|
129
|
+
maxWidth: (_k = calculateNumericProperty({ base: width, value: (_j = axisItem.labels) === null || _j === void 0 ? void 0 : _j.maxWidth })) !== null && _k !== void 0 ? _k : axisLabelsDefaults.maxWidth,
|
|
130
130
|
html: labelsHtml,
|
|
131
131
|
},
|
|
132
132
|
lineColor: get(axisItem, 'lineColor'),
|
|
@@ -140,11 +140,11 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
140
140
|
height: titleSize.maxHeight * estimatedTitleRows.length,
|
|
141
141
|
align: get(axisItem, 'title.align', yAxisTitleDefaults.align),
|
|
142
142
|
maxRowCount: titleMaxRowsCount,
|
|
143
|
-
html: (
|
|
143
|
+
html: (_m = (_l = axisItem.title) === null || _l === void 0 ? void 0 : _l.html) !== null && _m !== void 0 ? _m : false,
|
|
144
144
|
maxWidth: titleMaxWidth !== null && titleMaxWidth !== void 0 ? titleMaxWidth : Infinity,
|
|
145
145
|
rotation: titleRotation,
|
|
146
146
|
},
|
|
147
|
-
min: (
|
|
147
|
+
min: (_o = get(axisItem, 'min')) !== null && _o !== void 0 ? _o : getDefaultMinYAxisValue(axisSeriesData),
|
|
148
148
|
max: get(axisItem, 'max'),
|
|
149
149
|
startOnTick: get(axisItem, 'startOnTick'),
|
|
150
150
|
endOnTick: get(axisItem, 'endOnTick'),
|
|
@@ -153,15 +153,16 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
153
153
|
enabled: gridEnabled,
|
|
154
154
|
},
|
|
155
155
|
ticks: {
|
|
156
|
-
pixelInterval: ((
|
|
156
|
+
pixelInterval: ((_p = axisItem.ticks) === null || _p === void 0 ? void 0 : _p.interval)
|
|
157
157
|
? calculateNumericProperty({
|
|
158
158
|
base: height,
|
|
159
|
-
value: (
|
|
159
|
+
value: (_q = axisItem.ticks) === null || _q === void 0 ? void 0 : _q.interval,
|
|
160
160
|
})
|
|
161
|
-
: (
|
|
161
|
+
: (_r = axisItem.ticks) === null || _r === void 0 ? void 0 : _r.pixelInterval,
|
|
162
162
|
},
|
|
163
163
|
tickMarks: {
|
|
164
|
-
enabled:
|
|
164
|
+
enabled: isAxisVisible &&
|
|
165
|
+
get(axisItem, 'tickMarks.enabled', axisTickMarksDefaults.enabled),
|
|
165
166
|
length: get(axisItem, 'tickMarks.length', axisTickMarksDefaults.length),
|
|
166
167
|
},
|
|
167
168
|
position: axisPosition,
|
|
@@ -49,6 +49,9 @@ const getLeftOffset = ({ preparedLegend, legendConfig, }) => {
|
|
|
49
49
|
export const useChartDimensions = (args) => {
|
|
50
50
|
const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width, legendConfig, } = args;
|
|
51
51
|
return React.useMemo(() => {
|
|
52
|
+
if (!preparedLegend || (!legendConfig && (preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled))) {
|
|
53
|
+
return { boundsWidth: 0, boundsHeight: 0 };
|
|
54
|
+
}
|
|
52
55
|
const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
|
|
53
56
|
const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
|
|
54
57
|
const bottomOffset = getBottomOffset({
|
|
@@ -38,6 +38,9 @@ export const useShapes = (args) => {
|
|
|
38
38
|
const countedRef = React.useRef(0);
|
|
39
39
|
React.useEffect(() => {
|
|
40
40
|
countedRef.current++;
|
|
41
|
+
if (!boundsHeight || !boundsWidth) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
41
44
|
(async () => {
|
|
42
45
|
const currentRun = countedRef.current;
|
|
43
46
|
const visibleSeries = getOnlyVisibleSeries(series);
|
|
@@ -32,7 +32,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
32
32
|
}
|
|
33
33
|
if (runRef.current === currentRun && axisIndexesToRecalculateMap.size > 0) {
|
|
34
34
|
setAxes((prevState) => {
|
|
35
|
-
|
|
35
|
+
const newYAxis = prevState.yAxis.map((axis, i) => {
|
|
36
36
|
const width = axisIndexesToRecalculateMap.get(i);
|
|
37
37
|
if (width) {
|
|
38
38
|
const axisWithRecalculatedLabels = Object.assign(Object.assign({}, axis), { labels: Object.assign(Object.assign({}, axis.labels), { width }) });
|
|
@@ -40,7 +40,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
40
40
|
}
|
|
41
41
|
return axis;
|
|
42
42
|
});
|
|
43
|
-
return prevState;
|
|
43
|
+
return Object.assign(Object.assign({}, prevState), { yAxis: newYAxis });
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
})();
|
|
@@ -97,6 +97,9 @@ export interface ChartAxisTitle {
|
|
|
97
97
|
}
|
|
98
98
|
export interface ChartAxisTickMarks {
|
|
99
99
|
/** Enable or disable the tick marks on the axis.
|
|
100
|
+
*
|
|
101
|
+
* Note: tick marks are always hidden when the axis `visible` is set to `false`.
|
|
102
|
+
*
|
|
100
103
|
* @default false
|
|
101
104
|
*/
|
|
102
105
|
enabled?: boolean;
|
|
@@ -172,9 +175,12 @@ export interface ChartAxis {
|
|
|
172
175
|
plotLines?: AxisPlotLine[];
|
|
173
176
|
/** An array of colored bands stretching across the plot area marking an interval on the axis. */
|
|
174
177
|
plotBands?: AxisPlotBand[];
|
|
175
|
-
/** Small perpendicular marks on the axis line at each tick position.
|
|
178
|
+
/** Small perpendicular marks on the axis line at each tick position.
|
|
179
|
+
*
|
|
180
|
+
* Hidden when the axis `visible` is set to `false`.
|
|
181
|
+
*/
|
|
176
182
|
tickMarks?: ChartAxisTickMarks;
|
|
177
|
-
/** Whether axis, including axis title, line,
|
|
183
|
+
/** Whether axis, including axis title, line, tick marks, and labels, should be visible. */
|
|
178
184
|
visible?: boolean;
|
|
179
185
|
/** Setting the order of the axis values. It is not applied by default.
|
|
180
186
|
* the "reverse" value is needed to use the reverse order without sorting
|
package/dist/esm/utils/misc.d.ts
CHANGED
package/dist/esm/utils/misc.js
CHANGED