@gravity-ui/charts 1.38.5 → 1.38.7
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/prepare-axis-data.d.ts +1 -1
- package/dist/cjs/components/AxisX/prepare-axis-data.js +10 -9
- package/dist/cjs/components/AxisY/prepare-axis-data.d.ts +1 -1
- package/dist/cjs/components/AxisY/prepare-axis-data.js +2 -2
- package/dist/cjs/components/ChartInner/index.js +8 -3
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +18 -19
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +232 -138
- package/dist/cjs/components/ChartInner/useChartInnerState.js +2 -1
- package/dist/cjs/components/Legend/index.d.ts +1 -1
- package/dist/cjs/components/Legend/index.js +1 -1
- package/dist/cjs/hooks/useAxis/index.d.ts +40 -5
- package/dist/cjs/hooks/useAxis/index.js +55 -41
- package/dist/cjs/hooks/useAxis/types.d.ts +0 -2
- package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -0
- package/dist/cjs/hooks/useAxisScales/index.js +1 -1
- package/dist/cjs/hooks/useChartDimensions/index.d.ts +1 -1
- package/dist/cjs/hooks/useChartDimensions/index.js +14 -29
- package/dist/cjs/hooks/useCrosshair/index.d.ts +1 -1
- package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +29 -34
- package/dist/cjs/hooks/useNormalizedOriginalData/index.js +19 -30
- package/dist/cjs/hooks/useSeries/index.d.ts +10 -14
- package/dist/cjs/hooks/useSeries/index.js +8 -80
- package/dist/cjs/hooks/useShapes/index.d.ts +4 -0
- package/dist/cjs/hooks/useShapes/index.js +194 -189
- package/dist/cjs/hooks/useSplit/index.d.ts +5 -2
- package/dist/cjs/hooks/useSplit/index.js +27 -30
- package/dist/cjs/hooks/useYAxisLabelWidth/index.d.ts +39 -6
- package/dist/cjs/hooks/useYAxisLabelWidth/index.js +30 -43
- package/dist/cjs/hooks/useZoom/index.d.ts +1 -1
- package/dist/cjs/hooks/useZoom/index.js +2 -2
- package/dist/cjs/utils/chart/axis/common.d.ts +1 -1
- package/dist/cjs/utils/chart/axis/common.js +1 -1
- package/dist/esm/components/AxisX/prepare-axis-data.d.ts +1 -1
- package/dist/esm/components/AxisX/prepare-axis-data.js +10 -9
- package/dist/esm/components/AxisY/prepare-axis-data.d.ts +1 -1
- package/dist/esm/components/AxisY/prepare-axis-data.js +2 -2
- package/dist/esm/components/ChartInner/index.js +8 -3
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +18 -19
- package/dist/esm/components/ChartInner/useChartInnerProps.js +232 -138
- package/dist/esm/components/ChartInner/useChartInnerState.js +2 -1
- package/dist/esm/components/Legend/index.d.ts +1 -1
- package/dist/esm/components/Legend/index.js +1 -1
- package/dist/esm/hooks/useAxis/index.d.ts +40 -5
- package/dist/esm/hooks/useAxis/index.js +55 -41
- package/dist/esm/hooks/useAxis/types.d.ts +0 -2
- package/dist/esm/hooks/useAxisScales/index.d.ts +4 -0
- package/dist/esm/hooks/useAxisScales/index.js +1 -1
- package/dist/esm/hooks/useChartDimensions/index.d.ts +1 -1
- package/dist/esm/hooks/useChartDimensions/index.js +14 -29
- package/dist/esm/hooks/useCrosshair/index.d.ts +1 -1
- package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +29 -34
- package/dist/esm/hooks/useNormalizedOriginalData/index.js +19 -30
- package/dist/esm/hooks/useSeries/index.d.ts +10 -14
- package/dist/esm/hooks/useSeries/index.js +8 -80
- package/dist/esm/hooks/useShapes/index.d.ts +4 -0
- package/dist/esm/hooks/useShapes/index.js +194 -189
- package/dist/esm/hooks/useSplit/index.d.ts +5 -2
- package/dist/esm/hooks/useSplit/index.js +27 -30
- package/dist/esm/hooks/useYAxisLabelWidth/index.d.ts +39 -6
- package/dist/esm/hooks/useYAxisLabelWidth/index.js +30 -43
- package/dist/esm/hooks/useZoom/index.d.ts +1 -1
- package/dist/esm/hooks/useZoom/index.js +2 -2
- package/dist/esm/utils/chart/axis/common.d.ts +1 -1
- package/dist/esm/utils/chart/axis/common.js +1 -1
- package/package.json +1 -1
- package/dist/cjs/components/ChartInner/useLegend.d.ts +0 -14
- package/dist/cjs/components/ChartInner/useLegend.js +0 -34
- package/dist/esm/components/ChartInner/useLegend.d.ts +0 -14
- package/dist/esm/components/ChartInner/useLegend.js +0 -34
|
@@ -70,19 +70,20 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxWid
|
|
|
70
70
|
}
|
|
71
71
|
// eslint-disable-next-line complexity
|
|
72
72
|
export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRight, boundsWidth, height, scale, series, split, yAxis, }) {
|
|
73
|
-
var _a, _b, _c, _d, _e, _f;
|
|
73
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
74
74
|
const xAxisItems = [];
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const splitPlots = (_a = split === null || split === void 0 ? void 0 : split.plots) !== null && _a !== void 0 ? _a : [];
|
|
76
|
+
for (let plotIndex = 0; plotIndex < splitPlots.length; plotIndex++) {
|
|
77
|
+
const plot = splitPlots[plotIndex];
|
|
77
78
|
const axisTop = plot.top;
|
|
78
79
|
const axisHeight = plot.height;
|
|
79
80
|
const axisWidth = boundsWidth;
|
|
80
|
-
const isBottomPlot = plotIndex ===
|
|
81
|
+
const isBottomPlot = plotIndex === splitPlots.length - 1;
|
|
81
82
|
const plotYAxes = yAxis.filter((a) => a.plotIndex === plotIndex);
|
|
82
|
-
const yDomainLeftPosition = ((
|
|
83
|
+
const yDomainLeftPosition = ((_b = plotYAxes.find((a) => a.position === 'left')) === null || _b === void 0 ? void 0 : _b.visible)
|
|
83
84
|
? 0
|
|
84
85
|
: null;
|
|
85
|
-
const yDomainRightPosition = ((
|
|
86
|
+
const yDomainRightPosition = ((_c = plotYAxes.find((a) => a.position === 'right')) === null || _c === void 0 ? void 0 : _c.visible)
|
|
86
87
|
? axisWidth
|
|
87
88
|
: null;
|
|
88
89
|
let domain = null;
|
|
@@ -90,7 +91,7 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
90
91
|
domain = {
|
|
91
92
|
start: [0, axisTop + axisHeight],
|
|
92
93
|
end: [axisWidth, axisTop + axisHeight],
|
|
93
|
-
lineColor: (
|
|
94
|
+
lineColor: (_d = axis.lineColor) !== null && _d !== void 0 ? _d : '',
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
97
|
const ticks = [];
|
|
@@ -255,7 +256,7 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
255
256
|
axisScale,
|
|
256
257
|
axis: 'x',
|
|
257
258
|
});
|
|
258
|
-
const halfBandwidth = ((
|
|
259
|
+
const halfBandwidth = ((_f = (_e = axisScale.bandwidth) === null || _e === void 0 ? void 0 : _e.call(axisScale)) !== null && _f !== void 0 ? _f : 0) / 2;
|
|
259
260
|
const startPos = halfBandwidth + Math.min(from, to);
|
|
260
261
|
const endPos = Math.min(Math.abs(to - from), axisWidth - Math.min(from, to));
|
|
261
262
|
const getPlotLabelSize = getTextSizeFn({ style: plotBand.label.style });
|
|
@@ -279,7 +280,7 @@ export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRig
|
|
|
279
280
|
text: plotBand.label.text,
|
|
280
281
|
style: plotBand.label.style,
|
|
281
282
|
x: plotBand.label.padding,
|
|
282
|
-
y: plotBand.label.padding + ((
|
|
283
|
+
y: plotBand.label.padding + ((_g = labelSize === null || labelSize === void 0 ? void 0 : labelSize.width) !== null && _g !== void 0 ? _g : 0),
|
|
283
284
|
rotate: -90,
|
|
284
285
|
qa: plotBand.label.qa,
|
|
285
286
|
}
|
|
@@ -2,7 +2,7 @@ import type { ChartScale, PreparedAxis, PreparedSeries, PreparedSplit } from '..
|
|
|
2
2
|
import type { AxisYData } from './types';
|
|
3
3
|
export declare function prepareYAxisData({ axis, split, scale, top: topOffset, width, height, series, }: {
|
|
4
4
|
axis: PreparedAxis;
|
|
5
|
-
split: PreparedSplit;
|
|
5
|
+
split: PreparedSplit | undefined;
|
|
6
6
|
scale: ChartScale;
|
|
7
7
|
top: number;
|
|
8
8
|
width: number;
|
|
@@ -110,8 +110,8 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHei
|
|
|
110
110
|
}
|
|
111
111
|
export async function prepareYAxisData({ axis, split, scale, top: topOffset, width, height, series, }) {
|
|
112
112
|
var _a, _b, _c;
|
|
113
|
-
const axisPlotTopPosition = ((_a = split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
114
|
-
const axisHeight = ((_b = split.plots[axis.plotIndex]) === null || _b === void 0 ? void 0 : _b.height) || height;
|
|
113
|
+
const axisPlotTopPosition = ((_a = split === null || split === void 0 ? void 0 : split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
114
|
+
const axisHeight = ((_b = split === null || split === void 0 ? void 0 : split.plots[axis.plotIndex]) === null || _b === void 0 ? void 0 : _b.height) || height;
|
|
115
115
|
const domainX = axis.position === 'left' ? 0 : width;
|
|
116
116
|
let domain = null;
|
|
117
117
|
if (axis.visible) {
|
|
@@ -63,12 +63,14 @@ export const ChartInner = (props) => {
|
|
|
63
63
|
preparedRangeSlider,
|
|
64
64
|
tooltip: preparedTooltip,
|
|
65
65
|
});
|
|
66
|
-
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit,
|
|
66
|
+
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, shapes, shapesData, shapesReady, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
67
67
|
dispatcher,
|
|
68
68
|
htmlLayout, plotNode: plotRef.current, preparedChart,
|
|
69
69
|
rangeSliderState,
|
|
70
70
|
updateZoomState,
|
|
71
71
|
zoomState }));
|
|
72
|
+
const prevWidth = usePrevious(width);
|
|
73
|
+
const prevHeight = usePrevious(height);
|
|
72
74
|
const debouncedBoundsWidth = useDebouncedValue({
|
|
73
75
|
value: boundsWidth,
|
|
74
76
|
delay: DEBOUNCED_VALUE_DELAY,
|
|
@@ -237,7 +239,7 @@ export const ChartInner = (props) => {
|
|
|
237
239
|
React.createElement("clipPath", { id: getClipPathIdByBounds({ clipPathId, bounds: 'horizontal' }) },
|
|
238
240
|
React.createElement("rect", { x: 0, y: -boundsHeight, width: boundsWidth, height: boundsHeight * 3 }))),
|
|
239
241
|
preparedTitle && React.createElement(Title, Object.assign({}, preparedTitle, { chartWidth: width })),
|
|
240
|
-
React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit.plots.map((plot, index) => {
|
|
242
|
+
React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit === null || preparedSplit === void 0 ? void 0 : preparedSplit.plots.map((plot, index) => {
|
|
241
243
|
return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
|
|
242
244
|
})),
|
|
243
245
|
React.createElement("g", { className: b('content'), width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})`, ref: plotRef },
|
|
@@ -253,7 +255,10 @@ export const ChartInner = (props) => {
|
|
|
253
255
|
React.createElement("g", { ref: plotBeforeRef }),
|
|
254
256
|
shapes,
|
|
255
257
|
React.createElement("g", { ref: plotAfterRef })),
|
|
256
|
-
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) &&
|
|
258
|
+
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) &&
|
|
259
|
+
preparedLegend &&
|
|
260
|
+
debouncedAllPreparedSeries &&
|
|
261
|
+
preparedSeriesOptions && (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, legendConfig: legendConfig })),
|
|
257
262
|
(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 }))));
|
|
258
263
|
return (React.createElement("div", { className: b() },
|
|
259
264
|
React.createElement("svg", { ref: svgRef, width: width, height: height,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
|
-
import type { PreparedChart, PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
|
|
3
|
+
import type { ChartScale, LegendItem, OnLegendItemClick, PreparedChart, PreparedLegend, PreparedSeries, PreparedSplit, PreparedXAxis, RangeSliderState, ShapeData, ZoomState } from '../../hooks';
|
|
4
4
|
import type { LegendConfig } from '../../types';
|
|
5
5
|
import type { ChartInnerProps } from './types';
|
|
6
6
|
type Props = ChartInnerProps & {
|
|
@@ -14,26 +14,12 @@ type Props = ChartInnerProps & {
|
|
|
14
14
|
rangeSliderState?: RangeSliderState;
|
|
15
15
|
};
|
|
16
16
|
export declare function useChartInnerProps(props: Props): {
|
|
17
|
-
|
|
18
|
-
boundsHeight: number;
|
|
17
|
+
preparedSeries: PreparedSeries[];
|
|
19
18
|
boundsOffsetLeft: number;
|
|
20
19
|
boundsOffsetTop: number;
|
|
20
|
+
boundsHeight: number;
|
|
21
21
|
boundsWidth: number;
|
|
22
|
-
|
|
23
|
-
isOutsideBounds: (x: number, y: number) => boolean;
|
|
24
|
-
legendConfig: LegendConfig | undefined;
|
|
25
|
-
legendItems: import("../../hooks").LegendItem[][];
|
|
26
|
-
preparedLegend: PreparedLegend | null;
|
|
27
|
-
preparedSeries: import("../../hooks").PreparedSeries[];
|
|
28
|
-
preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
|
|
29
|
-
preparedSplit: import("../../hooks").PreparedSplit;
|
|
30
|
-
prevHeight: number | undefined;
|
|
31
|
-
prevWidth: number | undefined;
|
|
32
|
-
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
33
|
-
shapesData: import("../../hooks").ShapeData[];
|
|
34
|
-
shapesReady: boolean;
|
|
35
|
-
xAxis: import("../../hooks").PreparedXAxis | null;
|
|
36
|
-
xScale: import("../../hooks").ChartScale | undefined;
|
|
22
|
+
xAxis: PreparedXAxis | null;
|
|
37
23
|
yAxis: (Omit<import("../../types").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
|
|
38
24
|
type: import("../../types").ChartAxisType;
|
|
39
25
|
labels: Omit<import("../../types").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../../types").ChartAxisLabels, "margin" | "html" | "enabled" | "rotation" | "padding">> & {
|
|
@@ -71,6 +57,19 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
71
57
|
plotBands: import("../../hooks").PreparedAxisPlotBand[];
|
|
72
58
|
crosshair: Required<import("../../types").AxisCrosshair>;
|
|
73
59
|
})[];
|
|
74
|
-
|
|
60
|
+
shapesData: ShapeData[];
|
|
61
|
+
shapesReady: boolean;
|
|
62
|
+
handleLegendItemClick: OnLegendItemClick;
|
|
63
|
+
isOutsideBounds: (x: number, y: number) => boolean;
|
|
64
|
+
allPreparedSeries?: PreparedSeries[] | undefined;
|
|
65
|
+
legendConfig?: LegendConfig | undefined;
|
|
66
|
+
legendItems?: LegendItem[][] | undefined;
|
|
67
|
+
preparedLegend?: PreparedLegend | undefined;
|
|
68
|
+
preparedSeriesOptions?: import("../../constants").SeriesOptionsDefaults | undefined;
|
|
69
|
+
preparedSplit?: PreparedSplit | undefined;
|
|
70
|
+
shapes?: React.ReactElement<any, string | React.JSXElementConstructor<any>>[] | undefined;
|
|
71
|
+
xScale?: ChartScale | undefined;
|
|
72
|
+
yScale?: (ChartScale | undefined)[] | undefined;
|
|
73
|
+
activeLegendItems?: string[] | undefined;
|
|
75
74
|
};
|
|
76
75
|
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
2
3
|
import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
|
|
3
|
-
import {
|
|
4
|
+
import { createScales, getAxes, getChartDimensions, getNormalizedXAxis, getNormalizedYAxis, getPreparedSeries, getShapes, getSplit, getVisibleSeries, recalculateYAxisLabelsWidth, useZoom, } from '../../hooks';
|
|
4
5
|
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
6
|
+
import { getLegendComponents, getPreparedLegend } from '../../hooks/useSeries/prepare-legend';
|
|
5
7
|
import { getPreparedOptions } from '../../hooks/useSeries/prepare-options';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
+
import { getActiveLegendItems, getAllLegendItems } from '../../hooks/useSeries/utils';
|
|
9
|
+
import { getEffectiveXRange, getSortedSeriesData, getZoomedSeriesData, isAxisRelatedSeries, } from '../../utils';
|
|
8
10
|
import { hasAtLeastOneSeriesDataPerPlot } from './utils';
|
|
9
11
|
const CLIP_PATH_BY_SERIES_TYPE = {
|
|
10
12
|
[SERIES_TYPE.Scatter]: false,
|
|
@@ -34,111 +36,235 @@ function getBoundsOffsetLeft(args) {
|
|
|
34
36
|
}, 0);
|
|
35
37
|
return chartMarginLeft + legendOffset + leftAxisWidth;
|
|
36
38
|
}
|
|
39
|
+
// eslint-disable-next-line complexity
|
|
37
40
|
export function useChartInnerProps(props) {
|
|
41
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
38
42
|
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
43
|
+
const [selectedLegendItems, setSelectedLegendItems] = React.useState(null);
|
|
44
|
+
const [chartState, setState] = React.useState(null);
|
|
45
|
+
const prevStateValue = React.useRef(chartState);
|
|
46
|
+
const previousChartData = React.useRef(null);
|
|
47
|
+
const currentRunRef = React.useRef(0);
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
currentRunRef.current++;
|
|
50
|
+
const currentRun = currentRunRef.current;
|
|
51
|
+
(async function () {
|
|
52
|
+
var _a, _b, _c;
|
|
53
|
+
const chartDataChanged = !(previousChartData.current && isEqual(previousChartData.current, data));
|
|
54
|
+
const colors = (_a = data.colors) !== null && _a !== void 0 ? _a : DEFAULT_PALETTE;
|
|
55
|
+
const normalizedSeriesData = getSortedSeriesData({
|
|
56
|
+
seriesData: data.series.data,
|
|
57
|
+
xAxis: data.xAxis,
|
|
58
|
+
yAxis: data.yAxis,
|
|
59
|
+
});
|
|
60
|
+
const normalizedXAxis = getNormalizedXAxis({ xAxis: data.xAxis });
|
|
61
|
+
const normalizedYAxis = getNormalizedYAxis({ yAxis: data.yAxis });
|
|
62
|
+
const preparedSeriesOptions = getPreparedOptions(data.series.options);
|
|
63
|
+
const preparedLegend = await getPreparedLegend({
|
|
64
|
+
legend: data.legend,
|
|
65
|
+
series: normalizedSeriesData,
|
|
66
|
+
});
|
|
67
|
+
let allPreparedSeries;
|
|
68
|
+
if (chartDataChanged) {
|
|
69
|
+
allPreparedSeries = await getPreparedSeries({
|
|
70
|
+
seriesData: normalizedSeriesData,
|
|
71
|
+
seriesOptions: data.series.options,
|
|
72
|
+
preparedLegend,
|
|
73
|
+
colors,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
allPreparedSeries = (_c = (_b = prevStateValue.current) === null || _b === void 0 ? void 0 : _b.allPreparedSeries) !== null && _c !== void 0 ? _c : [];
|
|
78
|
+
}
|
|
79
|
+
const activeLegendItems = selectedLegendItems !== null && selectedLegendItems !== void 0 ? selectedLegendItems : getActiveLegendItems(allPreparedSeries);
|
|
80
|
+
const visiblePreparedSeries = getVisibleSeries({
|
|
81
|
+
preparedSeries: allPreparedSeries,
|
|
82
|
+
activeLegendItems,
|
|
83
|
+
});
|
|
84
|
+
const effectiveZoomState = {};
|
|
85
|
+
const effectiveX = getEffectiveXRange(zoomState.x, rangeSliderState);
|
|
86
|
+
if (effectiveX !== undefined) {
|
|
87
|
+
effectiveZoomState.x = effectiveX;
|
|
88
|
+
}
|
|
89
|
+
if (zoomState.y !== undefined) {
|
|
90
|
+
effectiveZoomState.y = zoomState.y;
|
|
91
|
+
}
|
|
92
|
+
const { preparedSeries, preparedShapesSeries } = getZoomedSeriesData({
|
|
93
|
+
seriesData: visiblePreparedSeries,
|
|
94
|
+
xAxis: normalizedXAxis,
|
|
95
|
+
yAxis: normalizedYAxis,
|
|
96
|
+
zoomState: effectiveZoomState,
|
|
97
|
+
});
|
|
98
|
+
const { legendConfig, legendItems } = await getLegendComponents({
|
|
99
|
+
chartWidth: width,
|
|
100
|
+
chartHeight: height,
|
|
101
|
+
chartMargin: preparedChart.margin,
|
|
102
|
+
series: preparedSeries,
|
|
103
|
+
preparedLegend,
|
|
104
|
+
});
|
|
105
|
+
const axes = await getAxes({
|
|
106
|
+
height,
|
|
107
|
+
preparedChart,
|
|
108
|
+
legendConfig,
|
|
109
|
+
preparedLegend,
|
|
110
|
+
preparedSeries,
|
|
111
|
+
preparedSeriesOptions,
|
|
112
|
+
width,
|
|
113
|
+
xAxis: normalizedXAxis,
|
|
114
|
+
yAxis: normalizedYAxis,
|
|
115
|
+
});
|
|
116
|
+
const xAxis = axes.xAxis;
|
|
117
|
+
let yAxis = axes.yAxis;
|
|
118
|
+
let preparedSplit = { plots: [], gap: 0 };
|
|
119
|
+
let xScale;
|
|
120
|
+
let yScale;
|
|
121
|
+
let boundsWidth = 0;
|
|
122
|
+
let boundsHeight = 0;
|
|
123
|
+
const calculateAxisBasedProps = () => {
|
|
124
|
+
const chartDimensions = getChartDimensions({
|
|
125
|
+
height,
|
|
126
|
+
margin: preparedChart.margin,
|
|
127
|
+
preparedLegend,
|
|
128
|
+
preparedSeries: preparedSeries,
|
|
129
|
+
preparedYAxis: yAxis,
|
|
130
|
+
preparedXAxis: xAxis,
|
|
131
|
+
width,
|
|
132
|
+
legendConfig,
|
|
133
|
+
});
|
|
134
|
+
boundsHeight = chartDimensions.boundsHeight;
|
|
135
|
+
boundsWidth = chartDimensions.boundsWidth;
|
|
136
|
+
preparedSplit = getSplit({ split: data.split, boundsHeight, chartWidth: width });
|
|
137
|
+
if (preparedSeries.some(isAxisRelatedSeries)) {
|
|
138
|
+
({ xScale, yScale } = createScales({
|
|
139
|
+
boundsWidth,
|
|
140
|
+
boundsHeight,
|
|
141
|
+
isRangeSlider: false,
|
|
142
|
+
rangeSliderState,
|
|
143
|
+
series: preparedSeries,
|
|
144
|
+
split: preparedSplit,
|
|
145
|
+
xAxis,
|
|
146
|
+
yAxis,
|
|
147
|
+
zoomState,
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
calculateAxisBasedProps();
|
|
152
|
+
const newYAxis = await recalculateYAxisLabelsWidth({
|
|
153
|
+
seriesData: preparedSeries,
|
|
154
|
+
yAxis,
|
|
155
|
+
yScale,
|
|
156
|
+
});
|
|
157
|
+
if (!isEqual(yAxis, newYAxis)) {
|
|
158
|
+
yAxis = newYAxis;
|
|
159
|
+
calculateAxisBasedProps();
|
|
160
|
+
}
|
|
161
|
+
const isOutsideBounds = (x, y) => {
|
|
162
|
+
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
163
|
+
};
|
|
164
|
+
const { shapes, shapesData } = await getShapes({
|
|
165
|
+
boundsWidth,
|
|
166
|
+
boundsHeight,
|
|
167
|
+
clipPathBySeriesType: CLIP_PATH_BY_SERIES_TYPE,
|
|
168
|
+
dispatcher,
|
|
169
|
+
series: preparedShapesSeries,
|
|
170
|
+
seriesOptions: preparedSeriesOptions,
|
|
171
|
+
xAxis,
|
|
172
|
+
xScale,
|
|
173
|
+
yAxis,
|
|
174
|
+
yScale,
|
|
175
|
+
split: preparedSplit,
|
|
176
|
+
htmlLayout,
|
|
177
|
+
clipPathId,
|
|
178
|
+
isOutsideBounds,
|
|
179
|
+
zoomState: effectiveZoomState,
|
|
180
|
+
});
|
|
181
|
+
const boundsOffsetTop = getBoundsOffsetTop({
|
|
182
|
+
chartMarginTop: preparedChart.margin.top,
|
|
183
|
+
preparedLegend,
|
|
184
|
+
legendConfig,
|
|
185
|
+
});
|
|
186
|
+
// We need to calculate the width of each left axis because the first axis can be hidden
|
|
187
|
+
const boundsOffsetLeft = getBoundsOffsetLeft({
|
|
188
|
+
chartMarginLeft: preparedChart.margin.left,
|
|
189
|
+
preparedLegend,
|
|
190
|
+
yAxis,
|
|
191
|
+
getYAxisWidth,
|
|
192
|
+
legendConfig,
|
|
193
|
+
});
|
|
194
|
+
//end
|
|
195
|
+
const newStateValue = {
|
|
196
|
+
allPreparedSeries,
|
|
197
|
+
boundsHeight,
|
|
198
|
+
boundsOffsetLeft,
|
|
199
|
+
boundsOffsetTop,
|
|
200
|
+
boundsWidth,
|
|
201
|
+
isOutsideBounds,
|
|
202
|
+
legendConfig,
|
|
203
|
+
legendItems,
|
|
204
|
+
preparedLegend,
|
|
205
|
+
preparedSeries,
|
|
206
|
+
preparedSeriesOptions,
|
|
207
|
+
preparedSplit,
|
|
208
|
+
shapes,
|
|
209
|
+
shapesData,
|
|
210
|
+
xAxis,
|
|
211
|
+
xScale,
|
|
212
|
+
yAxis,
|
|
213
|
+
yScale,
|
|
214
|
+
activeLegendItems,
|
|
215
|
+
};
|
|
216
|
+
if (currentRunRef.current === currentRun) {
|
|
217
|
+
if (!isEqual(prevStateValue.current, newStateValue)) {
|
|
218
|
+
setState(newStateValue);
|
|
219
|
+
prevStateValue.current = newStateValue;
|
|
220
|
+
}
|
|
221
|
+
previousChartData.current = data;
|
|
222
|
+
}
|
|
223
|
+
})();
|
|
224
|
+
}, [
|
|
87
225
|
height,
|
|
88
|
-
preparedChart,
|
|
89
|
-
legendConfig,
|
|
90
|
-
preparedLegend,
|
|
91
|
-
preparedSeries,
|
|
92
|
-
preparedSeriesOptions,
|
|
93
226
|
width,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
const { boundsWidth, boundsHeight } = useChartDimensions({
|
|
98
|
-
height,
|
|
99
|
-
margin: preparedChart.margin,
|
|
100
|
-
preparedLegend,
|
|
101
|
-
preparedSeries: preparedSeries,
|
|
102
|
-
preparedYAxis: yAxis,
|
|
103
|
-
preparedXAxis: xAxis,
|
|
104
|
-
width,
|
|
105
|
-
legendConfig,
|
|
106
|
-
});
|
|
107
|
-
const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
|
|
108
|
-
const { xScale, yScale } = useAxisScales({
|
|
109
|
-
boundsWidth,
|
|
110
|
-
boundsHeight,
|
|
111
|
-
rangeSliderState,
|
|
112
|
-
series: preparedSeries,
|
|
113
|
-
split: preparedSplit,
|
|
114
|
-
xAxis,
|
|
115
|
-
yAxis,
|
|
227
|
+
data,
|
|
228
|
+
selectedLegendItems,
|
|
116
229
|
zoomState,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const isOutsideBounds = React.useCallback((x, y) => {
|
|
120
|
-
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
121
|
-
}, [boundsHeight, boundsWidth]);
|
|
122
|
-
const { shapes, shapesData, shapesReady } = useShapes({
|
|
123
|
-
boundsWidth,
|
|
124
|
-
boundsHeight,
|
|
125
|
-
clipPathBySeriesType: CLIP_PATH_BY_SERIES_TYPE,
|
|
230
|
+
rangeSliderState,
|
|
231
|
+
preparedChart,
|
|
126
232
|
dispatcher,
|
|
127
|
-
series: preparedShapesSeries,
|
|
128
|
-
seriesOptions: preparedSeriesOptions,
|
|
129
|
-
xAxis,
|
|
130
|
-
xScale,
|
|
131
|
-
yAxis,
|
|
132
|
-
yScale,
|
|
133
|
-
split: preparedSplit,
|
|
134
233
|
htmlLayout,
|
|
135
234
|
clipPathId,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
});
|
|
139
|
-
const
|
|
235
|
+
]);
|
|
236
|
+
// additional start
|
|
237
|
+
const preparedSeries = React.useMemo(() => { var _a; return (_a = chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries) !== null && _a !== void 0 ? _a : []; }, [chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries]);
|
|
238
|
+
const activeLegendItems = React.useMemo(() => { var _a; return (_a = chartState === null || chartState === void 0 ? void 0 : chartState.activeLegendItems) !== null && _a !== void 0 ? _a : []; }, [chartState === null || chartState === void 0 ? void 0 : chartState.activeLegendItems]);
|
|
239
|
+
const boundsHeight = (_a = chartState === null || chartState === void 0 ? void 0 : chartState.boundsHeight) !== null && _a !== void 0 ? _a : 0;
|
|
240
|
+
const boundsWidth = (_b = chartState === null || chartState === void 0 ? void 0 : chartState.boundsWidth) !== null && _b !== void 0 ? _b : 0;
|
|
241
|
+
const handleLegendItemClick = React.useCallback(({ id, metaKey }) => {
|
|
242
|
+
const allItems = getAllLegendItems(preparedSeries);
|
|
243
|
+
const onlyItemSelected = (selectedLegendItems !== null && selectedLegendItems !== void 0 ? selectedLegendItems : []).length === 1 && activeLegendItems.includes(id);
|
|
244
|
+
let nextActiveLegendItems;
|
|
245
|
+
if (metaKey && activeLegendItems.includes(id)) {
|
|
246
|
+
nextActiveLegendItems = activeLegendItems.filter((item) => item !== id);
|
|
247
|
+
}
|
|
248
|
+
else if (metaKey && !activeLegendItems.includes(id)) {
|
|
249
|
+
nextActiveLegendItems = activeLegendItems.concat(id);
|
|
250
|
+
}
|
|
251
|
+
else if (onlyItemSelected && allItems.length === 1) {
|
|
252
|
+
nextActiveLegendItems = [];
|
|
253
|
+
}
|
|
254
|
+
else if (onlyItemSelected) {
|
|
255
|
+
nextActiveLegendItems = allItems;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
nextActiveLegendItems = [id];
|
|
259
|
+
}
|
|
260
|
+
setSelectedLegendItems(nextActiveLegendItems);
|
|
261
|
+
}, [preparedSeries, selectedLegendItems, activeLegendItems]);
|
|
262
|
+
const xAxis = (_c = chartState === null || chartState === void 0 ? void 0 : chartState.xAxis) !== null && _c !== void 0 ? _c : null;
|
|
263
|
+
const yAxis = (_d = chartState === null || chartState === void 0 ? void 0 : chartState.yAxis) !== null && _d !== void 0 ? _d : [];
|
|
264
|
+
const handleAttemptToSetZoomState = (nextZoomState) => {
|
|
265
|
+
var _a;
|
|
140
266
|
const { preparedSeries: nextZoomedSeriesData } = getZoomedSeriesData({
|
|
141
|
-
seriesData: preparedSeries,
|
|
267
|
+
seriesData: (_a = chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries) !== null && _a !== void 0 ? _a : [],
|
|
142
268
|
xAxis,
|
|
143
269
|
yAxis,
|
|
144
270
|
zoomState: nextZoomState,
|
|
@@ -147,54 +273,22 @@ export function useChartInnerProps(props) {
|
|
|
147
273
|
if (hasData) {
|
|
148
274
|
updateZoomState(nextZoomState);
|
|
149
275
|
}
|
|
150
|
-
}
|
|
276
|
+
};
|
|
151
277
|
useZoom({
|
|
152
278
|
node: plotNode,
|
|
153
279
|
onUpdate: handleAttemptToSetZoomState,
|
|
154
280
|
plotContainerHeight: boundsHeight,
|
|
155
281
|
plotContainerWidth: boundsWidth,
|
|
156
|
-
preparedSplit,
|
|
282
|
+
preparedSplit: chartState === null || chartState === void 0 ? void 0 : chartState.preparedSplit,
|
|
157
283
|
preparedZoom: preparedChart.zoom,
|
|
158
284
|
xAxis,
|
|
159
|
-
xScale,
|
|
285
|
+
xScale: chartState === null || chartState === void 0 ? void 0 : chartState.xScale,
|
|
160
286
|
yAxis,
|
|
161
|
-
yScale,
|
|
162
|
-
});
|
|
163
|
-
const boundsOffsetTop = getBoundsOffsetTop({
|
|
164
|
-
chartMarginTop: preparedChart.margin.top,
|
|
165
|
-
preparedLegend,
|
|
166
|
-
legendConfig,
|
|
287
|
+
yScale: chartState === null || chartState === void 0 ? void 0 : chartState.yScale,
|
|
167
288
|
});
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
chartMarginLeft: preparedChart.margin.left,
|
|
171
|
-
preparedLegend,
|
|
172
|
-
yAxis,
|
|
173
|
-
getYAxisWidth,
|
|
174
|
-
legendConfig,
|
|
175
|
-
});
|
|
176
|
-
return {
|
|
177
|
-
allPreparedSeries,
|
|
178
|
-
boundsHeight,
|
|
179
|
-
boundsOffsetLeft,
|
|
180
|
-
boundsOffsetTop,
|
|
289
|
+
// additional end
|
|
290
|
+
return Object.assign(Object.assign({}, chartState), { preparedSeries, boundsOffsetLeft: (_e = chartState === null || chartState === void 0 ? void 0 : chartState.boundsOffsetLeft) !== null && _e !== void 0 ? _e : 0, boundsOffsetTop: (_f = chartState === null || chartState === void 0 ? void 0 : chartState.boundsOffsetTop) !== null && _f !== void 0 ? _f : 0, boundsHeight,
|
|
181
291
|
boundsWidth,
|
|
182
|
-
handleLegendItemClick,
|
|
183
|
-
isOutsideBounds,
|
|
184
|
-
legendConfig,
|
|
185
|
-
legendItems,
|
|
186
|
-
preparedLegend,
|
|
187
|
-
preparedSeries,
|
|
188
|
-
preparedSeriesOptions,
|
|
189
|
-
preparedSplit,
|
|
190
|
-
prevHeight,
|
|
191
|
-
prevWidth,
|
|
192
|
-
shapes,
|
|
193
|
-
shapesData,
|
|
194
|
-
shapesReady,
|
|
195
292
|
xAxis,
|
|
196
|
-
|
|
197
|
-
yAxis,
|
|
198
|
-
yScale,
|
|
199
|
-
};
|
|
293
|
+
yAxis, shapesData: (_g = chartState === null || chartState === void 0 ? void 0 : chartState.shapesData) !== null && _g !== void 0 ? _g : [], shapesReady: Boolean(chartState), handleLegendItemClick, isOutsideBounds: (_h = chartState === null || chartState === void 0 ? void 0 : chartState.isOutsideBounds) !== null && _h !== void 0 ? _h : (() => false) });
|
|
200
294
|
}
|
|
@@ -41,8 +41,9 @@ export function useChartInnerState(props) {
|
|
|
41
41
|
else if (nextZoomState.x !== undefined) {
|
|
42
42
|
setRangeSliderState({ min: nextZoomState.x[0], max: nextZoomState.x[1] });
|
|
43
43
|
}
|
|
44
|
+
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
44
45
|
}
|
|
45
|
-
}, [zoomState]);
|
|
46
|
+
}, [dispatcher, zoomState]);
|
|
46
47
|
const updateRangeSliderState = React.useCallback((nextRangeSliderState) => {
|
|
47
48
|
if (!isEqual(rangeSliderState, nextRangeSliderState)) {
|
|
48
49
|
setRangeSliderState(nextRangeSliderState
|
|
@@ -130,7 +130,7 @@ function renderLegendSymbol(args) {
|
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
132
|
export const Legend = (props) => {
|
|
133
|
-
const { chartSeries, legend, items, config, htmlLayout, onItemClick, onUpdate } = props;
|
|
133
|
+
const { chartSeries, legend, items = [], config, htmlLayout, onItemClick, onUpdate } = props;
|
|
134
134
|
const ref = React.useRef(null);
|
|
135
135
|
const [pageIndex, setPageIndex] = React.useState(0);
|
|
136
136
|
React.useEffect(() => {
|