@octanejs/recharts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/package.json +53 -0
- package/src/animation/AnimatedItems.tsrx +82 -0
- package/src/animation/AnimationControllerImpl.js +33 -0
- package/src/animation/AnimationHandle.js +291 -0
- package/src/animation/JavascriptAnimate.tsrx +81 -0
- package/src/animation/easing.js +193 -0
- package/src/animation/matchBy.js +279 -0
- package/src/animation/timeoutController.js +49 -0
- package/src/animation/useAnimationController.ts +22 -0
- package/src/animation/useAnimationStartSnapshot.ts +43 -0
- package/src/animation/util.js +11 -0
- package/src/cartesian/Bar.ts +4 -0
- package/src/cartesian/Bar.tsrx +716 -0
- package/src/cartesian/Bar.tsrx.d.ts +4 -0
- package/src/cartesian/BarStack.tsrx +97 -0
- package/src/cartesian/BarStack.tsrx.d.ts +6 -0
- package/src/cartesian/CartesianAxis.tsrx +413 -0
- package/src/cartesian/CartesianAxis.tsrx.d.ts +3 -0
- package/src/cartesian/GraphicalItemClipPath.tsrx +44 -0
- package/src/cartesian/Line.ts +4 -0
- package/src/cartesian/Line.tsrx +544 -0
- package/src/cartesian/Line.tsrx.d.ts +4 -0
- package/src/cartesian/LineDrawShape.tsrx +106 -0
- package/src/cartesian/LineDrawShape.tsrx.d.ts +2 -0
- package/src/cartesian/XAxis.tsrx +156 -0
- package/src/cartesian/XAxis.tsrx.d.ts +3 -0
- package/src/cartesian/YAxis.tsrx +183 -0
- package/src/cartesian/YAxis.tsrx.d.ts +3 -0
- package/src/cartesian/getCartesianPosition.js +277 -0
- package/src/cartesian/getEquidistantTicks.js +133 -0
- package/src/cartesian/getTicks.js +280 -0
- package/src/cartesian/useAnimatedLineLength.ts +33 -0
- package/src/chart/BarChart.tsrx +22 -0
- package/src/chart/BarChart.tsrx.d.ts +2 -0
- package/src/chart/CartesianChart.tsrx +76 -0
- package/src/chart/CartesianChart.tsrx.d.ts +10 -0
- package/src/chart/CategoricalChart.tsrx +54 -0
- package/src/chart/LineChart.tsrx +22 -0
- package/src/chart/LineChart.tsrx.d.ts +2 -0
- package/src/chart/RechartsWrapper.tsrx +294 -0
- package/src/component/ActivePoints.tsrx +76 -0
- package/src/component/Cell.ts +37 -0
- package/src/component/Dots.tsrx +74 -0
- package/src/component/Label.tsrx +309 -0
- package/src/component/Label.tsrx.d.ts +12 -0
- package/src/component/LabelList.tsrx +83 -0
- package/src/component/LabelList.tsrx.d.ts +8 -0
- package/src/component/ResponsiveContainer.ts +22 -0
- package/src/component/Text.tsrx +281 -0
- package/src/component/Text.tsrx.d.ts +9 -0
- package/src/component/responsiveContainerUtils.js +111 -0
- package/src/container/ClipPathProvider.tsrx +29 -0
- package/src/container/Layer.tsrx +9 -0
- package/src/container/Layer.tsrx.d.ts +6 -0
- package/src/container/RootSurface.tsrx +76 -0
- package/src/container/Surface.tsrx +23 -0
- package/src/container/Surface.tsrx.d.ts +12 -0
- package/src/context/CellsContext.ts +80 -0
- package/src/context/ErrorBarContext.tsrx +53 -0
- package/src/context/PanoramaContext.ts +10 -0
- package/src/context/RegisterGraphicalItemId.tsrx +19 -0
- package/src/context/accessibilityContext.js +10 -0
- package/src/context/chartDataContext.ts +57 -0
- package/src/context/chartLayoutContext.ts +171 -0
- package/src/context/legendPortalContext.ts +5 -0
- package/src/context/tooltipContext.js +55 -0
- package/src/context/tooltipPortalContext.ts +5 -0
- package/src/hooks.js +509 -0
- package/src/index.ts +64 -0
- package/src/internal.ts +37 -0
- package/src/polar/defaultPolarAngleAxisProps.js +27 -0
- package/src/polar/defaultPolarRadiusAxisProps.js +24 -0
- package/src/shape/Cross.tsrx +25 -0
- package/src/shape/Cross.tsrx.d.ts +12 -0
- package/src/shape/Curve.tsrx +132 -0
- package/src/shape/Curve.tsrx.d.ts +42 -0
- package/src/shape/Dot.tsrx +21 -0
- package/src/shape/Dot.tsrx.d.ts +9 -0
- package/src/shape/Polygon.tsrx +95 -0
- package/src/shape/Polygon.tsrx.d.ts +13 -0
- package/src/shape/Rectangle.tsrx +162 -0
- package/src/shape/Rectangle.tsrx.d.ts +31 -0
- package/src/shape/Sector.tsrx +219 -0
- package/src/shape/Sector.tsrx.d.ts +29 -0
- package/src/shape/Symbols.tsrx +95 -0
- package/src/shape/Symbols.tsrx.d.ts +15 -0
- package/src/shape/Trapezoid.tsrx +56 -0
- package/src/shape/Trapezoid.tsrx.d.ts +29 -0
- package/src/state/RechartsReduxContext.ts +7 -0
- package/src/state/RechartsStoreProvider.tsrx +24 -0
- package/src/state/ReportChartProps.ts +13 -0
- package/src/state/ReportEventSettings.ts +15 -0
- package/src/state/ReportMainChartProps.ts +22 -0
- package/src/state/SetGraphicalItem.ts +61 -0
- package/src/state/SetLegendPayload.ts +61 -0
- package/src/state/SetTooltipEntrySettings.ts +40 -0
- package/src/state/brushSlice.js +36 -0
- package/src/state/cartesianAxisSlice.js +256 -0
- package/src/state/chartDataSlice.js +67 -0
- package/src/state/errorBarSlice.js +53 -0
- package/src/state/eventSettingsSlice.js +25 -0
- package/src/state/externalEventsMiddleware.js +127 -0
- package/src/state/graphicalItemsSlice.js +91 -0
- package/src/state/hooks.ts +46 -0
- package/src/state/keyboardEventsMiddleware.js +226 -0
- package/src/state/layoutSlice.js +57 -0
- package/src/state/legendSlice.js +83 -0
- package/src/state/mouseEventsMiddleware.js +130 -0
- package/src/state/optionsSlice.js +45 -0
- package/src/state/polarAxisSlice.js +33 -0
- package/src/state/polarOptionsSlice.js +26 -0
- package/src/state/reduxDevtoolsJsonStringifyReplacer.js +14 -0
- package/src/state/referenceElementsSlice.js +51 -0
- package/src/state/renderedTicksSlice.js +41 -0
- package/src/state/rootPropsSlice.js +48 -0
- package/src/state/selectors/arrayEqualityCheck.js +32 -0
- package/src/state/selectors/axisSelectors.js +2113 -0
- package/src/state/selectors/barSelectors.js +263 -0
- package/src/state/selectors/barStackSelectors.js +65 -0
- package/src/state/selectors/brushSelectors.js +21 -0
- package/src/state/selectors/combiners/combineActiveLabel.js +18 -0
- package/src/state/selectors/combiners/combineActiveTooltipIndex.js +75 -0
- package/src/state/selectors/combiners/combineAllBarPositions.js +169 -0
- package/src/state/selectors/combiners/combineAxisRangeWithReverse.js +11 -0
- package/src/state/selectors/combiners/combineBarPosition.js +17 -0
- package/src/state/selectors/combiners/combineBarSizeList.js +115 -0
- package/src/state/selectors/combiners/combineCheckedDomain.js +44 -0
- package/src/state/selectors/combiners/combineConfiguredScale.js +46 -0
- package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.js +48 -0
- package/src/state/selectors/combiners/combineDisplayedStackedData.js +54 -0
- package/src/state/selectors/combiners/combineInverseScaleFunction.js +12 -0
- package/src/state/selectors/combiners/combineRealScaleType.js +36 -0
- package/src/state/selectors/combiners/combineStackedData.js +22 -0
- package/src/state/selectors/combiners/combineTooltipInteractionState.js +121 -0
- package/src/state/selectors/combiners/combineTooltipPayload.js +248 -0
- package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.js +59 -0
- package/src/state/selectors/containerSelectors.js +6 -0
- package/src/state/selectors/dataSelectors.js +97 -0
- package/src/state/selectors/graphicalItemSelectors.js +25 -0
- package/src/state/selectors/legendSelectors.js +18 -0
- package/src/state/selectors/lineSelectors.js +106 -0
- package/src/state/selectors/numberDomainEqualityCheck.js +11 -0
- package/src/state/selectors/pickAxisId.js +3 -0
- package/src/state/selectors/pickAxisType.js +3 -0
- package/src/state/selectors/polarAxisSelectors.js +237 -0
- package/src/state/selectors/rootPropsSelectors.js +13 -0
- package/src/state/selectors/selectActivePropsFromChartPointer.js +23 -0
- package/src/state/selectors/selectAllAxes.js +15 -0
- package/src/state/selectors/selectChartOffset.js +12 -0
- package/src/state/selectors/selectChartOffsetInternal.js +174 -0
- package/src/state/selectors/selectPlotArea.js +19 -0
- package/src/state/selectors/selectTooltipAxisId.js +3 -0
- package/src/state/selectors/selectTooltipAxisType.js +25 -0
- package/src/state/selectors/selectTooltipEventType.js +27 -0
- package/src/state/selectors/selectTooltipPayloadSearcher.js +3 -0
- package/src/state/selectors/selectTooltipSettings.js +3 -0
- package/src/state/selectors/selectTooltipState.js +3 -0
- package/src/state/selectors/selectors.js +222 -0
- package/src/state/selectors/tooltipSelectors.js +471 -0
- package/src/state/selectors/touchSelectors.js +31 -0
- package/src/state/store.js +101 -0
- package/src/state/tooltipSlice.js +237 -0
- package/src/state/touchEventsMiddleware.js +140 -0
- package/src/state/types/StackedGraphicalItem.js +18 -0
- package/src/state/zIndexSlice.js +167 -0
- package/src/synchronisation/syncSelectors.js +5 -0
- package/src/synchronisation/useChartSynchronisation.tsrx +285 -0
- package/src/util/ActiveShapeUtils.tsrx +62 -0
- package/src/util/BarUtils.tsrx +35 -0
- package/src/util/CartesianUtils.js +66 -0
- package/src/util/ChartUtils.js +630 -0
- package/src/util/Constants.js +42 -0
- package/src/util/DOMUtils.js +180 -0
- package/src/util/DataUtils.js +199 -0
- package/src/util/Events.js +7 -0
- package/src/util/Global.js +13 -0
- package/src/util/LRUCache.js +58 -0
- package/src/util/LogUtils.js +29 -0
- package/src/util/PolarUtils.js +190 -0
- package/src/util/ReactUtils.ts +94 -0
- package/src/util/ReduceCSSCalc.js +260 -0
- package/src/util/TickUtils.js +43 -0
- package/src/util/YAxisUtils.js +43 -0
- package/src/util/axisPropsAreEqual.js +63 -0
- package/src/util/createEventProxy.js +18 -0
- package/src/util/excludeEventProps.js +172 -0
- package/src/util/getActiveCoordinate.js +253 -0
- package/src/util/getAxisTypeBasedOnLayout.js +17 -0
- package/src/util/getClassNameFromUnknown.js +8 -0
- package/src/util/getEveryNth.js +29 -0
- package/src/util/getRadiusAndStrokeWidthFromDot.js +28 -0
- package/src/util/getRelativeCoordinate.js +96 -0
- package/src/util/getSliced.js +11 -0
- package/src/util/isDomainSpecifiedByUser.js +255 -0
- package/src/util/isWellBehavedNumber.js +8 -0
- package/src/util/propsAreEqual.js +96 -0
- package/src/util/resolveDefaultProps.js +131 -0
- package/src/util/round.js +39 -0
- package/src/util/scale/RechartsScale.js +68 -0
- package/src/util/scale/createCategoricalInverse.js +77 -0
- package/src/util/scale/getNiceTickValues.js +354 -0
- package/src/util/scale/index.js +3 -0
- package/src/util/scale/util/arithmetic.js +51 -0
- package/src/util/stacks/getStackSeriesIdentifier.js +10 -0
- package/src/util/svgPropertiesAndEvents.ts +29 -0
- package/src/util/svgPropertiesNoEvents.js +383 -0
- package/src/util/types.ts +59 -0
- package/src/util/useAnimationId.ts +14 -0
- package/src/util/useId.ts +13 -0
- package/src/util/usePrefersReducedMotion.ts +30 -0
- package/src/util/useReportScale.ts +26 -0
- package/src/util/useUniqueId.js +34 -0
- package/src/zIndex/DefaultZIndexes.js +75 -0
- package/src/zIndex/ZIndexLayer.tsrx +80 -0
- package/src/zIndex/ZIndexLayer.tsrx.d.ts +2 -0
- package/src/zIndex/ZIndexPortal.tsrx +43 -0
- package/src/zIndex/getZIndexFromUnknown.js +15 -0
- package/src/zIndex/zIndexSelectors.js +45 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Port of cartesian/XAxis.tsx — registers x-axis settings in the store and
|
|
2
|
+
// renders through CartesianAxis with store-synchronized settings.
|
|
3
|
+
import { useLayoutEffect, useMemo, useRef, memo } from 'octane';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { CartesianAxis, defaultCartesianAxisProps } from './CartesianAxis.tsrx';
|
|
6
|
+
import { useAppDispatch, useAppSelector } from '../state/hooks';
|
|
7
|
+
import { addXAxis, replaceXAxis, removeXAxis } from '../state/cartesianAxisSlice';
|
|
8
|
+
import {
|
|
9
|
+
implicitXAxis,
|
|
10
|
+
selectTicksOfAxis,
|
|
11
|
+
selectXAxisPosition,
|
|
12
|
+
selectXAxisSettingsNoDefaults,
|
|
13
|
+
selectXAxisSize,
|
|
14
|
+
} from '../state/selectors/axisSelectors';
|
|
15
|
+
import { selectAxisViewBox } from '../state/selectors/selectChartOffsetInternal';
|
|
16
|
+
import { useIsPanorama } from '../context/PanoramaContext.ts';
|
|
17
|
+
import { resolveDefaultProps } from '../util/resolveDefaultProps';
|
|
18
|
+
import { axisPropsAreEqual } from '../util/axisPropsAreEqual';
|
|
19
|
+
import { useCartesianChartLayout } from '../context/chartLayoutContext.ts';
|
|
20
|
+
import { getAxisTypeBasedOnLayout } from '../util/getAxisTypeBasedOnLayout';
|
|
21
|
+
|
|
22
|
+
function SetXAxisSettings(props) {
|
|
23
|
+
const dispatch = useAppDispatch();
|
|
24
|
+
const prevSettingsRef = useRef(null);
|
|
25
|
+
const layout = useCartesianChartLayout();
|
|
26
|
+
const { type: typeFromProps, ...restProps } = props;
|
|
27
|
+
const evaluatedType = getAxisTypeBasedOnLayout(layout, 'xAxis', typeFromProps);
|
|
28
|
+
const settings = useMemo(() => {
|
|
29
|
+
if (evaluatedType == null) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return { ...restProps, type: evaluatedType };
|
|
33
|
+
}, [restProps, evaluatedType]);
|
|
34
|
+
useLayoutEffect(() => {
|
|
35
|
+
if (settings == null) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (prevSettingsRef.current === null) {
|
|
39
|
+
dispatch(addXAxis(settings));
|
|
40
|
+
} else if (prevSettingsRef.current !== settings) {
|
|
41
|
+
dispatch(replaceXAxis({ prev: prevSettingsRef.current, next: settings }));
|
|
42
|
+
}
|
|
43
|
+
prevSettingsRef.current = settings;
|
|
44
|
+
}, [settings, dispatch]);
|
|
45
|
+
useLayoutEffect(() => {
|
|
46
|
+
return () => {
|
|
47
|
+
if (prevSettingsRef.current) {
|
|
48
|
+
dispatch(removeXAxis(prevSettingsRef.current));
|
|
49
|
+
prevSettingsRef.current = null;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}, [dispatch]);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function XAxisImpl(props) {
|
|
57
|
+
const { xAxisId, className } = props;
|
|
58
|
+
const viewBox = useAppSelector(selectAxisViewBox);
|
|
59
|
+
const isPanorama = useIsPanorama();
|
|
60
|
+
const axisType = 'xAxis';
|
|
61
|
+
const cartesianTickItems = useAppSelector(
|
|
62
|
+
(state) => selectTicksOfAxis(state, axisType, xAxisId, isPanorama),
|
|
63
|
+
);
|
|
64
|
+
const axisSize = useAppSelector((state) => selectXAxisSize(state, xAxisId));
|
|
65
|
+
const position = useAppSelector((state) => selectXAxisPosition(state, xAxisId));
|
|
66
|
+
// Settings come back from the store (not props) so every component renders
|
|
67
|
+
// one consistent view of the axis (recharts#6257).
|
|
68
|
+
const synchronizedSettings = useAppSelector(
|
|
69
|
+
(state) => selectXAxisSettingsNoDefaults(state, xAxisId),
|
|
70
|
+
);
|
|
71
|
+
if (axisSize == null || position == null || synchronizedSettings == null) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const { dangerouslySetInnerHTML, ticks, scale: _del, ...allOtherProps } = props;
|
|
75
|
+
const { id, scale: _del2, ...restSynchronizedSettings } = synchronizedSettings;
|
|
76
|
+
return <CartesianAxis
|
|
77
|
+
{...allOtherProps}
|
|
78
|
+
{...restSynchronizedSettings}
|
|
79
|
+
x={position.x}
|
|
80
|
+
y={position.y}
|
|
81
|
+
width={axisSize.width}
|
|
82
|
+
height={axisSize.height}
|
|
83
|
+
className={clsx('recharts-' + axisType + ' ' + axisType, className)}
|
|
84
|
+
viewBox={viewBox}
|
|
85
|
+
ticks={cartesianTickItems}
|
|
86
|
+
axisType={axisType}
|
|
87
|
+
axisId={xAxisId}
|
|
88
|
+
/>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const xAxisDefaultProps = {
|
|
92
|
+
allowDataOverflow: implicitXAxis.allowDataOverflow,
|
|
93
|
+
allowDecimals: implicitXAxis.allowDecimals,
|
|
94
|
+
allowDuplicatedCategory: implicitXAxis.allowDuplicatedCategory,
|
|
95
|
+
angle: implicitXAxis.angle,
|
|
96
|
+
axisLine: defaultCartesianAxisProps.axisLine,
|
|
97
|
+
height: implicitXAxis.height,
|
|
98
|
+
hide: false,
|
|
99
|
+
includeHidden: implicitXAxis.includeHidden,
|
|
100
|
+
interval: implicitXAxis.interval,
|
|
101
|
+
label: false,
|
|
102
|
+
minTickGap: implicitXAxis.minTickGap,
|
|
103
|
+
mirror: implicitXAxis.mirror,
|
|
104
|
+
orientation: implicitXAxis.orientation,
|
|
105
|
+
padding: implicitXAxis.padding,
|
|
106
|
+
reversed: implicitXAxis.reversed,
|
|
107
|
+
scale: implicitXAxis.scale,
|
|
108
|
+
tick: implicitXAxis.tick,
|
|
109
|
+
tickCount: implicitXAxis.tickCount,
|
|
110
|
+
tickLine: defaultCartesianAxisProps.tickLine,
|
|
111
|
+
tickSize: defaultCartesianAxisProps.tickSize,
|
|
112
|
+
type: implicitXAxis.type,
|
|
113
|
+
niceTicks: implicitXAxis.niceTicks,
|
|
114
|
+
xAxisId: 0,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
function XAxisSettingsDispatcher(outsideProps) @{
|
|
118
|
+
const props = resolveDefaultProps(outsideProps, xAxisDefaultProps);
|
|
119
|
+
<>
|
|
120
|
+
<SetXAxisSettings
|
|
121
|
+
allowDataOverflow={props.allowDataOverflow}
|
|
122
|
+
allowDecimals={props.allowDecimals}
|
|
123
|
+
allowDuplicatedCategory={props.allowDuplicatedCategory}
|
|
124
|
+
angle={props.angle}
|
|
125
|
+
dataKey={props.dataKey}
|
|
126
|
+
domain={props.domain}
|
|
127
|
+
height={props.height}
|
|
128
|
+
hide={props.hide}
|
|
129
|
+
id={props.xAxisId}
|
|
130
|
+
includeHidden={props.includeHidden}
|
|
131
|
+
interval={props.interval}
|
|
132
|
+
minTickGap={props.minTickGap}
|
|
133
|
+
mirror={props.mirror}
|
|
134
|
+
name={props.name}
|
|
135
|
+
orientation={props.orientation}
|
|
136
|
+
padding={props.padding}
|
|
137
|
+
reversed={props.reversed}
|
|
138
|
+
scale={props.scale}
|
|
139
|
+
tick={props.tick}
|
|
140
|
+
tickCount={props.tickCount}
|
|
141
|
+
tickFormatter={props.tickFormatter}
|
|
142
|
+
ticks={props.ticks}
|
|
143
|
+
type={props.type}
|
|
144
|
+
unit={props.unit}
|
|
145
|
+
niceTicks={props.niceTicks}
|
|
146
|
+
/>
|
|
147
|
+
<XAxisImpl {...props} />
|
|
148
|
+
</>
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @consumes CartesianViewBoxContext
|
|
153
|
+
* @provides CartesianLabelContext
|
|
154
|
+
*/
|
|
155
|
+
export const XAxis = memo(XAxisSettingsDispatcher, axisPropsAreEqual);
|
|
156
|
+
XAxis.displayName = 'XAxis';
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// Port of cartesian/YAxis.tsx — registers y-axis settings in the store,
|
|
2
|
+
// renders through CartesianAxis, and drives width="auto" via the axis
|
|
3
|
+
// component's imperative getCalculatedWidth handle.
|
|
4
|
+
import { isValidElement, useLayoutEffect, useMemo, useRef, memo } from 'octane';
|
|
5
|
+
import { clsx } from 'clsx';
|
|
6
|
+
import { CartesianAxis, defaultCartesianAxisProps } from './CartesianAxis.tsrx';
|
|
7
|
+
import { addYAxis, replaceYAxis, removeYAxis, updateYAxisWidth } from '../state/cartesianAxisSlice';
|
|
8
|
+
import { useAppDispatch, useAppSelector } from '../state/hooks';
|
|
9
|
+
import {
|
|
10
|
+
implicitYAxis,
|
|
11
|
+
selectTicksOfAxis,
|
|
12
|
+
selectYAxisPosition,
|
|
13
|
+
selectYAxisSettingsNoDefaults,
|
|
14
|
+
selectYAxisSize,
|
|
15
|
+
} from '../state/selectors/axisSelectors';
|
|
16
|
+
import { selectAxisViewBox } from '../state/selectors/selectChartOffsetInternal';
|
|
17
|
+
import { useIsPanorama } from '../context/PanoramaContext.ts';
|
|
18
|
+
import { isLabelContentAFunction } from '../component/Label.tsrx';
|
|
19
|
+
import { resolveDefaultProps } from '../util/resolveDefaultProps';
|
|
20
|
+
import { axisPropsAreEqual } from '../util/axisPropsAreEqual';
|
|
21
|
+
import { useCartesianChartLayout } from '../context/chartLayoutContext.ts';
|
|
22
|
+
import { getAxisTypeBasedOnLayout } from '../util/getAxisTypeBasedOnLayout';
|
|
23
|
+
|
|
24
|
+
function SetYAxisSettings(props) {
|
|
25
|
+
const dispatch = useAppDispatch();
|
|
26
|
+
const prevSettingsRef = useRef(null);
|
|
27
|
+
const layout = useCartesianChartLayout();
|
|
28
|
+
const { type: typeFromProps, ...restProps } = props;
|
|
29
|
+
const evaluatedType = getAxisTypeBasedOnLayout(layout, 'yAxis', typeFromProps);
|
|
30
|
+
const settings = useMemo(() => {
|
|
31
|
+
if (evaluatedType == null) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
return { ...restProps, type: evaluatedType };
|
|
35
|
+
}, [evaluatedType, restProps]);
|
|
36
|
+
useLayoutEffect(() => {
|
|
37
|
+
if (settings == null) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (prevSettingsRef.current === null) {
|
|
41
|
+
dispatch(addYAxis(settings));
|
|
42
|
+
} else if (prevSettingsRef.current !== settings) {
|
|
43
|
+
dispatch(replaceYAxis({ prev: prevSettingsRef.current, next: settings }));
|
|
44
|
+
}
|
|
45
|
+
prevSettingsRef.current = settings;
|
|
46
|
+
}, [settings, dispatch]);
|
|
47
|
+
useLayoutEffect(() => {
|
|
48
|
+
return () => {
|
|
49
|
+
if (prevSettingsRef.current) {
|
|
50
|
+
dispatch(removeYAxis(prevSettingsRef.current));
|
|
51
|
+
prevSettingsRef.current = null;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}, [dispatch]);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function YAxisImpl(props) {
|
|
59
|
+
const { yAxisId, className, width, label } = props;
|
|
60
|
+
const cartesianAxisRef = useRef(null);
|
|
61
|
+
const labelRef = useRef(null);
|
|
62
|
+
const viewBox = useAppSelector(selectAxisViewBox);
|
|
63
|
+
const isPanorama = useIsPanorama();
|
|
64
|
+
const dispatch = useAppDispatch();
|
|
65
|
+
const axisType = 'yAxis';
|
|
66
|
+
const axisSize = useAppSelector((state) => selectYAxisSize(state, yAxisId));
|
|
67
|
+
const position = useAppSelector((state) => selectYAxisPosition(state, yAxisId));
|
|
68
|
+
const cartesianTickItems = useAppSelector(
|
|
69
|
+
(state) => selectTicksOfAxis(state, axisType, yAxisId, isPanorama),
|
|
70
|
+
);
|
|
71
|
+
// Settings come back from the store (not props) so every component renders
|
|
72
|
+
// one consistent view of the axis (recharts#6257).
|
|
73
|
+
const synchronizedSettings = useAppSelector(
|
|
74
|
+
(state) => selectYAxisSettingsNoDefaults(state, yAxisId),
|
|
75
|
+
);
|
|
76
|
+
useLayoutEffect(() => {
|
|
77
|
+
// No dynamic width calculation when width !== 'auto', or when a
|
|
78
|
+
// function/element label is used.
|
|
79
|
+
if (
|
|
80
|
+
width !== 'auto' || !axisSize || isLabelContentAFunction(label) || isValidElement(label) ||
|
|
81
|
+
synchronizedSettings == null
|
|
82
|
+
) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const axisComponent = cartesianAxisRef.current;
|
|
86
|
+
if (!axisComponent) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const updatedYAxisWidth = axisComponent.getCalculatedWidth();
|
|
90
|
+
// if the width has changed, dispatch an action to update the width
|
|
91
|
+
if (Math.round(axisSize.width) !== Math.round(updatedYAxisWidth)) {
|
|
92
|
+
dispatch(updateYAxisWidth({ id: yAxisId, width: updatedYAxisWidth }));
|
|
93
|
+
}
|
|
94
|
+
}, [cartesianTickItems, axisSize, dispatch, label, yAxisId, width, synchronizedSettings]);
|
|
95
|
+
if (axisSize == null || position == null || synchronizedSettings == null) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const { dangerouslySetInnerHTML, ticks, scale: _del, ...allOtherProps } = props;
|
|
99
|
+
const { id, scale: _del2, ...restSynchronizedSettings } = synchronizedSettings;
|
|
100
|
+
return <CartesianAxis
|
|
101
|
+
{...allOtherProps}
|
|
102
|
+
{...restSynchronizedSettings}
|
|
103
|
+
ref={cartesianAxisRef}
|
|
104
|
+
labelRef={labelRef}
|
|
105
|
+
x={position.x}
|
|
106
|
+
y={position.y}
|
|
107
|
+
tickTextProps={width === 'auto' ? { width: undefined } : { width }}
|
|
108
|
+
width={axisSize.width}
|
|
109
|
+
height={axisSize.height}
|
|
110
|
+
className={clsx('recharts-' + axisType + ' ' + axisType, className)}
|
|
111
|
+
viewBox={viewBox}
|
|
112
|
+
ticks={cartesianTickItems}
|
|
113
|
+
axisType={axisType}
|
|
114
|
+
axisId={yAxisId}
|
|
115
|
+
/>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const yAxisDefaultProps = {
|
|
119
|
+
allowDataOverflow: implicitYAxis.allowDataOverflow,
|
|
120
|
+
allowDecimals: implicitYAxis.allowDecimals,
|
|
121
|
+
allowDuplicatedCategory: implicitYAxis.allowDuplicatedCategory,
|
|
122
|
+
angle: implicitYAxis.angle,
|
|
123
|
+
axisLine: defaultCartesianAxisProps.axisLine,
|
|
124
|
+
hide: false,
|
|
125
|
+
includeHidden: implicitYAxis.includeHidden,
|
|
126
|
+
interval: implicitYAxis.interval,
|
|
127
|
+
label: false,
|
|
128
|
+
minTickGap: implicitYAxis.minTickGap,
|
|
129
|
+
mirror: implicitYAxis.mirror,
|
|
130
|
+
orientation: implicitYAxis.orientation,
|
|
131
|
+
padding: implicitYAxis.padding,
|
|
132
|
+
reversed: implicitYAxis.reversed,
|
|
133
|
+
scale: implicitYAxis.scale,
|
|
134
|
+
tick: implicitYAxis.tick,
|
|
135
|
+
tickCount: implicitYAxis.tickCount,
|
|
136
|
+
tickLine: defaultCartesianAxisProps.tickLine,
|
|
137
|
+
tickSize: defaultCartesianAxisProps.tickSize,
|
|
138
|
+
type: implicitYAxis.type,
|
|
139
|
+
niceTicks: implicitYAxis.niceTicks,
|
|
140
|
+
width: implicitYAxis.width,
|
|
141
|
+
yAxisId: 0,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
function YAxisSettingsDispatcher(outsideProps) @{
|
|
145
|
+
const props = resolveDefaultProps(outsideProps, yAxisDefaultProps);
|
|
146
|
+
<>
|
|
147
|
+
<SetYAxisSettings
|
|
148
|
+
interval={props.interval}
|
|
149
|
+
id={props.yAxisId}
|
|
150
|
+
scale={props.scale}
|
|
151
|
+
type={props.type}
|
|
152
|
+
domain={props.domain}
|
|
153
|
+
allowDataOverflow={props.allowDataOverflow}
|
|
154
|
+
dataKey={props.dataKey}
|
|
155
|
+
allowDuplicatedCategory={props.allowDuplicatedCategory}
|
|
156
|
+
allowDecimals={props.allowDecimals}
|
|
157
|
+
tickCount={props.tickCount}
|
|
158
|
+
padding={props.padding}
|
|
159
|
+
includeHidden={props.includeHidden}
|
|
160
|
+
reversed={props.reversed}
|
|
161
|
+
ticks={props.ticks}
|
|
162
|
+
width={props.width}
|
|
163
|
+
orientation={props.orientation}
|
|
164
|
+
mirror={props.mirror}
|
|
165
|
+
hide={props.hide}
|
|
166
|
+
unit={props.unit}
|
|
167
|
+
name={props.name}
|
|
168
|
+
angle={props.angle}
|
|
169
|
+
minTickGap={props.minTickGap}
|
|
170
|
+
tick={props.tick}
|
|
171
|
+
tickFormatter={props.tickFormatter}
|
|
172
|
+
niceTicks={props.niceTicks}
|
|
173
|
+
/>
|
|
174
|
+
<YAxisImpl {...props} />
|
|
175
|
+
</>
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @consumes CartesianViewBoxContext
|
|
180
|
+
* @provides CartesianLabelContext
|
|
181
|
+
*/
|
|
182
|
+
export const YAxis = memo(YAxisSettingsDispatcher, axisPropsAreEqual);
|
|
183
|
+
YAxis.displayName = 'YAxis';
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
// Vendored verbatim from recharts@3.9.2 es6/cartesian/getCartesianPosition.js (framework-agnostic).
|
|
2
|
+
// Do not edit — update by re-vendoring when the recharts devDependency moves.
|
|
3
|
+
function ownKeys(e, r) {
|
|
4
|
+
var t = Object.keys(e);
|
|
5
|
+
if (Object.getOwnPropertySymbols) {
|
|
6
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
7
|
+
(r &&
|
|
8
|
+
(o = o.filter(function (r) {
|
|
9
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
10
|
+
})),
|
|
11
|
+
t.push.apply(t, o));
|
|
12
|
+
}
|
|
13
|
+
return t;
|
|
14
|
+
}
|
|
15
|
+
function _objectSpread(e) {
|
|
16
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
17
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
18
|
+
r % 2
|
|
19
|
+
? ownKeys(Object(t), !0).forEach(function (r) {
|
|
20
|
+
_defineProperty(e, r, t[r]);
|
|
21
|
+
})
|
|
22
|
+
: Object.getOwnPropertyDescriptors
|
|
23
|
+
? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t))
|
|
24
|
+
: ownKeys(Object(t)).forEach(function (r) {
|
|
25
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return e;
|
|
29
|
+
}
|
|
30
|
+
function _defineProperty(e, r, t) {
|
|
31
|
+
return (
|
|
32
|
+
(r = _toPropertyKey(r)) in e
|
|
33
|
+
? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 })
|
|
34
|
+
: (e[r] = t),
|
|
35
|
+
e
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
function _toPropertyKey(t) {
|
|
39
|
+
var i = _toPrimitive(t, 'string');
|
|
40
|
+
return 'symbol' == typeof i ? i : i + '';
|
|
41
|
+
}
|
|
42
|
+
function _toPrimitive(t, r) {
|
|
43
|
+
if ('object' != typeof t || !t) return t;
|
|
44
|
+
var e = t[Symbol.toPrimitive];
|
|
45
|
+
if (void 0 !== e) {
|
|
46
|
+
var i = e.call(t, r || 'default');
|
|
47
|
+
if ('object' != typeof i) return i;
|
|
48
|
+
throw new TypeError('@@toPrimitive must return a primitive value.');
|
|
49
|
+
}
|
|
50
|
+
return ('string' === r ? String : Number)(t);
|
|
51
|
+
}
|
|
52
|
+
import { getPercentValue, isNumber, isPercent } from '../util/DataUtils';
|
|
53
|
+
import { cartesianViewBoxToTrapezoid } from '../context/chartLayoutContext';
|
|
54
|
+
/**
|
|
55
|
+
* Calculates the position and alignment for a generic element in a Cartesian coordinate system.
|
|
56
|
+
*
|
|
57
|
+
* @param options - The options including viewBox, position, and offset.
|
|
58
|
+
* @returns The calculated x, y, alignment and size.
|
|
59
|
+
*/
|
|
60
|
+
export var getCartesianPosition = (options) => {
|
|
61
|
+
var viewBox = options.viewBox,
|
|
62
|
+
position = options.position,
|
|
63
|
+
_options$offset = options.offset,
|
|
64
|
+
offset = _options$offset === void 0 ? 0 : _options$offset,
|
|
65
|
+
parentViewBoxFromOptions = options.parentViewBox,
|
|
66
|
+
clamp = options.clamp;
|
|
67
|
+
var _cartesianViewBoxToTr = cartesianViewBoxToTrapezoid(viewBox),
|
|
68
|
+
x = _cartesianViewBoxToTr.x,
|
|
69
|
+
y = _cartesianViewBoxToTr.y,
|
|
70
|
+
height = _cartesianViewBoxToTr.height,
|
|
71
|
+
upperWidth = _cartesianViewBoxToTr.upperWidth,
|
|
72
|
+
lowerWidth = _cartesianViewBoxToTr.lowerWidth;
|
|
73
|
+
|
|
74
|
+
// Funnel.tsx provides a viewBox where `x` is the top-left of the trapezoid shape.
|
|
75
|
+
var upperX = x;
|
|
76
|
+
// The trapezoid is centered, so we can calculate the other corners from the top-left.
|
|
77
|
+
var lowerX = x + (upperWidth - lowerWidth) / 2;
|
|
78
|
+
// middleX is the x-coordinate of the left edge at the vertical midpoint of the trapezoid.
|
|
79
|
+
var middleX = (upperX + lowerX) / 2;
|
|
80
|
+
// The width of the trapezoid at its vertical midpoint.
|
|
81
|
+
var midHeightWidth = (upperWidth + lowerWidth) / 2;
|
|
82
|
+
// The center x-coordinate is constant for the entire height of the trapezoid.
|
|
83
|
+
var centerX = upperX + upperWidth / 2;
|
|
84
|
+
|
|
85
|
+
// Define vertical offsets and position inverts based on the value being positive or negative.
|
|
86
|
+
// This allows labels to be positioned correctly for bars with negative height.
|
|
87
|
+
var verticalSign = height >= 0 ? 1 : -1;
|
|
88
|
+
var verticalOffset = verticalSign * offset;
|
|
89
|
+
var verticalEnd = verticalSign > 0 ? 'end' : 'start';
|
|
90
|
+
var verticalStart = verticalSign > 0 ? 'start' : 'end';
|
|
91
|
+
|
|
92
|
+
// Define horizontal offsets and position inverts based on the value being positive or negative.
|
|
93
|
+
// This allows labels to be positioned correctly for bars with negative width.
|
|
94
|
+
var horizontalSign = upperWidth >= 0 ? 1 : -1;
|
|
95
|
+
var horizontalOffset = horizontalSign * offset;
|
|
96
|
+
var horizontalEnd = horizontalSign > 0 ? 'end' : 'start';
|
|
97
|
+
var horizontalStart = horizontalSign > 0 ? 'start' : 'end';
|
|
98
|
+
|
|
99
|
+
// We assume parentViewBox is generic if provided.
|
|
100
|
+
// The user has asserted that parentViewBox will be CartesianViewBoxRequired if present.
|
|
101
|
+
var parentViewBox = parentViewBoxFromOptions;
|
|
102
|
+
if (position === 'top') {
|
|
103
|
+
var result = {
|
|
104
|
+
x: upperX + upperWidth / 2,
|
|
105
|
+
y: y - verticalOffset,
|
|
106
|
+
horizontalAnchor: 'middle',
|
|
107
|
+
verticalAnchor: verticalEnd,
|
|
108
|
+
};
|
|
109
|
+
if (clamp && parentViewBox) {
|
|
110
|
+
result.height = Math.max(y - parentViewBox.y, 0);
|
|
111
|
+
result.width = upperWidth;
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
if (position === 'bottom') {
|
|
116
|
+
var _result = {
|
|
117
|
+
x: lowerX + lowerWidth / 2,
|
|
118
|
+
y: y + height + verticalOffset,
|
|
119
|
+
horizontalAnchor: 'middle',
|
|
120
|
+
verticalAnchor: verticalStart,
|
|
121
|
+
};
|
|
122
|
+
if (clamp && parentViewBox) {
|
|
123
|
+
_result.height = Math.max(parentViewBox.y + parentViewBox.height - (y + height), 0);
|
|
124
|
+
_result.width = lowerWidth;
|
|
125
|
+
}
|
|
126
|
+
return _result;
|
|
127
|
+
}
|
|
128
|
+
if (position === 'left') {
|
|
129
|
+
var _result2 = {
|
|
130
|
+
x: middleX - horizontalOffset,
|
|
131
|
+
y: y + height / 2,
|
|
132
|
+
horizontalAnchor: horizontalEnd,
|
|
133
|
+
verticalAnchor: 'middle',
|
|
134
|
+
};
|
|
135
|
+
if (clamp && parentViewBox) {
|
|
136
|
+
_result2.width = Math.max(_result2.x - parentViewBox.x, 0);
|
|
137
|
+
_result2.height = height;
|
|
138
|
+
}
|
|
139
|
+
return _result2;
|
|
140
|
+
}
|
|
141
|
+
if (position === 'right') {
|
|
142
|
+
var _result3 = {
|
|
143
|
+
x: middleX + midHeightWidth + horizontalOffset,
|
|
144
|
+
y: y + height / 2,
|
|
145
|
+
horizontalAnchor: horizontalStart,
|
|
146
|
+
verticalAnchor: 'middle',
|
|
147
|
+
};
|
|
148
|
+
if (clamp && parentViewBox) {
|
|
149
|
+
_result3.width = Math.max(parentViewBox.x + parentViewBox.width - _result3.x, 0);
|
|
150
|
+
_result3.height = height;
|
|
151
|
+
}
|
|
152
|
+
return _result3;
|
|
153
|
+
}
|
|
154
|
+
var sizeAttrs =
|
|
155
|
+
clamp && parentViewBox
|
|
156
|
+
? {
|
|
157
|
+
width: midHeightWidth,
|
|
158
|
+
height,
|
|
159
|
+
}
|
|
160
|
+
: {};
|
|
161
|
+
if (position === 'insideLeft') {
|
|
162
|
+
return _objectSpread(
|
|
163
|
+
{
|
|
164
|
+
x: middleX + horizontalOffset,
|
|
165
|
+
y: y + height / 2,
|
|
166
|
+
horizontalAnchor: horizontalStart,
|
|
167
|
+
verticalAnchor: 'middle',
|
|
168
|
+
},
|
|
169
|
+
sizeAttrs,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
if (position === 'insideRight') {
|
|
173
|
+
return _objectSpread(
|
|
174
|
+
{
|
|
175
|
+
x: middleX + midHeightWidth - horizontalOffset,
|
|
176
|
+
y: y + height / 2,
|
|
177
|
+
horizontalAnchor: horizontalEnd,
|
|
178
|
+
verticalAnchor: 'middle',
|
|
179
|
+
},
|
|
180
|
+
sizeAttrs,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
if (position === 'insideTop') {
|
|
184
|
+
return _objectSpread(
|
|
185
|
+
{
|
|
186
|
+
x: upperX + upperWidth / 2,
|
|
187
|
+
y: y + verticalOffset,
|
|
188
|
+
horizontalAnchor: 'middle',
|
|
189
|
+
verticalAnchor: verticalStart,
|
|
190
|
+
},
|
|
191
|
+
sizeAttrs,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (position === 'insideBottom') {
|
|
195
|
+
return _objectSpread(
|
|
196
|
+
{
|
|
197
|
+
x: lowerX + lowerWidth / 2,
|
|
198
|
+
y: y + height - verticalOffset,
|
|
199
|
+
horizontalAnchor: 'middle',
|
|
200
|
+
verticalAnchor: verticalEnd,
|
|
201
|
+
},
|
|
202
|
+
sizeAttrs,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (position === 'insideTopLeft') {
|
|
206
|
+
return _objectSpread(
|
|
207
|
+
{
|
|
208
|
+
x: upperX + horizontalOffset,
|
|
209
|
+
y: y + verticalOffset,
|
|
210
|
+
horizontalAnchor: horizontalStart,
|
|
211
|
+
verticalAnchor: verticalStart,
|
|
212
|
+
},
|
|
213
|
+
sizeAttrs,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (position === 'insideTopRight') {
|
|
217
|
+
return _objectSpread(
|
|
218
|
+
{
|
|
219
|
+
x: upperX + upperWidth - horizontalOffset,
|
|
220
|
+
y: y + verticalOffset,
|
|
221
|
+
horizontalAnchor: horizontalEnd,
|
|
222
|
+
verticalAnchor: verticalStart,
|
|
223
|
+
},
|
|
224
|
+
sizeAttrs,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
if (position === 'insideBottomLeft') {
|
|
228
|
+
return _objectSpread(
|
|
229
|
+
{
|
|
230
|
+
x: lowerX + horizontalOffset,
|
|
231
|
+
y: y + height - verticalOffset,
|
|
232
|
+
horizontalAnchor: horizontalStart,
|
|
233
|
+
verticalAnchor: verticalEnd,
|
|
234
|
+
},
|
|
235
|
+
sizeAttrs,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (position === 'insideBottomRight') {
|
|
239
|
+
return _objectSpread(
|
|
240
|
+
{
|
|
241
|
+
x: lowerX + lowerWidth - horizontalOffset,
|
|
242
|
+
y: y + height - verticalOffset,
|
|
243
|
+
horizontalAnchor: horizontalEnd,
|
|
244
|
+
verticalAnchor: verticalEnd,
|
|
245
|
+
},
|
|
246
|
+
sizeAttrs,
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
if (
|
|
250
|
+
!!position &&
|
|
251
|
+
typeof position === 'object' &&
|
|
252
|
+
(isNumber(position.x) || isPercent(position.x)) &&
|
|
253
|
+
(isNumber(position.y) || isPercent(position.y))
|
|
254
|
+
) {
|
|
255
|
+
// TODO: This is not quite right. The width of the trapezoid changes with y.
|
|
256
|
+
// A percentage-based x should be relative to the width at that y.
|
|
257
|
+
// For now, we use the mid-height width as a reasonable approximation.
|
|
258
|
+
return _objectSpread(
|
|
259
|
+
{
|
|
260
|
+
x: x + getPercentValue(position.x, midHeightWidth),
|
|
261
|
+
y: y + getPercentValue(position.y, height),
|
|
262
|
+
horizontalAnchor: 'end',
|
|
263
|
+
verticalAnchor: 'end',
|
|
264
|
+
},
|
|
265
|
+
sizeAttrs,
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
return _objectSpread(
|
|
269
|
+
{
|
|
270
|
+
x: centerX,
|
|
271
|
+
y: y + height / 2,
|
|
272
|
+
horizontalAnchor: 'middle',
|
|
273
|
+
verticalAnchor: 'middle',
|
|
274
|
+
},
|
|
275
|
+
sizeAttrs,
|
|
276
|
+
);
|
|
277
|
+
};
|