@gravity-ui/charts 1.26.0 → 1.27.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.d.ts +5 -20
- package/dist/cjs/components/AxisX/AxisX.js +167 -212
- package/dist/cjs/components/AxisX/prepare-axis-data.d.ts +10 -0
- package/dist/cjs/components/AxisX/prepare-axis-data.js +267 -0
- package/dist/cjs/components/AxisX/styles.css +7 -10
- package/dist/cjs/components/AxisX/types.d.ts +85 -0
- package/dist/cjs/components/AxisX/types.js +1 -0
- package/dist/cjs/components/AxisY/AxisY.js +9 -3
- package/dist/cjs/components/AxisY/prepare-axis-data.d.ts +1 -1
- package/dist/cjs/components/AxisY/prepare-axis-data.js +17 -81
- package/dist/cjs/components/AxisY/prepare-axis-title.d.ts +16 -0
- package/dist/cjs/components/AxisY/prepare-axis-title.js +149 -0
- package/dist/cjs/components/AxisY/types.d.ts +16 -4
- package/dist/cjs/components/AxisY/utils.js +1 -8
- package/dist/cjs/components/ChartInner/index.js +62 -50
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +7 -7
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +15 -20
- package/dist/cjs/components/ChartInner/useChartInnerState.d.ts +3 -2
- package/dist/cjs/components/ChartInner/useChartInnerState.js +23 -4
- package/dist/cjs/components/Legend/index.js +21 -14
- package/dist/cjs/components/RangeSlider/index.d.ts +5 -3
- package/dist/cjs/components/RangeSlider/index.js +36 -4
- package/dist/cjs/components/Title/index.js +2 -2
- package/dist/cjs/components/utils.d.ts +9 -0
- package/dist/cjs/components/utils.js +34 -0
- package/dist/cjs/constants/defaults/axis.js +1 -1
- package/dist/cjs/hooks/index.d.ts +0 -1
- package/dist/cjs/hooks/index.js +0 -1
- package/dist/cjs/hooks/useAxis/index.js +10 -0
- package/dist/cjs/hooks/useAxis/types.d.ts +3 -0
- package/dist/cjs/hooks/useAxis/x-axis.d.ts +2 -1
- package/dist/cjs/hooks/useAxis/x-axis.js +36 -28
- package/dist/cjs/hooks/useAxis/y-axis.js +38 -11
- package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -1
- package/dist/cjs/hooks/useAxisScales/index.js +8 -7
- package/dist/cjs/hooks/useAxisScales/utils.d.ts +6 -0
- package/dist/cjs/hooks/useAxisScales/utils.js +17 -0
- package/dist/cjs/hooks/useChartDimensions/utils.js +7 -1
- package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +1 -7
- package/dist/cjs/hooks/useRangeSlider/index.js +1 -2
- package/dist/cjs/hooks/useRangeSlider/types.d.ts +1 -3
- package/dist/cjs/hooks/useZoom/index.d.ts +1 -0
- package/dist/cjs/hooks/useZoom/index.js +12 -2
- package/dist/cjs/types/chart/axis.d.ts +45 -17
- package/dist/cjs/types/chart/title.d.ts +3 -0
- package/dist/{esm/utils/chart/axis.d.ts → cjs/utils/chart/axis/common.d.ts} +4 -16
- package/dist/{esm/utils/chart/axis.js → cjs/utils/chart/axis/common.js} +7 -40
- package/dist/cjs/utils/chart/axis/x-axis.d.ts +12 -0
- package/dist/cjs/utils/chart/axis/x-axis.js +78 -0
- package/dist/cjs/utils/chart/axis-generators/bottom.js +1 -1
- package/dist/cjs/utils/chart/index.d.ts +1 -1
- package/dist/cjs/utils/chart/index.js +1 -1
- package/dist/cjs/utils/chart/text.d.ts +0 -6
- package/dist/cjs/utils/chart/text.js +7 -19
- package/dist/esm/components/AxisX/AxisX.d.ts +5 -20
- package/dist/esm/components/AxisX/AxisX.js +167 -212
- package/dist/esm/components/AxisX/prepare-axis-data.d.ts +10 -0
- package/dist/esm/components/AxisX/prepare-axis-data.js +267 -0
- package/dist/esm/components/AxisX/styles.css +7 -10
- package/dist/esm/components/AxisX/types.d.ts +85 -0
- package/dist/esm/components/AxisX/types.js +1 -0
- package/dist/esm/components/AxisY/AxisY.js +9 -3
- package/dist/esm/components/AxisY/prepare-axis-data.d.ts +1 -1
- package/dist/esm/components/AxisY/prepare-axis-data.js +17 -81
- package/dist/esm/components/AxisY/prepare-axis-title.d.ts +16 -0
- package/dist/esm/components/AxisY/prepare-axis-title.js +149 -0
- package/dist/esm/components/AxisY/types.d.ts +16 -4
- package/dist/esm/components/AxisY/utils.js +1 -8
- package/dist/esm/components/ChartInner/index.js +62 -50
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +7 -7
- package/dist/esm/components/ChartInner/useChartInnerProps.js +15 -20
- package/dist/esm/components/ChartInner/useChartInnerState.d.ts +3 -2
- package/dist/esm/components/ChartInner/useChartInnerState.js +23 -4
- package/dist/esm/components/Legend/index.js +21 -14
- package/dist/esm/components/RangeSlider/index.d.ts +5 -3
- package/dist/esm/components/RangeSlider/index.js +36 -4
- package/dist/esm/components/Title/index.js +2 -2
- package/dist/esm/components/utils.d.ts +9 -0
- package/dist/esm/components/utils.js +34 -0
- package/dist/esm/constants/defaults/axis.js +1 -1
- package/dist/esm/hooks/index.d.ts +0 -1
- package/dist/esm/hooks/index.js +0 -1
- package/dist/esm/hooks/useAxis/index.js +10 -0
- package/dist/esm/hooks/useAxis/types.d.ts +3 -0
- package/dist/esm/hooks/useAxis/x-axis.d.ts +2 -1
- package/dist/esm/hooks/useAxis/x-axis.js +36 -28
- package/dist/esm/hooks/useAxis/y-axis.js +38 -11
- package/dist/esm/hooks/useAxisScales/index.d.ts +4 -1
- package/dist/esm/hooks/useAxisScales/index.js +8 -7
- package/dist/esm/hooks/useAxisScales/utils.d.ts +6 -0
- package/dist/esm/hooks/useAxisScales/utils.js +17 -0
- package/dist/esm/hooks/useChartDimensions/utils.js +7 -1
- package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +1 -7
- package/dist/esm/hooks/useRangeSlider/index.js +1 -2
- package/dist/esm/hooks/useRangeSlider/types.d.ts +1 -3
- package/dist/esm/hooks/useZoom/index.d.ts +1 -0
- package/dist/esm/hooks/useZoom/index.js +12 -2
- package/dist/esm/types/chart/axis.d.ts +45 -17
- package/dist/esm/types/chart/title.d.ts +3 -0
- package/dist/{cjs/utils/chart/axis.d.ts → esm/utils/chart/axis/common.d.ts} +4 -16
- package/dist/{cjs/utils/chart/axis.js → esm/utils/chart/axis/common.js} +7 -40
- package/dist/esm/utils/chart/axis/x-axis.d.ts +12 -0
- package/dist/esm/utils/chart/axis/x-axis.js +78 -0
- package/dist/esm/utils/chart/axis-generators/bottom.js +1 -1
- package/dist/esm/utils/chart/index.d.ts +1 -1
- package/dist/esm/utils/chart/index.js +1 -1
- package/dist/esm/utils/chart/text.d.ts +0 -6
- package/dist/esm/utils/chart/text.js +7 -19
- package/package.json +1 -1
- package/dist/cjs/hooks/useChartOptions/index.d.ts +0 -16
- package/dist/cjs/hooks/useChartOptions/index.js +0 -21
- package/dist/esm/hooks/useChartOptions/index.d.ts +0 -16
- package/dist/esm/hooks/useChartOptions/index.js +0 -21
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { calculateCos, calculateSin, getLabelsSize, getTextSizeFn, getTextWithElipsis, wrapText, } from '../../utils';
|
|
2
|
+
export async function prepareSvgYAxisTitle({ axis, axisTop, axisHeight, axisWidth, axisLabelsWidth, }) {
|
|
3
|
+
if (!axis.title.text || axis.title.html) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const getTitleTextSize = getTextSizeFn({ style: axis.title.style });
|
|
7
|
+
const rotateAngle = axis.title.rotation;
|
|
8
|
+
const sin = Math.abs(calculateSin(rotateAngle));
|
|
9
|
+
const cos = Math.abs(calculateCos(rotateAngle));
|
|
10
|
+
const titleContent = [];
|
|
11
|
+
const titleMaxWidth = rotateAngle === 0 ? axis.title.maxWidth : sin * axisHeight;
|
|
12
|
+
if (axis.title.maxRowCount > 1) {
|
|
13
|
+
let titleTextRows = await wrapText({
|
|
14
|
+
text: axis.title.text,
|
|
15
|
+
style: axis.title.style,
|
|
16
|
+
width: titleMaxWidth,
|
|
17
|
+
getTextSize: getTitleTextSize,
|
|
18
|
+
});
|
|
19
|
+
titleTextRows = titleTextRows.reduce((acc, row, index) => {
|
|
20
|
+
if (index < axis.title.maxRowCount) {
|
|
21
|
+
acc.push(row);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
acc[axis.title.maxRowCount - 1].text += row.text;
|
|
25
|
+
}
|
|
26
|
+
return acc;
|
|
27
|
+
}, []);
|
|
28
|
+
for (let i = 0; i < titleTextRows.length; i++) {
|
|
29
|
+
const textRow = titleTextRows[i];
|
|
30
|
+
let textRowContent = textRow.text.trim();
|
|
31
|
+
if (i === titleTextRows.length - 1) {
|
|
32
|
+
textRowContent = await getTextWithElipsis({
|
|
33
|
+
text: textRowContent,
|
|
34
|
+
maxWidth: titleMaxWidth,
|
|
35
|
+
getTextWidth: async (s) => (await getTitleTextSize(s)).width,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const textRowSize = await getTitleTextSize(textRowContent);
|
|
39
|
+
titleContent.push({
|
|
40
|
+
text: textRowContent,
|
|
41
|
+
x: 0,
|
|
42
|
+
y: textRow.y,
|
|
43
|
+
size: textRowSize,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const text = await getTextWithElipsis({
|
|
49
|
+
text: axis.title.text,
|
|
50
|
+
maxWidth: titleMaxWidth,
|
|
51
|
+
getTextWidth: async (s) => (await getTitleTextSize(s)).width,
|
|
52
|
+
});
|
|
53
|
+
titleContent.push({
|
|
54
|
+
text,
|
|
55
|
+
x: 0,
|
|
56
|
+
y: 0,
|
|
57
|
+
size: await getTitleTextSize(text),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const originalTextSize = titleContent.reduce((acc, item) => {
|
|
61
|
+
acc.width = Math.max(acc.width, item.size.width);
|
|
62
|
+
acc.height += item.size.height;
|
|
63
|
+
return acc;
|
|
64
|
+
}, { width: 0, height: 0 });
|
|
65
|
+
const rotatedTitleSize = rotateAngle === 0
|
|
66
|
+
? originalTextSize
|
|
67
|
+
: {
|
|
68
|
+
width: sin * originalTextSize.height + cos * originalTextSize.width,
|
|
69
|
+
height: sin * originalTextSize.width + cos * originalTextSize.height,
|
|
70
|
+
};
|
|
71
|
+
const bottom = Math.max(0, calculateSin(rotateAngle) * originalTextSize.width);
|
|
72
|
+
let y = 0;
|
|
73
|
+
switch (axis.title.align) {
|
|
74
|
+
case 'left': {
|
|
75
|
+
y = -bottom + axisHeight;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'center': {
|
|
79
|
+
y = -bottom + axisHeight / 2 + rotatedTitleSize.height / 2;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case 'right': {
|
|
83
|
+
y = -bottom + rotatedTitleSize.height;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const left = rotateAngle === 0
|
|
88
|
+
? Math.min(originalTextSize.width, axis.title.maxWidth)
|
|
89
|
+
: Math.min(0, calculateCos(rotateAngle) * originalTextSize.width);
|
|
90
|
+
const x = axis.position === 'left'
|
|
91
|
+
? -left - axisLabelsWidth - axis.labels.margin - axis.title.margin
|
|
92
|
+
: -left + axisWidth + axisLabelsWidth + axis.labels.margin + axis.title.margin;
|
|
93
|
+
return {
|
|
94
|
+
html: false,
|
|
95
|
+
content: titleContent,
|
|
96
|
+
style: axis.title.style,
|
|
97
|
+
size: rotatedTitleSize,
|
|
98
|
+
x,
|
|
99
|
+
y: axisTop + y,
|
|
100
|
+
rotate: rotateAngle,
|
|
101
|
+
offset: -(originalTextSize.height / titleContent.length) * (titleContent.length - 1),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export async function prepareHtmlYAxisTitle({ axis, axisTop, axisHeight, axisWidth, axisLabelsWidth, }) {
|
|
105
|
+
if (!axis.title.text || !axis.title.html) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const content = axis.title.text;
|
|
109
|
+
const rotateAngle = axis.title.rotation;
|
|
110
|
+
const titleMaxWidth = rotateAngle === 0 ? axis.title.maxWidth : axisHeight;
|
|
111
|
+
const labelSize = await getLabelsSize({
|
|
112
|
+
labels: [content],
|
|
113
|
+
html: true,
|
|
114
|
+
style: Object.assign(Object.assign({}, axis.title.style), { whiteSpace: 'nowrap' }),
|
|
115
|
+
});
|
|
116
|
+
const size = { width: labelSize.maxWidth, height: labelSize.maxHeight };
|
|
117
|
+
const rotatedTitleSize = rotateAngle === 0 ? size : { width: size.height, height: size.width };
|
|
118
|
+
let y = 0;
|
|
119
|
+
switch (axis.title.align) {
|
|
120
|
+
case 'left': {
|
|
121
|
+
const yOffset = rotateAngle === 0 ? -rotatedTitleSize.height : 0;
|
|
122
|
+
y = axisHeight + yOffset;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case 'center': {
|
|
126
|
+
const yOffset = rotateAngle === 0 ? -rotatedTitleSize.height / 2 : rotatedTitleSize.height / 2;
|
|
127
|
+
y = axisHeight / 2 + yOffset;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'right': {
|
|
131
|
+
y = rotateAngle === 0 ? 0 : rotatedTitleSize.height;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const x = axis.position === 'left'
|
|
136
|
+
? -Math.min(titleMaxWidth, rotatedTitleSize.width) -
|
|
137
|
+
axisLabelsWidth -
|
|
138
|
+
axis.labels.margin -
|
|
139
|
+
axis.title.margin
|
|
140
|
+
: axisWidth + axisLabelsWidth + axis.labels.margin + axis.title.margin;
|
|
141
|
+
return {
|
|
142
|
+
html: true,
|
|
143
|
+
content: `<div style="max-width: ${titleMaxWidth}px; overflow: hidden; white-space: nowrap; transform-origin: 0 0; transform: rotate(${rotateAngle}deg);">${content}</div>`,
|
|
144
|
+
style: axis.title.style,
|
|
145
|
+
size: rotatedTitleSize,
|
|
146
|
+
x,
|
|
147
|
+
y: axisTop + y,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DashStyle } from 'src/constants';
|
|
2
|
-
import type { BaseTextStyle, HtmlItem, PlotLayerPlacement } from '../../types';
|
|
2
|
+
import type { BaseTextStyle, HtmlItem, PlotLayerPlacement, PointPosition } from '../../types';
|
|
3
3
|
export type TextRowData = {
|
|
4
4
|
text: string;
|
|
5
5
|
x: number;
|
|
@@ -22,14 +22,15 @@ export type AxisSvgLabelData = {
|
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
export type AxisTickLine = {
|
|
25
|
-
points: [
|
|
25
|
+
points: PointPosition[];
|
|
26
26
|
};
|
|
27
27
|
export type AxisTickData = {
|
|
28
28
|
line: AxisTickLine | null;
|
|
29
29
|
svgLabel: AxisSvgLabelData | null;
|
|
30
30
|
htmlLabel: HtmlItem | null;
|
|
31
31
|
};
|
|
32
|
-
export type
|
|
32
|
+
export type SvgAxisTitleData = {
|
|
33
|
+
html: false;
|
|
33
34
|
content: TextRowData[];
|
|
34
35
|
style: BaseTextStyle;
|
|
35
36
|
size: {
|
|
@@ -41,6 +42,17 @@ export type AxisTitleData = {
|
|
|
41
42
|
rotate: number;
|
|
42
43
|
offset: number;
|
|
43
44
|
};
|
|
45
|
+
export type HtmlAxisTitleData = {
|
|
46
|
+
html: true;
|
|
47
|
+
content: string;
|
|
48
|
+
style: BaseTextStyle & React.CSSProperties;
|
|
49
|
+
size: {
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
};
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
};
|
|
44
56
|
export type AxisPlotLineLabel = {
|
|
45
57
|
text: string;
|
|
46
58
|
style: BaseTextStyle;
|
|
@@ -76,7 +88,7 @@ export type AxisDomainData = {
|
|
|
76
88
|
};
|
|
77
89
|
export type AxisYData = {
|
|
78
90
|
id: string;
|
|
79
|
-
title:
|
|
91
|
+
title: HtmlAxisTitleData | SvgAxisTitleData | null;
|
|
80
92
|
domain: AxisDomainData | null;
|
|
81
93
|
ticks: AxisTickData[];
|
|
82
94
|
plotLines: AxisPlotLineData[];
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import { getDomainDataYBySeries, getMinSpaceBetween, getTicksCount, isBandScale } from '../../utils';
|
|
2
|
-
function thinOut(items, delta) {
|
|
3
|
-
const arr = [];
|
|
4
|
-
for (let i = 0; i < items.length; i = i + delta) {
|
|
5
|
-
arr.push(items[i]);
|
|
6
|
-
}
|
|
7
|
-
return arr;
|
|
8
|
-
}
|
|
1
|
+
import { getDomainDataYBySeries, getMinSpaceBetween, getTicksCount, isBandScale, thinOut, } from '../../utils';
|
|
9
2
|
export function getTickValues({ scale, axis, labelLineHeight, series, }) {
|
|
10
3
|
if ('ticks' in scale && typeof scale.ticks === 'function') {
|
|
11
4
|
const range = scale.range();
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { duration } from '@gravity-ui/date-utils';
|
|
3
2
|
import { ArrowRotateLeft } from '@gravity-ui/icons';
|
|
4
3
|
import { Button, ButtonIcon, useUniqId } from '@gravity-ui/uikit';
|
|
5
4
|
import { useCrosshair } from '../../hooks';
|
|
6
5
|
import { getPreparedRangeSlider } from '../../hooks/useAxis/range-slider';
|
|
6
|
+
import { getPreparedChart } from '../../hooks/useChartOptions/chart';
|
|
7
|
+
import { getPreparedTitle } from '../../hooks/useChartOptions/title';
|
|
7
8
|
import { getPreparedTooltip } from '../../hooks/useChartOptions/tooltip';
|
|
8
|
-
import { EventType, block, getDispatcher, isBandScale
|
|
9
|
+
import { EventType, block, getDispatcher, isBandScale } from '../../utils';
|
|
9
10
|
import { AxisX } from '../AxisX/AxisX';
|
|
11
|
+
import { prepareXAxisData } from '../AxisX/prepare-axis-data';
|
|
10
12
|
import { AxisY } from '../AxisY/AxisY';
|
|
11
|
-
import {
|
|
13
|
+
import { prepareYAxisData } from '../AxisY/prepare-axis-data';
|
|
12
14
|
import { Legend } from '../Legend';
|
|
13
15
|
import { PlotTitle } from '../PlotTitle';
|
|
14
16
|
import { RangeSlider } from '../RangeSlider';
|
|
15
17
|
import { Title } from '../Title';
|
|
16
18
|
import { Tooltip } from '../Tooltip';
|
|
19
|
+
import { getInitialRangeSliderState } from '../utils';
|
|
17
20
|
import { useChartInnerHandlers } from './useChartInnerHandlers';
|
|
18
21
|
import { useChartInnerProps } from './useChartInnerProps';
|
|
19
22
|
import { useChartInnerState } from './useChartInnerState';
|
|
@@ -22,7 +25,7 @@ import './styles.css';
|
|
|
22
25
|
const b = block('chart');
|
|
23
26
|
const DEBOUNCED_VALUE_DELAY = 10;
|
|
24
27
|
export const ChartInner = (props) => {
|
|
25
|
-
var _a, _b, _c, _d, _e;
|
|
28
|
+
var _a, _b, _c, _d, _e, _f;
|
|
26
29
|
const { width, height, data } = props;
|
|
27
30
|
const svgRef = React.useRef(null);
|
|
28
31
|
const resetZoomButtonRef = React.useRef(null);
|
|
@@ -30,8 +33,19 @@ export const ChartInner = (props) => {
|
|
|
30
33
|
const plotRef = React.useRef(null);
|
|
31
34
|
const plotBeforeRef = React.useRef(null);
|
|
32
35
|
const plotAfterRef = React.useRef(null);
|
|
36
|
+
const rangeSliderRef = React.useRef(null);
|
|
33
37
|
const dispatcher = React.useMemo(() => getDispatcher(), []);
|
|
34
38
|
const clipPathId = useUniqId();
|
|
39
|
+
const preparedTitle = React.useMemo(() => {
|
|
40
|
+
return getPreparedTitle({ title: data.title });
|
|
41
|
+
}, [data.title]);
|
|
42
|
+
const preparedChart = React.useMemo(() => {
|
|
43
|
+
return getPreparedChart({
|
|
44
|
+
chart: data.chart,
|
|
45
|
+
seriesData: data.series.data,
|
|
46
|
+
preparedTitle,
|
|
47
|
+
});
|
|
48
|
+
}, [data.chart, data.series.data, preparedTitle]);
|
|
35
49
|
const preparedTooltip = React.useMemo(() => {
|
|
36
50
|
return getPreparedTooltip({
|
|
37
51
|
tooltip: data.tooltip,
|
|
@@ -45,12 +59,13 @@ export const ChartInner = (props) => {
|
|
|
45
59
|
}, [data.xAxis]);
|
|
46
60
|
const { initialized, setInitialized, tooltipPinned, togglePinTooltip, unpinTooltip, rangeSliderState, updateRangeSliderState, updateZoomState, zoomState, } = useChartInnerState({
|
|
47
61
|
dispatcher,
|
|
48
|
-
|
|
62
|
+
preparedChart,
|
|
49
63
|
preparedRangeSlider,
|
|
64
|
+
tooltip: preparedTooltip,
|
|
50
65
|
});
|
|
51
|
-
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems,
|
|
66
|
+
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, prevHeight, prevWidth, shapes, shapesData, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
52
67
|
dispatcher,
|
|
53
|
-
htmlLayout, plotNode: plotRef.current, rangeSliderState, svgContainer: svgRef.current, updateZoomState,
|
|
68
|
+
htmlLayout, plotNode: plotRef.current, preparedChart, rangeSliderDomain: (_a = rangeSliderRef.current) === null || _a === void 0 ? void 0 : _a.getDomain(), rangeSliderState, svgContainer: svgRef.current, updateZoomState,
|
|
54
69
|
zoomState }));
|
|
55
70
|
const debouncedBoundsWidth = useDebouncedValue({
|
|
56
71
|
value: boundsWidth,
|
|
@@ -80,8 +95,8 @@ export const ChartInner = (props) => {
|
|
|
80
95
|
tooltipThrottle: preparedTooltip.throttle,
|
|
81
96
|
isOutsideBounds,
|
|
82
97
|
});
|
|
83
|
-
const clickHandler = (
|
|
84
|
-
const pointerMoveHandler = (
|
|
98
|
+
const clickHandler = (_c = (_b = data.chart) === null || _b === void 0 ? void 0 : _b.events) === null || _c === void 0 ? void 0 : _c.click;
|
|
99
|
+
const pointerMoveHandler = (_e = (_d = data.chart) === null || _d === void 0 ? void 0 : _d.events) === null || _e === void 0 ? void 0 : _e.pointermove;
|
|
85
100
|
useCrosshair({
|
|
86
101
|
split: preparedSplit,
|
|
87
102
|
plotElement: plotAfterRef.current,
|
|
@@ -121,7 +136,7 @@ export const ChartInner = (props) => {
|
|
|
121
136
|
const axis = yAxis[i];
|
|
122
137
|
const scale = yScale === null || yScale === void 0 ? void 0 : yScale[i];
|
|
123
138
|
if (scale) {
|
|
124
|
-
const axisData = await
|
|
139
|
+
const axisData = await prepareYAxisData({
|
|
125
140
|
axis,
|
|
126
141
|
scale,
|
|
127
142
|
top: boundsOffsetTop,
|
|
@@ -136,48 +151,42 @@ export const ChartInner = (props) => {
|
|
|
136
151
|
return items;
|
|
137
152
|
}, [boundsHeight, boundsOffsetTop, boundsWidth, preparedSeries, preparedSplit, yAxis, yScale]);
|
|
138
153
|
const yAxisDataItems = useAsyncState([], setYAxisDataItems);
|
|
154
|
+
const setXAxisDataItems = React.useCallback(async () => {
|
|
155
|
+
const items = [];
|
|
156
|
+
const axis = xAxis;
|
|
157
|
+
const scale = xScale;
|
|
158
|
+
if (axis && scale) {
|
|
159
|
+
const axisData = await prepareXAxisData({
|
|
160
|
+
axis,
|
|
161
|
+
scale,
|
|
162
|
+
boundsWidth,
|
|
163
|
+
boundsOffsetLeft: boundsOffsetLeft,
|
|
164
|
+
boundsOffsetRight: width - boundsWidth - boundsOffsetLeft,
|
|
165
|
+
height: boundsHeight,
|
|
166
|
+
});
|
|
167
|
+
items.push(axisData);
|
|
168
|
+
}
|
|
169
|
+
return items;
|
|
170
|
+
}, [boundsHeight, boundsOffsetLeft, boundsWidth, width, xAxis, xScale]);
|
|
171
|
+
const xAxisDataItems = useAsyncState([], setXAxisDataItems);
|
|
139
172
|
React.useEffect(() => {
|
|
140
173
|
if (!initialized && xScale) {
|
|
141
|
-
|
|
142
|
-
if (isBandScale(xScale)) {
|
|
174
|
+
if (!preparedRangeSlider.enabled || isBandScale(xScale)) {
|
|
143
175
|
setInitialized(true);
|
|
144
176
|
return;
|
|
145
177
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const durationMs = duration(defaultRange.size).asMilliseconds();
|
|
154
|
-
const minDefaultRangeMs = maxDomainMs - durationMs;
|
|
155
|
-
if (minDefaultRangeMs < maxDomainMs) {
|
|
156
|
-
minRangeMs = minDefaultRangeMs;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (_a) { }
|
|
161
|
-
updateRangeSliderState({ min: minRangeMs, max: maxDomainMs });
|
|
162
|
-
setInitialized(true);
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
const [minDomain, maxDomain] = xScale.domain();
|
|
166
|
-
let minRange = minDomain;
|
|
167
|
-
if (typeof (defaultRange === null || defaultRange === void 0 ? void 0 : defaultRange.size) === 'number') {
|
|
168
|
-
const minDefaultRange = maxDomain - defaultRange.size;
|
|
169
|
-
if (minDefaultRange < maxDomain) {
|
|
170
|
-
minRange = minDefaultRange;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
updateRangeSliderState({ min: minRange, max: maxDomain });
|
|
174
|
-
setInitialized(true);
|
|
175
|
-
}
|
|
178
|
+
const defaultRange = preparedRangeSlider.defaultRange;
|
|
179
|
+
const initialRangeSliderState = getInitialRangeSliderState({
|
|
180
|
+
defaultRange,
|
|
181
|
+
xScale,
|
|
182
|
+
});
|
|
183
|
+
updateRangeSliderState(initialRangeSliderState);
|
|
184
|
+
setInitialized(true);
|
|
176
185
|
}
|
|
177
186
|
}, [
|
|
178
187
|
initialized,
|
|
179
188
|
preparedRangeSlider.defaultRange,
|
|
180
|
-
|
|
189
|
+
preparedRangeSlider.enabled,
|
|
181
190
|
setInitialized,
|
|
182
191
|
updateRangeSliderState,
|
|
183
192
|
xScale,
|
|
@@ -186,13 +195,12 @@ export const ChartInner = (props) => {
|
|
|
186
195
|
React.createElement("defs", null,
|
|
187
196
|
React.createElement("clipPath", { id: clipPathId },
|
|
188
197
|
React.createElement("rect", { x: 0, y: 0, width: boundsWidth, height: boundsHeight }))),
|
|
189
|
-
|
|
198
|
+
preparedTitle && React.createElement(Title, Object.assign({}, preparedTitle, { chartWidth: width })),
|
|
190
199
|
React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit.plots.map((plot, index) => {
|
|
191
200
|
return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
|
|
192
201
|
})),
|
|
193
|
-
React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})`, ref: plotRef },
|
|
194
|
-
xScale &&
|
|
195
|
-
React.createElement(AxisX, { axis: xAxis, boundsOffsetLeft: boundsOffsetLeft, boundsOffsetTop: boundsOffsetTop, height: boundsHeight, htmlLayout: htmlLayout, leftmostLimit: svgXPos, plotAfterRef: plotAfterRef, plotBeforeRef: plotBeforeRef, scale: xScale, split: preparedSplit, width: boundsWidth }))),
|
|
202
|
+
React.createElement("g", { className: b('content'), width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})`, ref: plotRef },
|
|
203
|
+
xScale && xAxisDataItems.length && (React.createElement(AxisX, { htmlLayout: htmlLayout, plotAfterRef: plotAfterRef, plotBeforeRef: plotBeforeRef, preparedAxisData: xAxisDataItems[0] })),
|
|
196
204
|
Boolean(yAxisDataItems.length) && (React.createElement(React.Fragment, null, yAxisDataItems.map((axisData, index) => {
|
|
197
205
|
if (!axisData) {
|
|
198
206
|
return null;
|
|
@@ -202,7 +210,7 @@ export const ChartInner = (props) => {
|
|
|
202
210
|
React.createElement("g", { ref: plotBeforeRef }),
|
|
203
211
|
shapes,
|
|
204
212
|
React.createElement("g", { ref: plotAfterRef })),
|
|
205
|
-
((
|
|
213
|
+
((_f = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _f === void 0 ? void 0 : _f.enabled) && (React.createElement(RangeSlider, { boundsOffsetLeft: debouncedOffsetLeft, boundsWidth: debouncedBoundsWidth, height: height, htmlLayout: htmlLayout, onUpdate: updateRangeSliderState, preparedChart: preparedChart, preparedLegend: preparedLegend, preparedSeries: debouncedAllPreparedSeries, preparedSeriesOptions: preparedSeriesOptions, preparedRangeSlider: xAxis.rangeSlider, rangeSliderState: rangeSliderState, ref: rangeSliderRef, width: width, xAxis: data.xAxis, yAxis: data.yAxis })),
|
|
206
214
|
(preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && legendConfig && (React.createElement(Legend, { chartSeries: preparedSeries, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick, onUpdate: unpinTooltip, htmlLayout: htmlLayout }))));
|
|
207
215
|
return (React.createElement("div", { className: b() },
|
|
208
216
|
React.createElement("svg", { ref: svgRef, width: width, height: height,
|
|
@@ -212,10 +220,14 @@ export const ChartInner = (props) => {
|
|
|
212
220
|
React.createElement("div", { className: b('html-layer'), ref: setHtmlLayout, style: {
|
|
213
221
|
'--g-html-layout-transform': `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
214
222
|
} }),
|
|
215
|
-
Object.keys(zoomState).length > 0 &&
|
|
223
|
+
Object.keys(zoomState).length > 0 && preparedChart.zoom && (React.createElement(Button, { className: b('reset-zoom-button'), onClick: () => {
|
|
224
|
+
var _a;
|
|
225
|
+
updateZoomState({});
|
|
226
|
+
(_a = rangeSliderRef.current) === null || _a === void 0 ? void 0 : _a.resetState();
|
|
227
|
+
}, ref: resetZoomButtonRef, style: getResetZoomButtonStyle(Object.assign({ boundsHeight,
|
|
216
228
|
boundsOffsetLeft,
|
|
217
229
|
boundsOffsetTop,
|
|
218
|
-
boundsWidth, node: resetZoomButtonRef.current, titleHeight:
|
|
230
|
+
boundsWidth, node: resetZoomButtonRef.current, titleHeight: preparedTitle === null || preparedTitle === void 0 ? void 0 : preparedTitle.height }, preparedChart.zoom.resetButton)) },
|
|
219
231
|
React.createElement(ButtonIcon, null,
|
|
220
232
|
React.createElement(ArrowRotateLeft, null)))),
|
|
221
233
|
React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: preparedTooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0], onOutsideClick: unpinTooltip, tooltipPinned: tooltipPinned })));
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
|
-
import type { PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
|
|
3
|
+
import type { PreparedChart, PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
|
|
4
4
|
import type { ChartInnerProps } from './types';
|
|
5
5
|
type Props = ChartInnerProps & {
|
|
6
6
|
clipPathId: string;
|
|
7
7
|
dispatcher: Dispatch<object>;
|
|
8
8
|
htmlLayout: HTMLElement | null;
|
|
9
9
|
plotNode: SVGGElement | null;
|
|
10
|
+
preparedChart: PreparedChart;
|
|
10
11
|
svgContainer: SVGGElement | null;
|
|
11
12
|
updateZoomState: (nextZoomState: Partial<ZoomState>) => void;
|
|
12
13
|
zoomState: Partial<ZoomState>;
|
|
14
|
+
rangeSliderDomain?: [number, number];
|
|
13
15
|
rangeSliderState?: RangeSliderState;
|
|
14
16
|
};
|
|
15
17
|
export declare function useChartInnerProps(props: Props): {
|
|
@@ -34,25 +36,20 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
34
36
|
maxWidth: number;
|
|
35
37
|
} | undefined;
|
|
36
38
|
legendItems: never[] | import("../../hooks").LegendItem[][];
|
|
37
|
-
preparedChart: import("../../hooks").PreparedChart;
|
|
38
39
|
preparedLegend: PreparedLegend | null;
|
|
39
40
|
preparedSeries: import("../../hooks").PreparedSeries[];
|
|
40
41
|
preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
|
|
41
42
|
preparedSplit: import("../../hooks").PreparedSplit;
|
|
42
|
-
preparedZoom: import("../../hooks").PreparedZoom | null;
|
|
43
43
|
prevHeight: number | undefined;
|
|
44
44
|
prevWidth: number | undefined;
|
|
45
45
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
46
46
|
shapesData: import("../../hooks").ShapeData[];
|
|
47
47
|
svgXPos: number | undefined;
|
|
48
|
-
title: (import("../..").ChartTitle & {
|
|
49
|
-
height: number;
|
|
50
|
-
}) | undefined;
|
|
51
48
|
xAxis: import("../../hooks").PreparedXAxis | null;
|
|
52
49
|
xScale: import("../../hooks").ChartScale | undefined;
|
|
53
50
|
yAxis: (Omit<import("../..").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
|
|
54
51
|
type: import("../..").ChartAxisType;
|
|
55
|
-
labels: Omit<import("../..").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../..").ChartAxisLabels, "margin" | "html" | "enabled" | "
|
|
52
|
+
labels: Omit<import("../..").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../..").ChartAxisLabels, "margin" | "html" | "enabled" | "rotation" | "padding">> & {
|
|
56
53
|
style: import("../..").BaseTextStyle;
|
|
57
54
|
rotation: number;
|
|
58
55
|
height: number;
|
|
@@ -68,6 +65,9 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
68
65
|
style: import("../..").BaseTextStyle;
|
|
69
66
|
align: import("../..").ChartAxisTitleAlignment;
|
|
70
67
|
maxRowCount: number;
|
|
68
|
+
rotation: number;
|
|
69
|
+
maxWidth: number;
|
|
70
|
+
html: boolean;
|
|
71
71
|
};
|
|
72
72
|
min?: number;
|
|
73
73
|
grid: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { SERIES_TYPE } from '../../constants';
|
|
3
|
-
import { useAxis, useAxisScales, useChartDimensions,
|
|
2
|
+
import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
|
|
3
|
+
import { useAxis, useAxisScales, useChartDimensions, useNormalizedOriginalData, usePrevious, useSeries, useShapes, useSplit, useZoom, } from '../../hooks';
|
|
4
4
|
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
5
5
|
import { getLegendComponents } from '../../hooks/useSeries/prepare-legend';
|
|
6
6
|
import { getPreparedOptions } from '../../hooks/useSeries/prepare-options';
|
|
@@ -35,21 +35,18 @@ function getBoundsOffsetLeft(args) {
|
|
|
35
35
|
}
|
|
36
36
|
export function useChartInnerProps(props) {
|
|
37
37
|
var _a;
|
|
38
|
-
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
|
|
38
|
+
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderDomain, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
|
|
39
39
|
const prevWidth = usePrevious(width);
|
|
40
40
|
const prevHeight = usePrevious(height);
|
|
41
|
+
const colors = React.useMemo(() => {
|
|
42
|
+
var _a;
|
|
43
|
+
return (_a = data.colors) !== null && _a !== void 0 ? _a : DEFAULT_PALETTE;
|
|
44
|
+
}, [data.colors]);
|
|
41
45
|
const { normalizedSeriesData, normalizedXAxis, normalizedYAxis } = useNormalizedOriginalData({
|
|
42
46
|
seriesData: data.series.data,
|
|
43
47
|
xAxis: data.xAxis,
|
|
44
48
|
yAxis: data.yAxis,
|
|
45
49
|
});
|
|
46
|
-
const { chart, colors, title } = useChartOptions({
|
|
47
|
-
chart: data.chart,
|
|
48
|
-
colors: data.colors,
|
|
49
|
-
seriesData: normalizedSeriesData,
|
|
50
|
-
title: data.title,
|
|
51
|
-
xAxis: data.xAxis,
|
|
52
|
-
});
|
|
53
50
|
const preparedSeriesOptions = React.useMemo(() => {
|
|
54
51
|
return getPreparedOptions(data.series.options);
|
|
55
52
|
}, [data.series.options]);
|
|
@@ -75,14 +72,14 @@ export function useChartInnerProps(props) {
|
|
|
75
72
|
return getLegendComponents({
|
|
76
73
|
chartWidth: width,
|
|
77
74
|
chartHeight: height,
|
|
78
|
-
chartMargin:
|
|
75
|
+
chartMargin: preparedChart.margin,
|
|
79
76
|
series: preparedSeries,
|
|
80
77
|
preparedLegend,
|
|
81
78
|
});
|
|
82
|
-
}, [width, height,
|
|
79
|
+
}, [width, height, preparedChart.margin, preparedSeries, preparedLegend]);
|
|
83
80
|
const { xAxis, yAxis } = useAxis({
|
|
84
81
|
height,
|
|
85
|
-
preparedChart
|
|
82
|
+
preparedChart,
|
|
86
83
|
preparedLegend,
|
|
87
84
|
preparedSeries,
|
|
88
85
|
preparedSeriesOptions,
|
|
@@ -92,7 +89,7 @@ export function useChartInnerProps(props) {
|
|
|
92
89
|
});
|
|
93
90
|
const { boundsWidth, boundsHeight } = useChartDimensions({
|
|
94
91
|
height,
|
|
95
|
-
margin:
|
|
92
|
+
margin: preparedChart.margin,
|
|
96
93
|
preparedLegend,
|
|
97
94
|
preparedSeries: preparedSeries,
|
|
98
95
|
preparedYAxis: yAxis,
|
|
@@ -147,19 +144,20 @@ export function useChartInnerProps(props) {
|
|
|
147
144
|
plotContainerHeight: boundsHeight,
|
|
148
145
|
plotContainerWidth: boundsWidth,
|
|
149
146
|
preparedSplit,
|
|
150
|
-
preparedZoom:
|
|
147
|
+
preparedZoom: preparedChart.zoom,
|
|
148
|
+
rangeSliderDomain,
|
|
151
149
|
xAxis,
|
|
152
150
|
xScale,
|
|
153
151
|
yAxis,
|
|
154
152
|
yScale,
|
|
155
153
|
});
|
|
156
154
|
const boundsOffsetTop = getBoundsOffsetTop({
|
|
157
|
-
chartMarginTop:
|
|
155
|
+
chartMarginTop: preparedChart.margin.top,
|
|
158
156
|
preparedLegend,
|
|
159
157
|
});
|
|
160
158
|
// We need to calculate the width of each left axis because the first axis can be hidden
|
|
161
159
|
const boundsOffsetLeft = getBoundsOffsetLeft({
|
|
162
|
-
chartMarginLeft:
|
|
160
|
+
chartMarginLeft: preparedChart.margin.left,
|
|
163
161
|
preparedLegend,
|
|
164
162
|
yAxis,
|
|
165
163
|
getYAxisWidth,
|
|
@@ -175,18 +173,15 @@ export function useChartInnerProps(props) {
|
|
|
175
173
|
isOutsideBounds,
|
|
176
174
|
legendConfig,
|
|
177
175
|
legendItems,
|
|
178
|
-
preparedChart: chart,
|
|
179
176
|
preparedLegend,
|
|
180
177
|
preparedSeries,
|
|
181
178
|
preparedSeriesOptions,
|
|
182
179
|
preparedSplit,
|
|
183
|
-
preparedZoom: chart.zoom,
|
|
184
180
|
prevHeight,
|
|
185
181
|
prevWidth,
|
|
186
182
|
shapes,
|
|
187
183
|
shapesData,
|
|
188
184
|
svgXPos: x,
|
|
189
|
-
title,
|
|
190
185
|
xAxis,
|
|
191
186
|
xScale,
|
|
192
187
|
yAxis,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
|
-
import type { PreparedRangeSlider, PreparedTooltip, RangeSliderState, ZoomState } from '../../hooks';
|
|
3
|
+
import type { PreparedChart, PreparedRangeSlider, PreparedTooltip, RangeSliderState, ZoomState } from '../../hooks';
|
|
4
4
|
type Props = {
|
|
5
5
|
dispatcher: Dispatch<object>;
|
|
6
|
+
preparedChart: PreparedChart;
|
|
6
7
|
preparedRangeSlider: PreparedRangeSlider;
|
|
7
8
|
tooltip?: PreparedTooltip;
|
|
8
9
|
};
|
|
@@ -13,7 +14,7 @@ export declare function useChartInnerState(props: Props): {
|
|
|
13
14
|
tooltipPinned: boolean;
|
|
14
15
|
togglePinTooltip: ((value: boolean, event: React.MouseEvent) => void) | undefined;
|
|
15
16
|
unpinTooltip: (() => void) | undefined;
|
|
16
|
-
updateRangeSliderState: (nextRangeSliderState?: RangeSliderState) => void;
|
|
17
|
+
updateRangeSliderState: (nextRangeSliderState?: RangeSliderState, syncZoom?: boolean) => void;
|
|
17
18
|
updateZoomState: (nextZoomState: Partial<ZoomState>) => void;
|
|
18
19
|
zoomState: Partial<ZoomState>;
|
|
19
20
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import isEqual from 'lodash/isEqual';
|
|
3
|
+
import { ZOOM_TYPE } from '../../constants';
|
|
3
4
|
import { EventType, isMacintosh } from '../../utils';
|
|
5
|
+
const RANGE_SLIDER_SYNC_ZOOM_TYPES = [ZOOM_TYPE.X, ZOOM_TYPE.XY];
|
|
4
6
|
export function useChartInnerState(props) {
|
|
5
7
|
var _a, _b;
|
|
6
|
-
const { dispatcher, preparedRangeSlider, tooltip } = props;
|
|
8
|
+
const { dispatcher, preparedChart, preparedRangeSlider, tooltip } = props;
|
|
7
9
|
const [tooltipPinned, setTooltipPinned] = React.useState(false);
|
|
8
10
|
const [zoomState, setZoomState] = React.useState({});
|
|
9
11
|
const [rangeSliderState, setRangeSliderState] = React.useState();
|
|
@@ -11,6 +13,7 @@ export function useChartInnerState(props) {
|
|
|
11
13
|
const tooltipEnabled = tooltip === null || tooltip === void 0 ? void 0 : tooltip.enabled;
|
|
12
14
|
const tooltipPinEnabled = (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.pin) === null || _a === void 0 ? void 0 : _a.enabled;
|
|
13
15
|
const modifierKey = (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.pin) === null || _b === void 0 ? void 0 : _b.modifierKey;
|
|
16
|
+
const rangeSliderEnabled = preparedRangeSlider.enabled;
|
|
14
17
|
const togglePinTooltip = React.useCallback((value, event) => {
|
|
15
18
|
let resultValue = value;
|
|
16
19
|
if (value && modifierKey) {
|
|
@@ -33,9 +36,16 @@ export function useChartInnerState(props) {
|
|
|
33
36
|
const updateZoomState = React.useCallback((nextZoomState) => {
|
|
34
37
|
if (!isEqual(zoomState, nextZoomState)) {
|
|
35
38
|
setZoomState(nextZoomState);
|
|
39
|
+
if (rangeSliderEnabled && (nextZoomState === null || nextZoomState === void 0 ? void 0 : nextZoomState.x)) {
|
|
40
|
+
const [xMin, xMax] = nextZoomState.x;
|
|
41
|
+
setRangeSliderState({
|
|
42
|
+
max: xMax,
|
|
43
|
+
min: xMin,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
|
-
}, [zoomState]);
|
|
38
|
-
const updateRangeSliderState = React.useCallback((nextRangeSliderState) => {
|
|
47
|
+
}, [rangeSliderEnabled, zoomState]);
|
|
48
|
+
const updateRangeSliderState = React.useCallback((nextRangeSliderState, syncZoom = true) => {
|
|
39
49
|
if (!isEqual(rangeSliderState, nextRangeSliderState)) {
|
|
40
50
|
setRangeSliderState(nextRangeSliderState
|
|
41
51
|
? {
|
|
@@ -43,8 +53,17 @@ export function useChartInnerState(props) {
|
|
|
43
53
|
min: nextRangeSliderState.min,
|
|
44
54
|
}
|
|
45
55
|
: undefined);
|
|
56
|
+
if (syncZoom &&
|
|
57
|
+
nextRangeSliderState &&
|
|
58
|
+
preparedChart.zoom &&
|
|
59
|
+
Object.keys(zoomState || {}).length > 0 &&
|
|
60
|
+
RANGE_SLIDER_SYNC_ZOOM_TYPES.includes(preparedChart.zoom.type)) {
|
|
61
|
+
setZoomState({
|
|
62
|
+
x: [nextRangeSliderState.min, nextRangeSliderState.max],
|
|
63
|
+
});
|
|
64
|
+
}
|
|
46
65
|
}
|
|
47
|
-
}, [rangeSliderState]);
|
|
66
|
+
}, [preparedChart.zoom, rangeSliderState, zoomState]);
|
|
48
67
|
return {
|
|
49
68
|
initialized,
|
|
50
69
|
rangeSliderState,
|