@coinbase/cds-mobile-visualization 3.4.0-beta.22 → 3.4.0-beta.24
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 +12 -0
- package/dts/chart/CartesianChart.d.ts +58 -7
- package/dts/chart/CartesianChart.d.ts.map +1 -1
- package/dts/chart/Path.d.ts.map +1 -1
- package/dts/chart/area/Area.d.ts +7 -0
- package/dts/chart/area/Area.d.ts.map +1 -1
- package/dts/chart/area/AreaChart.d.ts +5 -5
- package/dts/chart/area/AreaChart.d.ts.map +1 -1
- package/dts/chart/area/DottedArea.d.ts.map +1 -1
- package/dts/chart/area/GradientArea.d.ts.map +1 -1
- package/dts/chart/area/SolidArea.d.ts.map +1 -1
- package/dts/chart/axis/Axis.d.ts +3 -1
- package/dts/chart/axis/Axis.d.ts.map +1 -1
- package/dts/chart/axis/XAxis.d.ts +6 -0
- package/dts/chart/axis/XAxis.d.ts.map +1 -1
- package/dts/chart/axis/YAxis.d.ts +1 -0
- package/dts/chart/axis/YAxis.d.ts.map +1 -1
- package/dts/chart/bar/Bar.d.ts +4 -2
- package/dts/chart/bar/Bar.d.ts.map +1 -1
- package/dts/chart/bar/BarChart.d.ts +49 -9
- package/dts/chart/bar/BarChart.d.ts.map +1 -1
- package/dts/chart/bar/BarPlot.d.ts.map +1 -1
- package/dts/chart/bar/BarStack.d.ts +30 -9
- package/dts/chart/bar/BarStack.d.ts.map +1 -1
- package/dts/chart/bar/BarStackGroup.d.ts +1 -1
- package/dts/chart/bar/BarStackGroup.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/gradient/Gradient.d.ts +5 -0
- package/dts/chart/gradient/Gradient.d.ts.map +1 -1
- package/dts/chart/line/DottedLine.d.ts.map +1 -1
- package/dts/chart/line/Line.d.ts +7 -0
- package/dts/chart/line/Line.d.ts.map +1 -1
- package/dts/chart/line/LineChart.d.ts +22 -8
- package/dts/chart/line/LineChart.d.ts.map +1 -1
- package/dts/chart/line/ReferenceLine.d.ts +1 -0
- package/dts/chart/line/ReferenceLine.d.ts.map +1 -1
- package/dts/chart/line/SolidLine.d.ts.map +1 -1
- package/dts/chart/point/Point.d.ts +7 -0
- package/dts/chart/point/Point.d.ts.map +1 -1
- package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts +2 -1
- package/dts/chart/scrubber/DefaultScrubberLabel.d.ts.map +1 -1
- package/dts/chart/scrubber/Scrubber.d.ts +8 -0
- package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
- package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts +12 -0
- package/dts/chart/scrubber/ScrubberAccessibilityView.d.ts.map +1 -0
- package/dts/chart/scrubber/ScrubberBeaconGroup.d.ts.map +1 -1
- package/dts/chart/scrubber/ScrubberProvider.d.ts.map +1 -1
- package/dts/chart/utils/axis.d.ts +20 -9
- package/dts/chart/utils/axis.d.ts.map +1 -1
- package/dts/chart/utils/bar.d.ts +4 -3
- package/dts/chart/utils/bar.d.ts.map +1 -1
- package/dts/chart/utils/chart.d.ts +13 -0
- package/dts/chart/utils/chart.d.ts.map +1 -1
- package/dts/chart/utils/context.d.ts +21 -6
- package/dts/chart/utils/context.d.ts.map +1 -1
- package/dts/chart/utils/gradient.d.ts +3 -1
- package/dts/chart/utils/gradient.d.ts.map +1 -1
- package/dts/chart/utils/path.d.ts +20 -0
- package/dts/chart/utils/path.d.ts.map +1 -1
- package/dts/chart/utils/point.d.ts +7 -0
- package/dts/chart/utils/point.d.ts.map +1 -1
- package/esm/chart/CartesianChart.js +145 -81
- package/esm/chart/Path.js +10 -7
- package/esm/chart/__stories__/CartesianChart.stories.js +10 -0
- package/esm/chart/__stories__/ChartAccessibility.stories.js +721 -0
- package/esm/chart/area/Area.js +19 -9
- package/esm/chart/area/AreaChart.js +11 -9
- package/esm/chart/area/DottedArea.js +11 -6
- package/esm/chart/area/GradientArea.js +11 -6
- package/esm/chart/area/SolidArea.js +3 -1
- package/esm/chart/area/__stories__/AreaChart.stories.js +47 -5
- package/esm/chart/axis/XAxis.js +14 -21
- package/esm/chart/axis/YAxis.js +4 -3
- package/esm/chart/axis/__stories__/Axis.stories.js +65 -48
- package/esm/chart/bar/Bar.js +9 -5
- package/esm/chart/bar/BarChart.js +34 -31
- package/esm/chart/bar/BarPlot.js +7 -5
- package/esm/chart/bar/BarStack.js +176 -36
- package/esm/chart/bar/BarStackGroup.js +37 -27
- package/esm/chart/bar/DefaultBar.js +24 -8
- package/esm/chart/bar/DefaultBarStack.js +24 -10
- package/esm/chart/bar/__stories__/BarChart.stories.js +105 -3
- package/esm/chart/gradient/Gradient.js +2 -1
- package/esm/chart/line/DottedLine.js +3 -1
- package/esm/chart/line/Line.js +32 -19
- package/esm/chart/line/LineChart.js +31 -9
- package/esm/chart/line/SolidLine.js +3 -1
- package/esm/chart/line/__stories__/LineChart.stories.js +115 -46
- package/esm/chart/point/Point.js +2 -1
- package/esm/chart/scrubber/DefaultScrubberBeacon.js +1 -1
- package/esm/chart/scrubber/DefaultScrubberLabel.js +26 -10
- package/esm/chart/scrubber/Scrubber.js +47 -21
- package/esm/chart/scrubber/ScrubberAccessibilityView.js +177 -0
- package/esm/chart/scrubber/ScrubberBeaconGroup.js +24 -20
- package/esm/chart/scrubber/ScrubberProvider.js +29 -24
- package/esm/chart/scrubber/__stories__/Scrubber.stories.js +192 -6
- package/esm/chart/utils/axis.js +42 -14
- package/esm/chart/utils/bar.js +5 -4
- package/esm/chart/utils/chart.js +18 -5
- package/esm/chart/utils/context.js +7 -0
- package/esm/chart/utils/gradient.js +8 -4
- package/esm/chart/utils/path.js +90 -61
- package/esm/chart/utils/point.js +28 -18
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/chart/utils/path.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/chart/utils/path.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,KAAK,kBAAkB,EAAsB,MAAM,SAAS,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,UAGxC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,cAAc,GACd,UAAU,GACV,SAAS,GACT,MAAM,GACN,YAAY,GACZ,WAAW,CAAC;AAEhB;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAO,kBAA6B,EACpC,SAAQ,oBAAiC,oCA2B1C,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,GAAI,sEASzB;IACD,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IACnD,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,KAAG,MAoBH,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,WAAW,GAAI,sEASzB;IACD,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IACzD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,KAAG,MAwFH,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,KAAG,MAE3E,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU,GACrB,GAAG,MAAM,EACT,GAAG,MAAM,EACT,OAAO,MAAM,EACb,QAAQ,MAAM,EACd,QAAQ,MAAM,EACd,UAAU,OAAO,EACjB,aAAa,OAAO,EACpB,SAAQ,oBAAiC,KACxC,MAgCF,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/D,aAAa,MAAM,EACnB,SAAS,MAAM,KACd,MAgCF,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TextHorizontalAlignment, TextVerticalAlignment } from '../text';
|
|
2
|
+
import type { CartesianChartLayout } from './context';
|
|
2
3
|
import { type ChartScaleFunction, type PointAnchor, type SerializableScale } from './scale';
|
|
3
4
|
/**
|
|
4
5
|
* Position a label should be placed relative to the point
|
|
@@ -99,6 +100,7 @@ export declare const projectPoints: ({
|
|
|
99
100
|
yScale,
|
|
100
101
|
xData,
|
|
101
102
|
yData,
|
|
103
|
+
layout,
|
|
102
104
|
}: {
|
|
103
105
|
data: (
|
|
104
106
|
| number
|
|
@@ -112,6 +114,11 @@ export declare const projectPoints: ({
|
|
|
112
114
|
yData?: number[];
|
|
113
115
|
xScale: ChartScaleFunction;
|
|
114
116
|
yScale: ChartScaleFunction;
|
|
117
|
+
/**
|
|
118
|
+
* Chart layout.
|
|
119
|
+
* @default 'vertical'
|
|
120
|
+
*/
|
|
121
|
+
layout?: CartesianChartLayout;
|
|
115
122
|
}) => Array<{
|
|
116
123
|
x: number;
|
|
117
124
|
y: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/chart/utils/point.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE9E,OAAO,EAIL,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/chart/utils/point.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAIL,KAAK,kBAAkB,EAGvB,KAAK,WAAW,EAEhB,KAAK,iBAAiB,EACvB,MAAM,SAAS,CAAC;AAEjB;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,MAAM,EACjB,OAAO,kBAAkB,EACzB,SAAQ,WAAsB,KAC7B,MAgCF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,iBAAiB,EACxB,MAAM,GAAE,WAAsB,GAC7B,MAAM,CAuCR;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,EAChD,CAAC,EACD,CAAC,EACD,MAAM,EACN,MAAM,GACP,EAAE;IACD,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;CAC3B,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAM3B;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,GAAI,2BAK1B;IACD,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,kBAAkB,CAAC;CAC5B,KAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAEzB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GAAI,iDAO3B;IACD,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,KAAG,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4CxC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,kBAAkB,KAC3B;IAAE,mBAAmB,EAAE,uBAAuB,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,CAAA;CAyB1F,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,GAAG,MAAM,EACT,GAAG,MAAM,EACT,UAAU,kBAAkB,EAC5B,QAAQ,MAAM,KACb;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CA0BxB,CAAC"}
|
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
const _excluded = ["series", "children", "animate", "enableScrubbing", "xAxis", "yAxis", "inset", "onScrubberPositionChange", "legend", "legendPosition", "legendAccessibilityLabel", "width", "height", "style", "styles", "allowOverflowGestures", "fontFamilies", "fontProvider", "collapsable"];
|
|
1
|
+
const _excluded = ["series", "children", "layout", "animate", "enableScrubbing", "getScrubberAccessibilityLabel", "scrubberAccessibilityLabelStep", "xAxis", "yAxis", "inset", "onScrubberPositionChange", "legend", "legendPosition", "legendAccessibilityLabel", "width", "height", "style", "styles", "allowOverflowGestures", "fontFamilies", "fontProvider", "collapsable", "accessible", "accessibilityLabel", "accessibilityLiveRegion"];
|
|
2
2
|
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); }
|
|
3
3
|
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; }
|
|
4
4
|
import React, { forwardRef, memo, useCallback, useMemo } from 'react';
|
|
5
5
|
import { useLayout } from '@coinbase/cds-mobile/hooks/useLayout';
|
|
6
6
|
import { Box } from '@coinbase/cds-mobile/layout';
|
|
7
7
|
import { Canvas, Skia } from '@shopify/react-native-skia';
|
|
8
|
+
import { ScrubberAccessibilityView } from './scrubber/ScrubberAccessibilityView';
|
|
8
9
|
import { ScrubberProvider } from './scrubber/ScrubberProvider';
|
|
9
10
|
import { convertToSerializableScale } from './utils/scale';
|
|
10
11
|
import { useChartContextBridge } from './ChartContextBridge';
|
|
11
12
|
import { CartesianChartProvider } from './ChartProvider';
|
|
12
13
|
import { Legend } from './legend';
|
|
13
|
-
import { defaultAxisId,
|
|
14
|
+
import { defaultAxisId, defaultHorizontalLayoutChartInset, defaultVerticalLayoutChartInset, getAxisConfig, getAxisRange, getCartesianAxisDomain, getCartesianAxisScale, getChartInset, getStackedSeriesData as calculateStackedSeriesData, useTotalAxisPadding } from './utils';
|
|
14
15
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
16
|
const ChartCanvas = /*#__PURE__*/memo(_ref => {
|
|
16
17
|
let {
|
|
17
18
|
children,
|
|
18
|
-
style
|
|
19
|
+
style,
|
|
20
|
+
accessible = true,
|
|
21
|
+
accessibilityLabel,
|
|
22
|
+
accessibilityLiveRegion = 'polite'
|
|
19
23
|
} = _ref;
|
|
20
24
|
const ContextBridge = useChartContextBridge();
|
|
25
|
+
const isAccessible = accessible && accessibilityLabel !== null;
|
|
21
26
|
return /*#__PURE__*/_jsx(Canvas, {
|
|
27
|
+
accessibilityLabel: isAccessible ? accessibilityLabel : undefined,
|
|
28
|
+
accessibilityLiveRegion: isAccessible ? accessibilityLiveRegion : undefined,
|
|
29
|
+
accessible: isAccessible,
|
|
22
30
|
style: [{
|
|
23
31
|
width: '100%',
|
|
24
32
|
height: '100%'
|
|
@@ -32,8 +40,11 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
32
40
|
let {
|
|
33
41
|
series,
|
|
34
42
|
children,
|
|
43
|
+
layout = 'vertical',
|
|
35
44
|
animate = true,
|
|
36
45
|
enableScrubbing,
|
|
46
|
+
getScrubberAccessibilityLabel,
|
|
47
|
+
scrubberAccessibilityLabelStep,
|
|
37
48
|
xAxis: xAxisConfigProp,
|
|
38
49
|
yAxis: yAxisConfigProp,
|
|
39
50
|
inset,
|
|
@@ -51,17 +62,27 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
51
62
|
// React Native will collapse views by default when only used
|
|
52
63
|
// to group children, which interferes with gesture-handler
|
|
53
64
|
// https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/gesture-detector/#:~:text=%7B%0A%20%20return%20%3C-,View,-collapsable%3D%7B
|
|
54
|
-
collapsable = false
|
|
65
|
+
collapsable = false,
|
|
66
|
+
accessible = true,
|
|
67
|
+
accessibilityLabel,
|
|
68
|
+
accessibilityLiveRegion = 'polite'
|
|
55
69
|
} = _ref2,
|
|
56
70
|
props = _objectWithoutPropertiesLoose(_ref2, _excluded);
|
|
57
71
|
const [containerLayout, onContainerLayout] = useLayout();
|
|
58
72
|
const chartWidth = containerLayout.width;
|
|
59
73
|
const chartHeight = containerLayout.height;
|
|
60
|
-
const calculatedInset = useMemo(() => getChartInset(inset,
|
|
61
|
-
|
|
62
|
-
// there can only be one x axis but the helper function always returns an array
|
|
63
|
-
const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigProp)[0], [xAxisConfigProp]);
|
|
74
|
+
const calculatedInset = useMemo(() => getChartInset(inset, layout === 'horizontal' ? defaultHorizontalLayoutChartInset : defaultVerticalLayoutChartInset), [inset, layout]);
|
|
75
|
+
const xAxisConfig = useMemo(() => getAxisConfig('x', xAxisConfigProp), [xAxisConfigProp]);
|
|
64
76
|
const yAxisConfig = useMemo(() => getAxisConfig('y', yAxisConfigProp), [yAxisConfigProp]);
|
|
77
|
+
|
|
78
|
+
// Horizontal layout supports multiple value axes on x, but only a single category axis on y.
|
|
79
|
+
// Vertical layout keeps a single x-axis to preserve existing behavior.
|
|
80
|
+
if (layout === 'horizontal' && yAxisConfig.length > 1) {
|
|
81
|
+
throw new Error('When layout="horizontal", only one y-axis is supported. See https://cds.coinbase.com/components/charts/CartesianChart.');
|
|
82
|
+
}
|
|
83
|
+
if (layout !== 'horizontal' && xAxisConfig.length > 1) {
|
|
84
|
+
throw new Error('Multiple x-axes are only supported when layout="horizontal". See https://cds.coinbase.com/components/charts/CartesianChart.');
|
|
85
|
+
}
|
|
65
86
|
const {
|
|
66
87
|
renderedAxes,
|
|
67
88
|
registerAxis,
|
|
@@ -91,54 +112,76 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
91
112
|
};
|
|
92
113
|
}, [chartHeight, chartWidth, totalInset]);
|
|
93
114
|
const {
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
xAxes,
|
|
116
|
+
xScales
|
|
96
117
|
} = useMemo(() => {
|
|
118
|
+
const axes = new Map();
|
|
119
|
+
const scales = new Map();
|
|
97
120
|
if (!chartRect || chartRect.width <= 0 || chartRect.height <= 0) return {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
};
|
|
101
|
-
const domain = getAxisDomain(xAxisConfig, series != null ? series : [], 'x');
|
|
102
|
-
const range = getAxisRange(xAxisConfig, chartRect, 'x');
|
|
103
|
-
const axisConfig = {
|
|
104
|
-
scaleType: xAxisConfig.scaleType,
|
|
105
|
-
domain,
|
|
106
|
-
range,
|
|
107
|
-
data: xAxisConfig.data,
|
|
108
|
-
categoryPadding: xAxisConfig.categoryPadding,
|
|
109
|
-
domainLimit: xAxisConfig.domainLimit
|
|
121
|
+
xAxes: axes,
|
|
122
|
+
xScales: scales
|
|
110
123
|
};
|
|
124
|
+
xAxisConfig.forEach(axisParam => {
|
|
125
|
+
var _axisParam$id, _series$filter, _axisParam$domainLimi;
|
|
126
|
+
const axisId = (_axisParam$id = axisParam.id) != null ? _axisParam$id : defaultAxisId;
|
|
111
127
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
// Get relevant series data.
|
|
129
|
+
const relevantSeries = xAxisConfig.length > 1 ? (_series$filter = series == null ? void 0 : series.filter(s => {
|
|
130
|
+
var _s$xAxisId;
|
|
131
|
+
return ((_s$xAxisId = s.xAxisId) != null ? _s$xAxisId : defaultAxisId) === axisId;
|
|
132
|
+
})) != null ? _series$filter : [] : series != null ? series : [];
|
|
133
|
+
|
|
134
|
+
// Calculate domain and range.
|
|
135
|
+
const dataDomain = getCartesianAxisDomain(axisParam, relevantSeries, 'x', layout);
|
|
136
|
+
const range = getAxisRange(axisParam, chartRect, 'x');
|
|
137
|
+
const axisConfig = {
|
|
138
|
+
scaleType: axisParam.scaleType,
|
|
139
|
+
domain: dataDomain,
|
|
140
|
+
range,
|
|
141
|
+
data: axisParam.data,
|
|
142
|
+
categoryPadding: axisParam.categoryPadding,
|
|
143
|
+
domainLimit: (_axisParam$domainLimi = axisParam.domainLimit) != null ? _axisParam$domainLimi : layout === 'horizontal' ? 'nice' : 'strict'
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Create the scale.
|
|
147
|
+
const scale = getCartesianAxisScale({
|
|
148
|
+
config: axisConfig,
|
|
149
|
+
type: 'x',
|
|
150
|
+
range: axisConfig.range,
|
|
151
|
+
dataDomain: axisConfig.domain,
|
|
152
|
+
layout
|
|
153
|
+
});
|
|
154
|
+
if (scale) {
|
|
155
|
+
scales.set(axisId, scale);
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
157
|
+
// Update axis config with actual scale domain (after .nice() or other adjustments).
|
|
158
|
+
const scaleDomain = scale.domain();
|
|
159
|
+
const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
|
|
160
|
+
min: scaleDomain[0],
|
|
161
|
+
max: scaleDomain[1]
|
|
162
|
+
} : axisConfig.domain;
|
|
163
|
+
axes.set(axisId, _extends({}, axisConfig, {
|
|
164
|
+
domain: actualDomain
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
132
167
|
});
|
|
133
168
|
return {
|
|
134
|
-
|
|
135
|
-
|
|
169
|
+
xAxes: axes,
|
|
170
|
+
xScales: scales
|
|
136
171
|
};
|
|
137
|
-
}, [xAxisConfig, series, chartRect]);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
172
|
+
}, [xAxisConfig, series, chartRect, layout]);
|
|
173
|
+
|
|
174
|
+
// We need a set of serialized scales usable in UI thread.
|
|
175
|
+
const xSerializableScales = useMemo(() => {
|
|
176
|
+
const serializableScales = new Map();
|
|
177
|
+
xScales.forEach((scale, id) => {
|
|
178
|
+
const serializableScale = convertToSerializableScale(scale);
|
|
179
|
+
if (serializableScale) {
|
|
180
|
+
serializableScales.set(id, serializableScale);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return serializableScales;
|
|
184
|
+
}, [xScales]);
|
|
142
185
|
const {
|
|
143
186
|
yAxes,
|
|
144
187
|
yScales
|
|
@@ -150,17 +193,17 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
150
193
|
yScales: scales
|
|
151
194
|
};
|
|
152
195
|
yAxisConfig.forEach(axisParam => {
|
|
153
|
-
var _axisParam$
|
|
154
|
-
const axisId = (_axisParam$
|
|
196
|
+
var _axisParam$id2, _series$filter2, _axisParam$domainLimi2;
|
|
197
|
+
const axisId = (_axisParam$id2 = axisParam.id) != null ? _axisParam$id2 : defaultAxisId;
|
|
155
198
|
|
|
156
|
-
// Get relevant series data
|
|
157
|
-
const relevantSeries = (_series$
|
|
199
|
+
// Get relevant series data.
|
|
200
|
+
const relevantSeries = yAxisConfig.length > 1 ? (_series$filter2 = series == null ? void 0 : series.filter(s => {
|
|
158
201
|
var _s$yAxisId;
|
|
159
202
|
return ((_s$yAxisId = s.yAxisId) != null ? _s$yAxisId : defaultAxisId) === axisId;
|
|
160
|
-
})) != null ? _series$
|
|
203
|
+
})) != null ? _series$filter2 : [] : series != null ? series : [];
|
|
161
204
|
|
|
162
|
-
// Calculate domain and range
|
|
163
|
-
const dataDomain =
|
|
205
|
+
// Calculate domain and range.
|
|
206
|
+
const dataDomain = getCartesianAxisDomain(axisParam, relevantSeries, 'y', layout);
|
|
164
207
|
const range = getAxisRange(axisParam, chartRect, 'y');
|
|
165
208
|
const axisConfig = {
|
|
166
209
|
scaleType: axisParam.scaleType,
|
|
@@ -168,20 +211,21 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
168
211
|
range,
|
|
169
212
|
data: axisParam.data,
|
|
170
213
|
categoryPadding: axisParam.categoryPadding,
|
|
171
|
-
domainLimit: (_axisParam$
|
|
214
|
+
domainLimit: (_axisParam$domainLimi2 = axisParam.domainLimit) != null ? _axisParam$domainLimi2 : layout === 'horizontal' ? 'strict' : 'nice'
|
|
172
215
|
};
|
|
173
216
|
|
|
174
|
-
// Create the scale
|
|
175
|
-
const scale =
|
|
217
|
+
// Create the scale.
|
|
218
|
+
const scale = getCartesianAxisScale({
|
|
176
219
|
config: axisConfig,
|
|
177
220
|
type: 'y',
|
|
178
221
|
range: axisConfig.range,
|
|
179
|
-
dataDomain: axisConfig.domain
|
|
222
|
+
dataDomain: axisConfig.domain,
|
|
223
|
+
layout
|
|
180
224
|
});
|
|
181
225
|
if (scale) {
|
|
182
226
|
scales.set(axisId, scale);
|
|
183
227
|
|
|
184
|
-
// Update axis config with actual scale domain (after .nice() or other adjustments)
|
|
228
|
+
// Update axis config with actual scale domain (after .nice() or other adjustments).
|
|
185
229
|
const scaleDomain = scale.domain();
|
|
186
230
|
const actualDomain = Array.isArray(scaleDomain) && scaleDomain.length === 2 ? {
|
|
187
231
|
min: scaleDomain[0],
|
|
@@ -196,7 +240,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
196
240
|
yAxes: axes,
|
|
197
241
|
yScales: scales
|
|
198
242
|
};
|
|
199
|
-
}, [yAxisConfig, series, chartRect]);
|
|
243
|
+
}, [yAxisConfig, series, chartRect, layout]);
|
|
200
244
|
|
|
201
245
|
// We need a set of serialized scales usable in UI thread
|
|
202
246
|
const ySerializableScales = useMemo(() => {
|
|
@@ -209,11 +253,11 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
209
253
|
});
|
|
210
254
|
return serializableScales;
|
|
211
255
|
}, [yScales]);
|
|
212
|
-
const getXAxis = useCallback(
|
|
256
|
+
const getXAxis = useCallback(id => xAxes.get(id != null ? id : defaultAxisId), [xAxes]);
|
|
213
257
|
const getYAxis = useCallback(id => yAxes.get(id != null ? id : defaultAxisId), [yAxes]);
|
|
214
|
-
const getXScale = useCallback(
|
|
258
|
+
const getXScale = useCallback(id => xScales.get(id != null ? id : defaultAxisId), [xScales]);
|
|
215
259
|
const getYScale = useCallback(id => yScales.get(id != null ? id : defaultAxisId), [yScales]);
|
|
216
|
-
const getXSerializableScale = useCallback(
|
|
260
|
+
const getXSerializableScale = useCallback(id => xSerializableScales.get(id != null ? id : defaultAxisId), [xSerializableScales]);
|
|
217
261
|
const getYSerializableScale = useCallback(id => ySerializableScales.get(id != null ? id : defaultAxisId), [ySerializableScales]);
|
|
218
262
|
const getSeries = useCallback(seriesId => series == null ? void 0 : series.find(s => s.id === seriesId), [series]);
|
|
219
263
|
const stackedDataMap = useMemo(() => {
|
|
@@ -224,20 +268,27 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
224
268
|
if (!seriesId) return undefined;
|
|
225
269
|
return stackedDataMap.get(seriesId);
|
|
226
270
|
}, [stackedDataMap]);
|
|
271
|
+
const categoryAxisIsX = useMemo(() => {
|
|
272
|
+
return layout !== 'horizontal';
|
|
273
|
+
}, [layout]);
|
|
274
|
+
const categoryAxisConfig = useMemo(() => {
|
|
275
|
+
var _xAxisConfig$, _yAxisConfig$;
|
|
276
|
+
return categoryAxisIsX ? (_xAxisConfig$ = xAxisConfig[0]) != null ? _xAxisConfig$ : yAxisConfig[0] : (_yAxisConfig$ = yAxisConfig[0]) != null ? _yAxisConfig$ : xAxisConfig[0];
|
|
277
|
+
}, [categoryAxisIsX, xAxisConfig, yAxisConfig]);
|
|
227
278
|
const dataLength = useMemo(() => {
|
|
228
|
-
// If
|
|
229
|
-
if (
|
|
230
|
-
return
|
|
279
|
+
// If category axis has categorical data, use that length.
|
|
280
|
+
if (categoryAxisConfig.data && categoryAxisConfig.data.length > 0) {
|
|
281
|
+
return categoryAxisConfig.data.length;
|
|
231
282
|
}
|
|
232
283
|
|
|
233
|
-
// Otherwise, find the longest series
|
|
284
|
+
// Otherwise, find the longest series.
|
|
234
285
|
if (!series || series.length === 0) return 0;
|
|
235
286
|
return series.reduce((max, s) => {
|
|
236
287
|
var _seriesData$length;
|
|
237
288
|
const seriesData = getStackedSeriesData(s.id);
|
|
238
289
|
return Math.max(max, (_seriesData$length = seriesData == null ? void 0 : seriesData.length) != null ? _seriesData$length : 0);
|
|
239
290
|
}, 0);
|
|
240
|
-
}, [
|
|
291
|
+
}, [categoryAxisConfig, series, getStackedSeriesData]);
|
|
241
292
|
const getAxisBounds = useCallback(axisId => {
|
|
242
293
|
const axis = renderedAxes.get(axisId);
|
|
243
294
|
if (!axis || !chartRect) return;
|
|
@@ -290,6 +341,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
290
341
|
return Skia.TypefaceFontProvider.Make();
|
|
291
342
|
}, [fontProviderProp]);
|
|
292
343
|
const contextValue = useMemo(() => ({
|
|
344
|
+
layout,
|
|
293
345
|
series: series != null ? series : [],
|
|
294
346
|
getSeries,
|
|
295
347
|
getSeriesData: getStackedSeriesData,
|
|
@@ -309,7 +361,7 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
309
361
|
registerAxis,
|
|
310
362
|
unregisterAxis,
|
|
311
363
|
getAxisBounds
|
|
312
|
-
}), [series, getSeries, getStackedSeriesData, animate, chartWidth, chartHeight, fontFamilies, fontProvider, getXAxis, getYAxis, getXScale, getYScale, getXSerializableScale, getYSerializableScale, chartRect, dataLength, registerAxis, unregisterAxis, getAxisBounds]);
|
|
364
|
+
}), [layout, series, getSeries, getStackedSeriesData, animate, chartWidth, chartHeight, fontFamilies, fontProvider, getXAxis, getYAxis, getXScale, getYScale, getXSerializableScale, getYSerializableScale, chartRect, dataLength, registerAxis, unregisterAxis, getAxisBounds]);
|
|
313
365
|
const rootStyles = useMemo(() => {
|
|
314
366
|
return [style, styles == null ? void 0 : styles.root];
|
|
315
367
|
}, [style, styles == null ? void 0 : styles.root]);
|
|
@@ -327,8 +379,6 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
327
379
|
}, [legend, legendAccessibilityLabel, legendPosition]);
|
|
328
380
|
const rootBoxProps = useMemo(() => _extends({
|
|
329
381
|
ref,
|
|
330
|
-
accessibilityLiveRegion: 'polite',
|
|
331
|
-
accessibilityRole: 'image',
|
|
332
382
|
height,
|
|
333
383
|
style: rootStyles,
|
|
334
384
|
width
|
|
@@ -339,26 +389,40 @@ export const CartesianChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2,
|
|
|
339
389
|
allowOverflowGestures: allowOverflowGestures,
|
|
340
390
|
enableScrubbing: enableScrubbing,
|
|
341
391
|
onScrubberPositionChange: onScrubberPositionChange,
|
|
342
|
-
children: legend ? /*#__PURE__*/_jsxs(Box, _extends({
|
|
343
|
-
flexDirection: legendPosition === 'top' || legendPosition === 'bottom' ? 'column' : 'row'
|
|
344
|
-
|
|
392
|
+
children: legend ? /*#__PURE__*/_jsxs(Box, _extends({
|
|
393
|
+
flexDirection: legendPosition === 'top' || legendPosition === 'bottom' ? 'column' : 'row'
|
|
394
|
+
}, rootBoxProps, {
|
|
395
|
+
children: [(legendPosition === 'top' || legendPosition === 'left') && legendElement, /*#__PURE__*/_jsxs(Box, {
|
|
345
396
|
collapsable: collapsable,
|
|
346
397
|
onLayout: onContainerLayout,
|
|
347
398
|
style: {
|
|
348
399
|
flex: 1
|
|
349
400
|
},
|
|
350
|
-
children: /*#__PURE__*/_jsx(ChartCanvas, {
|
|
401
|
+
children: [/*#__PURE__*/_jsx(ChartCanvas, {
|
|
402
|
+
accessibilityLabel: accessibilityLabel,
|
|
403
|
+
accessibilityLiveRegion: accessibilityLiveRegion,
|
|
404
|
+
accessible: accessible,
|
|
351
405
|
style: styles == null ? void 0 : styles.chart,
|
|
352
406
|
children: children
|
|
353
|
-
})
|
|
407
|
+
}), /*#__PURE__*/_jsx(ScrubberAccessibilityView, {
|
|
408
|
+
accessibilityLabel: getScrubberAccessibilityLabel,
|
|
409
|
+
accessibilityStep: scrubberAccessibilityLabelStep
|
|
410
|
+
})]
|
|
354
411
|
}), (legendPosition === 'bottom' || legendPosition === 'right') && legendElement]
|
|
355
|
-
})) : /*#__PURE__*/
|
|
412
|
+
})) : /*#__PURE__*/_jsxs(Box, _extends({
|
|
356
413
|
collapsable: collapsable,
|
|
357
|
-
onLayout: onContainerLayout
|
|
358
|
-
|
|
414
|
+
onLayout: onContainerLayout
|
|
415
|
+
}, rootBoxProps, {
|
|
416
|
+
children: [/*#__PURE__*/_jsx(ChartCanvas, {
|
|
417
|
+
accessibilityLabel: accessibilityLabel,
|
|
418
|
+
accessibilityLiveRegion: accessibilityLiveRegion,
|
|
419
|
+
accessible: accessible,
|
|
359
420
|
style: styles == null ? void 0 : styles.chart,
|
|
360
421
|
children: children
|
|
361
|
-
})
|
|
422
|
+
}), /*#__PURE__*/_jsx(ScrubberAccessibilityView, {
|
|
423
|
+
accessibilityLabel: getScrubberAccessibilityLabel,
|
|
424
|
+
accessibilityStep: scrubberAccessibilityLabelStep
|
|
425
|
+
})]
|
|
362
426
|
}))
|
|
363
427
|
})
|
|
364
428
|
});
|
package/esm/chart/Path.js
CHANGED
|
@@ -115,29 +115,32 @@ export const Path = /*#__PURE__*/memo(props => {
|
|
|
115
115
|
initialClipPath: null,
|
|
116
116
|
targetClipPath: null
|
|
117
117
|
};
|
|
118
|
+
const categoryAxisIsX = context.layout !== 'horizontal';
|
|
119
|
+
const fullWidth = rect.width + totalOffset;
|
|
120
|
+
const fullHeight = rect.height + totalOffset;
|
|
118
121
|
|
|
119
|
-
// Initial clip path
|
|
122
|
+
// Initial clip path starts collapsed on the category axis.
|
|
120
123
|
const initial = Skia.Path.Make();
|
|
121
124
|
initial.addRect({
|
|
122
125
|
x: rect.x - clipOffset,
|
|
123
126
|
y: rect.y - clipOffset,
|
|
124
|
-
width: 0,
|
|
125
|
-
height:
|
|
127
|
+
width: categoryAxisIsX ? 0 : fullWidth,
|
|
128
|
+
height: categoryAxisIsX ? fullHeight : 0
|
|
126
129
|
});
|
|
127
130
|
|
|
128
|
-
// Target clip path
|
|
131
|
+
// Target clip path is fully expanded.
|
|
129
132
|
const target = Skia.Path.Make();
|
|
130
133
|
target.addRect({
|
|
131
134
|
x: rect.x - clipOffset,
|
|
132
135
|
y: rect.y - clipOffset,
|
|
133
|
-
width:
|
|
134
|
-
height:
|
|
136
|
+
width: fullWidth,
|
|
137
|
+
height: fullHeight
|
|
135
138
|
});
|
|
136
139
|
return {
|
|
137
140
|
initialClipPath: initial,
|
|
138
141
|
targetClipPath: target
|
|
139
142
|
};
|
|
140
|
-
}, [rect, clipOffset, totalOffset]);
|
|
143
|
+
}, [rect, clipOffset, totalOffset, context.layout]);
|
|
141
144
|
|
|
142
145
|
// Use usePathInterpolation for animated clip path
|
|
143
146
|
const animatedClipPath = usePathInterpolation(clipProgress, [0, 1], shouldAnimateClip && initialClipPath && targetClipPath ? [initialClipPath, targetClipPath] : targetClipPath ? [targetClipPath, targetClipPath] : [Skia.Path.Make(), Skia.Path.Make()]);
|
|
@@ -250,11 +250,21 @@ const PriceWithVolumeChart = /*#__PURE__*/memo(_ref3 => {
|
|
|
250
250
|
day: 'numeric'
|
|
251
251
|
});
|
|
252
252
|
}, []);
|
|
253
|
+
const formatVolume = useCallback(volume => {
|
|
254
|
+
return (volume / 1000).toFixed(2) + "K";
|
|
255
|
+
}, []);
|
|
253
256
|
const scrubberLabel = useCallback(dataIndex => {
|
|
254
257
|
return formatDate(btcDates[dataIndex]);
|
|
255
258
|
}, [formatDate]);
|
|
259
|
+
const chartAccessibilityLabel = useMemo(() => {
|
|
260
|
+
const lastIndex = btcPrices.length - 1;
|
|
261
|
+
return "Bitcoin chart. Current date " + formatDate(btcDates[lastIndex]) + ". Current price " + formatPriceInThousands(btcPrices[lastIndex]) + ". Current volume " + formatVolume(btcVolumes[lastIndex]) + ".";
|
|
262
|
+
}, [formatDate, formatPriceInThousands, formatVolume]);
|
|
263
|
+
const getScrubberAccessibilityLabel = useCallback(dataIndex => "Bitcoin on " + formatDate(btcDates[dataIndex]) + ". Price " + formatPriceInThousands(btcPrices[dataIndex]) + ". Volume " + formatVolume(btcVolumes[dataIndex]) + ".", [formatDate, formatPriceInThousands, formatVolume]);
|
|
256
264
|
return /*#__PURE__*/_jsxs(CartesianChart, {
|
|
257
265
|
enableScrubbing: true,
|
|
266
|
+
accessibilityLabel: chartAccessibilityLabel,
|
|
267
|
+
getScrubberAccessibilityLabel: getScrubberAccessibilityLabel,
|
|
258
268
|
height: defaultChartHeight,
|
|
259
269
|
onScrubberPositionChange: onScrubberPositionChange,
|
|
260
270
|
series: [{
|