@gravity-ui/charts 0.4.1 → 0.6.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/ChartInner/index.d.ts +2 -8
- package/dist/cjs/components/ChartInner/index.js +22 -117
- package/dist/cjs/components/ChartInner/types.d.ts +6 -0
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +26 -0
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +94 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +43 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +81 -0
- package/dist/cjs/components/ChartInner/useChartInnerState.d.ts +13 -0
- package/dist/cjs/components/ChartInner/useChartInnerState.js +34 -0
- package/dist/cjs/components/Legend/index.d.ts +1 -0
- package/dist/cjs/components/Legend/index.js +26 -6
- package/dist/cjs/components/Tooltip/index.d.ts +2 -0
- package/dist/cjs/components/Tooltip/index.js +9 -3
- package/dist/cjs/components/Tooltip/styles.css +3 -0
- package/dist/cjs/hooks/index.d.ts +2 -1
- package/dist/cjs/hooks/index.js +2 -1
- package/dist/cjs/hooks/usePrevious/index.d.ts +1 -0
- package/dist/cjs/hooks/usePrevious/index.js +8 -0
- package/dist/cjs/hooks/useSeries/prepare-legend.js +1 -0
- package/dist/cjs/hooks/useSeries/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/area/index.js +8 -2
- package/dist/cjs/hooks/useShapes/bar-x/index.js +8 -2
- package/dist/cjs/hooks/useShapes/bar-y/index.js +8 -2
- package/dist/cjs/hooks/useShapes/line/index.js +8 -2
- package/dist/cjs/hooks/useShapes/scatter/index.js +8 -2
- package/dist/cjs/hooks/useShapes/treemap/index.js +8 -2
- package/dist/cjs/hooks/useShapes/utils.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/utils.js +5 -3
- package/dist/cjs/hooks/useShapes/waterfall/index.js +8 -2
- package/dist/cjs/hooks/useTooltip/index.d.ts +2 -3
- package/dist/cjs/types/chart/chart.d.ts +2 -2
- package/dist/cjs/types/chart/legend.d.ts +2 -0
- package/dist/cjs/types/chart/series.d.ts +1 -2
- package/dist/cjs/types/chart/tooltip.d.ts +6 -6
- package/dist/cjs/types/misc.d.ts +1 -0
- package/dist/cjs/utils/misc.d.ts +10 -2
- package/dist/cjs/utils/misc.js +15 -3
- package/dist/esm/components/ChartInner/index.d.ts +2 -8
- package/dist/esm/components/ChartInner/index.js +22 -117
- package/dist/esm/components/ChartInner/types.d.ts +6 -0
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +26 -0
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +94 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +43 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +81 -0
- package/dist/esm/components/ChartInner/useChartInnerState.d.ts +13 -0
- package/dist/esm/components/ChartInner/useChartInnerState.js +34 -0
- package/dist/esm/components/Legend/index.d.ts +1 -0
- package/dist/esm/components/Legend/index.js +26 -6
- package/dist/esm/components/Tooltip/index.d.ts +2 -0
- package/dist/esm/components/Tooltip/index.js +9 -3
- package/dist/esm/components/Tooltip/styles.css +3 -0
- package/dist/esm/hooks/index.d.ts +2 -1
- package/dist/esm/hooks/index.js +2 -1
- package/dist/esm/hooks/usePrevious/index.d.ts +1 -0
- package/dist/esm/hooks/usePrevious/index.js +8 -0
- package/dist/esm/hooks/useSeries/prepare-legend.js +1 -0
- package/dist/esm/hooks/useSeries/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/area/index.js +8 -2
- package/dist/esm/hooks/useShapes/bar-x/index.js +8 -2
- package/dist/esm/hooks/useShapes/bar-y/index.js +8 -2
- package/dist/esm/hooks/useShapes/line/index.js +8 -2
- package/dist/esm/hooks/useShapes/scatter/index.js +8 -2
- package/dist/esm/hooks/useShapes/treemap/index.js +8 -2
- package/dist/esm/hooks/useShapes/utils.d.ts +2 -2
- package/dist/esm/hooks/useShapes/utils.js +5 -3
- package/dist/esm/hooks/useShapes/waterfall/index.js +8 -2
- package/dist/esm/hooks/useTooltip/index.d.ts +2 -3
- package/dist/esm/types/chart/chart.d.ts +2 -2
- package/dist/esm/types/chart/legend.d.ts +2 -0
- package/dist/esm/types/chart/series.d.ts +1 -2
- package/dist/esm/types/chart/tooltip.d.ts +6 -6
- package/dist/esm/types/misc.d.ts +1 -0
- package/dist/esm/utils/misc.d.ts +10 -2
- package/dist/esm/utils/misc.js +15 -3
- package/package.json +1 -1
- package/dist/cjs/hooks/useTooltip/types.d.ts +0 -1
- package/dist/esm/hooks/useTooltip/types.d.ts +0 -1
- /package/dist/cjs/{hooks/useTooltip → components/ChartInner}/types.js +0 -0
- /package/dist/esm/{hooks/useTooltip → components/ChartInner}/types.js +0 -0
package/dist/cjs/hooks/index.js
CHANGED
|
@@ -2,9 +2,10 @@ export * from './useChartDimensions';
|
|
|
2
2
|
export * from './useChartOptions';
|
|
3
3
|
export * from './useChartOptions/types';
|
|
4
4
|
export * from './useAxisScales';
|
|
5
|
+
export * from './usePrevious';
|
|
5
6
|
export * from './useSeries';
|
|
6
7
|
export * from './useSeries/types';
|
|
7
8
|
export * from './useShapes';
|
|
8
9
|
export * from './useTooltip';
|
|
9
|
-
export * from './
|
|
10
|
+
export * from './useSplit';
|
|
10
11
|
export * from './useSplit/types';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function usePrevious<T>(value: T): T | undefined;
|
|
@@ -8,6 +8,7 @@ import { setActiveState } from '../utils';
|
|
|
8
8
|
const b = block('d3-area');
|
|
9
9
|
export const AreaSeriesShapes = (args) => {
|
|
10
10
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
11
|
+
const hoveredDataRef = React.useRef(null);
|
|
11
12
|
const ref = React.useRef(null);
|
|
12
13
|
React.useEffect(() => {
|
|
13
14
|
var _a;
|
|
@@ -72,7 +73,8 @@ export const AreaSeriesShapes = (args) => {
|
|
|
72
73
|
.call(renderMarker);
|
|
73
74
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
74
75
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
75
|
-
|
|
76
|
+
function handleShapeHover(data) {
|
|
77
|
+
hoveredDataRef.current = data;
|
|
76
78
|
const selected = (data === null || data === void 0 ? void 0 : data.filter((d) => d.series.type === 'area')) || [];
|
|
77
79
|
const selectedDataItems = selected.map((d) => d.data);
|
|
78
80
|
const selectedSeriesIds = selected.map((d) => { var _a; return (_a = d.series) === null || _a === void 0 ? void 0 : _a.id; });
|
|
@@ -132,7 +134,11 @@ export const AreaSeriesShapes = (args) => {
|
|
|
132
134
|
}
|
|
133
135
|
return d;
|
|
134
136
|
});
|
|
135
|
-
}
|
|
137
|
+
}
|
|
138
|
+
if (hoveredDataRef.current !== null) {
|
|
139
|
+
handleShapeHover(hoveredDataRef.current);
|
|
140
|
+
}
|
|
141
|
+
dispatcher.on('hover-shape.area', handleShapeHover);
|
|
136
142
|
return () => {
|
|
137
143
|
dispatcher.on('hover-shape.area', null);
|
|
138
144
|
};
|
|
@@ -8,6 +8,7 @@ export * from './types';
|
|
|
8
8
|
const b = block('d3-bar-x');
|
|
9
9
|
export const BarXSeriesShapes = (args) => {
|
|
10
10
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
11
|
+
const hoveredDataRef = React.useRef(null);
|
|
11
12
|
const ref = React.useRef(null);
|
|
12
13
|
React.useEffect(() => {
|
|
13
14
|
var _a;
|
|
@@ -46,7 +47,8 @@ export const BarXSeriesShapes = (args) => {
|
|
|
46
47
|
.style('font-size', (d) => d.style.fontSize)
|
|
47
48
|
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
48
49
|
.style('fill', (d) => d.style.fontColor || null);
|
|
49
|
-
|
|
50
|
+
function handleShapeHover(data) {
|
|
51
|
+
hoveredDataRef.current = data;
|
|
50
52
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
51
53
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
52
54
|
if (!data) {
|
|
@@ -84,7 +86,11 @@ export const BarXSeriesShapes = (args) => {
|
|
|
84
86
|
: (inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.opacity) || null;
|
|
85
87
|
});
|
|
86
88
|
}
|
|
87
|
-
}
|
|
89
|
+
}
|
|
90
|
+
if (hoveredDataRef.current !== null) {
|
|
91
|
+
handleShapeHover(hoveredDataRef.current);
|
|
92
|
+
}
|
|
93
|
+
dispatcher.on('hover-shape.bar-x', handleShapeHover);
|
|
88
94
|
return () => {
|
|
89
95
|
dispatcher.on('hover-shape.bar-x', null);
|
|
90
96
|
};
|
|
@@ -7,6 +7,7 @@ export { prepareBarYData } from './prepare-data';
|
|
|
7
7
|
const b = block('d3-bar-y');
|
|
8
8
|
export const BarYSeriesShapes = (args) => {
|
|
9
9
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
10
|
+
const hoveredDataRef = React.useRef(null);
|
|
10
11
|
const ref = React.useRef(null);
|
|
11
12
|
React.useEffect(() => {
|
|
12
13
|
if (!ref.current) {
|
|
@@ -46,7 +47,8 @@ export const BarYSeriesShapes = (args) => {
|
|
|
46
47
|
.style('fill', (d) => d.style.fontColor || null);
|
|
47
48
|
const hoverOptions = get(seriesOptions, 'bar-y.states.hover');
|
|
48
49
|
const inactiveOptions = get(seriesOptions, 'bar-y.states.inactive');
|
|
49
|
-
|
|
50
|
+
function handleShapeHover(data) {
|
|
51
|
+
hoveredDataRef.current = data;
|
|
50
52
|
if (hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled) {
|
|
51
53
|
const hovered = data === null || data === void 0 ? void 0 : data.reduce((acc, d) => {
|
|
52
54
|
acc.add(d.data.y);
|
|
@@ -73,7 +75,11 @@ export const BarYSeriesShapes = (args) => {
|
|
|
73
75
|
rectSelection.attr('opacity', newOpacity);
|
|
74
76
|
labelSelection.attr('opacity', newOpacity);
|
|
75
77
|
}
|
|
76
|
-
}
|
|
78
|
+
}
|
|
79
|
+
if (hoveredDataRef.current !== null) {
|
|
80
|
+
handleShapeHover(hoveredDataRef.current);
|
|
81
|
+
}
|
|
82
|
+
dispatcher.on('hover-shape.bar-y', handleShapeHover);
|
|
77
83
|
return () => {
|
|
78
84
|
dispatcher.on('hover-shape.bar-y', null);
|
|
79
85
|
};
|
|
@@ -8,6 +8,7 @@ import { getLineDashArray, setActiveState } from '../utils';
|
|
|
8
8
|
const b = block('d3-line');
|
|
9
9
|
export const LineSeriesShapes = (args) => {
|
|
10
10
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
11
|
+
const hoveredDataRef = React.useRef(null);
|
|
11
12
|
const ref = React.useRef(null);
|
|
12
13
|
React.useEffect(() => {
|
|
13
14
|
var _a;
|
|
@@ -60,7 +61,8 @@ export const LineSeriesShapes = (args) => {
|
|
|
60
61
|
.call(renderMarker);
|
|
61
62
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
62
63
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
63
|
-
|
|
64
|
+
function handleShapeHover(data) {
|
|
65
|
+
hoveredDataRef.current = data;
|
|
64
66
|
const selected = (data === null || data === void 0 ? void 0 : data.filter((d) => d.series.type === 'line')) || [];
|
|
65
67
|
const selectedDataItems = selected.map((d) => d.data);
|
|
66
68
|
const selectedSeriesIds = selected.map((d) => { var _a; return (_a = d.series) === null || _a === void 0 ? void 0 : _a.id; });
|
|
@@ -119,7 +121,11 @@ export const LineSeriesShapes = (args) => {
|
|
|
119
121
|
}
|
|
120
122
|
return d;
|
|
121
123
|
});
|
|
122
|
-
}
|
|
124
|
+
}
|
|
125
|
+
if (hoveredDataRef.current !== null) {
|
|
126
|
+
handleShapeHover(hoveredDataRef.current);
|
|
127
|
+
}
|
|
128
|
+
dispatcher.on('hover-shape.line', handleShapeHover);
|
|
123
129
|
return () => {
|
|
124
130
|
dispatcher.on('hover-shape.line', null);
|
|
125
131
|
};
|
|
@@ -9,6 +9,7 @@ export { prepareScatterData } from './prepare-data';
|
|
|
9
9
|
const b = block('d3-scatter');
|
|
10
10
|
export function ScatterSeriesShape(props) {
|
|
11
11
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = props;
|
|
12
|
+
const hoveredDataRef = React.useRef(null);
|
|
12
13
|
const ref = React.useRef(null);
|
|
13
14
|
React.useEffect(() => {
|
|
14
15
|
if (!ref.current) {
|
|
@@ -28,8 +29,9 @@ export function ScatterSeriesShape(props) {
|
|
|
28
29
|
.attr('cursor', (d) => d.point.series.cursor);
|
|
29
30
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
30
31
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
31
|
-
|
|
32
|
+
function handleShapeHover(data) {
|
|
32
33
|
var _a;
|
|
34
|
+
hoveredDataRef.current = data;
|
|
33
35
|
const selected = data === null || data === void 0 ? void 0 : data.find((d) => d.series.type === 'scatter');
|
|
34
36
|
const selectedDataItem = selected === null || selected === void 0 ? void 0 : selected.data;
|
|
35
37
|
const selectedSeriesId = (_a = selected === null || selected === void 0 ? void 0 : selected.series) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -58,7 +60,11 @@ export function ScatterSeriesShape(props) {
|
|
|
58
60
|
}
|
|
59
61
|
return d;
|
|
60
62
|
});
|
|
61
|
-
}
|
|
63
|
+
}
|
|
64
|
+
if (hoveredDataRef.current !== null) {
|
|
65
|
+
handleShapeHover(hoveredDataRef.current);
|
|
66
|
+
}
|
|
67
|
+
dispatcher.on('hover-shape.scatter', handleShapeHover);
|
|
62
68
|
return () => {
|
|
63
69
|
dispatcher.on('hover-shape.scatter', null);
|
|
64
70
|
};
|
|
@@ -6,6 +6,7 @@ import { HtmlLayer } from '../HtmlLayer';
|
|
|
6
6
|
const b = block('d3-treemap');
|
|
7
7
|
export const TreemapSeriesShape = (props) => {
|
|
8
8
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = props;
|
|
9
|
+
const hoveredDataRef = React.useRef(null);
|
|
9
10
|
const ref = React.useRef(null);
|
|
10
11
|
React.useEffect(() => {
|
|
11
12
|
if (!ref.current) {
|
|
@@ -48,8 +49,9 @@ export const TreemapSeriesShape = (props) => {
|
|
|
48
49
|
const eventName = `hover-shape.treemap`;
|
|
49
50
|
const hoverOptions = get(seriesOptions, 'treemap.states.hover');
|
|
50
51
|
const inactiveOptions = get(seriesOptions, 'treemap.states.inactive');
|
|
51
|
-
|
|
52
|
+
function handleShapeHover(data) {
|
|
52
53
|
var _a;
|
|
54
|
+
hoveredDataRef.current = data;
|
|
53
55
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
54
56
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
55
57
|
const hoveredData = (_a = data === null || data === void 0 ? void 0 : data[0]) === null || _a === void 0 ? void 0 : _a.data;
|
|
@@ -87,7 +89,11 @@ export const TreemapSeriesShape = (props) => {
|
|
|
87
89
|
});
|
|
88
90
|
return d;
|
|
89
91
|
});
|
|
90
|
-
}
|
|
92
|
+
}
|
|
93
|
+
if (hoveredDataRef.current !== null) {
|
|
94
|
+
handleShapeHover(hoveredDataRef.current);
|
|
95
|
+
}
|
|
96
|
+
dispatcher.on(eventName, handleShapeHover);
|
|
91
97
|
return () => {
|
|
92
98
|
dispatcher.on(eventName, null);
|
|
93
99
|
};
|
|
@@ -17,7 +17,7 @@ export declare function getYValue(args: {
|
|
|
17
17
|
yAxis: PreparedAxis;
|
|
18
18
|
yScale: ChartScale;
|
|
19
19
|
}): number;
|
|
20
|
-
export declare
|
|
20
|
+
export declare function shapeKey(d: unknown): string | -1;
|
|
21
21
|
export declare function setActiveState<T extends {
|
|
22
22
|
active?: boolean;
|
|
23
23
|
}>(args: {
|
|
@@ -26,4 +26,4 @@ export declare function setActiveState<T extends {
|
|
|
26
26
|
state: BasicInactiveState | undefined;
|
|
27
27
|
active: boolean;
|
|
28
28
|
}): T;
|
|
29
|
-
export declare
|
|
29
|
+
export declare function getLineDashArray(dashStyle: DashStyle, strokeWidth?: number): string;
|
|
@@ -23,7 +23,9 @@ export function getYValue(args) {
|
|
|
23
23
|
const yLinearScale = yScale;
|
|
24
24
|
return yLinearScale(point.y);
|
|
25
25
|
}
|
|
26
|
-
export
|
|
26
|
+
export function shapeKey(d) {
|
|
27
|
+
return d.id || -1;
|
|
28
|
+
}
|
|
27
29
|
export function setActiveState(args) {
|
|
28
30
|
const { element, datum, state, active } = args;
|
|
29
31
|
const elementSelection = select(element);
|
|
@@ -34,7 +36,7 @@ export function setActiveState(args) {
|
|
|
34
36
|
}
|
|
35
37
|
return datum;
|
|
36
38
|
}
|
|
37
|
-
export
|
|
39
|
+
export function getLineDashArray(dashStyle, strokeWidth = 2) {
|
|
38
40
|
const value = dashStyle.toLowerCase();
|
|
39
41
|
const arrayValue = value
|
|
40
42
|
.replace('shortdashdotdot', '3,1,1,1,1,1,')
|
|
@@ -50,4 +52,4 @@ export const getLineDashArray = (dashStyle, strokeWidth = 2) => {
|
|
|
50
52
|
return `${parseInt(part, 10) * strokeWidth}`;
|
|
51
53
|
});
|
|
52
54
|
return arrayValue.join(',').replace(/NaN/g, 'none');
|
|
53
|
-
}
|
|
55
|
+
}
|
|
@@ -10,6 +10,7 @@ export * from './types';
|
|
|
10
10
|
const b = block('d3-waterfall');
|
|
11
11
|
export const WaterfallSeriesShapes = (args) => {
|
|
12
12
|
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
13
|
+
const hoveredDataRef = React.useRef(null);
|
|
13
14
|
const ref = React.useRef(null);
|
|
14
15
|
const connectorSelector = `.${b('connector')}`;
|
|
15
16
|
React.useEffect(() => {
|
|
@@ -78,7 +79,8 @@ export const WaterfallSeriesShapes = (args) => {
|
|
|
78
79
|
})
|
|
79
80
|
.attr('stroke-width', 1)
|
|
80
81
|
.attr('stroke-dasharray', () => getLineDashArray(DashStyle.Dash, 1));
|
|
81
|
-
|
|
82
|
+
function handleShapeHover(data) {
|
|
83
|
+
hoveredDataRef.current = data;
|
|
82
84
|
const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
|
|
83
85
|
const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
|
|
84
86
|
if (!data) {
|
|
@@ -116,7 +118,11 @@ export const WaterfallSeriesShapes = (args) => {
|
|
|
116
118
|
: (inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.opacity) || null;
|
|
117
119
|
});
|
|
118
120
|
}
|
|
119
|
-
}
|
|
121
|
+
}
|
|
122
|
+
if (hoveredDataRef.current !== null) {
|
|
123
|
+
handleShapeHover(hoveredDataRef.current);
|
|
124
|
+
}
|
|
125
|
+
dispatcher.on('hover-shape.waterfall', handleShapeHover);
|
|
120
126
|
return () => {
|
|
121
127
|
dispatcher.on('hover-shape.waterfall', null);
|
|
122
128
|
};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { Dispatch } from 'd3';
|
|
2
|
-
import type { TooltipDataChunk } from '../../types';
|
|
2
|
+
import type { PointPosition, TooltipDataChunk } from '../../types';
|
|
3
3
|
import type { PreparedTooltip } from '../useChartOptions/types';
|
|
4
|
-
import type { PointerPosition } from './types';
|
|
5
4
|
type Args = {
|
|
6
5
|
dispatcher: Dispatch<object>;
|
|
7
6
|
tooltip: PreparedTooltip;
|
|
8
7
|
};
|
|
9
8
|
export declare const useTooltip: ({ dispatcher, tooltip }: Args) => {
|
|
10
9
|
hovered: TooltipDataChunk[] | undefined;
|
|
11
|
-
pointerPosition:
|
|
10
|
+
pointerPosition: PointPosition | undefined;
|
|
12
11
|
};
|
|
13
12
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MeaningfulAny } from '../misc';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ChartTooltipRendererArgs } from './tooltip';
|
|
3
3
|
export type ChartMargin = {
|
|
4
4
|
top: number;
|
|
5
5
|
right: number;
|
|
@@ -13,6 +13,6 @@ export type ChartOptions = {
|
|
|
13
13
|
point: MeaningfulAny;
|
|
14
14
|
series: MeaningfulAny;
|
|
15
15
|
}, event: PointerEvent) => void;
|
|
16
|
-
pointermove?: (data:
|
|
16
|
+
pointermove?: (data: ChartTooltipRendererArgs | undefined, event: PointerEvent) => void;
|
|
17
17
|
};
|
|
18
18
|
};
|
|
@@ -16,7 +16,7 @@ export type ChartSeriesData<T = MeaningfulAny> = ScatterSeriesData<T> | PieSerie
|
|
|
16
16
|
export type DataLabelRendererData<T = MeaningfulAny> = {
|
|
17
17
|
data: ChartSeriesData<T>;
|
|
18
18
|
};
|
|
19
|
-
type BasicHoverState = {
|
|
19
|
+
export type BasicHoverState = {
|
|
20
20
|
/**
|
|
21
21
|
* Enable separate styles for the hovered series.
|
|
22
22
|
*
|
|
@@ -223,4 +223,3 @@ export type ChartSeriesOptions = {
|
|
|
223
223
|
};
|
|
224
224
|
};
|
|
225
225
|
};
|
|
226
|
-
export {};
|
|
@@ -59,7 +59,7 @@ export type TooltipDataChunkWaterfall<T = MeaningfulAny> = {
|
|
|
59
59
|
export type TooltipDataChunk<T = MeaningfulAny> = (TooltipDataChunkBarX<T> | TooltipDataChunkBarY<T> | TooltipDataChunkPie<T> | TooltipDataChunkScatter<T> | TooltipDataChunkLine<T> | TooltipDataChunkArea<T> | TooltipDataChunkTreemap<T> | TooltipDataChunkWaterfall<T>) & {
|
|
60
60
|
closest?: boolean;
|
|
61
61
|
};
|
|
62
|
-
export type
|
|
62
|
+
export type ChartTooltipRendererArgs<T = MeaningfulAny> = {
|
|
63
63
|
hovered: TooltipDataChunk<T>[];
|
|
64
64
|
xAxis?: ChartXAxis;
|
|
65
65
|
yAxis?: ChartYAxis;
|
|
@@ -67,9 +67,9 @@ export type ChartTooltipRendererData<T = MeaningfulAny> = {
|
|
|
67
67
|
export type ChartTooltip<T = MeaningfulAny> = {
|
|
68
68
|
enabled?: boolean;
|
|
69
69
|
/** Specifies the renderer for the tooltip. If returned null default tooltip renderer will be used. */
|
|
70
|
-
renderer?: (args:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
70
|
+
renderer?: (args: ChartTooltipRendererArgs<T>) => React.ReactElement | null;
|
|
71
|
+
pin?: {
|
|
72
|
+
enabled?: boolean;
|
|
73
|
+
modifierKey?: 'altKey' | 'metaKey';
|
|
74
|
+
};
|
|
75
75
|
};
|
package/dist/cjs/types/misc.d.ts
CHANGED
package/dist/cjs/utils/misc.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
export declare
|
|
1
|
+
export declare function randomString(length: number, chars: string): string;
|
|
2
|
+
export declare function getUniqId(): string;
|
|
3
|
+
/**
|
|
4
|
+
* Checks Macintosh hardware is used.
|
|
5
|
+
*
|
|
6
|
+
* Note: there is no better way to get this information as using depricated property `navigator.platform`.
|
|
7
|
+
*
|
|
8
|
+
* More details [here](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#examples).
|
|
9
|
+
*/
|
|
10
|
+
export declare function isMacintosh(): boolean;
|
package/dist/cjs/utils/misc.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
export
|
|
1
|
+
export function randomString(length, chars) {
|
|
2
2
|
let result = '';
|
|
3
3
|
for (let i = length; i > 0; --i) {
|
|
4
4
|
result += chars[Math.floor(Math.random() * chars.length)];
|
|
5
5
|
}
|
|
6
6
|
return result;
|
|
7
|
-
}
|
|
8
|
-
export
|
|
7
|
+
}
|
|
8
|
+
export function getUniqId() {
|
|
9
|
+
return `gravity-chart.${randomString(5, '0123456789abcdefghijklmnopqrstuvwxyz')}`;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Checks Macintosh hardware is used.
|
|
13
|
+
*
|
|
14
|
+
* Note: there is no better way to get this information as using depricated property `navigator.platform`.
|
|
15
|
+
*
|
|
16
|
+
* More details [here](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#examples).
|
|
17
|
+
*/
|
|
18
|
+
export function isMacintosh() {
|
|
19
|
+
return typeof navigator === 'undefined' ? false : /Mac|iP(hone|[oa]d)/.test(navigator.platform);
|
|
20
|
+
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ChartInnerProps } from './types';
|
|
3
3
|
import './styles.css';
|
|
4
|
-
|
|
5
|
-
width: number;
|
|
6
|
-
height: number;
|
|
7
|
-
data: ChartData;
|
|
8
|
-
};
|
|
9
|
-
export declare const ChartInner: (props: Props) => React.JSX.Element;
|
|
10
|
-
export {};
|
|
4
|
+
export declare const ChartInner: (props: ChartInnerProps) => React.JSX.Element;
|
|
@@ -1,77 +1,39 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { pointer } from 'd3';
|
|
3
|
-
import throttle from 'lodash/throttle';
|
|
4
|
-
import { IS_TOUCH_ENABLED } from '../../constants';
|
|
5
|
-
import { useAxisScales, useChartDimensions, useChartOptions, useSeries, useShapes, } from '../../hooks';
|
|
6
|
-
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
7
|
-
import { getPreparedXAxis } from '../../hooks/useChartOptions/x-axis';
|
|
8
|
-
import { getPreparedYAxis } from '../../hooks/useChartOptions/y-axis';
|
|
9
|
-
import { useSplit } from '../../hooks/useSplit';
|
|
10
2
|
import { EventType, block, getD3Dispatcher } from '../../utils';
|
|
11
|
-
import { getClosestPoints } from '../../utils/chart/get-closest-data';
|
|
12
3
|
import { AxisX, AxisY } from '../Axis';
|
|
13
4
|
import { Legend } from '../Legend';
|
|
14
5
|
import { PlotTitle } from '../PlotTitle';
|
|
15
6
|
import { Title } from '../Title';
|
|
16
7
|
import { Tooltip } from '../Tooltip';
|
|
8
|
+
import { useChartInnerHandlers } from './useChartInnerHandlers';
|
|
9
|
+
import { useChartInnerProps } from './useChartInnerProps';
|
|
10
|
+
import { useChartInnerState } from './useChartInnerState';
|
|
17
11
|
import './styles.css';
|
|
18
12
|
const b = block('d3');
|
|
19
|
-
const THROTTLE_DELAY = 50;
|
|
20
13
|
export const ChartInner = (props) => {
|
|
21
14
|
var _a, _b, _c, _d;
|
|
22
15
|
const { width, height, data } = props;
|
|
23
16
|
const svgRef = React.useRef(null);
|
|
24
17
|
const htmlLayerRef = React.useRef(null);
|
|
25
|
-
const dispatcher = React.useMemo(() =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
const xAxis = React.useMemo(() => getPreparedXAxis({ xAxis: data.xAxis, width, series: data.series.data }), [data, width]);
|
|
32
|
-
const yAxis = React.useMemo(() => getPreparedYAxis({
|
|
33
|
-
series: data.series.data,
|
|
34
|
-
yAxis: data.yAxis,
|
|
35
|
-
height,
|
|
36
|
-
}), [data, height]);
|
|
37
|
-
const { legendItems, legendConfig, preparedSeries, preparedSeriesOptions, preparedLegend, handleLegendItemClick, } = useSeries({
|
|
38
|
-
chartWidth: width,
|
|
39
|
-
chartHeight: height,
|
|
40
|
-
chartMargin: chart.margin,
|
|
41
|
-
series: data.series,
|
|
42
|
-
legend: data.legend,
|
|
43
|
-
preparedYAxis: yAxis,
|
|
44
|
-
});
|
|
45
|
-
const { boundsWidth, boundsHeight } = useChartDimensions({
|
|
46
|
-
width,
|
|
47
|
-
height,
|
|
48
|
-
margin: chart.margin,
|
|
49
|
-
preparedLegend,
|
|
50
|
-
preparedXAxis: xAxis,
|
|
51
|
-
preparedYAxis: yAxis,
|
|
52
|
-
preparedSeries: preparedSeries,
|
|
18
|
+
const dispatcher = React.useMemo(() => getD3Dispatcher(), []);
|
|
19
|
+
const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, legendConfig, legendItems, preparedSeries, preparedSplit, preparedLegend, prevHeight, prevWidth, shapes, shapesData, title, tooltip, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { dispatcher, htmlLayout: htmlLayerRef.current }));
|
|
20
|
+
const { tooltipPinned, togglePinTooltip, unpinTooltip } = useChartInnerState({
|
|
21
|
+
dispatcher,
|
|
22
|
+
tooltip,
|
|
53
23
|
});
|
|
54
|
-
const
|
|
55
|
-
const { xScale, yScale } = useAxisScales({
|
|
56
|
-
boundsWidth,
|
|
24
|
+
const { handleChartClick, handleMouseLeave, throttledHandleMouseMove, throttledHandleTouchMove } = useChartInnerHandlers({
|
|
57
25
|
boundsHeight,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
yAxis,
|
|
61
|
-
split: preparedSplit,
|
|
62
|
-
});
|
|
63
|
-
const { shapes, shapesData } = useShapes({
|
|
26
|
+
boundsOffsetLeft,
|
|
27
|
+
boundsOffsetTop,
|
|
64
28
|
boundsWidth,
|
|
65
|
-
boundsHeight,
|
|
66
29
|
dispatcher,
|
|
67
|
-
|
|
68
|
-
|
|
30
|
+
shapesData,
|
|
31
|
+
svgContainer: svgRef.current,
|
|
32
|
+
togglePinTooltip,
|
|
33
|
+
tooltipPinned,
|
|
34
|
+
unpinTooltip,
|
|
69
35
|
xAxis,
|
|
70
|
-
xScale,
|
|
71
36
|
yAxis,
|
|
72
|
-
yScale,
|
|
73
|
-
split: preparedSplit,
|
|
74
|
-
htmlLayout: htmlLayerRef.current,
|
|
75
37
|
});
|
|
76
38
|
const clickHandler = (_b = (_a = data.chart) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.click;
|
|
77
39
|
const pointerMoveHandler = (_d = (_c = data.chart) === null || _c === void 0 ? void 0 : _c.events) === null || _d === void 0 ? void 0 : _d.pointermove;
|
|
@@ -90,68 +52,11 @@ export const ChartInner = (props) => {
|
|
|
90
52
|
dispatcher.on(EventType.POINTERMOVE_CHART, null);
|
|
91
53
|
};
|
|
92
54
|
}, [dispatcher, clickHandler, pointerMoveHandler]);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const isOutsideBounds = React.useCallback((x, y) => {
|
|
97
|
-
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
98
|
-
}, [boundsHeight, boundsWidth]);
|
|
99
|
-
const handleMove = ([pointerX, pointerY], event) => {
|
|
100
|
-
const x = pointerX - boundsOffsetLeft;
|
|
101
|
-
const y = pointerY - boundsOffsetTop;
|
|
102
|
-
if (isOutsideBounds(x, y)) {
|
|
103
|
-
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
104
|
-
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const closest = getClosestPoints({
|
|
108
|
-
position: [x, y],
|
|
109
|
-
shapesData,
|
|
110
|
-
});
|
|
111
|
-
dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY]);
|
|
112
|
-
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
113
|
-
hovered: closest,
|
|
114
|
-
xAxis,
|
|
115
|
-
yAxis: yAxis[0],
|
|
116
|
-
}, event);
|
|
117
|
-
};
|
|
118
|
-
const handleMouseMove = (event) => {
|
|
119
|
-
const [pointerX, pointerY] = pointer(event, svgRef.current);
|
|
120
|
-
handleMove([pointerX, pointerY], event);
|
|
121
|
-
};
|
|
122
|
-
const throttledHandleMouseMove = IS_TOUCH_ENABLED
|
|
123
|
-
? undefined
|
|
124
|
-
: throttle(handleMouseMove, THROTTLE_DELAY);
|
|
125
|
-
const handleMouseLeave = (event) => {
|
|
126
|
-
throttledHandleMouseMove === null || throttledHandleMouseMove === void 0 ? void 0 : throttledHandleMouseMove.cancel();
|
|
127
|
-
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
128
|
-
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
129
|
-
};
|
|
130
|
-
const handleTouchMove = (event) => {
|
|
131
|
-
const touch = event.touches[0];
|
|
132
|
-
const [pointerX, pointerY] = pointer(touch, svgRef.current);
|
|
133
|
-
handleMove([pointerX, pointerY], event);
|
|
134
|
-
};
|
|
135
|
-
const throttledHandleTouchMove = IS_TOUCH_ENABLED
|
|
136
|
-
? throttle(handleTouchMove, THROTTLE_DELAY)
|
|
137
|
-
: undefined;
|
|
138
|
-
const handleChartClick = React.useCallback((event) => {
|
|
139
|
-
const [pointerX, pointerY] = pointer(event, svgRef.current);
|
|
140
|
-
const x = pointerX - boundsOffsetLeft;
|
|
141
|
-
const y = pointerY - boundsOffsetTop;
|
|
142
|
-
if (isOutsideBounds(x, y)) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
const items = getClosestPoints({
|
|
146
|
-
position: [x, y],
|
|
147
|
-
shapesData,
|
|
148
|
-
});
|
|
149
|
-
const selected = items === null || items === void 0 ? void 0 : items.find((item) => item.closest);
|
|
150
|
-
if (!selected) {
|
|
151
|
-
return;
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
if ((prevWidth !== width || prevHeight !== height) && tooltipPinned) {
|
|
57
|
+
unpinTooltip === null || unpinTooltip === void 0 ? void 0 : unpinTooltip();
|
|
152
58
|
}
|
|
153
|
-
|
|
154
|
-
}, [boundsOffsetLeft, boundsOffsetTop, dispatcher, isOutsideBounds, shapesData]);
|
|
59
|
+
}, [prevWidth, width, prevHeight, height, tooltipPinned, unpinTooltip]);
|
|
155
60
|
return (React.createElement(React.Fragment, null,
|
|
156
61
|
React.createElement("svg", { ref: svgRef, className: b(), width: width, height: height, onMouseMove: throttledHandleMouseMove, onMouseLeave: handleMouseLeave, onTouchStart: throttledHandleTouchMove, onTouchMove: throttledHandleTouchMove, onClick: handleChartClick },
|
|
157
62
|
title && React.createElement(Title, Object.assign({}, title, { chartWidth: width })),
|
|
@@ -164,9 +69,9 @@ export const ChartInner = (props) => {
|
|
|
164
69
|
React.createElement("g", { transform: `translate(0, ${boundsHeight})` },
|
|
165
70
|
React.createElement(AxisX, { axis: xAxis, width: boundsWidth, height: boundsHeight, scale: xScale, split: preparedSplit })))),
|
|
166
71
|
shapes),
|
|
167
|
-
preparedLegend.enabled && (React.createElement(Legend, { chartSeries: preparedSeries, boundsWidth: boundsWidth, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick }))),
|
|
72
|
+
preparedLegend.enabled && (React.createElement(Legend, { chartSeries: preparedSeries, boundsWidth: boundsWidth, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick, onUpdate: unpinTooltip }))),
|
|
168
73
|
React.createElement("div", { className: b('html-layer'), ref: htmlLayerRef, style: {
|
|
169
74
|
transform: `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
170
75
|
} }),
|
|
171
|
-
React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: tooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0] })));
|
|
76
|
+
React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: tooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0], onOutsideClick: unpinTooltip, tooltipPinned: tooltipPinned })));
|
|
172
77
|
};
|