@gravity-ui/charts 0.5.0 → 0.6.1-beta.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/README.md +2 -2
- package/dist/cjs/components/Axis/AxisY.d.ts +1 -0
- package/dist/cjs/components/Axis/AxisY.js +55 -13
- package/dist/cjs/components/ChartInner/index.d.ts +2 -8
- package/dist/cjs/components/ChartInner/index.js +25 -119
- 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 +98 -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 +4 -4
- package/dist/cjs/components/PlotTitle/index.js +1 -1
- package/dist/cjs/components/PlotTitle/styles.css +1 -1
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +2 -2
- package/dist/cjs/components/Tooltip/DefaultContent.js +19 -3
- package/dist/cjs/components/Tooltip/index.d.ts +2 -0
- package/dist/cjs/components/Tooltip/index.js +10 -4
- package/dist/cjs/components/Tooltip/styles.css +13 -8
- package/dist/cjs/components/index.d.ts +10 -9
- package/dist/cjs/constants/index.d.ts +1 -0
- package/dist/cjs/constants/index.js +1 -0
- package/dist/cjs/hooks/index.d.ts +2 -1
- package/dist/cjs/hooks/index.js +2 -1
- package/dist/cjs/hooks/useChartOptions/types.d.ts +11 -1
- package/dist/cjs/hooks/useChartOptions/x-axis.js +1 -0
- package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -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-area.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-x.d.ts +2 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-x.js +2 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-y.js +3 -1
- package/dist/cjs/hooks/useSeries/prepare-line.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-pie.js +2 -2
- package/dist/cjs/hooks/useSeries/prepare-sankey.d.ts +11 -0
- package/dist/cjs/hooks/useSeries/prepare-sankey.js +38 -0
- package/dist/cjs/hooks/useSeries/prepareSeries.js +21 -2
- package/dist/cjs/hooks/useSeries/types.d.ts +12 -2
- package/dist/cjs/hooks/useSeries/utils.js +1 -1
- package/dist/cjs/hooks/useShapes/area/index.js +8 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +4 -0
- package/dist/cjs/hooks/useShapes/bar-x/index.js +24 -4
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +3 -1
- package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-y/index.js +24 -4
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +3 -1
- package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
- package/dist/cjs/hooks/useShapes/index.js +19 -0
- package/dist/cjs/hooks/useShapes/line/index.js +10 -4
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/pie/index.js +5 -4
- package/dist/cjs/hooks/useShapes/pie/prepare-data.js +168 -118
- package/dist/cjs/hooks/useShapes/pie/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/sankey/index.d.ts +12 -0
- package/dist/cjs/hooks/useShapes/sankey/index.js +67 -0
- package/dist/cjs/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
- package/dist/cjs/hooks/useShapes/sankey/prepare-data.js +72 -0
- package/dist/cjs/hooks/useShapes/sankey/types.d.ts +33 -0
- package/dist/cjs/hooks/useShapes/scatter/index.js +8 -2
- package/dist/cjs/hooks/useShapes/styles.css +2 -2
- package/dist/cjs/hooks/useShapes/treemap/index.js +8 -2
- package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/utils.d.ts +8 -3
- package/dist/cjs/hooks/useShapes/utils.js +26 -19
- package/dist/cjs/hooks/useShapes/waterfall/index.js +9 -4
- package/dist/cjs/hooks/useTooltip/index.d.ts +2 -3
- package/dist/cjs/types/chart/area.d.ts +6 -6
- package/dist/cjs/types/chart/axis.d.ts +32 -7
- package/dist/cjs/types/chart/bar-x.d.ts +9 -4
- package/dist/cjs/types/chart/bar-y.d.ts +10 -6
- package/dist/cjs/types/chart/base.d.ts +6 -6
- package/dist/cjs/types/chart/chart.d.ts +6 -6
- package/dist/cjs/types/chart/halo.d.ts +2 -2
- package/dist/cjs/types/chart/legend.d.ts +10 -10
- package/dist/cjs/types/chart/line.d.ts +4 -4
- package/dist/cjs/types/chart/marker.d.ts +2 -2
- package/dist/cjs/types/chart/pie.d.ts +6 -4
- package/dist/cjs/types/chart/sankey.d.ts +22 -0
- package/dist/cjs/types/chart/sankey.js +1 -0
- package/dist/cjs/types/chart/scatter.d.ts +4 -4
- package/dist/cjs/types/chart/series.d.ts +21 -11
- package/dist/cjs/types/chart/split.d.ts +4 -4
- package/dist/cjs/types/chart/title.d.ts +2 -2
- package/dist/cjs/types/chart/tooltip.d.ts +32 -26
- package/dist/cjs/types/chart/treemap.d.ts +4 -4
- package/dist/cjs/types/chart/waterfall.d.ts +4 -4
- package/dist/cjs/types/chart-ui.d.ts +10 -6
- package/dist/cjs/types/formatter.d.ts +4 -4
- package/dist/cjs/types/index.d.ts +35 -4
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/types/misc.d.ts +1 -0
- package/dist/cjs/utils/chart/get-closest-data.d.ts +2 -0
- package/dist/cjs/utils/chart/get-closest-data.js +39 -3
- package/dist/cjs/utils/chart/index.js +1 -1
- package/dist/cjs/utils/chart/series/index.d.ts +1 -0
- package/dist/cjs/utils/chart/series/index.js +1 -0
- package/dist/cjs/utils/chart/series/line.d.ts +2 -0
- package/dist/cjs/utils/chart/series/line.js +17 -0
- package/dist/cjs/utils/misc.d.ts +10 -2
- package/dist/cjs/utils/misc.js +15 -3
- package/dist/esm/components/Axis/AxisY.d.ts +1 -0
- package/dist/esm/components/Axis/AxisY.js +55 -13
- package/dist/esm/components/ChartInner/index.d.ts +2 -8
- package/dist/esm/components/ChartInner/index.js +25 -119
- package/dist/esm/components/ChartInner/types.d.ts +6 -0
- package/dist/esm/components/ChartInner/types.js +1 -0
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +26 -0
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +98 -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 +4 -4
- package/dist/esm/components/PlotTitle/index.js +1 -1
- package/dist/esm/components/PlotTitle/styles.css +1 -1
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +2 -2
- package/dist/esm/components/Tooltip/DefaultContent.js +19 -3
- package/dist/esm/components/Tooltip/index.d.ts +2 -0
- package/dist/esm/components/Tooltip/index.js +10 -4
- package/dist/esm/components/Tooltip/styles.css +13 -8
- package/dist/esm/components/index.d.ts +10 -9
- package/dist/esm/constants/index.d.ts +1 -0
- package/dist/esm/constants/index.js +1 -0
- package/dist/esm/hooks/index.d.ts +2 -1
- package/dist/esm/hooks/index.js +2 -1
- package/dist/esm/hooks/useChartOptions/types.d.ts +11 -1
- package/dist/esm/hooks/useChartOptions/x-axis.js +1 -0
- package/dist/esm/hooks/useChartOptions/y-axis.js +9 -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-area.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-bar-x.d.ts +2 -1
- package/dist/esm/hooks/useSeries/prepare-bar-x.js +2 -1
- package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +2 -1
- package/dist/esm/hooks/useSeries/prepare-bar-y.js +3 -1
- package/dist/esm/hooks/useSeries/prepare-line.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-pie.js +2 -2
- package/dist/esm/hooks/useSeries/prepare-sankey.d.ts +11 -0
- package/dist/esm/hooks/useSeries/prepare-sankey.js +38 -0
- package/dist/esm/hooks/useSeries/prepareSeries.js +21 -2
- package/dist/esm/hooks/useSeries/types.d.ts +12 -2
- package/dist/esm/hooks/useSeries/utils.js +1 -1
- package/dist/esm/hooks/useShapes/area/index.js +8 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.js +4 -0
- package/dist/esm/hooks/useShapes/bar-x/index.js +24 -4
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +3 -1
- package/dist/esm/hooks/useShapes/bar-x/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-y/index.js +24 -4
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +3 -1
- package/dist/esm/hooks/useShapes/bar-y/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/index.d.ts +2 -1
- package/dist/esm/hooks/useShapes/index.js +19 -0
- package/dist/esm/hooks/useShapes/line/index.js +10 -4
- package/dist/esm/hooks/useShapes/line/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/pie/index.js +5 -4
- package/dist/esm/hooks/useShapes/pie/prepare-data.js +168 -118
- package/dist/esm/hooks/useShapes/pie/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/sankey/index.d.ts +12 -0
- package/dist/esm/hooks/useShapes/sankey/index.js +67 -0
- package/dist/esm/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
- package/dist/esm/hooks/useShapes/sankey/prepare-data.js +72 -0
- package/dist/esm/hooks/useShapes/sankey/types.d.ts +33 -0
- package/dist/esm/hooks/useShapes/sankey/types.js +1 -0
- package/dist/esm/hooks/useShapes/scatter/index.js +8 -2
- package/dist/esm/hooks/useShapes/styles.css +2 -2
- package/dist/esm/hooks/useShapes/treemap/index.js +8 -2
- package/dist/esm/hooks/useShapes/treemap/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/utils.d.ts +8 -3
- package/dist/esm/hooks/useShapes/utils.js +26 -19
- package/dist/esm/hooks/useShapes/waterfall/index.js +9 -4
- package/dist/esm/hooks/useTooltip/index.d.ts +2 -3
- package/dist/esm/types/chart/area.d.ts +6 -6
- package/dist/esm/types/chart/axis.d.ts +32 -7
- package/dist/esm/types/chart/bar-x.d.ts +9 -4
- package/dist/esm/types/chart/bar-y.d.ts +10 -6
- package/dist/esm/types/chart/base.d.ts +6 -6
- package/dist/esm/types/chart/chart.d.ts +6 -6
- package/dist/esm/types/chart/halo.d.ts +2 -2
- package/dist/esm/types/chart/legend.d.ts +10 -10
- package/dist/esm/types/chart/line.d.ts +4 -4
- package/dist/esm/types/chart/marker.d.ts +2 -2
- package/dist/esm/types/chart/pie.d.ts +6 -4
- package/dist/esm/types/chart/sankey.d.ts +22 -0
- package/dist/esm/types/chart/sankey.js +1 -0
- package/dist/esm/types/chart/scatter.d.ts +4 -4
- package/dist/esm/types/chart/series.d.ts +21 -11
- package/dist/esm/types/chart/split.d.ts +4 -4
- package/dist/esm/types/chart/title.d.ts +2 -2
- package/dist/esm/types/chart/tooltip.d.ts +32 -26
- package/dist/esm/types/chart/treemap.d.ts +4 -4
- package/dist/esm/types/chart/waterfall.d.ts +4 -4
- package/dist/esm/types/chart-ui.d.ts +10 -6
- package/dist/esm/types/formatter.d.ts +4 -4
- package/dist/esm/types/index.d.ts +35 -4
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/misc.d.ts +1 -0
- package/dist/esm/utils/chart/get-closest-data.d.ts +2 -0
- package/dist/esm/utils/chart/get-closest-data.js +39 -3
- package/dist/esm/utils/chart/index.js +1 -1
- package/dist/esm/utils/chart/series/index.d.ts +1 -0
- package/dist/esm/utils/chart/series/index.js +1 -0
- package/dist/esm/utils/chart/series/line.d.ts +2 -0
- package/dist/esm/utils/chart/series/line.js +17 -0
- package/dist/esm/utils/misc.d.ts +10 -2
- package/dist/esm/utils/misc.js +15 -3
- package/package.json +7 -2
- 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 → cjs/hooks/useShapes/sankey}/types.js +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Gravity Charts · [](https://www.npmjs.com/package/@gravity-ui/charts) [](https://github.com/gravity-ui/charts/actions/workflows/ci.yml?query=branch:main) [](https://preview.gravity-ui.com/charts/)
|
|
2
2
|
|
|
3
3
|
> [!WARNING]
|
|
4
4
|
> The library may have major changes in minor releases while it is on version `0.*.*`.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
8
8
|
```shell
|
|
9
|
-
npm install
|
|
9
|
+
npm install @gravity-ui/uikit @gravity-ui/charts
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
## Development
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { axisLeft, axisRight, line, select } from 'd3';
|
|
3
|
-
import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisTitleRows, getClosestPointsRange, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
|
|
3
|
+
import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisTitleRows, getClosestPointsRange, getLineDashArray, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
|
|
4
4
|
import './styles.css';
|
|
5
5
|
const b = block('d3-axis');
|
|
6
6
|
function transformLabel(args) {
|
|
@@ -79,7 +79,7 @@ function getTitlePosition(args) {
|
|
|
79
79
|
return { x, y };
|
|
80
80
|
}
|
|
81
81
|
export const AxisY = (props) => {
|
|
82
|
-
const { axes, width, height: totalHeight, scale, split } = props;
|
|
82
|
+
const { axes, width, height: totalHeight, scale, split, plotRef } = props;
|
|
83
83
|
const height = getAxisHeight({ split, boundsHeight: totalHeight });
|
|
84
84
|
const ref = React.useRef(null);
|
|
85
85
|
React.useEffect(() => {
|
|
@@ -88,26 +88,34 @@ export const AxisY = (props) => {
|
|
|
88
88
|
}
|
|
89
89
|
const svgElement = select(ref.current);
|
|
90
90
|
svgElement.selectAll('*').remove();
|
|
91
|
+
const getAxisPosition = (axis) => {
|
|
92
|
+
var _a;
|
|
93
|
+
const top = ((_a = split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
94
|
+
if (axis.position === 'left') {
|
|
95
|
+
return `translate(0, ${top}px)`;
|
|
96
|
+
}
|
|
97
|
+
return `translate(${width}px, 0)`;
|
|
98
|
+
};
|
|
99
|
+
const plotLines = axes.reduce((acc, axis) => {
|
|
100
|
+
if (axis.plotLines.length) {
|
|
101
|
+
acc.push(...axis.plotLines.map((plotLine) => {
|
|
102
|
+
return Object.assign(Object.assign({}, plotLine), { transform: getAxisPosition(axis) });
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
return acc;
|
|
106
|
+
}, []);
|
|
91
107
|
const axisSelection = svgElement
|
|
92
108
|
.selectAll('axis')
|
|
93
109
|
.data(axes)
|
|
94
110
|
.join('g')
|
|
95
111
|
.attr('class', b())
|
|
96
|
-
.style('transform', (d) =>
|
|
97
|
-
var _a;
|
|
98
|
-
const top = ((_a = split.plots[d.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
99
|
-
if (d.position === 'left') {
|
|
100
|
-
return `translate(0, ${top}px)`;
|
|
101
|
-
}
|
|
102
|
-
return `translate(${width}px, 0)`;
|
|
103
|
-
});
|
|
112
|
+
.style('transform', (d) => getAxisPosition(d));
|
|
104
113
|
axisSelection.each((d, index, node) => {
|
|
105
114
|
const seriesScale = scale[index];
|
|
106
115
|
const axisItem = select(node[index]);
|
|
116
|
+
const axisScale = seriesScale;
|
|
107
117
|
const yAxisGenerator = getAxisGenerator({
|
|
108
|
-
axisGenerator: d.position === 'left'
|
|
109
|
-
? axisLeft(seriesScale)
|
|
110
|
-
: axisRight(seriesScale),
|
|
118
|
+
axisGenerator: d.position === 'left' ? axisLeft(axisScale) : axisRight(axisScale),
|
|
111
119
|
preparedAxis: d,
|
|
112
120
|
height,
|
|
113
121
|
width,
|
|
@@ -148,6 +156,40 @@ export const AxisY = (props) => {
|
|
|
148
156
|
})
|
|
149
157
|
.remove();
|
|
150
158
|
}
|
|
159
|
+
if (plotRef && d.plotLines.length > 0) {
|
|
160
|
+
const plotLineClassName = b('plotLine');
|
|
161
|
+
const plotLineContainer = select(plotRef.current);
|
|
162
|
+
plotLineContainer.selectAll(`.${plotLineClassName}`).remove();
|
|
163
|
+
const plotLinesSelection = plotLineContainer
|
|
164
|
+
.selectAll(`.${plotLineClassName}`)
|
|
165
|
+
.data(plotLines)
|
|
166
|
+
.join('g')
|
|
167
|
+
.attr('class', plotLineClassName)
|
|
168
|
+
.style('transform', (plotLine) => plotLine.transform);
|
|
169
|
+
plotLinesSelection
|
|
170
|
+
.append('path')
|
|
171
|
+
.attr('d', (plotLine) => {
|
|
172
|
+
const plotLineValue = Number(axisScale(plotLine.value));
|
|
173
|
+
const points = [
|
|
174
|
+
[0, plotLineValue],
|
|
175
|
+
[width, plotLineValue],
|
|
176
|
+
];
|
|
177
|
+
return line()(points);
|
|
178
|
+
})
|
|
179
|
+
.attr('stroke', (plotLine) => plotLine.color)
|
|
180
|
+
.attr('stroke-width', (plotLine) => plotLine.width)
|
|
181
|
+
.attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
|
|
182
|
+
.attr('opacity', (plotLine) => plotLine.opacity);
|
|
183
|
+
plotLinesSelection.each((plotLineData, i, nodes) => {
|
|
184
|
+
const plotLineSelection = select(nodes[i]);
|
|
185
|
+
if (plotLineData.layerPlacement === 'before') {
|
|
186
|
+
plotLineSelection.lower();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
plotLineSelection.raise();
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
151
193
|
return axisItem;
|
|
152
194
|
});
|
|
153
195
|
axisSelection
|
|
@@ -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,40 @@
|
|
|
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
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
const {
|
|
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 plotRef = React.useRef(null);
|
|
19
|
+
const dispatcher = React.useMemo(() => getD3Dispatcher(), []);
|
|
20
|
+
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 }));
|
|
21
|
+
const { tooltipPinned, togglePinTooltip, unpinTooltip } = useChartInnerState({
|
|
22
|
+
dispatcher,
|
|
23
|
+
tooltip,
|
|
53
24
|
});
|
|
54
|
-
const
|
|
55
|
-
const { xScale, yScale } = useAxisScales({
|
|
56
|
-
boundsWidth,
|
|
25
|
+
const { handleChartClick, handleMouseLeave, throttledHandleMouseMove, throttledHandleTouchMove } = useChartInnerHandlers({
|
|
57
26
|
boundsHeight,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
yAxis,
|
|
61
|
-
split: preparedSplit,
|
|
62
|
-
});
|
|
63
|
-
const { shapes, shapesData } = useShapes({
|
|
27
|
+
boundsOffsetLeft,
|
|
28
|
+
boundsOffsetTop,
|
|
64
29
|
boundsWidth,
|
|
65
|
-
boundsHeight,
|
|
66
30
|
dispatcher,
|
|
67
|
-
|
|
68
|
-
|
|
31
|
+
shapesData,
|
|
32
|
+
svgContainer: svgRef.current,
|
|
33
|
+
togglePinTooltip,
|
|
34
|
+
tooltipPinned,
|
|
35
|
+
unpinTooltip,
|
|
69
36
|
xAxis,
|
|
70
|
-
xScale,
|
|
71
37
|
yAxis,
|
|
72
|
-
yScale,
|
|
73
|
-
split: preparedSplit,
|
|
74
|
-
htmlLayout: htmlLayerRef.current,
|
|
75
38
|
});
|
|
76
39
|
const clickHandler = (_b = (_a = data.chart) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.click;
|
|
77
40
|
const pointerMoveHandler = (_d = (_c = data.chart) === null || _c === void 0 ? void 0 : _c.events) === null || _d === void 0 ? void 0 : _d.pointermove;
|
|
@@ -90,83 +53,26 @@ export const ChartInner = (props) => {
|
|
|
90
53
|
dispatcher.on(EventType.POINTERMOVE_CHART, null);
|
|
91
54
|
};
|
|
92
55
|
}, [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;
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
if ((prevWidth !== width || prevHeight !== height) && tooltipPinned) {
|
|
58
|
+
unpinTooltip === null || unpinTooltip === void 0 ? void 0 : unpinTooltip();
|
|
152
59
|
}
|
|
153
|
-
|
|
154
|
-
}, [boundsOffsetLeft, boundsOffsetTop, dispatcher, isOutsideBounds, shapesData]);
|
|
60
|
+
}, [prevWidth, width, prevHeight, height, tooltipPinned, unpinTooltip]);
|
|
155
61
|
return (React.createElement(React.Fragment, null,
|
|
156
62
|
React.createElement("svg", { ref: svgRef, className: b(), width: width, height: height, onMouseMove: throttledHandleMouseMove, onMouseLeave: handleMouseLeave, onTouchStart: throttledHandleTouchMove, onTouchMove: throttledHandleTouchMove, onClick: handleChartClick },
|
|
157
63
|
title && React.createElement(Title, Object.assign({}, title, { chartWidth: width })),
|
|
158
64
|
React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit.plots.map((plot, index) => {
|
|
159
65
|
return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
|
|
160
66
|
})),
|
|
161
|
-
React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})
|
|
67
|
+
React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})`, ref: plotRef },
|
|
162
68
|
xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length) && (React.createElement(React.Fragment, null,
|
|
163
|
-
React.createElement(AxisY, { axes: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale, split: preparedSplit }),
|
|
69
|
+
React.createElement(AxisY, { axes: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale, split: preparedSplit, plotRef: plotRef }),
|
|
164
70
|
React.createElement("g", { transform: `translate(0, ${boundsHeight})` },
|
|
165
71
|
React.createElement(AxisX, { axis: xAxis, width: boundsWidth, height: boundsHeight, scale: xScale, split: preparedSplit })))),
|
|
166
72
|
shapes),
|
|
167
|
-
preparedLegend.enabled && (React.createElement(Legend, { chartSeries: preparedSeries, boundsWidth: boundsWidth, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick }))),
|
|
73
|
+
preparedLegend.enabled && (React.createElement(Legend, { chartSeries: preparedSeries, boundsWidth: boundsWidth, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick, onUpdate: unpinTooltip }))),
|
|
168
74
|
React.createElement("div", { className: b('html-layer'), ref: htmlLayerRef, style: {
|
|
169
75
|
transform: `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
170
76
|
} }),
|
|
171
|
-
React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: tooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0] })));
|
|
77
|
+
React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: tooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0], onOutsideClick: unpinTooltip, tooltipPinned: tooltipPinned })));
|
|
172
78
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3';
|
|
3
|
+
import type { PreparedAxis, ShapeData } from '../../hooks';
|
|
4
|
+
import type { useChartInnerState } from './useChartInnerState';
|
|
5
|
+
type ChartInnerState = ReturnType<typeof useChartInnerState>;
|
|
6
|
+
type Props = {
|
|
7
|
+
boundsHeight: number;
|
|
8
|
+
boundsOffsetLeft: number;
|
|
9
|
+
boundsOffsetTop: number;
|
|
10
|
+
boundsWidth: number;
|
|
11
|
+
dispatcher: Dispatch<object>;
|
|
12
|
+
shapesData: ShapeData[];
|
|
13
|
+
svgContainer: SVGSVGElement | null;
|
|
14
|
+
togglePinTooltip: ChartInnerState['togglePinTooltip'];
|
|
15
|
+
tooltipPinned: boolean;
|
|
16
|
+
unpinTooltip: ChartInnerState['unpinTooltip'];
|
|
17
|
+
xAxis: PreparedAxis;
|
|
18
|
+
yAxis: PreparedAxis[];
|
|
19
|
+
};
|
|
20
|
+
export declare function useChartInnerHandlers(props: Props): {
|
|
21
|
+
handleChartClick: (event: React.MouseEvent<SVGSVGElement>) => void;
|
|
22
|
+
handleMouseLeave: React.MouseEventHandler<SVGSVGElement>;
|
|
23
|
+
throttledHandleMouseMove: import("lodash").DebouncedFuncLeading<React.MouseEventHandler<SVGSVGElement>> | undefined;
|
|
24
|
+
throttledHandleTouchMove: import("lodash").DebouncedFuncLeading<React.TouchEventHandler<SVGSVGElement>> | undefined;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
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 { EventType } from '../../utils';
|
|
6
|
+
import { getClosestPoints } from '../../utils/chart/get-closest-data';
|
|
7
|
+
const THROTTLE_DELAY = 50;
|
|
8
|
+
export function useChartInnerHandlers(props) {
|
|
9
|
+
const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, dispatcher, shapesData, svgContainer, togglePinTooltip, tooltipPinned, unpinTooltip, xAxis, yAxis, } = props;
|
|
10
|
+
const isOutsideBounds = React.useCallback((x, y) => {
|
|
11
|
+
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
12
|
+
}, [boundsHeight, boundsWidth]);
|
|
13
|
+
const handleMove = ([pointerX, pointerY], event) => {
|
|
14
|
+
if (tooltipPinned) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const x = pointerX - boundsOffsetLeft;
|
|
18
|
+
const y = pointerY - boundsOffsetTop;
|
|
19
|
+
if (isOutsideBounds(x, y)) {
|
|
20
|
+
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
21
|
+
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const closest = getClosestPoints({
|
|
25
|
+
position: [x, y],
|
|
26
|
+
shapesData,
|
|
27
|
+
boundsHeight,
|
|
28
|
+
boundsWidth,
|
|
29
|
+
});
|
|
30
|
+
dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY]);
|
|
31
|
+
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
32
|
+
hovered: closest,
|
|
33
|
+
xAxis,
|
|
34
|
+
yAxis: yAxis[0],
|
|
35
|
+
}, event);
|
|
36
|
+
};
|
|
37
|
+
const handleMouseMove = (event) => {
|
|
38
|
+
const [pointerX, pointerY] = pointer(event, svgContainer);
|
|
39
|
+
handleMove([pointerX, pointerY], event);
|
|
40
|
+
};
|
|
41
|
+
const throttledHandleMouseMove = IS_TOUCH_ENABLED
|
|
42
|
+
? undefined
|
|
43
|
+
: throttle(handleMouseMove, THROTTLE_DELAY);
|
|
44
|
+
const handleMouseLeave = (event) => {
|
|
45
|
+
if (tooltipPinned) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
throttledHandleMouseMove === null || throttledHandleMouseMove === void 0 ? void 0 : throttledHandleMouseMove.cancel();
|
|
49
|
+
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
50
|
+
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
51
|
+
};
|
|
52
|
+
const handleTouchMove = (event) => {
|
|
53
|
+
const touch = event.touches[0];
|
|
54
|
+
const [pointerX, pointerY] = pointer(touch, svgContainer);
|
|
55
|
+
handleMove([pointerX, pointerY], event);
|
|
56
|
+
};
|
|
57
|
+
const throttledHandleTouchMove = IS_TOUCH_ENABLED
|
|
58
|
+
? throttle(handleTouchMove, THROTTLE_DELAY)
|
|
59
|
+
: undefined;
|
|
60
|
+
const handleChartClick = (event) => {
|
|
61
|
+
const [pointerX, pointerY] = pointer(event, svgContainer);
|
|
62
|
+
const x = pointerX - boundsOffsetLeft;
|
|
63
|
+
const y = pointerY - boundsOffsetTop;
|
|
64
|
+
if (isOutsideBounds(x, y)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const items = getClosestPoints({
|
|
68
|
+
position: [x, y],
|
|
69
|
+
shapesData,
|
|
70
|
+
boundsHeight,
|
|
71
|
+
boundsWidth,
|
|
72
|
+
});
|
|
73
|
+
const selected = items === null || items === void 0 ? void 0 : items.find((item) => item.closest);
|
|
74
|
+
if (!selected) {
|
|
75
|
+
if (tooltipPinned) {
|
|
76
|
+
unpinTooltip === null || unpinTooltip === void 0 ? void 0 : unpinTooltip();
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
dispatcher.call(EventType.CLICK_CHART, undefined, { point: selected.data, series: selected.series }, event);
|
|
81
|
+
const nextTooltipFixed = !tooltipPinned;
|
|
82
|
+
if (!nextTooltipFixed) {
|
|
83
|
+
dispatcher.call(EventType.HOVER_SHAPE, event.target, items, [pointerX, pointerY]);
|
|
84
|
+
dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
|
|
85
|
+
hovered: items,
|
|
86
|
+
xAxis,
|
|
87
|
+
yAxis: yAxis[0],
|
|
88
|
+
}, event);
|
|
89
|
+
}
|
|
90
|
+
togglePinTooltip === null || togglePinTooltip === void 0 ? void 0 : togglePinTooltip(nextTooltipFixed, event);
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
handleChartClick,
|
|
94
|
+
handleMouseLeave,
|
|
95
|
+
throttledHandleMouseMove,
|
|
96
|
+
throttledHandleTouchMove,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3';
|
|
3
|
+
import type { ChartInnerProps } from './types';
|
|
4
|
+
type Props = ChartInnerProps & {
|
|
5
|
+
dispatcher: Dispatch<object>;
|
|
6
|
+
htmlLayout: HTMLElement | null;
|
|
7
|
+
};
|
|
8
|
+
export declare function useChartInnerProps(props: Props): {
|
|
9
|
+
boundsHeight: number;
|
|
10
|
+
boundsOffsetLeft: number;
|
|
11
|
+
boundsOffsetTop: number;
|
|
12
|
+
boundsWidth: number;
|
|
13
|
+
handleLegendItemClick: import("../../hooks").OnLegendItemClick;
|
|
14
|
+
legendConfig: {
|
|
15
|
+
offset: {
|
|
16
|
+
left: number;
|
|
17
|
+
top: number;
|
|
18
|
+
};
|
|
19
|
+
pagination: {
|
|
20
|
+
limit: number;
|
|
21
|
+
maxPage: number;
|
|
22
|
+
} | undefined;
|
|
23
|
+
};
|
|
24
|
+
legendItems: import("../../hooks").LegendItem[][];
|
|
25
|
+
preparedLegend: import("../../hooks").PreparedLegend;
|
|
26
|
+
preparedSeries: import("../../hooks").PreparedSeries[];
|
|
27
|
+
preparedSplit: import("../../hooks").PreparedSplit;
|
|
28
|
+
prevHeight: number | undefined;
|
|
29
|
+
prevWidth: number | undefined;
|
|
30
|
+
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
31
|
+
shapesData: import("../../hooks").ShapeData[];
|
|
32
|
+
title: (import("../../types").ChartTitle & {
|
|
33
|
+
height: number;
|
|
34
|
+
}) | undefined;
|
|
35
|
+
tooltip: import("../../types").ChartTooltip<any> & {
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
};
|
|
38
|
+
xAxis: import("../../hooks").PreparedAxis;
|
|
39
|
+
xScale: import("../../hooks").ChartScale | undefined;
|
|
40
|
+
yAxis: import("../../hooks").PreparedAxis[];
|
|
41
|
+
yScale: import("../../hooks").ChartScale[] | undefined;
|
|
42
|
+
};
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useAxisScales, useChartDimensions, useChartOptions, usePrevious, useSeries, useShapes, useSplit, } from '../../hooks';
|
|
3
|
+
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
4
|
+
import { getPreparedXAxis } from '../../hooks/useChartOptions/x-axis';
|
|
5
|
+
import { getPreparedYAxis } from '../../hooks/useChartOptions/y-axis';
|
|
6
|
+
export function useChartInnerProps(props) {
|
|
7
|
+
const { width, height, data, dispatcher, htmlLayout } = props;
|
|
8
|
+
const prevWidth = usePrevious(width);
|
|
9
|
+
const prevHeight = usePrevious(height);
|
|
10
|
+
const { chart, title, tooltip } = useChartOptions({ data });
|
|
11
|
+
const xAxis = React.useMemo(() => getPreparedXAxis({ xAxis: data.xAxis, width, series: data.series.data }), [data, width]);
|
|
12
|
+
const yAxis = React.useMemo(() => getPreparedYAxis({
|
|
13
|
+
series: data.series.data,
|
|
14
|
+
yAxis: data.yAxis,
|
|
15
|
+
height,
|
|
16
|
+
}), [data, height]);
|
|
17
|
+
const { legendItems, legendConfig, preparedSeries, preparedSeriesOptions, preparedLegend, handleLegendItemClick, } = useSeries({
|
|
18
|
+
chartWidth: width,
|
|
19
|
+
chartHeight: height,
|
|
20
|
+
chartMargin: chart.margin,
|
|
21
|
+
series: data.series,
|
|
22
|
+
legend: data.legend,
|
|
23
|
+
preparedYAxis: yAxis,
|
|
24
|
+
});
|
|
25
|
+
const { boundsWidth, boundsHeight } = useChartDimensions({
|
|
26
|
+
width,
|
|
27
|
+
height,
|
|
28
|
+
margin: chart.margin,
|
|
29
|
+
preparedLegend,
|
|
30
|
+
preparedXAxis: xAxis,
|
|
31
|
+
preparedYAxis: yAxis,
|
|
32
|
+
preparedSeries: preparedSeries,
|
|
33
|
+
});
|
|
34
|
+
const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
|
|
35
|
+
const { xScale, yScale } = useAxisScales({
|
|
36
|
+
boundsWidth,
|
|
37
|
+
boundsHeight,
|
|
38
|
+
series: preparedSeries,
|
|
39
|
+
xAxis,
|
|
40
|
+
yAxis,
|
|
41
|
+
split: preparedSplit,
|
|
42
|
+
});
|
|
43
|
+
const { shapes, shapesData } = useShapes({
|
|
44
|
+
boundsWidth,
|
|
45
|
+
boundsHeight,
|
|
46
|
+
dispatcher,
|
|
47
|
+
series: preparedSeries,
|
|
48
|
+
seriesOptions: preparedSeriesOptions,
|
|
49
|
+
xAxis,
|
|
50
|
+
xScale,
|
|
51
|
+
yAxis,
|
|
52
|
+
yScale,
|
|
53
|
+
split: preparedSplit,
|
|
54
|
+
htmlLayout,
|
|
55
|
+
});
|
|
56
|
+
const boundsOffsetTop = chart.margin.top;
|
|
57
|
+
// We only need to consider the width of the first left axis
|
|
58
|
+
const boundsOffsetLeft = chart.margin.left + getYAxisWidth(yAxis[0]);
|
|
59
|
+
return {
|
|
60
|
+
boundsHeight,
|
|
61
|
+
boundsOffsetLeft,
|
|
62
|
+
boundsOffsetTop,
|
|
63
|
+
boundsWidth,
|
|
64
|
+
handleLegendItemClick,
|
|
65
|
+
legendConfig,
|
|
66
|
+
legendItems,
|
|
67
|
+
preparedLegend,
|
|
68
|
+
preparedSeries,
|
|
69
|
+
preparedSplit,
|
|
70
|
+
prevHeight,
|
|
71
|
+
prevWidth,
|
|
72
|
+
shapes,
|
|
73
|
+
shapesData,
|
|
74
|
+
title,
|
|
75
|
+
tooltip,
|
|
76
|
+
xAxis,
|
|
77
|
+
xScale,
|
|
78
|
+
yAxis,
|
|
79
|
+
yScale,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3';
|
|
3
|
+
import type { ChartTooltip } from '../../types';
|
|
4
|
+
type Props = {
|
|
5
|
+
dispatcher: Dispatch<object>;
|
|
6
|
+
tooltip?: ChartTooltip;
|
|
7
|
+
};
|
|
8
|
+
export declare function useChartInnerState(props: Props): {
|
|
9
|
+
tooltipPinned: boolean;
|
|
10
|
+
togglePinTooltip: ((value: boolean, event: React.MouseEvent) => void) | undefined;
|
|
11
|
+
unpinTooltip: (() => void) | undefined;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { EventType, isMacintosh } from '../../utils';
|
|
3
|
+
export function useChartInnerState(props) {
|
|
4
|
+
var _a, _b;
|
|
5
|
+
const { dispatcher, tooltip } = props;
|
|
6
|
+
const [tooltipPinned, setTooltipPinned] = React.useState(false);
|
|
7
|
+
const tooltipEnabled = tooltip === null || tooltip === void 0 ? void 0 : tooltip.enabled;
|
|
8
|
+
const tooltipPinEnabled = (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.pin) === null || _a === void 0 ? void 0 : _a.enabled;
|
|
9
|
+
const modifierKey = (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.pin) === null || _b === void 0 ? void 0 : _b.modifierKey;
|
|
10
|
+
const togglePinTooltip = React.useCallback((value, event) => {
|
|
11
|
+
let resultValue = value;
|
|
12
|
+
if (value && modifierKey) {
|
|
13
|
+
switch (modifierKey) {
|
|
14
|
+
case 'altKey': {
|
|
15
|
+
resultValue = event.altKey;
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
case 'metaKey': {
|
|
19
|
+
resultValue = isMacintosh() ? event.metaKey : event.ctrlKey;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
setTooltipPinned(resultValue);
|
|
24
|
+
}, [modifierKey]);
|
|
25
|
+
const unpinTooltip = React.useCallback(() => {
|
|
26
|
+
setTooltipPinned(false);
|
|
27
|
+
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
28
|
+
}, [dispatcher]);
|
|
29
|
+
return {
|
|
30
|
+
tooltipPinned,
|
|
31
|
+
togglePinTooltip: tooltipEnabled && tooltipPinEnabled ? togglePinTooltip : undefined,
|
|
32
|
+
unpinTooltip: tooltipEnabled && tooltipPinEnabled ? unpinTooltip : undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|