@coinbase/cds-mobile-visualization 3.4.0-beta.22 → 3.4.0-beta.23
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 +6 -0
- package/dts/chart/CartesianChart.d.ts +39 -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 +5 -5
- 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/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 +107 -68
- package/esm/chart/Path.js +10 -7
- 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 +30 -2
- package/esm/chart/axis/XAxis.js +14 -21
- package/esm/chart/axis/YAxis.js +4 -3
- 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 +99 -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 +9 -8
- package/esm/chart/line/SolidLine.js +3 -1
- package/esm/chart/line/__stories__/LineChart.stories.js +31 -0
- 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/ScrubberBeaconGroup.js +24 -20
- package/esm/chart/scrubber/ScrubberProvider.js +29 -24
- package/esm/chart/scrubber/__stories__/Scrubber.stories.js +135 -1
- 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
package/esm/chart/axis/XAxis.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const _excluded = ["position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height", "bandGridLinePlacement", "bandTickMarkPlacement"];
|
|
1
|
+
const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height", "bandGridLinePlacement", "bandTickMarkPlacement"];
|
|
2
2
|
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; }
|
|
3
3
|
import { memo, useCallback, useEffect, useId, useMemo } from 'react';
|
|
4
4
|
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
@@ -15,6 +15,7 @@ const AXIS_HEIGHT = 32;
|
|
|
15
15
|
const LABEL_SIZE = 20;
|
|
16
16
|
export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
17
17
|
let {
|
|
18
|
+
axisId,
|
|
18
19
|
position = 'bottom',
|
|
19
20
|
showGrid,
|
|
20
21
|
requestedTickCount,
|
|
@@ -44,14 +45,15 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
|
44
45
|
const {
|
|
45
46
|
animate,
|
|
46
47
|
drawingArea,
|
|
48
|
+
layout,
|
|
47
49
|
getXScale,
|
|
48
50
|
getXAxis,
|
|
49
51
|
registerAxis,
|
|
50
52
|
unregisterAxis,
|
|
51
53
|
getAxisBounds
|
|
52
54
|
} = useCartesianChartContext();
|
|
53
|
-
const xScale = getXScale();
|
|
54
|
-
const xAxis = getXAxis();
|
|
55
|
+
const xScale = getXScale(axisId);
|
|
56
|
+
const xAxis = getXAxis(axisId);
|
|
55
57
|
const axisBounds = getAxisBounds(registrationId);
|
|
56
58
|
useEffect(() => {
|
|
57
59
|
registerAxis(registrationId, position, height);
|
|
@@ -62,15 +64,12 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
|
62
64
|
// If we have string labels and no custom formatter, use the labels
|
|
63
65
|
const axisData = xAxis == null ? void 0 : xAxis.data;
|
|
64
66
|
const hasStringLabels = axisData && Array.isArray(axisData) && typeof axisData[0] === 'string';
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// For band scales with string data, value is an index
|
|
68
|
-
if (hasStringLabels && typeof value === 'number' && axisData[value] !== undefined) {
|
|
69
|
-
finalValue = axisData[value];
|
|
67
|
+
if (hasStringLabels && !tickLabelFormatter && axisData[value] !== undefined) {
|
|
68
|
+
return axisData[value];
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
//
|
|
73
|
-
return (_tickLabelFormatter = tickLabelFormatter == null ? void 0 : tickLabelFormatter(
|
|
71
|
+
// Otherwise passes raw index to formatter
|
|
72
|
+
return (_tickLabelFormatter = tickLabelFormatter == null ? void 0 : tickLabelFormatter(value)) != null ? _tickLabelFormatter : value;
|
|
74
73
|
}, [xAxis == null ? void 0 : xAxis.data, tickLabelFormatter]);
|
|
75
74
|
const ticksData = useMemo(() => {
|
|
76
75
|
if (!xScale) return [];
|
|
@@ -89,27 +88,21 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
|
|
|
89
88
|
const domain = xScale.domain();
|
|
90
89
|
categories = domain.map(String);
|
|
91
90
|
}
|
|
92
|
-
let possibleTickValues;
|
|
93
|
-
|
|
94
|
-
// If we have discrete data, we can use the indices as possible tick values
|
|
95
|
-
if (axisData && Array.isArray(axisData) && (typeof axisData[0] === 'string' || typeof axisData[0] === 'number' && isCategoricalScale(xScale))) {
|
|
96
|
-
possibleTickValues = Array.from({
|
|
97
|
-
length: axisData.length
|
|
98
|
-
}, (_, i) => i);
|
|
99
|
-
}
|
|
100
91
|
return getAxisTicksData({
|
|
101
92
|
scaleFunction: xScale,
|
|
102
93
|
ticks,
|
|
103
|
-
requestedTickCount,
|
|
94
|
+
requestedTickCount: requestedTickCount != null ? requestedTickCount : layout === 'horizontal' ? 5 : undefined,
|
|
104
95
|
categories,
|
|
105
|
-
possibleTickValues
|
|
96
|
+
possibleTickValues: axisData && Array.isArray(axisData) && typeof axisData[0] === 'string' ? Array.from({
|
|
97
|
+
length: axisData.length
|
|
98
|
+
}, (_, i) => i) : undefined,
|
|
106
99
|
tickInterval: tickInterval,
|
|
107
100
|
options: {
|
|
108
101
|
minStep: tickMinStep,
|
|
109
102
|
maxStep: tickMaxStep
|
|
110
103
|
}
|
|
111
104
|
});
|
|
112
|
-
}, [ticks, xScale, requestedTickCount, tickInterval, tickMinStep, tickMaxStep, xAxis == null ? void 0 : xAxis.data]);
|
|
105
|
+
}, [ticks, xScale, requestedTickCount, tickInterval, tickMinStep, tickMaxStep, xAxis == null ? void 0 : xAxis.data, layout]);
|
|
113
106
|
const isBandScale = useMemo(() => {
|
|
114
107
|
if (!xScale) return false;
|
|
115
108
|
return isCategoricalScale(xScale);
|
package/esm/chart/axis/YAxis.js
CHANGED
|
@@ -18,7 +18,7 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
18
18
|
axisId,
|
|
19
19
|
position = 'right',
|
|
20
20
|
showGrid,
|
|
21
|
-
requestedTickCount
|
|
21
|
+
requestedTickCount,
|
|
22
22
|
ticks,
|
|
23
23
|
tickLabelFormatter,
|
|
24
24
|
TickLabelComponent = DefaultAxisTickLabel,
|
|
@@ -43,6 +43,7 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
43
43
|
const {
|
|
44
44
|
animate,
|
|
45
45
|
drawingArea,
|
|
46
|
+
layout,
|
|
46
47
|
getYScale,
|
|
47
48
|
getYAxis,
|
|
48
49
|
registerAxis,
|
|
@@ -94,12 +95,12 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
|
|
|
94
95
|
return getAxisTicksData({
|
|
95
96
|
scaleFunction: yScale,
|
|
96
97
|
ticks,
|
|
97
|
-
requestedTickCount: tickInterval !== undefined ? undefined : requestedTickCount != null ? requestedTickCount : 5,
|
|
98
|
+
requestedTickCount: tickInterval !== undefined ? undefined : requestedTickCount != null ? requestedTickCount : layout === 'horizontal' ? undefined : 5,
|
|
98
99
|
categories,
|
|
99
100
|
possibleTickValues: axisData && Array.isArray(axisData) && typeof axisData[0] === 'number' ? axisData : undefined,
|
|
100
101
|
tickInterval: tickInterval
|
|
101
102
|
});
|
|
102
|
-
}, [ticks, yScale, requestedTickCount, tickInterval, yAxis == null ? void 0 : yAxis.data]);
|
|
103
|
+
}, [ticks, yScale, requestedTickCount, tickInterval, yAxis == null ? void 0 : yAxis.data, layout]);
|
|
103
104
|
const isBandScale = useMemo(() => {
|
|
104
105
|
if (!yScale) return false;
|
|
105
106
|
return isCategoricalScale(yScale);
|
package/esm/chart/bar/Bar.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { memo, useMemo } from 'react';
|
|
2
2
|
import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
|
|
3
|
+
import { useCartesianChartContext } from '../ChartProvider';
|
|
3
4
|
import { getBarPath } from '../utils';
|
|
4
5
|
import { DefaultBar } from './DefaultBar';
|
|
5
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -21,7 +22,7 @@ export const Bar = /*#__PURE__*/memo(_ref => {
|
|
|
21
22
|
y,
|
|
22
23
|
width,
|
|
23
24
|
height,
|
|
24
|
-
|
|
25
|
+
origin: originProp,
|
|
25
26
|
dataX,
|
|
26
27
|
dataY,
|
|
27
28
|
seriesId,
|
|
@@ -37,14 +38,17 @@ export const Bar = /*#__PURE__*/memo(_ref => {
|
|
|
37
38
|
transition
|
|
38
39
|
} = _ref;
|
|
39
40
|
const theme = useTheme();
|
|
41
|
+
const {
|
|
42
|
+
layout
|
|
43
|
+
} = useCartesianChartContext();
|
|
40
44
|
|
|
41
45
|
// Use theme color as default if no fill is provided
|
|
42
46
|
const effectiveFill = fill != null ? fill : theme.color.fgPrimary;
|
|
43
47
|
const borderRadiusPixels = useMemo(() => borderRadius != null ? borderRadius : 0, [borderRadius]);
|
|
44
48
|
const barPath = useMemo(() => {
|
|
45
|
-
return getBarPath(x, y, width, height, borderRadiusPixels, roundTop, roundBottom);
|
|
46
|
-
}, [x, y, width, height, borderRadiusPixels, roundTop, roundBottom]);
|
|
47
|
-
const
|
|
49
|
+
return getBarPath(x, y, width, height, borderRadiusPixels, roundTop, roundBottom, layout);
|
|
50
|
+
}, [x, y, width, height, borderRadiusPixels, roundTop, roundBottom, layout]);
|
|
51
|
+
const effectiveOrigin = originProp != null ? originProp : layout === 'horizontal' ? x : y + height;
|
|
48
52
|
if (!barPath) {
|
|
49
53
|
return null;
|
|
50
54
|
}
|
|
@@ -58,7 +62,7 @@ export const Bar = /*#__PURE__*/memo(_ref => {
|
|
|
58
62
|
fill: effectiveFill,
|
|
59
63
|
fillOpacity: fillOpacity,
|
|
60
64
|
height: height,
|
|
61
|
-
|
|
65
|
+
origin: effectiveOrigin,
|
|
62
66
|
roundBottom: roundBottom,
|
|
63
67
|
roundTop: roundTop,
|
|
64
68
|
seriesId: seriesId,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
const _excluded = ["series", "stacked", "showXAxis", "showYAxis", "xAxis", "yAxis", "inset", "children", "barPadding", "BarComponent", "fillOpacity", "stroke", "strokeWidth", "borderRadius", "roundBaseline", "BarStackComponent", "stackGap", "barMinSize", "stackMinSize", "transitions", "transition"],
|
|
2
|
-
_excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range"],
|
|
2
|
+
_excluded2 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"],
|
|
3
3
|
_excluded3 = ["scaleType", "data", "categoryPadding", "domain", "domainLimit", "range", "id"];
|
|
4
4
|
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); }
|
|
5
5
|
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
6
|
import { forwardRef, memo, useMemo } from 'react';
|
|
7
7
|
import { XAxis, YAxis } from '../axis';
|
|
8
8
|
import { CartesianChart } from '../CartesianChart';
|
|
9
|
-
import {
|
|
9
|
+
import { defaultStackId } from '../utils';
|
|
10
10
|
import { BarPlot } from './BarPlot';
|
|
11
11
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
12
|
export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
13
13
|
let {
|
|
14
|
-
series,
|
|
14
|
+
series: seriesProp,
|
|
15
15
|
stacked,
|
|
16
16
|
showXAxis,
|
|
17
17
|
showYAxis,
|
|
@@ -34,21 +34,19 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
|
|
|
34
34
|
transition
|
|
35
35
|
} = _ref,
|
|
36
36
|
chartProps = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return series.map(s => {
|
|
37
|
+
const series = useMemo(() => {
|
|
38
|
+
if (!stacked || !seriesProp) return seriesProp;
|
|
39
|
+
return seriesProp.map(s => {
|
|
41
40
|
var _s$stackId;
|
|
42
41
|
return _extends({}, s, {
|
|
43
42
|
stackId: (_s$stackId = s.stackId) != null ? _s$stackId : defaultStackId
|
|
44
43
|
});
|
|
45
44
|
});
|
|
46
|
-
}, [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const seriesIds = seriesToRender == null ? void 0 : seriesToRender.map(s => s.id);
|
|
45
|
+
}, [seriesProp, stacked]);
|
|
46
|
+
const seriesIds = useMemo(() => series == null ? void 0 : series.map(s => s.id), [series]);
|
|
47
|
+
const isHorizontal = chartProps.layout === 'horizontal';
|
|
48
|
+
const defaultXScaleType = isHorizontal ? 'linear' : 'band';
|
|
49
|
+
const defaultYScaleType = isHorizontal ? 'band' : 'linear';
|
|
52
50
|
|
|
53
51
|
// Split axis props into config props for Chart and visual props for axis components
|
|
54
52
|
const _ref2 = xAxis || {},
|
|
@@ -58,7 +56,8 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
|
|
|
58
56
|
categoryPadding: xCategoryPadding,
|
|
59
57
|
domain: xDomain,
|
|
60
58
|
domainLimit: xDomainLimit,
|
|
61
|
-
range: xRange
|
|
59
|
+
range: xRange,
|
|
60
|
+
id: xAxisId
|
|
62
61
|
} = _ref2,
|
|
63
62
|
xAxisVisualProps = _objectWithoutPropertiesLoose(_ref2, _excluded2);
|
|
64
63
|
const _ref3 = yAxis || {},
|
|
@@ -72,14 +71,6 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
|
|
|
72
71
|
id: yAxisId
|
|
73
72
|
} = _ref3,
|
|
74
73
|
yAxisVisualProps = _objectWithoutPropertiesLoose(_ref3, _excluded3);
|
|
75
|
-
const xAxisConfig = {
|
|
76
|
-
scaleType: xScaleType != null ? xScaleType : 'band',
|
|
77
|
-
data: xData,
|
|
78
|
-
categoryPadding: xCategoryPadding,
|
|
79
|
-
domain: xDomain,
|
|
80
|
-
domainLimit: xDomainLimit,
|
|
81
|
-
range: xRange
|
|
82
|
-
};
|
|
83
74
|
const hasNegativeValues = useMemo(() => {
|
|
84
75
|
if (!series) return false;
|
|
85
76
|
return series.some(s => {
|
|
@@ -87,25 +78,37 @@ export const BarChart = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =>
|
|
|
87
78
|
return (_s$data = s.data) == null ? void 0 : _s$data.some(value => typeof value === 'number' && value < 0 || Array.isArray(value) && value.some(v => typeof v === 'number' && v < 0));
|
|
88
79
|
});
|
|
89
80
|
}, [series]);
|
|
81
|
+
const xAxisConfig = useMemo(() => ({
|
|
82
|
+
scaleType: xScaleType != null ? xScaleType : defaultXScaleType,
|
|
83
|
+
data: xData,
|
|
84
|
+
categoryPadding: xCategoryPadding,
|
|
85
|
+
domain: isHorizontal && !hasNegativeValues ? _extends({
|
|
86
|
+
min: 0
|
|
87
|
+
}, xDomain) : xDomain,
|
|
88
|
+
domainLimit: xDomainLimit,
|
|
89
|
+
range: xRange
|
|
90
|
+
}), [xScaleType, defaultXScaleType, xData, xCategoryPadding, isHorizontal, hasNegativeValues, xDomain, xDomainLimit, xRange]);
|
|
90
91
|
|
|
91
|
-
// Set default min domain to 0 for
|
|
92
|
-
const yAxisConfig = {
|
|
93
|
-
scaleType: yScaleType,
|
|
92
|
+
// Set default min domain to 0 for bar chart, but only if there are no negative values.
|
|
93
|
+
const yAxisConfig = useMemo(() => ({
|
|
94
|
+
scaleType: yScaleType != null ? yScaleType : defaultYScaleType,
|
|
94
95
|
data: yData,
|
|
95
96
|
categoryPadding: yCategoryPadding,
|
|
96
|
-
domain: hasNegativeValues ?
|
|
97
|
+
domain: !isHorizontal && !hasNegativeValues ? _extends({
|
|
97
98
|
min: 0
|
|
98
|
-
}, yDomain),
|
|
99
|
+
}, yDomain) : yDomain,
|
|
99
100
|
domainLimit: yDomainLimit,
|
|
100
101
|
range: yRange
|
|
101
|
-
};
|
|
102
|
+
}), [yScaleType, defaultYScaleType, yData, yCategoryPadding, isHorizontal, hasNegativeValues, yDomain, yDomainLimit, yRange]);
|
|
102
103
|
return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, chartProps, {
|
|
103
104
|
ref: ref,
|
|
104
|
-
inset:
|
|
105
|
-
series:
|
|
105
|
+
inset: inset,
|
|
106
|
+
series: series,
|
|
106
107
|
xAxis: xAxisConfig,
|
|
107
108
|
yAxis: yAxisConfig,
|
|
108
|
-
children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({
|
|
109
|
+
children: [showXAxis && /*#__PURE__*/_jsx(XAxis, _extends({
|
|
110
|
+
axisId: xAxisId
|
|
111
|
+
}, xAxisVisualProps)), showYAxis && /*#__PURE__*/_jsx(YAxis, _extends({
|
|
109
112
|
axisId: yAxisId
|
|
110
113
|
}, yAxisVisualProps)), /*#__PURE__*/_jsx(BarPlot, {
|
|
111
114
|
BarComponent: BarComponent,
|
package/esm/chart/bar/BarPlot.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memo,
|
|
1
|
+
import { memo, useMemo } from 'react';
|
|
2
2
|
import { Group, Skia } from '@shopify/react-native-skia';
|
|
3
3
|
import { useCartesianChartContext } from '../ChartProvider';
|
|
4
4
|
import { defaultAxisId } from '../utils';
|
|
@@ -31,7 +31,6 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
|
|
|
31
31
|
series: allSeries,
|
|
32
32
|
drawingArea
|
|
33
33
|
} = useCartesianChartContext();
|
|
34
|
-
const clipPathId = useId();
|
|
35
34
|
const targetSeries = useMemo(() => {
|
|
36
35
|
// Then filter by seriesIds if provided
|
|
37
36
|
if (seriesIds !== undefined) {
|
|
@@ -42,16 +41,18 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
|
|
|
42
41
|
const stackGroups = useMemo(() => {
|
|
43
42
|
const groups = new Map();
|
|
44
43
|
|
|
45
|
-
// Group series into stacks based on stackId +
|
|
44
|
+
// Group series into stacks based on stackId + axis ID combination
|
|
46
45
|
targetSeries.forEach(series => {
|
|
47
|
-
var _series$yAxisId;
|
|
46
|
+
var _series$xAxisId, _series$yAxisId;
|
|
47
|
+
const xAxisId = (_series$xAxisId = series.xAxisId) != null ? _series$xAxisId : defaultAxisId;
|
|
48
48
|
const yAxisId = (_series$yAxisId = series.yAxisId) != null ? _series$yAxisId : defaultAxisId;
|
|
49
49
|
const stackId = series.stackId || "individual-" + series.id;
|
|
50
|
-
const stackKey = stackId + ":" + yAxisId;
|
|
50
|
+
const stackKey = stackId + ":" + xAxisId + ":" + yAxisId;
|
|
51
51
|
if (!groups.has(stackKey)) {
|
|
52
52
|
groups.set(stackKey, {
|
|
53
53
|
stackId: stackKey,
|
|
54
54
|
series: [],
|
|
55
|
+
xAxisId: series.xAxisId,
|
|
55
56
|
yAxisId: series.yAxisId
|
|
56
57
|
});
|
|
57
58
|
}
|
|
@@ -98,6 +99,7 @@ export const BarPlot = /*#__PURE__*/memo(_ref => {
|
|
|
98
99
|
totalStacks: stackGroups.length,
|
|
99
100
|
transition: transition,
|
|
100
101
|
transitions: transitions,
|
|
102
|
+
xAxisId: group.xAxisId,
|
|
101
103
|
yAxisId: group.yAxisId
|
|
102
104
|
}, group.stackId))
|
|
103
105
|
});
|
|
@@ -21,10 +21,13 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
21
21
|
let {
|
|
22
22
|
series,
|
|
23
23
|
categoryIndex,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
indexPos,
|
|
25
|
+
thickness,
|
|
26
|
+
indexScale,
|
|
27
|
+
valueScale,
|
|
27
28
|
rect,
|
|
29
|
+
xAxisId,
|
|
30
|
+
yAxisId,
|
|
28
31
|
BarComponent: defaultBarComponent,
|
|
29
32
|
fillOpacity: defaultFillOpacity,
|
|
30
33
|
stroke: defaultStroke,
|
|
@@ -40,24 +43,30 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
40
43
|
} = _ref;
|
|
41
44
|
const theme = useTheme();
|
|
42
45
|
const {
|
|
46
|
+
layout,
|
|
43
47
|
getSeriesData,
|
|
44
48
|
getXAxis,
|
|
45
|
-
|
|
49
|
+
getYAxis
|
|
46
50
|
} = useCartesianChartContext();
|
|
47
|
-
const xAxis = getXAxis();
|
|
48
|
-
const
|
|
51
|
+
const xAxis = getXAxis(xAxisId);
|
|
52
|
+
const yAxis = getYAxis(yAxisId);
|
|
53
|
+
const barsGrowVertically = layout !== 'horizontal';
|
|
49
54
|
const baseline = useMemo(() => {
|
|
50
|
-
var
|
|
51
|
-
const domain =
|
|
55
|
+
var _valueScale;
|
|
56
|
+
const domain = valueScale.domain();
|
|
52
57
|
const [domainMin, domainMax] = domain;
|
|
53
58
|
const baselineValue = domainMin >= 0 ? domainMin : domainMax <= 0 ? domainMax : 0;
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
const fallback = barsGrowVertically ? rect.y + rect.height : rect.x;
|
|
60
|
+
const baselinePos = (_valueScale = valueScale(baselineValue)) != null ? _valueScale : fallback;
|
|
61
|
+
if (barsGrowVertically) {
|
|
62
|
+
return Math.max(rect.y, Math.min(baselinePos, rect.y + rect.height));
|
|
63
|
+
}
|
|
64
|
+
return Math.max(rect.x, Math.min(baselinePos, rect.x + rect.width));
|
|
65
|
+
}, [rect, valueScale, barsGrowVertically]);
|
|
57
66
|
const seriesGradients = useMemo(() => {
|
|
58
67
|
return series.map(s => {
|
|
59
|
-
if (!s.gradient
|
|
60
|
-
const gradientScale = s.gradient.axis === 'x' ?
|
|
68
|
+
if (!s.gradient) return;
|
|
69
|
+
const gradientScale = s.gradient.axis === 'x' ? barsGrowVertically ? indexScale : valueScale : barsGrowVertically ? valueScale : indexScale;
|
|
61
70
|
const serializableScale = convertToSerializableScale(gradientScale);
|
|
62
71
|
if (!serializableScale) return;
|
|
63
72
|
const domain = {
|
|
@@ -72,14 +81,140 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
72
81
|
stops
|
|
73
82
|
};
|
|
74
83
|
});
|
|
75
|
-
}, [series,
|
|
84
|
+
}, [series, indexScale, valueScale, barsGrowVertically]);
|
|
76
85
|
|
|
77
86
|
// Calculate bars for this specific category
|
|
78
87
|
const {
|
|
79
88
|
bars,
|
|
80
89
|
stackRect
|
|
81
90
|
} = useMemo(() => {
|
|
91
|
+
const x = indexPos;
|
|
92
|
+
const width = thickness;
|
|
93
|
+
const yScale = valueScale;
|
|
82
94
|
let allBars = [];
|
|
95
|
+
if (!barsGrowVertically) {
|
|
96
|
+
let minX = Infinity;
|
|
97
|
+
let maxX = -Infinity;
|
|
98
|
+
series.forEach(s => {
|
|
99
|
+
var _yScale, _yScale2;
|
|
100
|
+
const data = getSeriesData(s.id);
|
|
101
|
+
if (!data) return;
|
|
102
|
+
const value = data[categoryIndex];
|
|
103
|
+
if (value === null || value === undefined) return;
|
|
104
|
+
const originalData = s.data;
|
|
105
|
+
const originalValue = originalData == null ? void 0 : originalData[categoryIndex];
|
|
106
|
+
const shouldApplyGap = !Array.isArray(originalValue);
|
|
107
|
+
const [bottom, top] = value.sort((a, b) => a - b);
|
|
108
|
+
const edgeBottom = (_yScale = yScale(bottom)) != null ? _yScale : baseline;
|
|
109
|
+
const edgeTop = (_yScale2 = yScale(top)) != null ? _yScale2 : baseline;
|
|
110
|
+
const length = Math.abs(edgeBottom - edgeTop);
|
|
111
|
+
const barX = Math.min(edgeBottom, edgeTop);
|
|
112
|
+
if (length <= 0) return;
|
|
113
|
+
minX = Math.min(minX, barX);
|
|
114
|
+
maxX = Math.max(maxX, barX + length);
|
|
115
|
+
let barFill = s.color || theme.color.fgPrimary;
|
|
116
|
+
const seriesGradientConfig = seriesGradients.find(g => (g == null ? void 0 : g.seriesId) === s.id);
|
|
117
|
+
if (seriesGradientConfig && originalValue !== null && originalValue !== undefined) {
|
|
118
|
+
var _seriesGradientConfig;
|
|
119
|
+
const axis = (_seriesGradientConfig = seriesGradientConfig.gradient.axis) != null ? _seriesGradientConfig : 'y';
|
|
120
|
+
const evalValue = axis === 'x' ? Array.isArray(originalValue) ? originalValue[1] : originalValue : categoryIndex;
|
|
121
|
+
const evaluatedColor = evaluateGradientAtValue(seriesGradientConfig.stops, evalValue, seriesGradientConfig.scale);
|
|
122
|
+
if (evaluatedColor) {
|
|
123
|
+
barFill = evaluatedColor;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const roundTop = roundBaseline || Math.abs(edgeTop - baseline) >= EPSILON;
|
|
127
|
+
const roundBottom = roundBaseline || Math.abs(edgeBottom - baseline) >= EPSILON;
|
|
128
|
+
allBars.push({
|
|
129
|
+
seriesId: s.id,
|
|
130
|
+
x: barX,
|
|
131
|
+
y: x,
|
|
132
|
+
width: length,
|
|
133
|
+
height: width,
|
|
134
|
+
dataY: value,
|
|
135
|
+
fill: barFill,
|
|
136
|
+
roundTop,
|
|
137
|
+
roundBottom,
|
|
138
|
+
BarComponent: s.BarComponent,
|
|
139
|
+
shouldApplyGap
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
if (stackGap && allBars.length > 1) {
|
|
143
|
+
const barsAboveBaseline = allBars.filter(bar => {
|
|
144
|
+
const [bottom, top] = bar.dataY.sort((a, b) => a - b);
|
|
145
|
+
return bottom >= 0 && top !== bottom && bar.shouldApplyGap;
|
|
146
|
+
});
|
|
147
|
+
const barsBelowBaseline = allBars.filter(bar => {
|
|
148
|
+
const [bottom, top] = bar.dataY.sort((a, b) => a - b);
|
|
149
|
+
return bottom <= 0 && bottom !== top && bar.shouldApplyGap;
|
|
150
|
+
});
|
|
151
|
+
if (barsAboveBaseline.length > 1) {
|
|
152
|
+
const totalGapSpace = stackGap * (barsAboveBaseline.length - 1);
|
|
153
|
+
const totalDataLength = barsAboveBaseline.reduce((sum, bar) => sum + bar.width, 0);
|
|
154
|
+
const lengthReduction = totalGapSpace / totalDataLength;
|
|
155
|
+
const sortedBars = barsAboveBaseline.sort((a, b) => a.x - b.x);
|
|
156
|
+
let currentEdge = baseline;
|
|
157
|
+
sortedBars.forEach((bar, index) => {
|
|
158
|
+
const newLength = bar.width * (1 - lengthReduction);
|
|
159
|
+
const newX = currentEdge;
|
|
160
|
+
currentEdge = newX + newLength + (index < sortedBars.length - 1 ? stackGap : 0);
|
|
161
|
+
const barIndex = allBars.findIndex(b => b.seriesId === bar.seriesId);
|
|
162
|
+
if (barIndex !== -1) {
|
|
163
|
+
allBars[barIndex] = _extends({}, allBars[barIndex], {
|
|
164
|
+
width: newLength,
|
|
165
|
+
x: newX
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (barsBelowBaseline.length > 1) {
|
|
171
|
+
const totalGapSpace = stackGap * (barsBelowBaseline.length - 1);
|
|
172
|
+
const totalDataLength = barsBelowBaseline.reduce((sum, bar) => sum + bar.width, 0);
|
|
173
|
+
const lengthReduction = totalGapSpace / totalDataLength;
|
|
174
|
+
const sortedBars = barsBelowBaseline.sort((a, b) => b.x - a.x);
|
|
175
|
+
let currentEdge = baseline;
|
|
176
|
+
sortedBars.forEach((bar, index) => {
|
|
177
|
+
const newLength = bar.width * (1 - lengthReduction);
|
|
178
|
+
const newX = currentEdge - newLength;
|
|
179
|
+
currentEdge = newX - (index < sortedBars.length - 1 ? stackGap : 0);
|
|
180
|
+
const barIndex = allBars.findIndex(b => b.seriesId === bar.seriesId);
|
|
181
|
+
if (barIndex !== -1) {
|
|
182
|
+
allBars[barIndex] = _extends({}, allBars[barIndex], {
|
|
183
|
+
width: newLength,
|
|
184
|
+
x: newX
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
if (allBars.length > 0) {
|
|
190
|
+
minX = Math.min(...allBars.map(bar => bar.x));
|
|
191
|
+
maxX = Math.max(...allBars.map(bar => bar.x + bar.width));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Horizontal border radius logic: left-to-right sorting.
|
|
196
|
+
const sortedBars = [...allBars].sort((a, b) => a.x - b.x);
|
|
197
|
+
const roundedBars = sortedBars.map((bar, index) => {
|
|
198
|
+
const barBefore = index > 0 ? sortedBars[index - 1] : null;
|
|
199
|
+
const barAfter = index < sortedBars.length - 1 ? sortedBars[index + 1] : null;
|
|
200
|
+
const shouldRoundLower = index === 0 || bar.shouldApplyGap && stackGap || !bar.shouldApplyGap && barAfter && barAfter.x + barAfter.width !== bar.x;
|
|
201
|
+
const shouldRoundHigher = index === sortedBars.length - 1 || bar.shouldApplyGap && stackGap || !bar.shouldApplyGap && barBefore && barBefore.x !== bar.x + bar.width;
|
|
202
|
+
return _extends({}, bar, {
|
|
203
|
+
roundTop: Boolean(bar.roundTop && shouldRoundHigher),
|
|
204
|
+
roundBottom: Boolean(bar.roundBottom && shouldRoundLower)
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
const stackBounds = {
|
|
208
|
+
x: minX === Infinity ? baseline : minX,
|
|
209
|
+
y: x,
|
|
210
|
+
width: maxX === -Infinity ? 0 : maxX - minX,
|
|
211
|
+
height: width
|
|
212
|
+
};
|
|
213
|
+
return {
|
|
214
|
+
bars: roundedBars,
|
|
215
|
+
stackRect: stackBounds
|
|
216
|
+
};
|
|
217
|
+
}
|
|
83
218
|
|
|
84
219
|
// Track how many bars we've stacked in each direction for gap calculation
|
|
85
220
|
let positiveBarCount = 0;
|
|
@@ -91,7 +226,7 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
91
226
|
|
|
92
227
|
// Process each series in the stack
|
|
93
228
|
series.forEach(s => {
|
|
94
|
-
var
|
|
229
|
+
var _yScale3, _yScale4;
|
|
95
230
|
const data = getSeriesData(s.id);
|
|
96
231
|
if (!data) return;
|
|
97
232
|
const value = data[categoryIndex];
|
|
@@ -105,8 +240,8 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
105
240
|
const [bottom, top] = value.sort((a, b) => a - b);
|
|
106
241
|
const isAboveBaseline = bottom >= 0 && top !== bottom;
|
|
107
242
|
const isBelowBaseline = bottom <= 0 && bottom !== top;
|
|
108
|
-
const barBottom = (
|
|
109
|
-
const barTop = (
|
|
243
|
+
const barBottom = (_yScale3 = yScale(bottom)) != null ? _yScale3 : baseline;
|
|
244
|
+
const barTop = (_yScale4 = yScale(top)) != null ? _yScale4 : baseline;
|
|
110
245
|
|
|
111
246
|
// Track bar counts for later gap calculations
|
|
112
247
|
if (shouldApplyGap) {
|
|
@@ -136,8 +271,8 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
136
271
|
// Evaluate gradient if provided (using precomputed stops)
|
|
137
272
|
const seriesGradientConfig = seriesGradients.find(g => (g == null ? void 0 : g.seriesId) === s.id);
|
|
138
273
|
if (seriesGradientConfig) {
|
|
139
|
-
var
|
|
140
|
-
const axis = (
|
|
274
|
+
var _seriesGradientConfig2;
|
|
275
|
+
const axis = (_seriesGradientConfig2 = seriesGradientConfig.gradient.axis) != null ? _seriesGradientConfig2 : 'y';
|
|
141
276
|
// For x-axis gradient, use the categoryIndex
|
|
142
277
|
// For y-axis gradient, use the actual data value
|
|
143
278
|
const dataValue = axis === 'x' ? categoryIndex : top;
|
|
@@ -243,14 +378,14 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
243
378
|
// First, expand bars that need it and track the expansion
|
|
244
379
|
const expandedBars = allBars.map((bar, index) => {
|
|
245
380
|
if (bar.height < barMinSize) {
|
|
246
|
-
var
|
|
381
|
+
var _yScale5, _yScale6, _yScale7, _yScale8;
|
|
247
382
|
const heightIncrease = barMinSize - bar.height;
|
|
248
383
|
const [bottom, top] = bar.dataY.sort((a, b) => a - b);
|
|
249
384
|
|
|
250
385
|
// Determine how to expand the bar
|
|
251
386
|
let newBottom = bottom;
|
|
252
387
|
let newTop = top;
|
|
253
|
-
const scaleUnit = Math.abs(((
|
|
388
|
+
const scaleUnit = Math.abs(((_yScale5 = yScale(1)) != null ? _yScale5 : 0) - ((_yScale6 = yScale(0)) != null ? _yScale6 : 0));
|
|
254
389
|
if (bottom === 0) {
|
|
255
390
|
// Expand away from baseline (upward for positive)
|
|
256
391
|
newTop = top + heightIncrease / scaleUnit;
|
|
@@ -265,8 +400,8 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
265
400
|
}
|
|
266
401
|
|
|
267
402
|
// Recalculate bar position with new data values
|
|
268
|
-
const newBarBottom = (
|
|
269
|
-
const newBarTop = (
|
|
403
|
+
const newBarBottom = (_yScale7 = yScale(newBottom)) != null ? _yScale7 : baseline;
|
|
404
|
+
const newBarTop = (_yScale8 = yScale(newTop)) != null ? _yScale8 : baseline;
|
|
270
405
|
const newHeight = Math.abs(newBarBottom - newBarTop);
|
|
271
406
|
const newY = Math.min(newBarBottom, newBarTop);
|
|
272
407
|
return _extends({}, bar, {
|
|
@@ -383,7 +518,7 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
383
518
|
// Apply stackMinSize constraints
|
|
384
519
|
if (stackMinSize) {
|
|
385
520
|
if (allBars.length === 1 && stackBounds.height < stackMinSize) {
|
|
386
|
-
var
|
|
521
|
+
var _yScale9, _yScale0, _yScale1, _yScale10;
|
|
387
522
|
// For single bars (non-stacked), treat stackMinSize like barMinSize
|
|
388
523
|
|
|
389
524
|
const bar = allBars[0];
|
|
@@ -393,7 +528,7 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
393
528
|
// Determine how to expand the bar (same logic as barMinSize)
|
|
394
529
|
let newBottom = bottom;
|
|
395
530
|
let newTop = top;
|
|
396
|
-
const scaleUnit = Math.abs(((
|
|
531
|
+
const scaleUnit = Math.abs(((_yScale9 = yScale(1)) != null ? _yScale9 : 0) - ((_yScale0 = yScale(0)) != null ? _yScale0 : 0));
|
|
397
532
|
if (bottom === 0) {
|
|
398
533
|
// Expand away from baseline (upward for positive)
|
|
399
534
|
newTop = top + heightIncrease / scaleUnit;
|
|
@@ -408,8 +543,8 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
408
543
|
}
|
|
409
544
|
|
|
410
545
|
// Recalculate bar position with new data values
|
|
411
|
-
const newBarBottom = (
|
|
412
|
-
const newBarTop = (
|
|
546
|
+
const newBarBottom = (_yScale1 = yScale(newBottom)) != null ? _yScale1 : baseline;
|
|
547
|
+
const newBarTop = (_yScale10 = yScale(newTop)) != null ? _yScale10 : baseline;
|
|
413
548
|
const newHeight = Math.abs(newBarBottom - newBarTop);
|
|
414
549
|
const newY = Math.min(newBarBottom, newBarTop);
|
|
415
550
|
allBars[0] = _extends({}, bar, {
|
|
@@ -517,18 +652,19 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
517
652
|
bars: allBars,
|
|
518
653
|
stackRect: stackBounds
|
|
519
654
|
};
|
|
520
|
-
}, [series,
|
|
521
|
-
const
|
|
522
|
-
const
|
|
655
|
+
}, [series, indexPos, thickness, getSeriesData, categoryIndex, roundBaseline, baseline, stackGap, barMinSize, stackMinSize, valueScale, seriesGradients, theme.color.fgPrimary, barsGrowVertically]);
|
|
656
|
+
const categoryAxis = barsGrowVertically ? xAxis : yAxis;
|
|
657
|
+
const categoryData = categoryAxis != null && categoryAxis.data && Array.isArray(categoryAxis.data) && typeof categoryAxis.data[0] === 'number' ? categoryAxis.data : undefined;
|
|
658
|
+
const categoryValue = categoryData ? categoryData[categoryIndex] : categoryIndex;
|
|
523
659
|
const barElements = bars.map((bar, index) => /*#__PURE__*/_jsx(Bar, {
|
|
524
660
|
BarComponent: bar.BarComponent || defaultBarComponent,
|
|
525
661
|
borderRadius: borderRadius,
|
|
526
|
-
dataX:
|
|
527
|
-
dataY: bar.dataY,
|
|
662
|
+
dataX: barsGrowVertically ? categoryValue : bar.dataY,
|
|
663
|
+
dataY: barsGrowVertically ? bar.dataY : categoryValue,
|
|
528
664
|
fill: bar.fill,
|
|
529
665
|
fillOpacity: defaultFillOpacity,
|
|
530
666
|
height: bar.height,
|
|
531
|
-
|
|
667
|
+
origin: baseline,
|
|
532
668
|
roundBottom: bar.roundBottom,
|
|
533
669
|
roundTop: bar.roundTop,
|
|
534
670
|
seriesId: bar.seriesId,
|
|
@@ -541,9 +677,13 @@ export const BarStack = /*#__PURE__*/memo(_ref => {
|
|
|
541
677
|
y: bar.y
|
|
542
678
|
}, bar.seriesId + "-" + categoryIndex + "-" + index));
|
|
543
679
|
|
|
544
|
-
// Check if the
|
|
545
|
-
const
|
|
546
|
-
const
|
|
680
|
+
// Check if the stack should be rounded based on baseline, across both orientations.
|
|
681
|
+
const edge = barsGrowVertically ? stackRect.y : stackRect.x;
|
|
682
|
+
const size = barsGrowVertically ? stackRect.height : stackRect.width;
|
|
683
|
+
const stackRoundLower = roundBaseline || Math.abs(edge - baseline) >= EPSILON;
|
|
684
|
+
const stackRoundHigher = roundBaseline || Math.abs(edge + size - baseline) >= EPSILON;
|
|
685
|
+
const stackRoundTop = barsGrowVertically ? stackRoundLower : stackRoundHigher;
|
|
686
|
+
const stackRoundBottom = barsGrowVertically ? stackRoundHigher : stackRoundLower;
|
|
547
687
|
return /*#__PURE__*/_jsx(BarStackComponent, {
|
|
548
688
|
borderRadius: borderRadius,
|
|
549
689
|
categoryIndex: categoryIndex,
|