@gravity-ui/charts 0.6.1 → 0.8.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/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.js +3 -2
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +4 -0
- package/dist/cjs/components/Legend/index.js +1 -2
- 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.js +5 -5
- package/dist/cjs/components/Tooltip/styles.css +2 -15
- 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/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/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/bar-x/index.js +16 -2
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +2 -1
- package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-y/index.js +16 -2
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +2 -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 +2 -2
- package/dist/cjs/hooks/useShapes/pie/index.js +3 -3
- package/dist/cjs/hooks/useShapes/pie/prepare-data.js +37 -35
- package/dist/cjs/hooks/useShapes/pie/types.d.ts +1 -1
- 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/sankey/types.js +1 -0
- package/dist/cjs/hooks/useShapes/styles.css +2 -2
- package/dist/cjs/hooks/useShapes/utils.d.ts +7 -2
- package/dist/cjs/hooks/useShapes/utils.js +22 -17
- package/dist/cjs/hooks/useShapes/waterfall/index.js +1 -2
- 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 +4 -4
- 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 -10
- 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 +27 -21
- 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 +6 -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/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/esm/components/Axis/AxisY.d.ts +1 -0
- package/dist/esm/components/Axis/AxisY.js +55 -13
- package/dist/esm/components/ChartInner/index.js +3 -2
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +4 -0
- package/dist/esm/components/Legend/index.js +1 -2
- 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.js +5 -5
- package/dist/esm/components/Tooltip/styles.css +2 -15
- 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/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/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/bar-x/index.js +16 -2
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +2 -1
- package/dist/esm/hooks/useShapes/bar-x/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-y/index.js +16 -2
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +2 -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 +2 -2
- package/dist/esm/hooks/useShapes/pie/index.js +3 -3
- package/dist/esm/hooks/useShapes/pie/prepare-data.js +37 -35
- package/dist/esm/hooks/useShapes/pie/types.d.ts +1 -1
- 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/styles.css +2 -2
- package/dist/esm/hooks/useShapes/utils.d.ts +7 -2
- package/dist/esm/hooks/useShapes/utils.js +22 -17
- package/dist/esm/hooks/useShapes/waterfall/index.js +1 -2
- 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 +4 -4
- 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 -10
- 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 +27 -21
- 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 +6 -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/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/package.json +9 -4
|
@@ -19,15 +19,13 @@ export function preparePieData(args) {
|
|
|
19
19
|
const maxRadius = Math.min(boundsWidth, boundsHeight) / 2;
|
|
20
20
|
const groupedPieSeries = group(preparedSeries, (pieSeries) => pieSeries.stackId);
|
|
21
21
|
const prepareItem = (stackId, items) => {
|
|
22
|
-
var _a
|
|
22
|
+
var _a;
|
|
23
23
|
const series = items[0];
|
|
24
|
-
const { center, borderWidth, borderColor, borderRadius,
|
|
25
|
-
const radius = (_a = calculateNumericProperty({ value: seriesRadius, base: maxRadius })) !== null && _a !== void 0 ? _a : maxRadius;
|
|
24
|
+
const { center, borderWidth, borderColor, borderRadius, innerRadius: seriesInnerRadius, dataLabels, } = series;
|
|
26
25
|
const data = {
|
|
27
26
|
id: stackId,
|
|
28
27
|
center: getCenter(boundsWidth, boundsHeight, center),
|
|
29
|
-
innerRadius:
|
|
30
|
-
radius,
|
|
28
|
+
innerRadius: 0,
|
|
31
29
|
segments: [],
|
|
32
30
|
labels: [],
|
|
33
31
|
htmlLabels: [],
|
|
@@ -43,7 +41,19 @@ export function preparePieData(args) {
|
|
|
43
41
|
size: series.states.hover.halo.size,
|
|
44
42
|
},
|
|
45
43
|
};
|
|
44
|
+
const { maxHeight: labelHeight } = getLabelsSize({
|
|
45
|
+
labels: ['Some Label'],
|
|
46
|
+
style: dataLabels.style,
|
|
47
|
+
});
|
|
48
|
+
let segmentMaxRadius = 0;
|
|
46
49
|
const segments = items.map((item) => {
|
|
50
|
+
var _a;
|
|
51
|
+
let maxSegmentRadius = maxRadius;
|
|
52
|
+
if (dataLabels.enabled) {
|
|
53
|
+
maxSegmentRadius -= dataLabels.distance + dataLabels.connectorPadding + labelHeight;
|
|
54
|
+
}
|
|
55
|
+
const segmentRadius = (_a = calculateNumericProperty({ value: item.radius, base: maxSegmentRadius })) !== null && _a !== void 0 ? _a : maxSegmentRadius;
|
|
56
|
+
segmentMaxRadius = Math.max(segmentMaxRadius, segmentRadius);
|
|
47
57
|
return {
|
|
48
58
|
value: item.value,
|
|
49
59
|
color: item.color,
|
|
@@ -52,19 +62,12 @@ export function preparePieData(args) {
|
|
|
52
62
|
hovered: false,
|
|
53
63
|
active: true,
|
|
54
64
|
pie: data,
|
|
65
|
+
radius: segmentRadius,
|
|
55
66
|
};
|
|
56
67
|
});
|
|
57
68
|
data.segments = pieGenerator(segments);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const { maxHeight: labelHeight } = getLabelsSize({ labels: ['Some Label'], style });
|
|
61
|
-
const minSegmentRadius = maxRadius - distance - connectorPadding - labelHeight;
|
|
62
|
-
if (data.radius > minSegmentRadius) {
|
|
63
|
-
data.radius = minSegmentRadius;
|
|
64
|
-
data.innerRadius =
|
|
65
|
-
(_c = calculateNumericProperty({ value: seriesInnerRadius, base: data.radius })) !== null && _c !== void 0 ? _c : 0;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
69
|
+
data.innerRadius =
|
|
70
|
+
(_a = calculateNumericProperty({ value: seriesInnerRadius, base: segmentMaxRadius })) !== null && _a !== void 0 ? _a : 0;
|
|
68
71
|
return data;
|
|
69
72
|
};
|
|
70
73
|
const prepareLabels = (prepareLabelsArgs) => {
|
|
@@ -84,20 +87,17 @@ export function preparePieData(args) {
|
|
|
84
87
|
const { style, connectorPadding, distance } = dataLabels;
|
|
85
88
|
const { maxHeight: labelHeight } = getLabelsSize({ labels: ['Some Label'], style });
|
|
86
89
|
const connectorStartPointGenerator = arc()
|
|
87
|
-
.innerRadius(data.radius)
|
|
88
|
-
.outerRadius(data.radius);
|
|
89
|
-
const connectorMidPointRadius = data.radius + distance / 2;
|
|
90
|
+
.innerRadius((d) => d.data.radius)
|
|
91
|
+
.outerRadius((d) => d.data.radius);
|
|
90
92
|
const connectorMidPointGenerator = arc()
|
|
91
|
-
.innerRadius(
|
|
92
|
-
.outerRadius(
|
|
93
|
-
const connectorArcRadius = data.radius + distance;
|
|
93
|
+
.innerRadius((d) => d.data.radius + distance / 2)
|
|
94
|
+
.outerRadius((d) => d.data.radius + distance / 2);
|
|
94
95
|
const connectorEndPointGenerator = arc()
|
|
95
|
-
.innerRadius(
|
|
96
|
-
.outerRadius(
|
|
97
|
-
const labelArcRadius = connectorArcRadius + connectorPadding;
|
|
96
|
+
.innerRadius((d) => d.data.radius + distance)
|
|
97
|
+
.outerRadius((d) => d.data.radius + distance);
|
|
98
98
|
const labelArcGenerator = arc()
|
|
99
|
-
.innerRadius(
|
|
100
|
-
.outerRadius(
|
|
99
|
+
.innerRadius((d) => d.data.radius + distance + connectorPadding)
|
|
100
|
+
.outerRadius((d) => d.data.radius + distance + connectorPadding);
|
|
101
101
|
series.forEach((d, index) => {
|
|
102
102
|
const prevLabel = labels[labels.length - 1];
|
|
103
103
|
const text = String(d.data.label || d.data.value);
|
|
@@ -179,8 +179,8 @@ export function preparePieData(args) {
|
|
|
179
179
|
}
|
|
180
180
|
if (shouldUseHtml) {
|
|
181
181
|
htmlLabels.push({
|
|
182
|
-
x:
|
|
183
|
-
y:
|
|
182
|
+
x: data.center[0] + label.x,
|
|
183
|
+
y: Math.max(0, data.center[1] + label.y),
|
|
184
184
|
content: label.text,
|
|
185
185
|
size: label.size,
|
|
186
186
|
});
|
|
@@ -207,19 +207,21 @@ export function preparePieData(args) {
|
|
|
207
207
|
data,
|
|
208
208
|
series: items,
|
|
209
209
|
});
|
|
210
|
-
const
|
|
211
|
-
const top = Math.min(data.center[1] -
|
|
212
|
-
const bottom = Math.max(data.center[1] +
|
|
210
|
+
const segmentMaxRadius = Math.max(...data.segments.map((s) => s.data.radius));
|
|
211
|
+
const top = Math.min(data.center[1] - segmentMaxRadius, ...preparedLabels.labels.map((l) => l.y + data.center[1]), ...preparedLabels.htmlLabels.map((l) => l.y));
|
|
212
|
+
const bottom = Math.max(data.center[1] + segmentMaxRadius, ...preparedLabels.labels.map((l) => l.y + data.center[1] + l.size.height), ...preparedLabels.htmlLabels.map((l) => l.y + l.size.height));
|
|
213
213
|
const topAdjustment = Math.floor(top - data.halo.size);
|
|
214
214
|
if (topAdjustment > 0) {
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
data.segments.forEach((s) => {
|
|
216
|
+
s.data.radius += topAdjustment / 2;
|
|
217
|
+
});
|
|
217
218
|
data.center[1] -= topAdjustment / 2;
|
|
218
219
|
}
|
|
219
220
|
const bottomAdjustment = Math.floor(boundsHeight - bottom - data.halo.size);
|
|
220
221
|
if (bottomAdjustment > 0) {
|
|
221
|
-
|
|
222
|
-
|
|
222
|
+
data.segments.forEach((s) => {
|
|
223
|
+
s.data.radius += bottomAdjustment / 2;
|
|
224
|
+
});
|
|
223
225
|
data.center[1] += bottomAdjustment / 2;
|
|
224
226
|
}
|
|
225
227
|
const { labels, htmlLabels, connectors } = prepareLabels({
|
|
@@ -9,6 +9,7 @@ export type SegmentData = {
|
|
|
9
9
|
hovered: boolean;
|
|
10
10
|
active: boolean;
|
|
11
11
|
pie: PreparedPieData;
|
|
12
|
+
radius: number;
|
|
12
13
|
};
|
|
13
14
|
export type PieLabelData = LabelData & {
|
|
14
15
|
segment: SegmentData;
|
|
@@ -25,7 +26,6 @@ export type PreparedPieData = {
|
|
|
25
26
|
labels: PieLabelData[];
|
|
26
27
|
connectors: PieConnectorData[];
|
|
27
28
|
center: [number, number];
|
|
28
|
-
radius: number;
|
|
29
29
|
innerRadius: number;
|
|
30
30
|
borderRadius: number;
|
|
31
31
|
borderWidth: number;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3';
|
|
3
|
+
import type { PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
|
+
import type { PreparedSankeyData } from './types';
|
|
5
|
+
type ShapeProps = {
|
|
6
|
+
dispatcher: Dispatch<object>;
|
|
7
|
+
preparedData: PreparedSankeyData;
|
|
8
|
+
seriesOptions: PreparedSeriesOptions;
|
|
9
|
+
htmlLayout: HTMLElement | null;
|
|
10
|
+
};
|
|
11
|
+
export declare const SankeySeriesShape: (props: ShapeProps) => React.JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { select } from 'd3';
|
|
3
|
+
import { block } from '../../../utils';
|
|
4
|
+
import { HtmlLayer } from '../HtmlLayer';
|
|
5
|
+
const b = block('sankey');
|
|
6
|
+
export const SankeySeriesShape = (props) => {
|
|
7
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout } = props;
|
|
8
|
+
const hoveredDataRef = React.useRef(null);
|
|
9
|
+
const ref = React.useRef(null);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
if (!ref.current) {
|
|
12
|
+
return () => { };
|
|
13
|
+
}
|
|
14
|
+
const svgElement = select(ref.current);
|
|
15
|
+
svgElement.selectAll('*').remove();
|
|
16
|
+
// nodes
|
|
17
|
+
svgElement
|
|
18
|
+
.append('g')
|
|
19
|
+
.selectAll()
|
|
20
|
+
.data(preparedData.nodes)
|
|
21
|
+
.join('rect')
|
|
22
|
+
.attr('x', (d) => d.x0)
|
|
23
|
+
.attr('y', (d) => d.y0)
|
|
24
|
+
.attr('height', (d) => d.y1 - d.y0)
|
|
25
|
+
.attr('width', (d) => d.x1 - d.x0)
|
|
26
|
+
.attr('fill', (d) => d.color);
|
|
27
|
+
// links
|
|
28
|
+
svgElement
|
|
29
|
+
.append('g')
|
|
30
|
+
.attr('fill', 'none')
|
|
31
|
+
.selectAll()
|
|
32
|
+
.data(preparedData.links)
|
|
33
|
+
.join('g')
|
|
34
|
+
.append('path')
|
|
35
|
+
.attr('stroke-opacity', (d) => d.opacity)
|
|
36
|
+
.attr('d', (d) => d.path)
|
|
37
|
+
.attr('stroke', (d) => d.color)
|
|
38
|
+
.attr('stroke-width', (d) => d.strokeWidth);
|
|
39
|
+
// dataLabels
|
|
40
|
+
svgElement
|
|
41
|
+
.append('g')
|
|
42
|
+
.selectAll()
|
|
43
|
+
.data(preparedData.labels)
|
|
44
|
+
.join('text')
|
|
45
|
+
.text((d) => d.text)
|
|
46
|
+
.attr('class', b('label'))
|
|
47
|
+
.attr('x', (d) => d.x)
|
|
48
|
+
.attr('y', (d) => d.y)
|
|
49
|
+
.attr('dy', '0.35em')
|
|
50
|
+
.attr('text-anchor', (d) => d.textAnchor)
|
|
51
|
+
.attr('fill', (d) => { var _a; return (_a = d.style.fontColor) !== null && _a !== void 0 ? _a : null; });
|
|
52
|
+
const eventName = `hover-shape.sankey`;
|
|
53
|
+
function handleShapeHover(data) {
|
|
54
|
+
hoveredDataRef.current = data;
|
|
55
|
+
}
|
|
56
|
+
if (hoveredDataRef.current !== null) {
|
|
57
|
+
handleShapeHover(hoveredDataRef.current);
|
|
58
|
+
}
|
|
59
|
+
dispatcher.on(eventName, handleShapeHover);
|
|
60
|
+
return () => {
|
|
61
|
+
dispatcher.on(eventName, null);
|
|
62
|
+
};
|
|
63
|
+
}, [dispatcher, preparedData, seriesOptions]);
|
|
64
|
+
return (React.createElement(React.Fragment, null,
|
|
65
|
+
React.createElement("g", { ref: ref, className: b() }),
|
|
66
|
+
React.createElement(HtmlLayer, { preparedData: preparedData, htmlLayout: htmlLayout })));
|
|
67
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { sankey, sankeyLinkHorizontal } from 'd3-sankey';
|
|
2
|
+
export function prepareSankeyData(args) {
|
|
3
|
+
const { series, width, height } = args;
|
|
4
|
+
const htmlElements = [];
|
|
5
|
+
const sankeyGenerator = sankey()
|
|
6
|
+
.nodeId((d) => d.name)
|
|
7
|
+
.nodeSort((d) => d.index)
|
|
8
|
+
.nodeWidth(15)
|
|
9
|
+
.nodePadding(10)
|
|
10
|
+
.extent([
|
|
11
|
+
[1, 5],
|
|
12
|
+
[width - 1, height - 5],
|
|
13
|
+
]);
|
|
14
|
+
const { nodes, links } = sankeyGenerator({
|
|
15
|
+
nodes: series.data,
|
|
16
|
+
links: series.data.reduce((acc, item) => {
|
|
17
|
+
item.links.forEach((l) => {
|
|
18
|
+
const target = series.data.find((d) => d.name === l.name);
|
|
19
|
+
if (target) {
|
|
20
|
+
acc.push({
|
|
21
|
+
source: item,
|
|
22
|
+
target,
|
|
23
|
+
value: l.value,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return acc;
|
|
28
|
+
}, []),
|
|
29
|
+
});
|
|
30
|
+
const sankeyNodes = nodes.map((node) => {
|
|
31
|
+
var _a, _b, _c, _d, _e, _f;
|
|
32
|
+
return {
|
|
33
|
+
x0: (_a = node.x0) !== null && _a !== void 0 ? _a : 0,
|
|
34
|
+
x1: (_b = node.x1) !== null && _b !== void 0 ? _b : 0,
|
|
35
|
+
y0: (_c = node.y0) !== null && _c !== void 0 ? _c : 0,
|
|
36
|
+
y1: (_d = node.y1) !== null && _d !== void 0 ? _d : 0,
|
|
37
|
+
color: (_e = node.color) !== null && _e !== void 0 ? _e : '',
|
|
38
|
+
data: series.data[(_f = node.index) !== null && _f !== void 0 ? _f : 0],
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
const sankeyLinks = links.map((d) => {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
return {
|
|
44
|
+
opacity: 0.75,
|
|
45
|
+
color: (_a = d.source.color) !== null && _a !== void 0 ? _a : '',
|
|
46
|
+
path: sankeyLinkHorizontal()(d),
|
|
47
|
+
strokeWidth: Math.max(1, (_b = d.width) !== null && _b !== void 0 ? _b : 0),
|
|
48
|
+
source: d.source,
|
|
49
|
+
target: d.target,
|
|
50
|
+
value: d.value,
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
const dataLabels = [];
|
|
54
|
+
if (series.dataLabels.enabled) {
|
|
55
|
+
const labels = nodes.map((d) => {
|
|
56
|
+
var _a, _b, _c, _d;
|
|
57
|
+
const x0 = (_a = d.x0) !== null && _a !== void 0 ? _a : 0;
|
|
58
|
+
const x1 = (_b = d.x1) !== null && _b !== void 0 ? _b : 0;
|
|
59
|
+
const y0 = (_c = d.y0) !== null && _c !== void 0 ? _c : 0;
|
|
60
|
+
const y1 = (_d = d.y1) !== null && _d !== void 0 ? _d : 0;
|
|
61
|
+
return {
|
|
62
|
+
text: d.name,
|
|
63
|
+
x: x0 < width / 2 ? x1 + 6 : x0 - 6,
|
|
64
|
+
y: (y1 + y0) / 2,
|
|
65
|
+
textAnchor: x0 < width / 2 ? 'start' : 'end',
|
|
66
|
+
style: series.dataLabels.style,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
dataLabels.push(...labels);
|
|
70
|
+
}
|
|
71
|
+
return { series, nodes: sankeyNodes, links: sankeyLinks, htmlElements, labels: dataLabels };
|
|
72
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BaseTextStyle, HtmlItem, SankeySeriesData } from '../../../types';
|
|
2
|
+
import type { PreparedSankeySeries } from '../../useSeries/types';
|
|
3
|
+
export type SankeyDataLabel = {
|
|
4
|
+
text: string;
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
textAnchor: 'start' | 'end';
|
|
8
|
+
style: BaseTextStyle;
|
|
9
|
+
};
|
|
10
|
+
export type SankeyNode = {
|
|
11
|
+
x0: number;
|
|
12
|
+
x1: number;
|
|
13
|
+
y0: number;
|
|
14
|
+
y1: number;
|
|
15
|
+
color: string;
|
|
16
|
+
data: SankeySeriesData;
|
|
17
|
+
};
|
|
18
|
+
export type SankeyLink = {
|
|
19
|
+
opacity: number;
|
|
20
|
+
color: string;
|
|
21
|
+
path: string | null;
|
|
22
|
+
strokeWidth: number;
|
|
23
|
+
source: SankeySeriesData;
|
|
24
|
+
target: SankeySeriesData;
|
|
25
|
+
value: number;
|
|
26
|
+
};
|
|
27
|
+
export type PreparedSankeyData = {
|
|
28
|
+
series: PreparedSankeySeries;
|
|
29
|
+
htmlElements: HtmlItem[];
|
|
30
|
+
nodes: SankeyNode[];
|
|
31
|
+
links: SankeyLink[];
|
|
32
|
+
labels: SankeyDataLabel[];
|
|
33
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
alignment-baseline: before-edge;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
.gcharts-
|
|
15
|
+
.gcharts-bar-x__label {
|
|
16
16
|
user-select: none;
|
|
17
17
|
fill: var(--g-color-text-complementary);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
.gcharts-
|
|
20
|
+
.gcharts-bar-y__label {
|
|
21
21
|
user-select: none;
|
|
22
22
|
fill: var(--g-color-text-complementary);
|
|
23
23
|
alignment-baseline: after-edge;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { BaseType } from 'd3';
|
|
2
|
-
import type { DashStyle } from '../../constants';
|
|
3
2
|
import type { BasicInactiveState } from '../../types';
|
|
4
3
|
import type { ChartScale } from '../useAxisScales';
|
|
5
4
|
import type { PreparedAxis } from '../useChartOptions/types';
|
|
@@ -26,4 +25,10 @@ export declare function setActiveState<T extends {
|
|
|
26
25
|
state: BasicInactiveState | undefined;
|
|
27
26
|
active: boolean;
|
|
28
27
|
}): T;
|
|
29
|
-
export declare function
|
|
28
|
+
export declare function getRectPath(args: {
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
borderRadius?: number | number[];
|
|
34
|
+
}): import("d3-path").Path;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { select } from 'd3';
|
|
1
|
+
import { path, select } from 'd3';
|
|
2
2
|
import get from 'lodash/get';
|
|
3
3
|
import { getDataCategoryValue } from '../../utils';
|
|
4
4
|
export function getXValue(args) {
|
|
@@ -36,20 +36,25 @@ export function setActiveState(args) {
|
|
|
36
36
|
}
|
|
37
37
|
return datum;
|
|
38
38
|
}
|
|
39
|
-
export function
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
export function getRectPath(args) {
|
|
40
|
+
const { x, y, width, height, borderRadius = 0 } = args;
|
|
41
|
+
const borderRadiuses = typeof borderRadius === 'number' ? new Array(4).fill(borderRadius) : borderRadius;
|
|
42
|
+
const [borderRadiusTopLeft = 0, borderRadiusTopRight = 0, borderRadiusBottomRight = 0, borderRadiusBottomLeft = 0,] = borderRadiuses !== null && borderRadiuses !== void 0 ? borderRadiuses : [];
|
|
43
|
+
const p = path();
|
|
44
|
+
let startAngle = -Math.PI / 2;
|
|
45
|
+
const angle = Math.PI / 2;
|
|
46
|
+
p.moveTo(x + borderRadiusTopLeft, y);
|
|
47
|
+
p.lineTo(x + width - borderRadiusTopRight, y);
|
|
48
|
+
p.arc(x + width - borderRadiusTopRight, y + borderRadiusTopRight, borderRadiusTopRight, startAngle, startAngle + angle);
|
|
49
|
+
startAngle += angle;
|
|
50
|
+
p.lineTo(x + width, y + height - borderRadiusBottomRight);
|
|
51
|
+
p.arc(x + width - borderRadiusBottomRight, y + height - borderRadiusBottomRight, borderRadiusBottomRight, startAngle, startAngle + angle);
|
|
52
|
+
startAngle += angle;
|
|
53
|
+
p.lineTo(x + borderRadiusBottomLeft, y + height);
|
|
54
|
+
p.arc(x + borderRadiusBottomLeft, y + height - borderRadiusBottomLeft, borderRadiusBottomLeft, startAngle, startAngle + angle);
|
|
55
|
+
startAngle += angle;
|
|
56
|
+
p.lineTo(x, y + borderRadiusTopLeft);
|
|
57
|
+
p.arc(x + borderRadiusTopLeft, y + borderRadiusTopLeft, borderRadiusTopLeft, startAngle, startAngle + angle);
|
|
58
|
+
p.closePath();
|
|
59
|
+
return p;
|
|
55
60
|
}
|
|
@@ -2,9 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import { color, line as lineGenerator, select } from 'd3';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import { DashStyle } from '../../../constants';
|
|
5
|
-
import { block, filterOverlappingLabels, getWaterfallPointColor } from '../../../utils';
|
|
5
|
+
import { block, filterOverlappingLabels, getLineDashArray, getWaterfallPointColor, } from '../../../utils';
|
|
6
6
|
import { HtmlLayer } from '../HtmlLayer';
|
|
7
|
-
import { getLineDashArray } from '../utils';
|
|
8
7
|
export { prepareWaterfallData } from './prepare-data';
|
|
9
8
|
export * from './types';
|
|
10
9
|
const b = block('d3-waterfall');
|
|
@@ -3,7 +3,7 @@ import type { MeaningfulAny } from '../misc';
|
|
|
3
3
|
import type { BaseSeries, BaseSeriesData } from './base';
|
|
4
4
|
import type { ChartLegend, RectLegendSymbolOptions } from './legend';
|
|
5
5
|
import type { PointMarkerOptions } from './marker';
|
|
6
|
-
export
|
|
6
|
+
export interface AreaSeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
|
|
7
7
|
/**
|
|
8
8
|
* The `x` value of the point. Depending on the context , it may represents:
|
|
9
9
|
* - numeric value (for `linear` x axis)
|
|
@@ -35,12 +35,12 @@ export type AreaSeriesData<T = MeaningfulAny> = BaseSeriesData<T> & {
|
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
39
|
export type AreaMarkerSymbol = 'circle' | 'square';
|
|
40
|
-
export
|
|
40
|
+
export interface AreaMarkerOptions extends PointMarkerOptions {
|
|
41
41
|
symbol?: AreaMarkerSymbol;
|
|
42
|
-
}
|
|
43
|
-
export
|
|
42
|
+
}
|
|
43
|
+
export interface AreaSeries<T = MeaningfulAny> extends BaseSeries {
|
|
44
44
|
type: typeof SeriesType.Area;
|
|
45
45
|
data: AreaSeriesData<T>[];
|
|
46
46
|
/** The name of the series (used in legend, tooltip etc) */
|
|
@@ -73,4 +73,4 @@ export type AreaSeries<T = MeaningfulAny> = BaseSeries & {
|
|
|
73
73
|
marker?: AreaMarkerOptions;
|
|
74
74
|
/** Y-axis index (when using two axes) */
|
|
75
75
|
yAxis?: number;
|
|
76
|
-
}
|
|
76
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { DashStyle } from 'src/constants';
|
|
1
2
|
import type { FormatNumberOptions } from '../formatter';
|
|
2
3
|
import type { BaseTextStyle } from './base';
|
|
3
4
|
export type ChartAxisType = 'category' | 'datetime' | 'linear' | 'logarithmic';
|
|
4
5
|
export type ChartAxisTitleAlignment = 'left' | 'center' | 'right';
|
|
5
|
-
export
|
|
6
|
+
export interface ChartAxisLabels {
|
|
6
7
|
/** Enable or disable the axis labels. */
|
|
7
8
|
enabled?: boolean;
|
|
8
9
|
/** The label's pixel distance from the perimeter of the plot area.
|
|
@@ -27,8 +28,8 @@ export type ChartAxisLabels = {
|
|
|
27
28
|
* @default: 0
|
|
28
29
|
*/
|
|
29
30
|
rotation?: number;
|
|
30
|
-
}
|
|
31
|
-
export
|
|
31
|
+
}
|
|
32
|
+
export interface ChartAxis {
|
|
32
33
|
categories?: string[];
|
|
33
34
|
timestamps?: number[];
|
|
34
35
|
type?: ChartAxisType;
|
|
@@ -72,9 +73,31 @@ export type ChartAxis = {
|
|
|
72
73
|
* Defaults to 0.05 for Y axis and to 0.01 for X axis.
|
|
73
74
|
* */
|
|
74
75
|
maxPadding?: number;
|
|
75
|
-
}
|
|
76
|
-
export
|
|
77
|
-
|
|
76
|
+
}
|
|
77
|
+
export interface ChartXAxis extends ChartAxis {
|
|
78
|
+
}
|
|
79
|
+
export interface AxisPlotLine {
|
|
80
|
+
/** The position of the line in axis units. */
|
|
81
|
+
value?: number;
|
|
82
|
+
/** The color of the plot line (hex, rgba). */
|
|
83
|
+
color?: string;
|
|
84
|
+
/** Pixel width of the plot line.
|
|
85
|
+
*
|
|
86
|
+
* @default 1
|
|
87
|
+
* */
|
|
88
|
+
width?: number;
|
|
89
|
+
/** Option for line stroke style. */
|
|
90
|
+
dashStyle?: `${DashStyle}`;
|
|
91
|
+
/**
|
|
92
|
+
* Individual opacity for the line.
|
|
93
|
+
*
|
|
94
|
+
* @default 1
|
|
95
|
+
* */
|
|
96
|
+
opacity?: number;
|
|
97
|
+
/** Place the line behind or above the chart. */
|
|
98
|
+
layerPlacement?: 'before' | 'after';
|
|
99
|
+
}
|
|
100
|
+
export interface ChartYAxis extends ChartAxis {
|
|
78
101
|
/** Axis location.
|
|
79
102
|
* Possible values - 'left' and 'right'.
|
|
80
103
|
* */
|
|
@@ -82,4 +105,6 @@ export type ChartYAxis = ChartAxis & {
|
|
|
82
105
|
/** Property for splitting charts. Determines which area the axis is located in.
|
|
83
106
|
* */
|
|
84
107
|
plotIndex?: number;
|
|
85
|
-
|
|
108
|
+
/** An array of lines stretching across the plot area, marking a specific value */
|
|
109
|
+
plotLines?: AxisPlotLine[];
|
|
110
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { MeaningfulAny } from '../misc';
|
|
|
3
3
|
import type { BaseSeries, BaseSeriesData } from './base';
|
|
4
4
|
import type { ChartLegend, RectLegendSymbolOptions } from './legend';
|
|
5
5
|
import type { ChartSeriesOptions } from './series';
|
|
6
|
-
export
|
|
6
|
+
export interface BarXSeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
|
|
7
7
|
/**
|
|
8
8
|
* The `x` value of the bar. Depending on the context , it may represents:
|
|
9
9
|
* - numeric value (for `linear` x axis)
|
|
@@ -28,14 +28,19 @@ export type BarXSeriesData<T = MeaningfulAny> = BaseSeriesData<T> & {
|
|
|
28
28
|
label?: string | number;
|
|
29
29
|
/** Individual opacity for the bar-x column. */
|
|
30
30
|
opacity?: number;
|
|
31
|
-
}
|
|
32
|
-
export
|
|
31
|
+
}
|
|
32
|
+
export interface BarXSeries<T = MeaningfulAny> extends BaseSeries {
|
|
33
33
|
type: typeof SeriesType.BarX;
|
|
34
34
|
data: BarXSeriesData<T>[];
|
|
35
35
|
/** The name of the series (used in legend, tooltip etc) */
|
|
36
36
|
name: string;
|
|
37
37
|
/** The main color of the series (hex, rgba) */
|
|
38
38
|
color?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The corner radius of the border surrounding each bar.
|
|
41
|
+
* @default 0
|
|
42
|
+
*/
|
|
43
|
+
borderRadius?: number;
|
|
39
44
|
/** Whether to stack the values of each series on top of each other.
|
|
40
45
|
* Possible values are undefined to disable, "normal" to stack by value or "percent"
|
|
41
46
|
*
|
|
@@ -64,4 +69,4 @@ export type BarXSeries<T = MeaningfulAny> = BaseSeries & {
|
|
|
64
69
|
};
|
|
65
70
|
/** Y-axis index (when using two axes) */
|
|
66
71
|
yAxis?: number;
|
|
67
|
-
}
|
|
72
|
+
}
|
|
@@ -2,8 +2,7 @@ import type { SeriesType } from '../../constants';
|
|
|
2
2
|
import type { MeaningfulAny } from '../misc';
|
|
3
3
|
import type { BaseSeries, BaseSeriesData } from './base';
|
|
4
4
|
import type { ChartLegend, RectLegendSymbolOptions } from './legend';
|
|
5
|
-
|
|
6
|
-
export type BarYSeriesData<T = MeaningfulAny> = BaseSeriesData<T> & {
|
|
5
|
+
export interface BarYSeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
|
|
7
6
|
/**
|
|
8
7
|
* The `x` value of the bar. Depending on the context , it may represents:
|
|
9
8
|
* - numeric value (for `linear` x axis)
|
|
@@ -22,14 +21,19 @@ export type BarYSeriesData<T = MeaningfulAny> = BaseSeriesData<T> & {
|
|
|
22
21
|
label?: string | number;
|
|
23
22
|
/** Individual opacity for the bar. */
|
|
24
23
|
opacity?: number;
|
|
25
|
-
}
|
|
26
|
-
export
|
|
24
|
+
}
|
|
25
|
+
export interface BarYSeries<T = MeaningfulAny> extends BaseSeries {
|
|
27
26
|
type: typeof SeriesType.BarY;
|
|
28
27
|
data: BarYSeriesData<T>[];
|
|
29
28
|
/** The name of the series (used in legend, tooltip etc) */
|
|
30
29
|
name: string;
|
|
31
30
|
/** The main color of the series (hex, rgba) */
|
|
32
31
|
color?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The corner radius of the border surrounding each bar.
|
|
34
|
+
* @default 0
|
|
35
|
+
*/
|
|
36
|
+
borderRadius?: number;
|
|
33
37
|
/** Whether to stack the values of each series on top of each other.
|
|
34
38
|
* Possible values are undefined to disable, "normal" to stack by value or "percent"
|
|
35
39
|
*
|
|
@@ -44,7 +48,7 @@ export type BarYSeries<T = MeaningfulAny> = BaseSeries & {
|
|
|
44
48
|
* @default true
|
|
45
49
|
* */
|
|
46
50
|
grouping?: boolean;
|
|
47
|
-
dataLabels?:
|
|
51
|
+
dataLabels?: BaseSeries['dataLabels'] & {
|
|
48
52
|
/**
|
|
49
53
|
* Whether to align the data label inside or outside the box.
|
|
50
54
|
* For charts with a percentage stack, it is always true.
|
|
@@ -57,4 +61,4 @@ export type BarYSeries<T = MeaningfulAny> = BaseSeries & {
|
|
|
57
61
|
legend?: ChartLegend & {
|
|
58
62
|
symbol?: RectLegendSymbolOptions;
|
|
59
63
|
};
|
|
60
|
-
}
|
|
64
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MeaningfulAny } from '../misc';
|
|
2
|
-
export
|
|
2
|
+
export interface BaseSeries {
|
|
3
3
|
/** Initial visibility of the series */
|
|
4
4
|
visible?: boolean;
|
|
5
5
|
/**
|
|
@@ -30,8 +30,8 @@ export type BaseSeries = {
|
|
|
30
30
|
};
|
|
31
31
|
/** You can set the cursor to "pointer" if you have click events attached to the series, to signal to the user that the points and lines can be clicked. */
|
|
32
32
|
cursor?: string;
|
|
33
|
-
}
|
|
34
|
-
export
|
|
33
|
+
}
|
|
34
|
+
export interface BaseSeriesData<T = MeaningfulAny> {
|
|
35
35
|
/**
|
|
36
36
|
* A reserved subspace to store options and values for customized functionality
|
|
37
37
|
*
|
|
@@ -40,9 +40,9 @@ export type BaseSeriesData<T = MeaningfulAny> = {
|
|
|
40
40
|
custom?: T;
|
|
41
41
|
/** Individual color for the data chunk (point in scatter, segment in pie, bar etc) */
|
|
42
42
|
color?: string;
|
|
43
|
-
}
|
|
44
|
-
export
|
|
43
|
+
}
|
|
44
|
+
export interface BaseTextStyle {
|
|
45
45
|
fontSize: string;
|
|
46
46
|
fontWeight?: string;
|
|
47
47
|
fontColor?: string;
|
|
48
|
-
}
|
|
48
|
+
}
|