@gravity-ui/charts 1.27.1 → 1.27.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.
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { ArrowRotateLeft } from '@gravity-ui/icons';
3
3
  import { Button, ButtonIcon, useUniqId } from '@gravity-ui/uikit';
4
- import { useCrosshair } from '../../hooks';
4
+ import { useCrosshair, usePrevious } from '../../hooks';
5
5
  import { getPreparedRangeSlider } from '../../hooks/useAxis/range-slider';
6
6
  import { getPreparedChart } from '../../hooks/useChartOptions/chart';
7
7
  import { getPreparedTitle } from '../../hooks/useChartOptions/title';
@@ -97,6 +97,7 @@ export const ChartInner = (props) => {
97
97
  });
98
98
  const clickHandler = (_c = (_b = data.chart) === null || _b === void 0 ? void 0 : _b.events) === null || _c === void 0 ? void 0 : _c.click;
99
99
  const pointerMoveHandler = (_e = (_d = data.chart) === null || _d === void 0 ? void 0 : _d.events) === null || _e === void 0 ? void 0 : _e.pointermove;
100
+ const prevRangeSliderDefaultRange = usePrevious(preparedRangeSlider.defaultRange);
100
101
  useCrosshair({
101
102
  split: preparedSplit,
102
103
  plotElement: plotAfterRef.current,
@@ -185,10 +186,22 @@ export const ChartInner = (props) => {
185
186
  updateRangeSliderState(initialRangeSliderState);
186
187
  setInitialized(true);
187
188
  }
189
+ else if (preparedRangeSlider.defaultRange !== prevRangeSliderDefaultRange && xScale) {
190
+ if (!preparedRangeSlider.enabled || isBandScale(xScale)) {
191
+ return;
192
+ }
193
+ const defaultRange = preparedRangeSlider.defaultRange;
194
+ const initialRangeSliderState = getInitialRangeSliderState({
195
+ defaultRange,
196
+ xScale,
197
+ });
198
+ updateRangeSliderState(initialRangeSliderState);
199
+ }
188
200
  }, [
189
201
  initialized,
190
202
  preparedRangeSlider.defaultRange,
191
203
  preparedRangeSlider.enabled,
204
+ prevRangeSliderDefaultRange,
192
205
  setInitialized,
193
206
  updateRangeSliderState,
194
207
  xScale,
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import isEqual from 'lodash/isEqual';
3
+ import { getWidthOccupiedByYAxis } from '../useChartDimensions/utils';
3
4
  import { getPreparedXAxis } from './x-axis';
4
5
  import { getPreparedYAxis } from './y-axis';
5
6
  export function useAxis(props) {
@@ -21,7 +22,7 @@ export function useAxis(props) {
21
22
  seriesData,
22
23
  yAxis,
23
24
  });
24
- const axesWidth = estimatedPreparedYAxis.reduce((acc, a) => acc + a.title.height + a.title.margin + a.labels.margin + a.labels.width, 0);
25
+ const axesWidth = getWidthOccupiedByYAxis({ preparedAxis: estimatedPreparedYAxis });
25
26
  const estimatedBoundsWidth = width - (axesWidth + preparedChart.margin.left + preparedChart.margin.right);
26
27
  const preparedXAxis = await getPreparedXAxis({
27
28
  xAxis,
@@ -37,6 +38,9 @@ export function useAxis(props) {
37
38
  preparedXAxis.title.margin +
38
39
  preparedXAxis.labels.margin +
39
40
  preparedXAxis.labels.height +
41
+ (preparedXAxis.rangeSlider.enabled
42
+ ? preparedXAxis.rangeSlider.height + preparedXAxis.rangeSlider.margin
43
+ : 0) +
40
44
  (preparedLegend ? preparedLegend.height + preparedLegend.margin : 0) +
41
45
  preparedChart.margin.top +
42
46
  preparedChart.margin.bottom);
@@ -17,7 +17,7 @@ async function setLabelSettings({ axis, seriesData, width, axisLabels, }) {
17
17
  const labelLineHeight = (await getTextSize('Tmp')).height;
18
18
  const tickValues = getXAxisTickValues({ axis, scale, labelLineHeight });
19
19
  const tickStep = getMinSpaceBetween(tickValues, (d) => Number(d.value));
20
- if (axis.type === 'datetime' && !axis.labels.dateFormat) {
20
+ if (axis.type === 'datetime' && !(axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.dateFormat)) {
21
21
  axis.labels.dateFormat = getDefaultDateFormat(tickStep);
22
22
  }
23
23
  const labels = tickValues.map((tick) => formatAxisTickLabel({
@@ -60,7 +60,7 @@ function getMaxPaddingBySeries({ series }) {
60
60
  return 0.01;
61
61
  }
62
62
  export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth, }) => {
63
- var _a, _b, _c, _d;
63
+ var _a, _b, _c, _d, _e, _f, _g, _h;
64
64
  const hasAxisRelatedSeries = seriesData.some(isAxisRelatedSeries);
65
65
  if (!hasAxisRelatedSeries) {
66
66
  return Promise.resolve(null);
@@ -77,13 +77,17 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
77
77
  labels: [titleText],
78
78
  style: titleStyle,
79
79
  });
80
+ const isLabelsEnabled = (_b = (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;
80
81
  const labelsStyle = {
81
82
  fontSize: get(xAxis, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE),
82
83
  };
83
- const labelsHtml = get(xAxis, 'labels.html', false);
84
- const labelsLineHeight = labelsHtml
85
- ? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
86
- : getHorizontalSvgTextHeight({ text: 'Tmp', style: labelsStyle });
84
+ const labelsHtml = (_d = (_c = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _c === void 0 ? void 0 : _c.html) !== null && _d !== void 0 ? _d : false;
85
+ let labelsLineHeight = 0;
86
+ if (isLabelsEnabled) {
87
+ labelsLineHeight = labelsHtml
88
+ ? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
89
+ : getHorizontalSvgTextHeight({ text: 'Tmp', style: labelsStyle });
90
+ }
87
91
  const shouldHideGrid = seriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
88
92
  const preparedRangeSlider = getPreparedRangeSlider({ xAxis });
89
93
  const maxPadding = preparedRangeSlider.enabled
@@ -92,8 +96,8 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
92
96
  const preparedXAxis = {
93
97
  type: get(xAxis, 'type', 'linear'),
94
98
  labels: {
95
- enabled: get(xAxis, 'labels.enabled', true),
96
- margin: get(xAxis, 'labels.margin', axisLabelsDefaults.margin),
99
+ enabled: isLabelsEnabled,
100
+ margin: isLabelsEnabled ? get(xAxis, 'labels.margin', axisLabelsDefaults.margin) : 0,
97
101
  padding: get(xAxis, 'labels.padding', axisLabelsDefaults.padding),
98
102
  dateFormat: get(xAxis, 'labels.dateFormat'),
99
103
  numberFormat: get(xAxis, 'labels.numberFormat'),
@@ -102,7 +106,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
102
106
  width: 0,
103
107
  height: 0,
104
108
  lineHeight: labelsLineHeight,
105
- maxWidth: (_b = calculateNumericProperty({ base: width, value: (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _a === void 0 ? void 0 : _a.maxWidth })) !== null && _b !== void 0 ? _b : axisLabelsDefaults.maxWidth,
109
+ maxWidth: (_f = calculateNumericProperty({ base: width, value: (_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _e === void 0 ? void 0 : _e.maxWidth })) !== null && _f !== void 0 ? _f : axisLabelsDefaults.maxWidth,
106
110
  html: labelsHtml,
107
111
  },
108
112
  lineColor: get(xAxis, 'lineColor'),
@@ -127,12 +131,12 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
127
131
  enabled: shouldHideGrid ? false : get(xAxis, 'grid.enabled', true),
128
132
  },
129
133
  ticks: {
130
- pixelInterval: ((_c = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _c === void 0 ? void 0 : _c.interval)
134
+ pixelInterval: ((_g = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _g === void 0 ? void 0 : _g.interval)
131
135
  ? calculateNumericProperty({
132
136
  base: width,
133
137
  value: xAxis.ticks.interval,
134
138
  })
135
- : (_d = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _d === void 0 ? void 0 : _d.pixelInterval,
139
+ : (_h = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _h === void 0 ? void 0 : _h.pixelInterval,
136
140
  },
137
141
  position: 'bottom',
138
142
  plotIndex: 0,
@@ -166,11 +170,13 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
166
170
  order: xAxis === null || xAxis === void 0 ? void 0 : xAxis.order,
167
171
  rangeSlider: preparedRangeSlider,
168
172
  };
169
- await setLabelSettings({
170
- axis: preparedXAxis,
171
- seriesData,
172
- width: boundsWidth,
173
- axisLabels: xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels,
174
- });
173
+ if (isLabelsEnabled) {
174
+ await setLabelSettings({
175
+ axis: preparedXAxis,
176
+ seriesData,
177
+ width: boundsWidth,
178
+ axisLabels: xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels,
179
+ });
180
+ }
175
181
  return preparedXAxis;
176
182
  };
@@ -3,11 +3,11 @@ import { getTicksCount, isBandScale, thinOut } from './common';
3
3
  export function getXAxisTickValues({ scale, axis, labelLineHeight, }) {
4
4
  if ('ticks' in scale && typeof scale.ticks === 'function') {
5
5
  const range = scale.range();
6
- const height = Math.abs(range[0] - range[1]);
7
- if (!height) {
6
+ const axisWidth = Math.abs(range[0] - range[1]);
7
+ if (!axisWidth) {
8
8
  return [];
9
9
  }
10
- const scaleTicksCount = getTicksCount({ axis, range: height });
10
+ const scaleTicksCount = getTicksCount({ axis, range: axisWidth });
11
11
  const scaleTicks = scale.ticks(scaleTicksCount);
12
12
  const originalTickValues = scaleTicks.map((t) => ({
13
13
  x: scale(t),
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { ArrowRotateLeft } from '@gravity-ui/icons';
3
3
  import { Button, ButtonIcon, useUniqId } from '@gravity-ui/uikit';
4
- import { useCrosshair } from '../../hooks';
4
+ import { useCrosshair, usePrevious } from '../../hooks';
5
5
  import { getPreparedRangeSlider } from '../../hooks/useAxis/range-slider';
6
6
  import { getPreparedChart } from '../../hooks/useChartOptions/chart';
7
7
  import { getPreparedTitle } from '../../hooks/useChartOptions/title';
@@ -97,6 +97,7 @@ export const ChartInner = (props) => {
97
97
  });
98
98
  const clickHandler = (_c = (_b = data.chart) === null || _b === void 0 ? void 0 : _b.events) === null || _c === void 0 ? void 0 : _c.click;
99
99
  const pointerMoveHandler = (_e = (_d = data.chart) === null || _d === void 0 ? void 0 : _d.events) === null || _e === void 0 ? void 0 : _e.pointermove;
100
+ const prevRangeSliderDefaultRange = usePrevious(preparedRangeSlider.defaultRange);
100
101
  useCrosshair({
101
102
  split: preparedSplit,
102
103
  plotElement: plotAfterRef.current,
@@ -185,10 +186,22 @@ export const ChartInner = (props) => {
185
186
  updateRangeSliderState(initialRangeSliderState);
186
187
  setInitialized(true);
187
188
  }
189
+ else if (preparedRangeSlider.defaultRange !== prevRangeSliderDefaultRange && xScale) {
190
+ if (!preparedRangeSlider.enabled || isBandScale(xScale)) {
191
+ return;
192
+ }
193
+ const defaultRange = preparedRangeSlider.defaultRange;
194
+ const initialRangeSliderState = getInitialRangeSliderState({
195
+ defaultRange,
196
+ xScale,
197
+ });
198
+ updateRangeSliderState(initialRangeSliderState);
199
+ }
188
200
  }, [
189
201
  initialized,
190
202
  preparedRangeSlider.defaultRange,
191
203
  preparedRangeSlider.enabled,
204
+ prevRangeSliderDefaultRange,
192
205
  setInitialized,
193
206
  updateRangeSliderState,
194
207
  xScale,
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import isEqual from 'lodash/isEqual';
3
+ import { getWidthOccupiedByYAxis } from '../useChartDimensions/utils';
3
4
  import { getPreparedXAxis } from './x-axis';
4
5
  import { getPreparedYAxis } from './y-axis';
5
6
  export function useAxis(props) {
@@ -21,7 +22,7 @@ export function useAxis(props) {
21
22
  seriesData,
22
23
  yAxis,
23
24
  });
24
- const axesWidth = estimatedPreparedYAxis.reduce((acc, a) => acc + a.title.height + a.title.margin + a.labels.margin + a.labels.width, 0);
25
+ const axesWidth = getWidthOccupiedByYAxis({ preparedAxis: estimatedPreparedYAxis });
25
26
  const estimatedBoundsWidth = width - (axesWidth + preparedChart.margin.left + preparedChart.margin.right);
26
27
  const preparedXAxis = await getPreparedXAxis({
27
28
  xAxis,
@@ -37,6 +38,9 @@ export function useAxis(props) {
37
38
  preparedXAxis.title.margin +
38
39
  preparedXAxis.labels.margin +
39
40
  preparedXAxis.labels.height +
41
+ (preparedXAxis.rangeSlider.enabled
42
+ ? preparedXAxis.rangeSlider.height + preparedXAxis.rangeSlider.margin
43
+ : 0) +
40
44
  (preparedLegend ? preparedLegend.height + preparedLegend.margin : 0) +
41
45
  preparedChart.margin.top +
42
46
  preparedChart.margin.bottom);
@@ -17,7 +17,7 @@ async function setLabelSettings({ axis, seriesData, width, axisLabels, }) {
17
17
  const labelLineHeight = (await getTextSize('Tmp')).height;
18
18
  const tickValues = getXAxisTickValues({ axis, scale, labelLineHeight });
19
19
  const tickStep = getMinSpaceBetween(tickValues, (d) => Number(d.value));
20
- if (axis.type === 'datetime' && !axis.labels.dateFormat) {
20
+ if (axis.type === 'datetime' && !(axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.dateFormat)) {
21
21
  axis.labels.dateFormat = getDefaultDateFormat(tickStep);
22
22
  }
23
23
  const labels = tickValues.map((tick) => formatAxisTickLabel({
@@ -60,7 +60,7 @@ function getMaxPaddingBySeries({ series }) {
60
60
  return 0.01;
61
61
  }
62
62
  export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth, }) => {
63
- var _a, _b, _c, _d;
63
+ var _a, _b, _c, _d, _e, _f, _g, _h;
64
64
  const hasAxisRelatedSeries = seriesData.some(isAxisRelatedSeries);
65
65
  if (!hasAxisRelatedSeries) {
66
66
  return Promise.resolve(null);
@@ -77,13 +77,17 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
77
77
  labels: [titleText],
78
78
  style: titleStyle,
79
79
  });
80
+ const isLabelsEnabled = (_b = (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : true;
80
81
  const labelsStyle = {
81
82
  fontSize: get(xAxis, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE),
82
83
  };
83
- const labelsHtml = get(xAxis, 'labels.html', false);
84
- const labelsLineHeight = labelsHtml
85
- ? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
86
- : getHorizontalSvgTextHeight({ text: 'Tmp', style: labelsStyle });
84
+ const labelsHtml = (_d = (_c = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _c === void 0 ? void 0 : _c.html) !== null && _d !== void 0 ? _d : false;
85
+ let labelsLineHeight = 0;
86
+ if (isLabelsEnabled) {
87
+ labelsLineHeight = labelsHtml
88
+ ? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
89
+ : getHorizontalSvgTextHeight({ text: 'Tmp', style: labelsStyle });
90
+ }
87
91
  const shouldHideGrid = seriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
88
92
  const preparedRangeSlider = getPreparedRangeSlider({ xAxis });
89
93
  const maxPadding = preparedRangeSlider.enabled
@@ -92,8 +96,8 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
92
96
  const preparedXAxis = {
93
97
  type: get(xAxis, 'type', 'linear'),
94
98
  labels: {
95
- enabled: get(xAxis, 'labels.enabled', true),
96
- margin: get(xAxis, 'labels.margin', axisLabelsDefaults.margin),
99
+ enabled: isLabelsEnabled,
100
+ margin: isLabelsEnabled ? get(xAxis, 'labels.margin', axisLabelsDefaults.margin) : 0,
97
101
  padding: get(xAxis, 'labels.padding', axisLabelsDefaults.padding),
98
102
  dateFormat: get(xAxis, 'labels.dateFormat'),
99
103
  numberFormat: get(xAxis, 'labels.numberFormat'),
@@ -102,7 +106,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
102
106
  width: 0,
103
107
  height: 0,
104
108
  lineHeight: labelsLineHeight,
105
- maxWidth: (_b = calculateNumericProperty({ base: width, value: (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _a === void 0 ? void 0 : _a.maxWidth })) !== null && _b !== void 0 ? _b : axisLabelsDefaults.maxWidth,
109
+ maxWidth: (_f = calculateNumericProperty({ base: width, value: (_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels) === null || _e === void 0 ? void 0 : _e.maxWidth })) !== null && _f !== void 0 ? _f : axisLabelsDefaults.maxWidth,
106
110
  html: labelsHtml,
107
111
  },
108
112
  lineColor: get(xAxis, 'lineColor'),
@@ -127,12 +131,12 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
127
131
  enabled: shouldHideGrid ? false : get(xAxis, 'grid.enabled', true),
128
132
  },
129
133
  ticks: {
130
- pixelInterval: ((_c = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _c === void 0 ? void 0 : _c.interval)
134
+ pixelInterval: ((_g = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _g === void 0 ? void 0 : _g.interval)
131
135
  ? calculateNumericProperty({
132
136
  base: width,
133
137
  value: xAxis.ticks.interval,
134
138
  })
135
- : (_d = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _d === void 0 ? void 0 : _d.pixelInterval,
139
+ : (_h = xAxis === null || xAxis === void 0 ? void 0 : xAxis.ticks) === null || _h === void 0 ? void 0 : _h.pixelInterval,
136
140
  },
137
141
  position: 'bottom',
138
142
  plotIndex: 0,
@@ -166,11 +170,13 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
166
170
  order: xAxis === null || xAxis === void 0 ? void 0 : xAxis.order,
167
171
  rangeSlider: preparedRangeSlider,
168
172
  };
169
- await setLabelSettings({
170
- axis: preparedXAxis,
171
- seriesData,
172
- width: boundsWidth,
173
- axisLabels: xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels,
174
- });
173
+ if (isLabelsEnabled) {
174
+ await setLabelSettings({
175
+ axis: preparedXAxis,
176
+ seriesData,
177
+ width: boundsWidth,
178
+ axisLabels: xAxis === null || xAxis === void 0 ? void 0 : xAxis.labels,
179
+ });
180
+ }
175
181
  return preparedXAxis;
176
182
  };
@@ -3,11 +3,11 @@ import { getTicksCount, isBandScale, thinOut } from './common';
3
3
  export function getXAxisTickValues({ scale, axis, labelLineHeight, }) {
4
4
  if ('ticks' in scale && typeof scale.ticks === 'function') {
5
5
  const range = scale.range();
6
- const height = Math.abs(range[0] - range[1]);
7
- if (!height) {
6
+ const axisWidth = Math.abs(range[0] - range[1]);
7
+ if (!axisWidth) {
8
8
  return [];
9
9
  }
10
- const scaleTicksCount = getTicksCount({ axis, range: height });
10
+ const scaleTicksCount = getTicksCount({ axis, range: axisWidth });
11
11
  const scaleTicks = scale.ticks(scaleTicksCount);
12
12
  const originalTickValues = scaleTicks.map((t) => ({
13
13
  x: scale(t),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/charts",
3
- "version": "1.27.1",
3
+ "version": "1.27.3",
4
4
  "description": "React component used to render charts",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",