@gravity-ui/charts 1.24.0 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/ChartInner/index.js +2 -1
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +1 -2
- package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -4
- package/dist/cjs/hooks/useAxisScales/index.js +74 -27
- package/dist/cjs/hooks/useAxisScales/utils.d.ts +19 -0
- package/dist/cjs/hooks/useAxisScales/utils.js +34 -0
- package/dist/cjs/hooks/useRangeSlider/index.js +2 -1
- package/dist/cjs/hooks/useRangeSlider/types.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +158 -157
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +87 -72
- package/dist/cjs/hooks/useShapes/index.js +2 -0
- package/dist/cjs/hooks/useShapes/styles.css +5 -13
- package/dist/cjs/utils/chart/index.js +1 -1
- package/dist/esm/components/ChartInner/index.js +2 -1
- package/dist/esm/components/ChartInner/useChartInnerProps.js +1 -2
- package/dist/esm/hooks/useAxisScales/index.d.ts +4 -4
- package/dist/esm/hooks/useAxisScales/index.js +74 -27
- package/dist/esm/hooks/useAxisScales/utils.d.ts +19 -0
- package/dist/esm/hooks/useAxisScales/utils.js +34 -0
- package/dist/esm/hooks/useRangeSlider/index.js +2 -1
- package/dist/esm/hooks/useRangeSlider/types.d.ts +2 -0
- package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +2 -0
- package/dist/esm/hooks/useShapes/area/prepare-data.js +158 -157
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.d.ts +2 -0
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +87 -72
- package/dist/esm/hooks/useShapes/index.js +2 -0
- package/dist/esm/hooks/useShapes/styles.css +5 -13
- package/dist/esm/utils/chart/index.js +1 -1
- package/package.json +1 -1
|
@@ -177,6 +177,7 @@ export const ChartInner = (props) => {
|
|
|
177
177
|
}, [
|
|
178
178
|
initialized,
|
|
179
179
|
preparedRangeSlider.defaultRange,
|
|
180
|
+
preparedSeries,
|
|
180
181
|
setInitialized,
|
|
181
182
|
updateRangeSliderState,
|
|
182
183
|
xScale,
|
|
@@ -201,7 +202,7 @@ export const ChartInner = (props) => {
|
|
|
201
202
|
React.createElement("g", { ref: plotBeforeRef }),
|
|
202
203
|
shapes,
|
|
203
204
|
React.createElement("g", { ref: plotAfterRef })),
|
|
204
|
-
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.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, width: width, xAxis: data.xAxis, yAxis: data.yAxis })),
|
|
205
|
+
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.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, width: width, xAxis: data.xAxis, yAxis: data.yAxis, zoomState: zoomState })),
|
|
205
206
|
(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 }))));
|
|
206
207
|
return (React.createElement("div", { className: b() },
|
|
207
208
|
React.createElement("svg", { ref: svgRef, width: width, height: height,
|
|
@@ -79,14 +79,13 @@ export function useChartInnerProps(props) {
|
|
|
79
79
|
const { xScale, yScale } = useAxisScales({
|
|
80
80
|
boundsWidth,
|
|
81
81
|
boundsHeight,
|
|
82
|
-
hasZoomX: Boolean(zoomState.x),
|
|
83
|
-
hasZoomY: Boolean(zoomState.y),
|
|
84
82
|
rangeSliderState,
|
|
85
83
|
series: preparedSeries,
|
|
86
84
|
seriesOptions: preparedSeriesOptions,
|
|
87
85
|
split: preparedSplit,
|
|
88
86
|
xAxis,
|
|
89
87
|
yAxis,
|
|
88
|
+
zoomState,
|
|
90
89
|
});
|
|
91
90
|
const isOutsideBounds = React.useCallback((x, y) => {
|
|
92
91
|
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ScaleBand, ScaleLinear, ScaleTime } from 'd3';
|
|
2
|
-
import type { PreparedAxis, PreparedSeries, PreparedSeriesOptions, PreparedSplit, RangeSliderState } from '../../hooks';
|
|
2
|
+
import type { PreparedAxis, PreparedSeries, PreparedSeriesOptions, PreparedSplit, RangeSliderState, ZoomState } from '../../hooks';
|
|
3
3
|
import type { ChartAxis, ChartSeries } from '../../types';
|
|
4
4
|
export type ChartScale = ScaleLinear<number, number> | ScaleBand<string> | ScaleTime<number, number>;
|
|
5
5
|
type Args = {
|
|
@@ -10,9 +10,8 @@ type Args = {
|
|
|
10
10
|
xAxis: PreparedAxis | null;
|
|
11
11
|
yAxis: PreparedAxis[];
|
|
12
12
|
split: PreparedSplit;
|
|
13
|
-
hasZoomX?: boolean;
|
|
14
|
-
hasZoomY?: boolean;
|
|
15
13
|
rangeSliderState?: RangeSliderState;
|
|
14
|
+
zoomState?: Partial<ZoomState>;
|
|
16
15
|
};
|
|
17
16
|
type ReturnValue = {
|
|
18
17
|
xScale?: ChartScale;
|
|
@@ -22,14 +21,15 @@ export declare function createYScale(args: {
|
|
|
22
21
|
axis: PreparedAxis;
|
|
23
22
|
boundsHeight: number;
|
|
24
23
|
series: (PreparedSeries | ChartSeries)[];
|
|
24
|
+
zoomStateY?: [number, number];
|
|
25
25
|
}): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never> | undefined;
|
|
26
26
|
export declare function createXScale(args: {
|
|
27
27
|
axis: PreparedAxis | ChartAxis;
|
|
28
28
|
boundsWidth: number;
|
|
29
29
|
series: (PreparedSeries | ChartSeries)[];
|
|
30
30
|
seriesOptions: PreparedSeriesOptions;
|
|
31
|
-
hasZoomX?: boolean;
|
|
32
31
|
rangeSliderState?: RangeSliderState;
|
|
32
|
+
zoomStateX?: [number, number];
|
|
33
33
|
}): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never> | undefined;
|
|
34
34
|
/**
|
|
35
35
|
* Uses to create scales for axis related series
|
|
@@ -5,6 +5,7 @@ import { DEFAULT_AXIS_TYPE, SERIES_TYPE } from '../../constants';
|
|
|
5
5
|
import { CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, getAxisCategories, getAxisHeight, getDataCategoryValue, getDefaultMaxXAxisValue, getDefaultMinXAxisValue, getDomainDataXBySeries, getDomainDataYBySeries, getOnlyVisibleSeries, isAxisRelatedSeries, isSeriesWithCategoryValues, } from '../../utils';
|
|
6
6
|
import { getBarXLayoutForNumericScale, groupBarXDataByXValue } from '../utils/bar-x';
|
|
7
7
|
import { getBandSize } from '../utils/get-band-size';
|
|
8
|
+
import { checkIsPointDomain, getMinMaxPropsOrState, hasOnlyMarkerSeries } from './utils';
|
|
8
9
|
const X_AXIS_ZOOM_PADDING = 0.02;
|
|
9
10
|
function validateArrayData(data) {
|
|
10
11
|
let hasNumberAndNullValues;
|
|
@@ -65,9 +66,12 @@ function isSeriesWithYAxisOffset(series) {
|
|
|
65
66
|
}
|
|
66
67
|
// eslint-disable-next-line complexity
|
|
67
68
|
export function createYScale(args) {
|
|
68
|
-
const { axis, boundsHeight, series } = args;
|
|
69
|
-
const
|
|
70
|
-
|
|
69
|
+
const { axis, boundsHeight, series, zoomStateY } = args;
|
|
70
|
+
const [yMinPropsOrState, yMaxPropsOrState] = getMinMaxPropsOrState({
|
|
71
|
+
axis,
|
|
72
|
+
maxValues: [zoomStateY === null || zoomStateY === void 0 ? void 0 : zoomStateY[1]],
|
|
73
|
+
minValues: [zoomStateY === null || zoomStateY === void 0 ? void 0 : zoomStateY[0]],
|
|
74
|
+
});
|
|
71
75
|
const yCategories = get(axis, 'categories');
|
|
72
76
|
const yTimestamps = get(axis, 'timestamps');
|
|
73
77
|
const range = getYScaleRange({ axis, boundsHeight });
|
|
@@ -84,10 +88,15 @@ export function createYScale(args) {
|
|
|
84
88
|
}
|
|
85
89
|
if (hasNumberAndNullValues) {
|
|
86
90
|
const [yMinDomain, yMaxDomain] = extent(domain);
|
|
87
|
-
const
|
|
91
|
+
const isPointDomain = hasOnlyMarkerSeries(series)
|
|
92
|
+
? checkIsPointDomain([yMinDomain, yMaxDomain])
|
|
93
|
+
: false;
|
|
94
|
+
const yMin = typeof yMinPropsOrState === 'number' && !isPointDomain
|
|
95
|
+
? yMinPropsOrState
|
|
96
|
+
: yMinDomain;
|
|
88
97
|
let yMax;
|
|
89
|
-
if (typeof
|
|
90
|
-
yMax =
|
|
98
|
+
if (typeof yMaxPropsOrState === 'number' && !isPointDomain) {
|
|
99
|
+
yMax = yMaxPropsOrState;
|
|
91
100
|
}
|
|
92
101
|
else {
|
|
93
102
|
const hasSeriesWithVolumeOnYAxis = series.some((s) => CHART_SERIES_WITH_VOLUME_ON_Y_AXIS.includes(s.type));
|
|
@@ -128,8 +137,19 @@ export function createYScale(args) {
|
|
|
128
137
|
case 'datetime': {
|
|
129
138
|
if (yTimestamps) {
|
|
130
139
|
const [yMinTimestamp, yMaxTimestamp] = extent(yTimestamps);
|
|
131
|
-
const
|
|
132
|
-
|
|
140
|
+
const isPointDomain = hasOnlyMarkerSeries(series)
|
|
141
|
+
? checkIsPointDomain([yMinTimestamp, yMaxTimestamp])
|
|
142
|
+
: false;
|
|
143
|
+
const yMin = typeof yMinPropsOrState === 'number' &&
|
|
144
|
+
!isPointDomain &&
|
|
145
|
+
yMinPropsOrState > yMinTimestamp
|
|
146
|
+
? yMinPropsOrState
|
|
147
|
+
: yMinTimestamp;
|
|
148
|
+
const yMax = typeof yMaxPropsOrState === 'number' &&
|
|
149
|
+
!isPointDomain &&
|
|
150
|
+
yMaxPropsOrState < yMaxTimestamp
|
|
151
|
+
? yMaxPropsOrState
|
|
152
|
+
: yMaxTimestamp;
|
|
133
153
|
return scaleUtc().domain([yMin, yMax]).range(range).nice();
|
|
134
154
|
}
|
|
135
155
|
else {
|
|
@@ -140,8 +160,19 @@ export function createYScale(args) {
|
|
|
140
160
|
}
|
|
141
161
|
if (hasNumberAndNullValues) {
|
|
142
162
|
const [yMinTimestamp, yMaxTimestamp] = extent(domain);
|
|
143
|
-
const
|
|
144
|
-
|
|
163
|
+
const isPointDomain = hasOnlyMarkerSeries(series)
|
|
164
|
+
? checkIsPointDomain([yMinTimestamp, yMaxTimestamp])
|
|
165
|
+
: false;
|
|
166
|
+
const yMin = typeof yMinPropsOrState === 'number' &&
|
|
167
|
+
!isPointDomain &&
|
|
168
|
+
yMinPropsOrState > yMinTimestamp
|
|
169
|
+
? yMinPropsOrState
|
|
170
|
+
: yMinTimestamp;
|
|
171
|
+
const yMax = typeof yMaxPropsOrState === 'number' &&
|
|
172
|
+
!isPointDomain &&
|
|
173
|
+
yMaxPropsOrState < yMaxTimestamp
|
|
174
|
+
? yMaxPropsOrState
|
|
175
|
+
: yMaxTimestamp;
|
|
145
176
|
const scale = scaleUtc().domain([yMin, yMax]).range(range);
|
|
146
177
|
let offsetMin = 0;
|
|
147
178
|
let offsetMax = boundsHeight * axis.maxPadding;
|
|
@@ -208,11 +239,14 @@ function getXScaleRange({ boundsWidth, series, seriesOptions, hasZoomX, axis, ma
|
|
|
208
239
|
}
|
|
209
240
|
// eslint-disable-next-line complexity
|
|
210
241
|
export function createXScale(args) {
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
242
|
+
const { axis, boundsWidth, series, seriesOptions, rangeSliderState, zoomStateX } = args;
|
|
243
|
+
const [xMinPropsOrState, xMaxPropsOrState] = getMinMaxPropsOrState({
|
|
244
|
+
axis,
|
|
245
|
+
maxValues: [zoomStateX === null || zoomStateX === void 0 ? void 0 : zoomStateX[1], rangeSliderState === null || rangeSliderState === void 0 ? void 0 : rangeSliderState.max],
|
|
246
|
+
minValues: [zoomStateX === null || zoomStateX === void 0 ? void 0 : zoomStateX[0], rangeSliderState === null || rangeSliderState === void 0 ? void 0 : rangeSliderState.min],
|
|
247
|
+
});
|
|
215
248
|
const xType = get(axis, 'type', DEFAULT_AXIS_TYPE);
|
|
249
|
+
const hasZoomX = Boolean(zoomStateX);
|
|
216
250
|
let xCategories = get(axis, 'categories');
|
|
217
251
|
if (rangeSliderState && xCategories) {
|
|
218
252
|
xCategories = getAxisCategories({
|
|
@@ -251,17 +285,20 @@ export function createXScale(args) {
|
|
|
251
285
|
}
|
|
252
286
|
if (hasNumberAndNullValues) {
|
|
253
287
|
const [xMinDomain, xMaxDomain] = extent(domainData);
|
|
288
|
+
const isPointDomain = hasOnlyMarkerSeries(series)
|
|
289
|
+
? checkIsPointDomain([xMinDomain, xMaxDomain])
|
|
290
|
+
: false;
|
|
254
291
|
let xMin;
|
|
255
292
|
let xMax;
|
|
256
|
-
if (typeof
|
|
257
|
-
xMin =
|
|
293
|
+
if (typeof xMinPropsOrState === 'number' && !isPointDomain) {
|
|
294
|
+
xMin = xMinPropsOrState;
|
|
258
295
|
}
|
|
259
296
|
else {
|
|
260
297
|
const xMinDefault = getDefaultMinXAxisValue(series);
|
|
261
298
|
xMin = xMinDefault !== null && xMinDefault !== void 0 ? xMinDefault : xMinDomain;
|
|
262
299
|
}
|
|
263
|
-
if (typeof
|
|
264
|
-
xMax =
|
|
300
|
+
if (typeof xMaxPropsOrState === 'number' && !isPointDomain) {
|
|
301
|
+
xMax = xMaxPropsOrState;
|
|
265
302
|
}
|
|
266
303
|
else {
|
|
267
304
|
const xMaxDefault = getDefaultMaxXAxisValue(series);
|
|
@@ -320,8 +357,17 @@ export function createXScale(args) {
|
|
|
320
357
|
}
|
|
321
358
|
if (hasNumberAndNullValues) {
|
|
322
359
|
const [xMinTimestamp, xMaxTimestamp] = extent(domainData);
|
|
323
|
-
const
|
|
324
|
-
const
|
|
360
|
+
const isPointDomain = checkIsPointDomain([xMinTimestamp, xMaxTimestamp]);
|
|
361
|
+
const xMin = typeof xMinPropsOrState === 'number' &&
|
|
362
|
+
xMinPropsOrState > xMinTimestamp &&
|
|
363
|
+
!isPointDomain
|
|
364
|
+
? xMinPropsOrState
|
|
365
|
+
: xMinTimestamp;
|
|
366
|
+
const xMax = typeof xMaxPropsOrState === 'number' &&
|
|
367
|
+
xMaxPropsOrState < xMaxTimestamp &&
|
|
368
|
+
!isPointDomain
|
|
369
|
+
? xMaxPropsOrState
|
|
370
|
+
: xMaxTimestamp;
|
|
325
371
|
domain = [xMin, xMax];
|
|
326
372
|
const scale = scaleUtc().domain(domain).range(range);
|
|
327
373
|
let offsetMin = 0;
|
|
@@ -352,7 +398,7 @@ export function createXScale(args) {
|
|
|
352
398
|
throw new Error('Failed to create xScale');
|
|
353
399
|
}
|
|
354
400
|
const createScales = (args) => {
|
|
355
|
-
const { boundsWidth, boundsHeight,
|
|
401
|
+
const { boundsWidth, boundsHeight, rangeSliderState, series, seriesOptions, split, xAxis, yAxis, zoomState, } = args;
|
|
356
402
|
let visibleSeries = getOnlyVisibleSeries(series);
|
|
357
403
|
// Reassign to all series in case of all series unselected,
|
|
358
404
|
// otherwise we will get an empty space without grid
|
|
@@ -365,20 +411,23 @@ const createScales = (args) => {
|
|
|
365
411
|
rangeSliderState,
|
|
366
412
|
series: visibleSeries,
|
|
367
413
|
seriesOptions,
|
|
368
|
-
|
|
414
|
+
zoomStateX: zoomState === null || zoomState === void 0 ? void 0 : zoomState.x,
|
|
369
415
|
})
|
|
370
416
|
: undefined,
|
|
371
417
|
yScale: yAxis.map((axis, index) => {
|
|
418
|
+
var _a;
|
|
372
419
|
const axisSeries = series.filter((s) => {
|
|
373
420
|
const seriesAxisIndex = get(s, 'yAxis', 0);
|
|
374
421
|
return seriesAxisIndex === index;
|
|
375
422
|
});
|
|
376
423
|
const visibleAxisSeries = getOnlyVisibleSeries(axisSeries);
|
|
377
424
|
const axisHeight = getAxisHeight({ boundsHeight, split });
|
|
425
|
+
const zoomStateY = (_a = zoomState === null || zoomState === void 0 ? void 0 : zoomState.y) === null || _a === void 0 ? void 0 : _a[index];
|
|
378
426
|
return createYScale({
|
|
379
427
|
axis,
|
|
380
428
|
boundsHeight: axisHeight,
|
|
381
429
|
series: visibleAxisSeries.length ? visibleAxisSeries : axisSeries,
|
|
430
|
+
zoomStateY,
|
|
382
431
|
});
|
|
383
432
|
}),
|
|
384
433
|
};
|
|
@@ -387,7 +436,7 @@ const createScales = (args) => {
|
|
|
387
436
|
* Uses to create scales for axis related series
|
|
388
437
|
*/
|
|
389
438
|
export const useAxisScales = (args) => {
|
|
390
|
-
const { boundsWidth, boundsHeight,
|
|
439
|
+
const { boundsWidth, boundsHeight, rangeSliderState, series, seriesOptions, split, xAxis, yAxis, zoomState, } = args;
|
|
391
440
|
return React.useMemo(() => {
|
|
392
441
|
let xScale;
|
|
393
442
|
let yScale;
|
|
@@ -396,27 +445,25 @@ export const useAxisScales = (args) => {
|
|
|
396
445
|
({ xScale, yScale } = createScales({
|
|
397
446
|
boundsWidth,
|
|
398
447
|
boundsHeight,
|
|
399
|
-
hasZoomX,
|
|
400
|
-
hasZoomY,
|
|
401
448
|
rangeSliderState,
|
|
402
449
|
series,
|
|
403
450
|
seriesOptions,
|
|
404
451
|
split,
|
|
405
452
|
xAxis,
|
|
406
453
|
yAxis,
|
|
454
|
+
zoomState,
|
|
407
455
|
}));
|
|
408
456
|
}
|
|
409
457
|
return { xScale, yScale };
|
|
410
458
|
}, [
|
|
411
459
|
boundsWidth,
|
|
412
460
|
boundsHeight,
|
|
413
|
-
hasZoomX,
|
|
414
|
-
hasZoomY,
|
|
415
461
|
rangeSliderState,
|
|
416
462
|
series,
|
|
417
463
|
seriesOptions,
|
|
418
464
|
split,
|
|
419
465
|
xAxis,
|
|
420
466
|
yAxis,
|
|
467
|
+
zoomState,
|
|
421
468
|
]);
|
|
422
469
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PreparedAxis, PreparedSeries } from '../../hooks';
|
|
2
|
+
import type { ChartAxis, ChartSeries } from '../../types';
|
|
3
|
+
type OptionalNumber = number | undefined;
|
|
4
|
+
export declare function getMinMaxPropsOrState(args: {
|
|
5
|
+
axis: PreparedAxis | ChartAxis;
|
|
6
|
+
maxValues: OptionalNumber[];
|
|
7
|
+
minValues: OptionalNumber[];
|
|
8
|
+
}): [OptionalNumber, OptionalNumber];
|
|
9
|
+
/**
|
|
10
|
+
* Checks whether a domain represents a single point (when minimum and maximum values are equal).
|
|
11
|
+
*
|
|
12
|
+
* This is necessary for cases where exactly one marker needs to be rendered on an axis.
|
|
13
|
+
* In such cases, it is not allowed to use axis extremums (min/max)
|
|
14
|
+
* that differ from those in the domain, as this can lead to incorrect visualization
|
|
15
|
+
* and scale stretching around a single point.
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkIsPointDomain(domain: [number, number]): boolean;
|
|
18
|
+
export declare function hasOnlyMarkerSeries(series: (PreparedSeries | ChartSeries)[]): boolean;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import { SERIES_TYPE } from '../../constants';
|
|
3
|
+
const MARKER_SERIES_TYPES = [SERIES_TYPE.Area, SERIES_TYPE.Line, SERIES_TYPE.Scatter];
|
|
4
|
+
function getNormilizedMinMax(args) {
|
|
5
|
+
const { maxValues, minValues } = args;
|
|
6
|
+
const filteredMaxValues = maxValues.filter((v) => typeof v === 'number');
|
|
7
|
+
const filteredMinValues = minValues.filter((v) => typeof v === 'number');
|
|
8
|
+
const max = filteredMaxValues.length ? Math.max(...filteredMaxValues) : undefined;
|
|
9
|
+
const min = filteredMinValues.length ? Math.min(...filteredMinValues) : undefined;
|
|
10
|
+
return [min, max];
|
|
11
|
+
}
|
|
12
|
+
export function getMinMaxPropsOrState(args) {
|
|
13
|
+
const { axis, maxValues, minValues } = args;
|
|
14
|
+
const minProps = get(axis, 'min');
|
|
15
|
+
const maxProps = get(axis, 'max');
|
|
16
|
+
const [minState, maxState] = getNormilizedMinMax({ maxValues, minValues });
|
|
17
|
+
const min = minState !== null && minState !== void 0 ? minState : minProps;
|
|
18
|
+
const max = maxState !== null && maxState !== void 0 ? maxState : maxProps;
|
|
19
|
+
return [min, max];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Checks whether a domain represents a single point (when minimum and maximum values are equal).
|
|
23
|
+
*
|
|
24
|
+
* This is necessary for cases where exactly one marker needs to be rendered on an axis.
|
|
25
|
+
* In such cases, it is not allowed to use axis extremums (min/max)
|
|
26
|
+
* that differ from those in the domain, as this can lead to incorrect visualization
|
|
27
|
+
* and scale stretching around a single point.
|
|
28
|
+
*/
|
|
29
|
+
export function checkIsPointDomain(domain) {
|
|
30
|
+
return domain[0] === domain[1];
|
|
31
|
+
}
|
|
32
|
+
export function hasOnlyMarkerSeries(series) {
|
|
33
|
+
return series.every((s) => MARKER_SERIES_TYPES.includes(s.type));
|
|
34
|
+
}
|
|
@@ -17,7 +17,7 @@ const CLIP_PATH_BY_SERIES_TYPE = {
|
|
|
17
17
|
[SERIES_TYPE.Scatter]: true,
|
|
18
18
|
};
|
|
19
19
|
export function useRangeSlider(props) {
|
|
20
|
-
const { boundsWidth, boundsOffsetLeft, clipPathId, height, htmlLayout, onUpdate, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, preparedRangeSlider, rangeSliderState, width, xAxis, yAxis, } = props;
|
|
20
|
+
const { boundsWidth, boundsOffsetLeft, clipPathId, height, htmlLayout, onUpdate, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, preparedRangeSlider, rangeSliderState, width, xAxis, yAxis, zoomState, } = props;
|
|
21
21
|
const filteredPreparedSeries = React.useMemo(() => {
|
|
22
22
|
return preparedSeries.filter((s) => {
|
|
23
23
|
if ('rangeSlider' in s && !s.rangeSlider.visible) {
|
|
@@ -45,6 +45,7 @@ export function useRangeSlider(props) {
|
|
|
45
45
|
split: EMPTY_PREPARED_SPLIT,
|
|
46
46
|
xAxis: preparedXAxis,
|
|
47
47
|
yAxis: preparedYAxis,
|
|
48
|
+
zoomState,
|
|
48
49
|
});
|
|
49
50
|
const { shapes } = useShapes({
|
|
50
51
|
boundsHeight: preparedRangeSlider.height,
|
|
@@ -4,6 +4,7 @@ import type { ChartScale } from '../useAxisScales';
|
|
|
4
4
|
import type { BrushSelection, UseBrushProps } from '../useBrush/types';
|
|
5
5
|
import type { PreparedChart } from '../useChartOptions/types';
|
|
6
6
|
import type { PreparedLegend, PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
7
|
+
import type { ZoomState } from '../useZoom/types';
|
|
7
8
|
export type RangeSliderState = {
|
|
8
9
|
max: number;
|
|
9
10
|
min: number;
|
|
@@ -23,6 +24,7 @@ export interface RangeSliderProps {
|
|
|
23
24
|
rangeSliderState?: RangeSliderState;
|
|
24
25
|
xAxis?: ChartXAxis;
|
|
25
26
|
yAxis?: ChartYAxis[];
|
|
27
|
+
zoomState?: Partial<ZoomState>;
|
|
26
28
|
}
|
|
27
29
|
export interface UseRangeSliderProps extends RangeSliderProps {
|
|
28
30
|
clipPathId: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
2
|
import type { ChartScale } from '../../useAxisScales';
|
|
3
3
|
import type { PreparedAreaSeries } from '../../useSeries/types';
|
|
4
|
+
import type { PreparedSplit } from '../../useSplit/types';
|
|
4
5
|
import type { PreparedAreaData } from './types';
|
|
5
6
|
export declare const prepareAreaData: (args: {
|
|
6
7
|
series: PreparedAreaSeries[];
|
|
@@ -9,5 +10,6 @@ export declare const prepareAreaData: (args: {
|
|
|
9
10
|
yAxis: PreparedYAxis[];
|
|
10
11
|
yScale: (ChartScale | undefined)[];
|
|
11
12
|
boundsHeight: number;
|
|
13
|
+
split: PreparedSplit;
|
|
12
14
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
13
15
|
}) => Promise<PreparedAreaData[]>;
|