@ledgerhq/lumen-ui-rnative-visualization 0.1.17 → 0.1.19
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/module/lib/Components/Axis/XAxis/XAxis.js +4 -3
- package/dist/module/lib/Components/Axis/XAxis/XAxis.js.map +1 -1
- package/dist/module/lib/Components/Axis/XAxis/XAxis.test.js +14 -0
- package/dist/module/lib/Components/Axis/XAxis/XAxis.test.js.map +1 -1
- package/dist/module/lib/Components/Axis/YAxis/YAxis.js +4 -3
- package/dist/module/lib/Components/Axis/YAxis/YAxis.js.map +1 -1
- package/dist/module/lib/Components/Axis/YAxis/YAxis.test.js +14 -0
- package/dist/module/lib/Components/Axis/YAxis/YAxis.test.js.map +1 -1
- package/dist/module/lib/Components/CartesianChart/CartesianChart.js +30 -23
- package/dist/module/lib/Components/CartesianChart/CartesianChart.js.map +1 -1
- package/dist/module/lib/Components/CartesianChart/ChartEmptyLabel/ChartEmptyLabel.js +61 -0
- package/dist/module/lib/Components/CartesianChart/ChartEmptyLabel/ChartEmptyLabel.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/ChartEmptyLabel/index.js +4 -0
- package/dist/module/lib/Components/CartesianChart/ChartEmptyLabel/index.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/{RevealClip/RevealClipDefs.js → RevealAnimation/RevealAnimationProvider.js} +13 -13
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/RevealAnimationProvider.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/{RevealClip/RevealClipDefs.test.js → RevealAnimation/RevealAnimationProvider.test.js} +51 -12
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/RevealAnimationProvider.test.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/context.js +35 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/context.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/index.js +5 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/index.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/types.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/utils.js +64 -0
- package/dist/module/lib/Components/CartesianChart/RevealAnimation/utils.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/hooks/useShimmerAnimation.js +37 -0
- package/dist/module/lib/Components/CartesianChart/hooks/useShimmerAnimation.js.map +1 -0
- package/dist/module/lib/Components/CartesianChart/utils.js +1 -1
- package/dist/module/lib/Components/CartesianChart/utils.js.map +1 -1
- package/dist/module/lib/Components/Line/Line.js +18 -11
- package/dist/module/lib/Components/Line/Line.js.map +1 -1
- package/dist/module/lib/Components/Line/constants.js +5 -0
- package/dist/module/lib/Components/Line/constants.js.map +1 -0
- package/dist/module/lib/Components/Line/types.js +2 -0
- package/dist/module/lib/Components/Line/utils.js +38 -11
- package/dist/module/lib/Components/Line/utils.js.map +1 -1
- package/dist/module/lib/Components/Line/utils.test.js +49 -3
- package/dist/module/lib/Components/Line/utils.test.js.map +1 -1
- package/dist/module/lib/Components/LineChart/LineChart.js +131 -27
- package/dist/module/lib/Components/LineChart/LineChart.js.map +1 -1
- package/dist/module/lib/Components/LineChart/LineChart.test.js +147 -0
- package/dist/module/lib/Components/LineChart/LineChart.test.js.map +1 -1
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.js +72 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.js.map +1 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.test.js +47 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.test.js.map +1 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/index.js +4 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/index.js.map +1 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/types.js +4 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/types.js.map +1 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/utils.js +22 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/utils.js.map +1 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/utils.test.js +21 -0
- package/dist/module/lib/Components/LineChart/LineChartEmptyState/utils.test.js.map +1 -0
- package/dist/module/lib/Components/LineChart/utils.js +83 -0
- package/dist/module/lib/Components/LineChart/utils.js.map +1 -0
- package/dist/module/lib/Components/LineChart/utils.test.js +174 -0
- package/dist/module/lib/Components/LineChart/utils.test.js.map +1 -0
- package/dist/module/lib/Components/Point/Point.js +6 -4
- package/dist/module/lib/Components/Point/Point.js.map +1 -1
- package/dist/module/lib/Components/ReferenceLine/ReferenceLine.js +4 -4
- package/dist/module/lib/Components/ReferenceLine/ReferenceLine.js.map +1 -1
- package/dist/module/lib/Components/ReferenceLine/constants.js +2 -2
- package/dist/module/lib/Components/ReferenceLine/constants.js.map +1 -1
- package/dist/module/lib/Components/ReferenceLine/utils.js +2 -1
- package/dist/module/lib/Components/ReferenceLine/utils.js.map +1 -1
- package/dist/module/lib/Components/Scrubber/DefaultScrubberTooltip/utils.js +2 -1
- package/dist/module/lib/Components/Scrubber/DefaultScrubberTooltip/utils.js.map +1 -1
- package/dist/module/lib/Components/Scrubber/Scrubber.js +2 -2
- package/dist/module/lib/Components/Scrubber/Scrubber.js.map +1 -1
- package/dist/module/lib/Components/Scrubber/ScrubberProvider.js +10 -2
- package/dist/module/lib/Components/Scrubber/ScrubberProvider.js.map +1 -1
- package/dist/module/lib/Components/Scrubber/ScrubberProvider.test.js +79 -1
- package/dist/module/lib/Components/Scrubber/ScrubberProvider.test.js.map +1 -1
- package/dist/module/lib/Components/Scrubber/utils.js +3 -2
- package/dist/module/lib/Components/Scrubber/utils.js.map +1 -1
- package/dist/module/lib/utils/numbers.js +16 -0
- package/dist/module/lib/utils/numbers.js.map +1 -0
- package/dist/module/lib/utils/ticks/ticks.js +0 -16
- package/dist/module/lib/utils/ticks/ticks.js.map +1 -1
- package/dist/typescript/src/lib/Components/Axis/Axis.types.d.ts +6 -0
- package/dist/typescript/src/lib/Components/Axis/Axis.types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Axis/XAxis/XAxis.d.ts +1 -1
- package/dist/typescript/src/lib/Components/Axis/XAxis/XAxis.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Axis/YAxis/YAxis.d.ts +1 -1
- package/dist/typescript/src/lib/Components/Axis/YAxis/YAxis.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/CartesianChart/CartesianChart.d.ts +1 -1
- package/dist/typescript/src/lib/Components/CartesianChart/CartesianChart.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/CartesianChart/ChartEmptyLabel/ChartEmptyLabel.d.ts +18 -0
- package/dist/typescript/src/lib/Components/CartesianChart/ChartEmptyLabel/ChartEmptyLabel.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/ChartEmptyLabel/index.d.ts +2 -0
- package/dist/typescript/src/lib/Components/CartesianChart/ChartEmptyLabel/index.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/RevealAnimationProvider.d.ts +3 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/RevealAnimationProvider.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/context.d.ts +22 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/context.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/index.d.ts +3 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/index.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/{RevealClip → RevealAnimation}/types.d.ts +15 -2
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/types.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/utils.d.ts +33 -0
- package/dist/typescript/src/lib/Components/CartesianChart/RevealAnimation/utils.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/hooks/useShimmerAnimation.d.ts +13 -0
- package/dist/typescript/src/lib/Components/CartesianChart/hooks/useShimmerAnimation.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/CartesianChart/types.d.ts +12 -0
- package/dist/typescript/src/lib/Components/CartesianChart/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/CartesianChart/utils.d.ts +1 -1
- package/dist/typescript/src/lib/Components/CartesianChart/utils.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Line/Line.d.ts +1 -1
- package/dist/typescript/src/lib/Components/Line/Line.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Line/constants.d.ts +3 -0
- package/dist/typescript/src/lib/Components/Line/constants.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/Line/index.d.ts +1 -1
- package/dist/typescript/src/lib/Components/Line/index.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Line/types.d.ts +15 -0
- package/dist/typescript/src/lib/Components/Line/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Line/utils.d.ts +11 -6
- package/dist/typescript/src/lib/Components/Line/utils.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/LineChart/LineChart.d.ts +1 -1
- package/dist/typescript/src/lib/Components/LineChart/LineChart.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.d.ts +9 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/index.d.ts +3 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/index.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/types.d.ts +3 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/types.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/utils.d.ts +14 -0
- package/dist/typescript/src/lib/Components/LineChart/LineChartEmptyState/utils.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/LineChart/types.d.ts +41 -1
- package/dist/typescript/src/lib/Components/LineChart/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/LineChart/utils.d.ts +43 -0
- package/dist/typescript/src/lib/Components/LineChart/utils.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/Point/Point.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/ReferenceLine/ReferenceLine.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/ReferenceLine/constants.d.ts +2 -2
- package/dist/typescript/src/lib/Components/ReferenceLine/constants.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/ReferenceLine/utils.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Scrubber/DefaultScrubberTooltip/utils.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Scrubber/Scrubber.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Scrubber/ScrubberProvider.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Scrubber/utils.d.ts.map +1 -1
- package/dist/typescript/src/lib/utils/index.d.ts +1 -1
- package/dist/typescript/src/lib/utils/index.d.ts.map +1 -1
- package/dist/typescript/src/lib/utils/numbers.d.ts +13 -0
- package/dist/typescript/src/lib/utils/numbers.d.ts.map +1 -0
- package/dist/typescript/src/lib/utils/ticks/ticks.d.ts +1 -11
- package/dist/typescript/src/lib/utils/ticks/ticks.d.ts.map +1 -1
- package/dist/typescript/src/lib/utils/types.d.ts +27 -2
- package/dist/typescript/src/lib/utils/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/lib/Components/Axis/Axis.types.ts +6 -0
- package/src/lib/Components/Axis/XAxis/XAxis.test.tsx +12 -0
- package/src/lib/Components/Axis/XAxis/XAxis.tsx +29 -32
- package/src/lib/Components/Axis/YAxis/YAxis.test.tsx +12 -0
- package/src/lib/Components/Axis/YAxis/YAxis.tsx +29 -32
- package/src/lib/Components/CartesianChart/CartesianChart.tsx +30 -24
- package/src/lib/Components/CartesianChart/ChartEmptyLabel/ChartEmptyLabel.tsx +68 -0
- package/src/lib/Components/CartesianChart/ChartEmptyLabel/index.ts +1 -0
- package/src/lib/Components/CartesianChart/{RevealClip/RevealClipDefs.test.tsx → RevealAnimation/RevealAnimationProvider.test.tsx} +60 -17
- package/src/lib/Components/CartesianChart/{RevealClip/RevealClipDefs.tsx → RevealAnimation/RevealAnimationProvider.tsx} +11 -11
- package/src/lib/Components/CartesianChart/RevealAnimation/context.ts +39 -0
- package/src/lib/Components/CartesianChart/RevealAnimation/index.ts +2 -0
- package/src/lib/Components/CartesianChart/{RevealClip → RevealAnimation}/types.ts +16 -2
- package/src/lib/Components/CartesianChart/RevealAnimation/utils.ts +87 -0
- package/src/lib/Components/CartesianChart/hooks/useShimmerAnimation.ts +52 -0
- package/src/lib/Components/CartesianChart/types.ts +12 -0
- package/src/lib/Components/CartesianChart/utils.ts +2 -1
- package/src/lib/Components/Line/Line.tsx +26 -14
- package/src/lib/Components/Line/constants.ts +2 -0
- package/src/lib/Components/Line/index.ts +1 -1
- package/src/lib/Components/Line/types.ts +17 -0
- package/src/lib/Components/Line/utils.test.ts +77 -3
- package/src/lib/Components/Line/utils.ts +63 -12
- package/src/lib/Components/LineChart/LineChart.test.tsx +135 -0
- package/src/lib/Components/LineChart/LineChart.tsx +157 -38
- package/src/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.test.tsx +39 -0
- package/src/lib/Components/LineChart/LineChartEmptyState/LineChartEmptyState.tsx +72 -0
- package/src/lib/Components/LineChart/LineChartEmptyState/index.ts +2 -0
- package/src/lib/Components/LineChart/LineChartEmptyState/types.ts +3 -0
- package/src/lib/Components/LineChart/LineChartEmptyState/utils.test.ts +22 -0
- package/src/lib/Components/LineChart/LineChartEmptyState/utils.ts +24 -0
- package/src/lib/Components/LineChart/types.ts +49 -1
- package/src/lib/Components/LineChart/utils.test.ts +196 -0
- package/src/lib/Components/LineChart/utils.ts +107 -0
- package/src/lib/Components/Point/Point.tsx +7 -4
- package/src/lib/Components/ReferenceLine/ReferenceLine.tsx +8 -4
- package/src/lib/Components/ReferenceLine/constants.ts +2 -2
- package/src/lib/Components/ReferenceLine/utils.ts +2 -1
- package/src/lib/Components/Scrubber/DefaultScrubberTooltip/utils.ts +2 -1
- package/src/lib/Components/Scrubber/Scrubber.tsx +13 -2
- package/src/lib/Components/Scrubber/ScrubberProvider.test.tsx +83 -1
- package/src/lib/Components/Scrubber/ScrubberProvider.tsx +17 -2
- package/src/lib/Components/Scrubber/utils.ts +3 -5
- package/src/lib/utils/index.ts +1 -0
- package/src/lib/utils/numbers.ts +15 -0
- package/src/lib/utils/ticks/ticks.ts +1 -23
- package/src/lib/utils/types.ts +35 -2
- package/dist/module/lib/Components/CartesianChart/RevealClip/RevealClipDefs.js.map +0 -1
- package/dist/module/lib/Components/CartesianChart/RevealClip/RevealClipDefs.test.js.map +0 -1
- package/dist/module/lib/Components/CartesianChart/RevealClip/context.js +0 -8
- package/dist/module/lib/Components/CartesianChart/RevealClip/context.js.map +0 -1
- package/dist/module/lib/Components/CartesianChart/RevealClip/index.js +0 -5
- package/dist/module/lib/Components/CartesianChart/RevealClip/index.js.map +0 -1
- package/dist/module/lib/Components/CartesianChart/RevealClip/types.js.map +0 -1
- package/dist/module/lib/Components/CartesianChart/RevealClip/utils.js +0 -32
- package/dist/module/lib/Components/CartesianChart/RevealClip/utils.js.map +0 -1
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/RevealClipDefs.d.ts +0 -3
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/RevealClipDefs.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/context.d.ts +0 -7
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/context.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/index.d.ts +0 -3
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/index.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/types.d.ts.map +0 -1
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/utils.d.ts +0 -17
- package/dist/typescript/src/lib/Components/CartesianChart/RevealClip/utils.d.ts.map +0 -1
- package/src/lib/Components/CartesianChart/RevealClip/context.ts +0 -13
- package/src/lib/Components/CartesianChart/RevealClip/index.ts +0 -2
- package/src/lib/Components/CartesianChart/RevealClip/utils.ts +0 -51
- /package/dist/module/lib/Components/CartesianChart/{RevealClip → RevealAnimation}/types.js +0 -0
|
@@ -1,13 +1,111 @@
|
|
|
1
|
+
import { useTheme } from '@ledgerhq/lumen-ui-rnative';
|
|
1
2
|
import { useMemo } from 'react';
|
|
3
|
+
import Animated from 'react-native-reanimated';
|
|
4
|
+
import { G } from 'react-native-svg';
|
|
2
5
|
|
|
3
|
-
import type { ChartInset } from '../../utils/types';
|
|
4
6
|
import { defaultXAxisProps, defaultYAxisProps } from '../Axis';
|
|
5
|
-
import {
|
|
7
|
+
import { XAxis } from '../Axis/XAxis';
|
|
6
8
|
import { YAxis } from '../Axis/YAxis';
|
|
7
9
|
import { CartesianChart } from '../CartesianChart';
|
|
10
|
+
import { ChartEmptyLabel } from '../CartesianChart/ChartEmptyLabel';
|
|
11
|
+
import { useShimmerAnimation } from '../CartesianChart/hooks/useShimmerAnimation';
|
|
8
12
|
import { Line } from '../Line';
|
|
9
13
|
|
|
10
|
-
import
|
|
14
|
+
import { LineChartEmptyState } from './LineChartEmptyState';
|
|
15
|
+
import type {
|
|
16
|
+
LineChartContentProps,
|
|
17
|
+
LineChartLinesProps,
|
|
18
|
+
LineChartProps,
|
|
19
|
+
LineChartTransitionLinesProps,
|
|
20
|
+
} from './types';
|
|
21
|
+
import {
|
|
22
|
+
canRenderLine,
|
|
23
|
+
computeAxisPadding,
|
|
24
|
+
getChartDisplayState,
|
|
25
|
+
} from './utils';
|
|
26
|
+
|
|
27
|
+
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
28
|
+
|
|
29
|
+
const LineChartLines = ({
|
|
30
|
+
series,
|
|
31
|
+
showArea,
|
|
32
|
+
areaType,
|
|
33
|
+
stroke,
|
|
34
|
+
connectNulls,
|
|
35
|
+
}: Readonly<LineChartLinesProps>) => {
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
{series.map((s) => (
|
|
39
|
+
<Line
|
|
40
|
+
key={s.id}
|
|
41
|
+
seriesId={s.id}
|
|
42
|
+
stroke={stroke ?? s.stroke}
|
|
43
|
+
showArea={showArea}
|
|
44
|
+
areaType={areaType}
|
|
45
|
+
connectNulls={connectNulls}
|
|
46
|
+
/>
|
|
47
|
+
))}
|
|
48
|
+
</>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const LineChartTransitionLines = ({
|
|
53
|
+
series,
|
|
54
|
+
showArea,
|
|
55
|
+
areaType,
|
|
56
|
+
connectNulls,
|
|
57
|
+
}: Readonly<LineChartTransitionLinesProps>) => {
|
|
58
|
+
const { theme } = useTheme();
|
|
59
|
+
const { animatedProps } = useShimmerAnimation();
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<AnimatedG animatedProps={animatedProps}>
|
|
63
|
+
<LineChartLines
|
|
64
|
+
series={series}
|
|
65
|
+
showArea={showArea}
|
|
66
|
+
areaType={areaType}
|
|
67
|
+
stroke={theme.colors.border.mutedSubtle}
|
|
68
|
+
connectNulls={connectNulls}
|
|
69
|
+
/>
|
|
70
|
+
</AnimatedG>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const LineChartContent = ({
|
|
75
|
+
series,
|
|
76
|
+
showArea,
|
|
77
|
+
areaType,
|
|
78
|
+
showXAxis,
|
|
79
|
+
showYAxis,
|
|
80
|
+
xAxisConfig,
|
|
81
|
+
yAxisConfig,
|
|
82
|
+
isTransitionLoading,
|
|
83
|
+
connectNulls,
|
|
84
|
+
children,
|
|
85
|
+
}: Readonly<LineChartContentProps>) => {
|
|
86
|
+
return (
|
|
87
|
+
<>
|
|
88
|
+
{showXAxis && <XAxis {...xAxisConfig} />}
|
|
89
|
+
{showYAxis && <YAxis {...yAxisConfig} />}
|
|
90
|
+
{isTransitionLoading ? (
|
|
91
|
+
<LineChartTransitionLines
|
|
92
|
+
series={series}
|
|
93
|
+
showArea={showArea}
|
|
94
|
+
areaType={areaType}
|
|
95
|
+
connectNulls={connectNulls}
|
|
96
|
+
/>
|
|
97
|
+
) : (
|
|
98
|
+
<LineChartLines
|
|
99
|
+
series={series}
|
|
100
|
+
showArea={showArea}
|
|
101
|
+
areaType={areaType}
|
|
102
|
+
connectNulls={connectNulls}
|
|
103
|
+
/>
|
|
104
|
+
)}
|
|
105
|
+
{children}
|
|
106
|
+
</>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
11
109
|
|
|
12
110
|
export const LineChart = ({
|
|
13
111
|
series,
|
|
@@ -18,47 +116,55 @@ export const LineChart = ({
|
|
|
18
116
|
xAxis,
|
|
19
117
|
yAxis,
|
|
20
118
|
width,
|
|
21
|
-
height =
|
|
119
|
+
height = 228,
|
|
22
120
|
inset,
|
|
23
121
|
children,
|
|
24
122
|
enableScrubbing = false,
|
|
25
123
|
onScrubberPositionChange,
|
|
26
124
|
animate,
|
|
27
125
|
magnetRadius,
|
|
28
|
-
|
|
126
|
+
loading = false,
|
|
127
|
+
emptyLabel = 'No data',
|
|
128
|
+
connectNulls,
|
|
129
|
+
}: Readonly<LineChartProps>) => {
|
|
29
130
|
const xAxisConfig = {
|
|
30
131
|
...defaultXAxisProps,
|
|
31
132
|
...xAxis,
|
|
133
|
+
position: xAxis?.position ?? defaultXAxisProps.position,
|
|
32
134
|
};
|
|
33
135
|
const yAxisConfig = {
|
|
34
136
|
...defaultYAxisProps,
|
|
35
137
|
...yAxis,
|
|
138
|
+
position: yAxis?.position ?? defaultYAxisProps.position,
|
|
139
|
+
width: yAxis?.width ?? defaultYAxisProps.width,
|
|
36
140
|
};
|
|
37
141
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
142
|
+
const xAxisPosition = xAxisConfig.position;
|
|
143
|
+
const yAxisPosition = yAxisConfig.position;
|
|
144
|
+
const yAxisWidth = yAxisConfig.width;
|
|
42
145
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
146
|
+
const axisPadding = useMemo(
|
|
147
|
+
() =>
|
|
148
|
+
computeAxisPadding({
|
|
149
|
+
showXAxis,
|
|
150
|
+
showYAxis,
|
|
151
|
+
xAxisPosition,
|
|
152
|
+
yAxisPosition,
|
|
153
|
+
yAxisWidth,
|
|
154
|
+
}),
|
|
155
|
+
[showXAxis, showYAxis, xAxisPosition, yAxisPosition, yAxisWidth],
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const hasData = canRenderLine(series, xAxisConfig.data);
|
|
159
|
+
|
|
160
|
+
const { status, ariaLabel } = getChartDisplayState({
|
|
161
|
+
loading,
|
|
162
|
+
hasData,
|
|
163
|
+
emptyLabel,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const isTransitionLoading = status === 'transition-loading';
|
|
167
|
+
const isPlaceholder = status === 'initial-loading' || status === 'empty';
|
|
62
168
|
|
|
63
169
|
return (
|
|
64
170
|
<CartesianChart
|
|
@@ -71,20 +177,33 @@ export const LineChart = ({
|
|
|
71
177
|
axisPadding={axisPadding}
|
|
72
178
|
enableScrubbing={enableScrubbing}
|
|
73
179
|
onScrubberPositionChange={onScrubberPositionChange}
|
|
74
|
-
animate={animate}
|
|
180
|
+
animate={isTransitionLoading ? false : animate}
|
|
75
181
|
magnetRadius={magnetRadius}
|
|
182
|
+
ariaLabel={ariaLabel}
|
|
183
|
+
ariaBusy={loading}
|
|
184
|
+
overlay={
|
|
185
|
+
status === 'empty' ? (
|
|
186
|
+
<ChartEmptyLabel>{emptyLabel}</ChartEmptyLabel>
|
|
187
|
+
) : undefined
|
|
188
|
+
}
|
|
76
189
|
>
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
seriesId={s.id}
|
|
190
|
+
{isPlaceholder ? (
|
|
191
|
+
<LineChartEmptyState loading={status === 'initial-loading'} />
|
|
192
|
+
) : (
|
|
193
|
+
<LineChartContent
|
|
194
|
+
series={series ?? []}
|
|
83
195
|
showArea={showArea}
|
|
84
196
|
areaType={areaType}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
197
|
+
showXAxis={showXAxis}
|
|
198
|
+
showYAxis={showYAxis}
|
|
199
|
+
xAxisConfig={xAxisConfig}
|
|
200
|
+
yAxisConfig={yAxisConfig}
|
|
201
|
+
isTransitionLoading={isTransitionLoading}
|
|
202
|
+
connectNulls={connectNulls}
|
|
203
|
+
>
|
|
204
|
+
{children}
|
|
205
|
+
</LineChartContent>
|
|
206
|
+
)}
|
|
88
207
|
</CartesianChart>
|
|
89
208
|
);
|
|
90
209
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, it } from '@jest/globals';
|
|
2
|
+
import { ledgerLiveThemes } from '@ledgerhq/lumen-design-core';
|
|
3
|
+
import { ThemeProvider } from '@ledgerhq/lumen-ui-rnative';
|
|
4
|
+
import { render } from '@testing-library/react-native';
|
|
5
|
+
|
|
6
|
+
import { CartesianChart } from '../../CartesianChart';
|
|
7
|
+
import { LineChartEmptyState } from './LineChartEmptyState';
|
|
8
|
+
import type { LineChartEmptyStateProps } from './types';
|
|
9
|
+
|
|
10
|
+
const renderInChart = (props: LineChartEmptyStateProps) => {
|
|
11
|
+
return render(
|
|
12
|
+
<ThemeProvider themes={ledgerLiveThemes} colorScheme='light'>
|
|
13
|
+
<CartesianChart series={[]} width={400} height={200}>
|
|
14
|
+
<LineChartEmptyState {...props} />
|
|
15
|
+
</CartesianChart>
|
|
16
|
+
</ThemeProvider>,
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
describe('LineChartEmptyState', () => {
|
|
21
|
+
it('renders the placeholder line', () => {
|
|
22
|
+
const { getByTestId } = renderInChart({});
|
|
23
|
+
|
|
24
|
+
getByTestId('chart-empty-state-line');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('renders the grid lines', () => {
|
|
28
|
+
const { getByTestId } = renderInChart({});
|
|
29
|
+
|
|
30
|
+
getByTestId('chart-empty-state-grid');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('renders the placeholder while loading', () => {
|
|
34
|
+
const { getByTestId } = renderInChart({ loading: true });
|
|
35
|
+
|
|
36
|
+
getByTestId('chart-empty-state');
|
|
37
|
+
getByTestId('chart-empty-state-line');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useTheme } from '@ledgerhq/lumen-ui-rnative';
|
|
2
|
+
import Animated from 'react-native-reanimated';
|
|
3
|
+
import { G, Line as SvgLine, Path } from 'react-native-svg';
|
|
4
|
+
|
|
5
|
+
import { useCartesianChartContext } from '../../CartesianChart/context';
|
|
6
|
+
import { useShimmerAnimation } from '../../CartesianChart/hooks/useShimmerAnimation';
|
|
7
|
+
import { usePathReveal } from '../../CartesianChart/RevealAnimation';
|
|
8
|
+
|
|
9
|
+
import type { LineChartEmptyStateProps } from './types';
|
|
10
|
+
import { buildPlaceholderTransform, PLACEHOLDER_LINE_PATH } from './utils';
|
|
11
|
+
|
|
12
|
+
const GRID_LINE_RATIOS = [0.3, 0.5, 0.7];
|
|
13
|
+
const GRID_STROKE_WIDTH = 1;
|
|
14
|
+
const PLACEHOLDER_STROKE_WIDTH = 2;
|
|
15
|
+
|
|
16
|
+
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* SVG placeholder line shown when a LineChart is loading with no data yet (with
|
|
20
|
+
* a shimmer) or has no data to display (static). Uses a fixed line shape scaled
|
|
21
|
+
* into the chart's reserved drawing area, plus static horizontal grid lines, so
|
|
22
|
+
* axes are not needed.
|
|
23
|
+
*/
|
|
24
|
+
export function LineChartEmptyState({
|
|
25
|
+
loading = false,
|
|
26
|
+
}: Readonly<LineChartEmptyStateProps>) {
|
|
27
|
+
const { drawingArea } = useCartesianChartContext();
|
|
28
|
+
const { theme } = useTheme();
|
|
29
|
+
const { animatedProps } = useShimmerAnimation(loading);
|
|
30
|
+
const clipPath = usePathReveal();
|
|
31
|
+
|
|
32
|
+
if (drawingArea.width <= 0 || drawingArea.height <= 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<G testID='chart-empty-state'>
|
|
38
|
+
<G testID='chart-empty-state-grid'>
|
|
39
|
+
{GRID_LINE_RATIOS.map((ratio) => {
|
|
40
|
+
const y = drawingArea.y + drawingArea.height * ratio;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<SvgLine
|
|
44
|
+
key={ratio}
|
|
45
|
+
x1={drawingArea.x}
|
|
46
|
+
y1={y}
|
|
47
|
+
x2={drawingArea.x + drawingArea.width}
|
|
48
|
+
y2={y}
|
|
49
|
+
stroke={theme.colors.border.mutedSubtleTransparent}
|
|
50
|
+
strokeWidth={GRID_STROKE_WIDTH}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
})}
|
|
54
|
+
</G>
|
|
55
|
+
<G clipPath={clipPath}>
|
|
56
|
+
<AnimatedG animatedProps={animatedProps}>
|
|
57
|
+
<Path
|
|
58
|
+
testID='chart-empty-state-line'
|
|
59
|
+
d={PLACEHOLDER_LINE_PATH}
|
|
60
|
+
transform={buildPlaceholderTransform(drawingArea)}
|
|
61
|
+
vectorEffect='non-scaling-stroke'
|
|
62
|
+
fill='none'
|
|
63
|
+
stroke={theme.colors.border.muted}
|
|
64
|
+
strokeWidth={PLACEHOLDER_STROKE_WIDTH}
|
|
65
|
+
strokeLinecap='round'
|
|
66
|
+
strokeLinejoin='round'
|
|
67
|
+
/>
|
|
68
|
+
</AnimatedG>
|
|
69
|
+
</G>
|
|
70
|
+
</G>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
|
|
3
|
+
import { buildPlaceholderTransform, PLACEHOLDER_LINE_PATH } from './utils';
|
|
4
|
+
|
|
5
|
+
describe('PLACEHOLDER_LINE_PATH', () => {
|
|
6
|
+
it('is an svg path starting with a move command', () => {
|
|
7
|
+
expect(PLACEHOLDER_LINE_PATH).toMatch(/^M/);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe('buildPlaceholderTransform', () => {
|
|
12
|
+
it('translates to the drawing area origin and scales the viewBox to fit', () => {
|
|
13
|
+
const transform = buildPlaceholderTransform({
|
|
14
|
+
x: 10,
|
|
15
|
+
y: 20,
|
|
16
|
+
width: 364,
|
|
17
|
+
height: 104,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
expect(transform).toBe('translate(10, 20) scale(0.5, 0.5)');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DrawingArea } from '../../../utils/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fixed placeholder line shape, authored against a {@link PLACEHOLDER_VIEW_WIDTH}
|
|
5
|
+
* x {@link PLACEHOLDER_VIEW_HEIGHT} viewBox. Reused for every empty/loading
|
|
6
|
+
* state so the placeholder always reads the same.
|
|
7
|
+
*/
|
|
8
|
+
export const PLACEHOLDER_LINE_PATH =
|
|
9
|
+
'M1.00 128.27 C4.02 127.46 13.09 125.96 19.13 123.47 C25.19 120.97 31.23 116.53 37.28 113.31 C43.33 110.10 49.38 106.15 55.42 104.20 C61.48 102.24 67.52 102.53 73.57 101.61 C79.61 100.69 85.65 99.89 91.71 98.70 C97.75 97.51 103.80 95.67 109.84 94.47 C115.90 93.27 121.94 91.71 127.99 91.49 C134.03 91.26 140.09 91.53 146.13 93.16 C152.19 94.79 158.23 98.37 164.27 101.25 C170.32 104.13 176.36 108.16 182.42 110.45 C188.46 112.74 194.51 114.41 200.55 115.00 C206.61 115.60 212.65 114.56 218.70 114.03 C224.75 113.50 230.80 112.56 236.84 111.86 C242.88 111.17 248.94 110.27 254.98 109.87 C261.03 109.48 267.07 109.14 273.13 109.49 C279.17 109.82 285.22 110.90 291.26 111.90 C297.32 112.90 303.36 114.47 309.41 115.50 C315.46 116.54 321.50 118.12 327.55 118.11 C333.59 118.10 339.65 118.08 345.69 115.45 C351.74 112.81 357.78 107.02 363.84 102.29 C369.88 97.54 375.93 90.87 381.97 87.01 C388.03 83.16 394.07 79.81 400.11 79.12 C406.17 78.43 412.21 80.79 418.26 82.88 C424.30 84.99 430.36 88.88 436.40 91.74 C442.45 94.59 448.49 98.24 454.55 100.02 C460.59 101.80 466.64 102.08 472.68 102.44 C478.72 102.81 484.78 102.31 490.82 102.21 C496.87 102.11 502.92 101.95 508.97 101.84 C515.01 101.74 521.07 101.47 527.11 101.58 C533.16 101.68 539.20 101.57 545.26 102.48 C551.30 103.39 557.34 105.37 563.39 107.02 C569.43 108.68 575.49 111.02 581.53 112.40 C587.59 113.79 593.63 114.62 599.68 115.30 C605.72 115.98 611.78 115.81 617.82 116.48 C623.87 117.16 629.91 118.39 635.95 119.32 C642.01 120.25 648.05 121.51 654.10 122.04 C660.15 122.57 666.20 123.89 672.24 122.47 C678.30 121.07 684.34 117.39 690.39 113.54 C696.43 109.69 702.49 103.53 708.53 99.38 C714.57 95.23 722.31 90.65 726.66 88.61';
|
|
10
|
+
|
|
11
|
+
const PLACEHOLDER_VIEW_WIDTH = 728;
|
|
12
|
+
const PLACEHOLDER_VIEW_HEIGHT = 208;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Transform that fits {@link PLACEHOLDER_LINE_PATH} into the drawing area. Pair
|
|
16
|
+
* with `vector-effect: non-scaling-stroke` on the path so the stroke keeps a
|
|
17
|
+
* constant width despite the (potentially non-uniform) scale.
|
|
18
|
+
*/
|
|
19
|
+
export const buildPlaceholderTransform = (drawingArea: DrawingArea): string => {
|
|
20
|
+
const scaleX = drawingArea.width / PLACEHOLDER_VIEW_WIDTH;
|
|
21
|
+
const scaleY = drawingArea.height / PLACEHOLDER_VIEW_HEIGHT;
|
|
22
|
+
|
|
23
|
+
return `translate(${drawingArea.x}, ${drawingArea.y}) scale(${scaleX}, ${scaleY})`;
|
|
24
|
+
};
|
|
@@ -48,7 +48,7 @@ export type LineChartProps = {
|
|
|
48
48
|
width?: number;
|
|
49
49
|
/**
|
|
50
50
|
* Height of the chart in pixels.
|
|
51
|
-
* @default
|
|
51
|
+
* @default 228
|
|
52
52
|
*/
|
|
53
53
|
height?: number;
|
|
54
54
|
/**
|
|
@@ -83,4 +83,52 @@ export type LineChartProps = {
|
|
|
83
83
|
* @default 6
|
|
84
84
|
*/
|
|
85
85
|
magnetRadius?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Whether the chart is loading. When there is no data, renders an animated
|
|
88
|
+
* shimmer placeholder line (initial loading). When data is present (e.g. a
|
|
89
|
+
* time-range change), the current line is recoloured to a muted grey and
|
|
90
|
+
* shimmers until the new `series` is provided (transition loading).
|
|
91
|
+
*
|
|
92
|
+
* To get the transition behaviour, keep passing the previous `series` while
|
|
93
|
+
* refetching; clearing it falls back to the initial placeholder.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
loading?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Text shown in the centre of the chart when there is no data and the chart
|
|
99
|
+
* is not loading.
|
|
100
|
+
* @default 'No data'
|
|
101
|
+
*/
|
|
102
|
+
emptyLabel?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Chart-wide override controlling how null values are handled across all lines.
|
|
105
|
+
* When true, skips null values and draws continuous lines across gaps.
|
|
106
|
+
* When false, null values create gaps in the lines.
|
|
107
|
+
* When omitted, each series' own `connectNulls` value is used (defaulting to `false`).
|
|
108
|
+
*/
|
|
109
|
+
connectNulls?: boolean;
|
|
86
110
|
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Series-render fields shared by `LineChart` and its internal line
|
|
114
|
+
* sub-components. Derived from {@link LineChartProps} so the option types stay
|
|
115
|
+
* in sync.
|
|
116
|
+
*/
|
|
117
|
+
type LineSeriesRenderProps = Required<
|
|
118
|
+
Pick<LineChartProps, 'series' | 'showArea' | 'areaType'>
|
|
119
|
+
>;
|
|
120
|
+
|
|
121
|
+
export type LineChartLinesProps = LineSeriesRenderProps &
|
|
122
|
+
Pick<LineChartProps, 'connectNulls'> & {
|
|
123
|
+
stroke?: string;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export type LineChartTransitionLinesProps = Omit<LineChartLinesProps, 'stroke'>;
|
|
127
|
+
|
|
128
|
+
export type LineChartContentProps = LineChartLinesProps &
|
|
129
|
+
Required<Pick<LineChartProps, 'showXAxis' | 'showYAxis'>> &
|
|
130
|
+
Pick<LineChartProps, 'children'> & {
|
|
131
|
+
xAxisConfig: XAxisProps;
|
|
132
|
+
yAxisConfig: YAxisProps;
|
|
133
|
+
isTransitionLoading: boolean;
|
|
134
|
+
};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
|
|
3
|
+
import type { Series } from '../../utils/types';
|
|
4
|
+
import { DEFAULT_AXIS_HEIGHT } from '../Axis/XAxis';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
canRenderLine,
|
|
8
|
+
computeAxisPadding,
|
|
9
|
+
getChartDisplayState,
|
|
10
|
+
} from './utils';
|
|
11
|
+
|
|
12
|
+
const makeSeries = (data: (number | null)[]): Series => ({
|
|
13
|
+
id: 'a',
|
|
14
|
+
stroke: '#000',
|
|
15
|
+
data,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('canRenderLine', () => {
|
|
19
|
+
it('returns false for undefined or empty series', () => {
|
|
20
|
+
expect(canRenderLine(undefined)).toBe(false);
|
|
21
|
+
expect(canRenderLine([])).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('returns false when no series has at least two finite points', () => {
|
|
25
|
+
expect(canRenderLine([makeSeries([1])])).toBe(false);
|
|
26
|
+
expect(canRenderLine([makeSeries([1, null])])).toBe(false);
|
|
27
|
+
expect(canRenderLine([makeSeries([null, null])])).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('returns true once a series has two finite points', () => {
|
|
31
|
+
expect(canRenderLine([makeSeries([1, 2])])).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('ignores null gaps when counting drawable points', () => {
|
|
35
|
+
expect(canRenderLine([makeSeries([1, null, 3])])).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('does not count NaN, Infinity, or holes as drawable points', () => {
|
|
39
|
+
expect(canRenderLine([makeSeries([NaN, NaN])])).toBe(false);
|
|
40
|
+
expect(canRenderLine([makeSeries([Infinity, -Infinity])])).toBe(false);
|
|
41
|
+
expect(canRenderLine([makeSeries([NaN, 1])])).toBe(false);
|
|
42
|
+
expect(
|
|
43
|
+
canRenderLine([makeSeries([1, undefined as unknown as number, 2])]),
|
|
44
|
+
).toBe(true);
|
|
45
|
+
expect(
|
|
46
|
+
canRenderLine([makeSeries([1, undefined as unknown as number])]),
|
|
47
|
+
).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('returns true when any series is drawable', () => {
|
|
51
|
+
expect(canRenderLine([makeSeries([1]), makeSeries([1, 2, 3])])).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('treats a missing data array as no points', () => {
|
|
55
|
+
expect(canRenderLine([{ id: 'a', stroke: '#000' }])).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('caps counted points to the x-axis domain length (like toScaledPoints)', () => {
|
|
59
|
+
expect(canRenderLine([makeSeries([1, 2, 3])], ['Jan'])).toBe(false);
|
|
60
|
+
expect(canRenderLine([makeSeries([1, 2, 3])], ['Jan', 'Feb'])).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('does not reduce drawable points when xData is longer than the series', () => {
|
|
64
|
+
expect(canRenderLine([makeSeries([1, 2])], ['a', 'b', 'c', 'd'])).toBe(
|
|
65
|
+
true,
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('counts only finite points within the capped range', () => {
|
|
70
|
+
expect(canRenderLine([makeSeries([null, 2, 3])], ['Jan', 'Feb'])).toBe(
|
|
71
|
+
false,
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('computeAxisPadding', () => {
|
|
77
|
+
const base = {
|
|
78
|
+
xAxisPosition: 'bottom' as const,
|
|
79
|
+
yAxisPosition: 'start' as const,
|
|
80
|
+
yAxisWidth: 40,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
it('returns undefined when no axis is shown', () => {
|
|
84
|
+
expect(
|
|
85
|
+
computeAxisPadding({ ...base, showXAxis: false, showYAxis: false }),
|
|
86
|
+
).toBeUndefined();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('reserves height on the side where the x-axis sits', () => {
|
|
90
|
+
expect(
|
|
91
|
+
computeAxisPadding({
|
|
92
|
+
...base,
|
|
93
|
+
showXAxis: true,
|
|
94
|
+
showYAxis: false,
|
|
95
|
+
xAxisPosition: 'bottom',
|
|
96
|
+
}),
|
|
97
|
+
).toEqual({ top: 0, bottom: DEFAULT_AXIS_HEIGHT, left: 0, right: 0 });
|
|
98
|
+
|
|
99
|
+
expect(
|
|
100
|
+
computeAxisPadding({
|
|
101
|
+
...base,
|
|
102
|
+
showXAxis: true,
|
|
103
|
+
showYAxis: false,
|
|
104
|
+
xAxisPosition: 'top',
|
|
105
|
+
}),
|
|
106
|
+
).toEqual({ top: DEFAULT_AXIS_HEIGHT, bottom: 0, left: 0, right: 0 });
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('reserves the y-axis width on the side where it sits', () => {
|
|
110
|
+
expect(
|
|
111
|
+
computeAxisPadding({
|
|
112
|
+
...base,
|
|
113
|
+
showXAxis: false,
|
|
114
|
+
showYAxis: true,
|
|
115
|
+
yAxisPosition: 'start',
|
|
116
|
+
yAxisWidth: 56,
|
|
117
|
+
}),
|
|
118
|
+
).toEqual({ top: 0, bottom: 0, left: 56, right: 0 });
|
|
119
|
+
|
|
120
|
+
expect(
|
|
121
|
+
computeAxisPadding({
|
|
122
|
+
...base,
|
|
123
|
+
showXAxis: false,
|
|
124
|
+
showYAxis: true,
|
|
125
|
+
yAxisPosition: 'end',
|
|
126
|
+
yAxisWidth: 56,
|
|
127
|
+
}),
|
|
128
|
+
).toEqual({ top: 0, bottom: 0, left: 0, right: 56 });
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('combines padding when both axes are shown', () => {
|
|
132
|
+
expect(
|
|
133
|
+
computeAxisPadding({
|
|
134
|
+
showXAxis: true,
|
|
135
|
+
showYAxis: true,
|
|
136
|
+
xAxisPosition: 'bottom',
|
|
137
|
+
yAxisPosition: 'start',
|
|
138
|
+
yAxisWidth: 40,
|
|
139
|
+
}),
|
|
140
|
+
).toEqual({ top: 0, bottom: DEFAULT_AXIS_HEIGHT, left: 40, right: 0 });
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('getChartDisplayState', () => {
|
|
145
|
+
it('is initial-loading when loading with no data', () => {
|
|
146
|
+
expect(
|
|
147
|
+
getChartDisplayState({
|
|
148
|
+
loading: true,
|
|
149
|
+
hasData: false,
|
|
150
|
+
emptyLabel: 'No data',
|
|
151
|
+
}),
|
|
152
|
+
).toEqual({
|
|
153
|
+
status: 'initial-loading',
|
|
154
|
+
ariaLabel: 'Loading chart',
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('is empty when not loading with no data', () => {
|
|
159
|
+
expect(
|
|
160
|
+
getChartDisplayState({
|
|
161
|
+
loading: false,
|
|
162
|
+
hasData: false,
|
|
163
|
+
emptyLabel: 'Nothing here',
|
|
164
|
+
}),
|
|
165
|
+
).toEqual({
|
|
166
|
+
status: 'empty',
|
|
167
|
+
ariaLabel: 'Nothing here',
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('is transition-loading when loading with data', () => {
|
|
172
|
+
expect(
|
|
173
|
+
getChartDisplayState({
|
|
174
|
+
loading: true,
|
|
175
|
+
hasData: true,
|
|
176
|
+
emptyLabel: 'No data',
|
|
177
|
+
}),
|
|
178
|
+
).toEqual({
|
|
179
|
+
status: 'transition-loading',
|
|
180
|
+
ariaLabel: 'Loading chart',
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('is ready with no aria label when data is present and not loading', () => {
|
|
185
|
+
expect(
|
|
186
|
+
getChartDisplayState({
|
|
187
|
+
loading: false,
|
|
188
|
+
hasData: true,
|
|
189
|
+
emptyLabel: 'No data',
|
|
190
|
+
}),
|
|
191
|
+
).toEqual({
|
|
192
|
+
status: 'ready',
|
|
193
|
+
ariaLabel: undefined,
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|