@coinbase/cds-mobile-visualization 3.4.0-beta.24 → 3.4.0-beta.25
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/CHANGELOG.md +10 -0
- package/dts/chart/Path.d.ts +2 -1
- package/dts/chart/Path.d.ts.map +1 -1
- package/dts/chart/bar/Bar.d.ts +18 -54
- package/dts/chart/bar/Bar.d.ts.map +1 -1
- package/dts/chart/bar/BarChart.d.ts +2 -2
- package/dts/chart/bar/BarPlot.d.ts.map +1 -1
- package/dts/chart/bar/BarStack.d.ts +4 -4
- package/dts/chart/bar/BarStack.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
- package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
- package/dts/chart/point/Point.d.ts +2 -1
- package/dts/chart/point/Point.d.ts.map +1 -1
- package/dts/chart/scrubber/Scrubber.d.ts +4 -2
- package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
- package/dts/chart/utils/bar.d.ts +155 -0
- package/dts/chart/utils/bar.d.ts.map +1 -1
- package/dts/chart/utils/chart.d.ts +2 -1
- package/dts/chart/utils/chart.d.ts.map +1 -1
- package/dts/chart/utils/path.d.ts.map +1 -1
- package/dts/sparkline/Sparkline.d.ts +2 -1
- package/dts/sparkline/Sparkline.d.ts.map +1 -1
- package/dts/sparkline/SparklineArea.d.ts +2 -1
- package/dts/sparkline/SparklineArea.d.ts.map +1 -1
- package/dts/sparkline/SparklineGradient.d.ts +2 -1
- package/dts/sparkline/SparklineGradient.d.ts.map +1 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts +2 -1
- package/dts/sparkline/sparkline-interactive/SparklineInteractive.d.ts.map +1 -1
- package/esm/chart/bar/Bar.js +8 -14
- package/esm/chart/bar/BarChart.js +7 -7
- package/esm/chart/bar/BarPlot.js +37 -46
- package/esm/chart/bar/BarStack.js +71 -604
- package/esm/chart/bar/DefaultBar.js +11 -18
- package/esm/chart/bar/DefaultBarStack.js +12 -21
- package/esm/chart/bar/__stories__/BarChart.stories.js +104 -6
- package/esm/chart/utils/bar.js +775 -0
- package/esm/chart/utils/chart.js +2 -1
- package/esm/chart/utils/path.js +5 -12
- package/esm/sparkline/Sparkline.js +2 -1
- package/esm/sparkline/SparklineArea.js +2 -1
- package/esm/sparkline/SparklineGradient.js +2 -1
- package/esm/sparkline/sparkline-interactive/SparklineInteractive.js +2 -1
- package/package.json +5 -5
|
@@ -3,6 +3,7 @@ import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
|
3
3
|
import { useCartesianChartContext } from '../ChartProvider';
|
|
4
4
|
import { Path } from '../Path';
|
|
5
5
|
import { defaultBarEnterTransition, getBarPath, withStaggerDelayTransition } from '../utils';
|
|
6
|
+
import { getNormalizedStagger } from '../utils/bar';
|
|
6
7
|
import { defaultTransition, getTransition } from '../utils/transition';
|
|
7
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
9
|
/**
|
|
@@ -23,6 +24,7 @@ export const DefaultBar = /*#__PURE__*/memo(_ref => {
|
|
|
23
24
|
stroke,
|
|
24
25
|
strokeWidth,
|
|
25
26
|
origin,
|
|
27
|
+
minSize = 1,
|
|
26
28
|
transitions,
|
|
27
29
|
transition
|
|
28
30
|
} = _ref;
|
|
@@ -33,28 +35,19 @@ export const DefaultBar = /*#__PURE__*/memo(_ref => {
|
|
|
33
35
|
} = useCartesianChartContext();
|
|
34
36
|
const theme = useTheme();
|
|
35
37
|
const defaultFill = fill || theme.color.fgPrimary;
|
|
36
|
-
|
|
37
|
-
// For vertical layout, stagger by x (category axis). For horizontal, stagger by y (category axis).
|
|
38
|
-
const normalizedStagger = useMemo(() => {
|
|
39
|
-
const barsGrowVertically = layout !== 'horizontal';
|
|
40
|
-
if (barsGrowVertically) {
|
|
41
|
-
return drawingArea.width > 0 ? (x - drawingArea.x) / drawingArea.width : 0;
|
|
42
|
-
}
|
|
43
|
-
return drawingArea.height > 0 ? (y - drawingArea.y) / drawingArea.height : 0;
|
|
44
|
-
}, [layout, x, y, drawingArea.x, drawingArea.y, drawingArea.width, drawingArea.height]);
|
|
38
|
+
const normalizedStagger = useMemo(() => getNormalizedStagger(layout, x, y, drawingArea), [layout, x, y, drawingArea]);
|
|
45
39
|
const enterTransition = useMemo(() => withStaggerDelayTransition(getTransition(transitions == null ? void 0 : transitions.enter, animate, defaultBarEnterTransition), normalizedStagger), [transitions == null ? void 0 : transitions.enter, animate, normalizedStagger]);
|
|
46
40
|
const updateTransition = useMemo(() => withStaggerDelayTransition(getTransition((transitions == null ? void 0 : transitions.update) !== undefined ? transitions.update : transition, animate, defaultTransition), normalizedStagger), [transitions == null ? void 0 : transitions.update, transition, animate, normalizedStagger]);
|
|
47
41
|
const initialPath = useMemo(() => {
|
|
48
|
-
if (!animate) return
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const initialHeight = barsGrowVertically ? minSize : height;
|
|
42
|
+
if (!animate) return;
|
|
43
|
+
const isHorizontalLayout = layout === 'horizontal';
|
|
44
|
+
const baseline = origin != null ? origin : isHorizontalLayout ? x : y + height;
|
|
45
|
+
const initialX = isHorizontalLayout ? baseline : x;
|
|
46
|
+
const initialY = isHorizontalLayout ? y : baseline;
|
|
47
|
+
const initialWidth = isHorizontalLayout ? minSize : width;
|
|
48
|
+
const initialHeight = isHorizontalLayout ? height : minSize;
|
|
56
49
|
return getBarPath(initialX, initialY, initialWidth, initialHeight, borderRadius, !!roundTop, !!roundBottom, layout);
|
|
57
|
-
}, [animate, layout, x, y, origin, width, height, borderRadius, roundTop, roundBottom]);
|
|
50
|
+
}, [animate, layout, x, y, origin, width, height, borderRadius, roundTop, roundBottom, minSize]);
|
|
58
51
|
return /*#__PURE__*/_jsx(Path, {
|
|
59
52
|
animate: animate,
|
|
60
53
|
clipPath: null,
|
|
@@ -2,7 +2,7 @@ import { memo, useMemo } from 'react';
|
|
|
2
2
|
import { Group } from '@shopify/react-native-skia';
|
|
3
3
|
import { useCartesianChartContext } from '../ChartProvider';
|
|
4
4
|
import { getBarPath } from '../utils';
|
|
5
|
-
import { defaultBarEnterTransition, withStaggerDelayTransition } from '../utils/bar';
|
|
5
|
+
import { defaultBarEnterTransition, getNormalizedStagger, getStackInitialClipRect, withStaggerDelayTransition } from '../utils/bar';
|
|
6
6
|
import { defaultTransition, getTransition, usePathTransition } from '../utils/transition';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
/**
|
|
@@ -18,7 +18,7 @@ export const DefaultBarStack = /*#__PURE__*/memo(_ref => {
|
|
|
18
18
|
borderRadius = 4,
|
|
19
19
|
roundTop = true,
|
|
20
20
|
roundBottom = true,
|
|
21
|
-
|
|
21
|
+
origin,
|
|
22
22
|
transitions,
|
|
23
23
|
transition
|
|
24
24
|
} = _ref;
|
|
@@ -27,15 +27,7 @@ export const DefaultBarStack = /*#__PURE__*/memo(_ref => {
|
|
|
27
27
|
drawingArea,
|
|
28
28
|
layout
|
|
29
29
|
} = useCartesianChartContext();
|
|
30
|
-
|
|
31
|
-
// For vertical layout, stagger by x (category axis). For horizontal, stagger by y (category axis).
|
|
32
|
-
const normalizedStagger = useMemo(() => {
|
|
33
|
-
const barsGrowVertically = layout !== 'horizontal';
|
|
34
|
-
if (barsGrowVertically) {
|
|
35
|
-
return drawingArea.width > 0 ? (x - drawingArea.x) / drawingArea.width : 0;
|
|
36
|
-
}
|
|
37
|
-
return drawingArea.height > 0 ? (y - drawingArea.y) / drawingArea.height : 0;
|
|
38
|
-
}, [layout, x, y, drawingArea.x, drawingArea.y, drawingArea.width, drawingArea.height]);
|
|
30
|
+
const normalizedStagger = useMemo(() => getNormalizedStagger(layout, x, y, drawingArea), [layout, x, y, drawingArea]);
|
|
39
31
|
const enterTransition = useMemo(() => withStaggerDelayTransition(getTransition(transitions == null ? void 0 : transitions.enter, animate, defaultBarEnterTransition), normalizedStagger), [animate, transitions == null ? void 0 : transitions.enter, normalizedStagger]);
|
|
40
32
|
const updateTransition = useMemo(() => withStaggerDelayTransition(getTransition((transitions == null ? void 0 : transitions.update) !== undefined ? transitions.update : transition, animate, defaultTransition), normalizedStagger), [animate, transitions == null ? void 0 : transitions.update, transition, normalizedStagger]);
|
|
41
33
|
|
|
@@ -46,16 +38,15 @@ export const DefaultBarStack = /*#__PURE__*/memo(_ref => {
|
|
|
46
38
|
|
|
47
39
|
// Initial clip path for entry animation (bar at baseline with minimal height)
|
|
48
40
|
const initialPath = useMemo(() => {
|
|
49
|
-
if (!animate) return
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}, [animate, layout, x, yOrigin, y, height, width, borderRadius, roundTop, roundBottom]);
|
|
41
|
+
if (!animate) return;
|
|
42
|
+
const initialClipRect = getStackInitialClipRect({
|
|
43
|
+
x,
|
|
44
|
+
y,
|
|
45
|
+
width,
|
|
46
|
+
height
|
|
47
|
+
}, layout, origin);
|
|
48
|
+
return getBarPath(initialClipRect.x, initialClipRect.y, initialClipRect.width, initialClipRect.height, borderRadius, roundTop, roundBottom, layout);
|
|
49
|
+
}, [animate, layout, x, y, height, width, borderRadius, roundTop, roundBottom, origin]);
|
|
59
50
|
const animatedClipPath = usePathTransition({
|
|
60
51
|
currentPath: targetPath,
|
|
61
52
|
initialPath,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const _excluded = ["children"],
|
|
2
2
|
_excluded2 = ["animate"],
|
|
3
3
|
_excluded3 = ["x", "y", "width", "height", "dataX"],
|
|
4
|
-
_excluded4 = ["data", "height"]
|
|
4
|
+
_excluded4 = ["data", "height"],
|
|
5
|
+
_excluded5 = ["buy", "sell", "animate", "borderRadius", "height", "inset", "layout", "stackGap", "xAxis", "yAxis", "barMinSize"];
|
|
5
6
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
6
7
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
7
8
|
import { memo, useCallback, useEffect, useId, useMemo, useState } from 'react';
|
|
@@ -17,6 +18,7 @@ import { Line as SkiaLine, Rect } from '@shopify/react-native-skia';
|
|
|
17
18
|
import { XAxis, YAxis } from '../../axis';
|
|
18
19
|
import { CartesianChart } from '../../CartesianChart';
|
|
19
20
|
import { useCartesianChartContext } from '../../ChartProvider';
|
|
21
|
+
import { DefaultLegendEntry } from '../../legend';
|
|
20
22
|
import { ReferenceLine, SolidLine } from '../../line';
|
|
21
23
|
import { Scrubber } from '../../scrubber';
|
|
22
24
|
import { getPointOnSerializableScale, unwrapAnimatedValue, useScrubberContext } from '../../utils';
|
|
@@ -125,6 +127,7 @@ const CustomBarStackComponent = /*#__PURE__*/memo(_ref => {
|
|
|
125
127
|
}));
|
|
126
128
|
});
|
|
127
129
|
const MonthlyRewards = () => {
|
|
130
|
+
const theme = useTheme();
|
|
128
131
|
const months = ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'];
|
|
129
132
|
const purple = [null, 6, 8, 10, 7, 6, 6, 8, null, null, null, null];
|
|
130
133
|
const blue = [null, 10, 12, 11, 10, 9, 10, 11, null, null, null, null];
|
|
@@ -134,19 +137,19 @@ const MonthlyRewards = () => {
|
|
|
134
137
|
const series = [{
|
|
135
138
|
id: 'purple',
|
|
136
139
|
data: purple,
|
|
137
|
-
color:
|
|
140
|
+
color: "rgb(" + theme.spectrum.purple30 + ")"
|
|
138
141
|
}, {
|
|
139
142
|
id: 'blue',
|
|
140
143
|
data: blue,
|
|
141
|
-
color:
|
|
144
|
+
color: "rgb(" + theme.spectrum.blue30 + ")"
|
|
142
145
|
}, {
|
|
143
146
|
id: 'cyan',
|
|
144
147
|
data: cyan,
|
|
145
|
-
color:
|
|
148
|
+
color: "rgb(" + theme.spectrum.teal30 + ")"
|
|
146
149
|
}, {
|
|
147
150
|
id: 'green',
|
|
148
151
|
data: green,
|
|
149
|
-
color:
|
|
152
|
+
color: "rgb(" + theme.spectrum.green30 + ")"
|
|
150
153
|
}];
|
|
151
154
|
return /*#__PURE__*/_jsxs(VStack, {
|
|
152
155
|
gap: 2,
|
|
@@ -165,7 +168,7 @@ const MonthlyRewards = () => {
|
|
|
165
168
|
tickLabelFormatter: index => {
|
|
166
169
|
return months[index];
|
|
167
170
|
},
|
|
168
|
-
categoryPadding: 0.
|
|
171
|
+
categoryPadding: 0.25
|
|
169
172
|
}
|
|
170
173
|
}), /*#__PURE__*/_jsx(Button, {
|
|
171
174
|
onPress: () => setRoundBaseline(!roundBaseline),
|
|
@@ -1061,6 +1064,98 @@ const HorizontalBarChart = () => {
|
|
|
1061
1064
|
}
|
|
1062
1065
|
});
|
|
1063
1066
|
};
|
|
1067
|
+
function BuyVsSellExample() {
|
|
1068
|
+
function BuyVsSellLegend(_ref15) {
|
|
1069
|
+
let {
|
|
1070
|
+
buy,
|
|
1071
|
+
sell
|
|
1072
|
+
} = _ref15;
|
|
1073
|
+
const theme = useTheme();
|
|
1074
|
+
return /*#__PURE__*/_jsxs(HStack, {
|
|
1075
|
+
gap: 1,
|
|
1076
|
+
justifyContent: "space-between",
|
|
1077
|
+
children: [/*#__PURE__*/_jsx(DefaultLegendEntry, {
|
|
1078
|
+
color: theme.color.fgPositive,
|
|
1079
|
+
label: /*#__PURE__*/_jsxs(Text, {
|
|
1080
|
+
color: "fgMuted",
|
|
1081
|
+
font: "legal",
|
|
1082
|
+
children: [buy, "% bought"]
|
|
1083
|
+
}),
|
|
1084
|
+
seriesId: "buy"
|
|
1085
|
+
}), /*#__PURE__*/_jsx(DefaultLegendEntry, {
|
|
1086
|
+
color: theme.color.fgNegative,
|
|
1087
|
+
label: /*#__PURE__*/_jsxs(Text, {
|
|
1088
|
+
color: "fgMuted",
|
|
1089
|
+
font: "legal",
|
|
1090
|
+
children: [sell, "% sold"]
|
|
1091
|
+
}),
|
|
1092
|
+
seriesId: "sell"
|
|
1093
|
+
})]
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
function BuyVsSellChart(_ref16) {
|
|
1097
|
+
let {
|
|
1098
|
+
buy,
|
|
1099
|
+
sell,
|
|
1100
|
+
animate = true,
|
|
1101
|
+
borderRadius = 3,
|
|
1102
|
+
height = 6,
|
|
1103
|
+
inset = 0,
|
|
1104
|
+
layout = 'horizontal',
|
|
1105
|
+
stackGap = 4,
|
|
1106
|
+
xAxis,
|
|
1107
|
+
yAxis,
|
|
1108
|
+
barMinSize = height
|
|
1109
|
+
} = _ref16,
|
|
1110
|
+
props = _objectWithoutPropertiesLoose(_ref16, _excluded5);
|
|
1111
|
+
const theme = useTheme();
|
|
1112
|
+
return /*#__PURE__*/_jsxs(VStack, {
|
|
1113
|
+
gap: 1.5,
|
|
1114
|
+
children: [/*#__PURE__*/_jsx(BarChart, _extends({
|
|
1115
|
+
roundBaseline: true,
|
|
1116
|
+
stacked: true,
|
|
1117
|
+
animate: animate,
|
|
1118
|
+
barMinSize: barMinSize,
|
|
1119
|
+
borderRadius: borderRadius,
|
|
1120
|
+
height: height,
|
|
1121
|
+
inset: inset,
|
|
1122
|
+
layout: layout,
|
|
1123
|
+
series: [{
|
|
1124
|
+
id: 'buy',
|
|
1125
|
+
data: [buy],
|
|
1126
|
+
color: theme.color.fgPositive,
|
|
1127
|
+
legendShape: 'circle'
|
|
1128
|
+
}, {
|
|
1129
|
+
id: 'sell',
|
|
1130
|
+
data: [sell],
|
|
1131
|
+
color: theme.color.fgNegative,
|
|
1132
|
+
legendShape: 'circle'
|
|
1133
|
+
}],
|
|
1134
|
+
stackGap: stackGap,
|
|
1135
|
+
transitions: {
|
|
1136
|
+
enter: {
|
|
1137
|
+
type: 'timing',
|
|
1138
|
+
duration: 5000,
|
|
1139
|
+
delay: 2000
|
|
1140
|
+
}
|
|
1141
|
+
},
|
|
1142
|
+
xAxis: _extends({
|
|
1143
|
+
domainLimit: 'strict'
|
|
1144
|
+
}, xAxis),
|
|
1145
|
+
yAxis: _extends({
|
|
1146
|
+
categoryPadding: 0
|
|
1147
|
+
}, yAxis)
|
|
1148
|
+
}, props)), /*#__PURE__*/_jsx(BuyVsSellLegend, {
|
|
1149
|
+
buy: buy,
|
|
1150
|
+
sell: sell
|
|
1151
|
+
})]
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
return /*#__PURE__*/_jsx(BuyVsSellChart, {
|
|
1155
|
+
buy: 76,
|
|
1156
|
+
sell: 24
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1064
1159
|
const PopulationPyramid = () => {
|
|
1065
1160
|
const theme = useTheme();
|
|
1066
1161
|
const ageGroups = ['100+ yrs', '95-99 yrs', '90-94 yrs', '85-89 yrs', '80-84 yrs', '75-79 yrs', '70-74 yrs', '65-69 yrs', '60-64 yrs', '55-59 yrs', '50-54 yrs', '45-49 yrs', '40-44 yrs', '35-39 yrs', '30-34 yrs', '25-29 yrs', '20-24 yrs', '15-19 yrs', '10-14 yrs', '5-9 yrs', '0-4 yrs'];
|
|
@@ -1192,6 +1287,9 @@ function ExampleNavigator() {
|
|
|
1192
1287
|
}, {
|
|
1193
1288
|
title: 'Horizontal Layout',
|
|
1194
1289
|
component: /*#__PURE__*/_jsx(HorizontalBarChart, {})
|
|
1290
|
+
}, {
|
|
1291
|
+
title: 'Buy vs Sell',
|
|
1292
|
+
component: /*#__PURE__*/_jsx(BuyVsSellExample, {})
|
|
1195
1293
|
}, {
|
|
1196
1294
|
title: 'Population Pyramid',
|
|
1197
1295
|
component: /*#__PURE__*/_jsx(PopulationPyramid, {})
|