@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,97 @@
|
|
|
1
|
+
// Port of cartesian/BarStack.tsx — rounded-corner clipping for whole bar
|
|
2
|
+
// stacks: one clipPath per stack rectangle, referenced by the bars.
|
|
3
|
+
import { createContext, memo, useContext, useMemo } from 'octane';
|
|
4
|
+
import { getNormalizedStackId } from '../util/ChartUtils';
|
|
5
|
+
import { useUniqueId } from '../util/useUniqueId';
|
|
6
|
+
import { resolveDefaultProps } from '../util/resolveDefaultProps';
|
|
7
|
+
import { useAppSelector } from '../state/hooks';
|
|
8
|
+
import { selectStackRects } from '../state/selectors/barStackSelectors';
|
|
9
|
+
import { useIsPanorama } from '../context/PanoramaContext.ts';
|
|
10
|
+
import { Layer } from '../container/Layer.tsrx';
|
|
11
|
+
import { Rectangle } from '../shape/Rectangle.tsrx';
|
|
12
|
+
import { propsAreEqual } from '../util/propsAreEqual';
|
|
13
|
+
|
|
14
|
+
const BarStackContext = createContext(undefined);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Resolves the stack ID for a Bar: explicit prop wins, then BarStack context.
|
|
18
|
+
*/
|
|
19
|
+
export function useStackId(childStackId) {
|
|
20
|
+
const stackSettings = useContext(BarStackContext);
|
|
21
|
+
if (stackSettings != null) {
|
|
22
|
+
return stackSettings.stackId;
|
|
23
|
+
}
|
|
24
|
+
if (childStackId == null) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return getNormalizedStackId(childStackId);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const defaultBarStackProps = {
|
|
31
|
+
radius: 0,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const getClipPathId = (stackId, index) => {
|
|
35
|
+
return 'recharts-bar-stack-clip-path-' + stackId + '-' + index;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function useBarStackClipPathUrl(index) {
|
|
39
|
+
const barStackContext = useContext(BarStackContext);
|
|
40
|
+
if (barStackContext == null) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const { stackId } = barStackContext;
|
|
44
|
+
return 'url(#' + getClipPathId(stackId, index) + ')';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function BarStackClipLayer(props) {
|
|
48
|
+
const { index, ...rest } = props;
|
|
49
|
+
const clipPathUrl = useBarStackClipPathUrl(index);
|
|
50
|
+
return <Layer className="recharts-bar-stack-layer" clipPath={clipPathUrl} {...rest} />;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Renders one clipPath per stack rectangle so the whole stack gets rounded
|
|
55
|
+
* corners.
|
|
56
|
+
*/
|
|
57
|
+
function BarStackClipPath(props) {
|
|
58
|
+
const { stackId, radius } = props;
|
|
59
|
+
const isPanorama = useIsPanorama();
|
|
60
|
+
const positions = useAppSelector((state) => selectStackRects(state, stackId, isPanorama));
|
|
61
|
+
if (positions == null || positions.length === 0) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return <defs>{positions.map((pos, index) => {
|
|
65
|
+
if (pos == null) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const clipPathId = getClipPathId(stackId, index);
|
|
69
|
+
return <clipPath key={clipPathId} id={clipPathId}>
|
|
70
|
+
<Rectangle
|
|
71
|
+
isAnimationActive={false}
|
|
72
|
+
isUpdateAnimationActive={false}
|
|
73
|
+
x={pos.x}
|
|
74
|
+
y={pos.y}
|
|
75
|
+
width={pos.width}
|
|
76
|
+
height={pos.height}
|
|
77
|
+
radius={radius}
|
|
78
|
+
/>
|
|
79
|
+
</clipPath>;
|
|
80
|
+
})}</defs>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function BarStackImpl(props) @{
|
|
84
|
+
const resolvedStackId = useUniqueId('recharts-bar-stack', getNormalizedStackId(props.stackId));
|
|
85
|
+
const { children, radius } = resolveDefaultProps(props, defaultBarStackProps);
|
|
86
|
+
const context = useMemo(() => ({ stackId: resolvedStackId, radius }), [resolvedStackId, radius]);
|
|
87
|
+
<BarStackContext.Provider value={context}>
|
|
88
|
+
<BarStackClipPath stackId={resolvedStackId} radius={radius} />
|
|
89
|
+
{children}
|
|
90
|
+
</BarStackContext.Provider>
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @provides BarStackContext
|
|
95
|
+
* @since 3.6
|
|
96
|
+
*/
|
|
97
|
+
export const BarStack = memo(BarStackImpl, propsAreEqual);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Type declaration for the .tsrx component (resolved by relative path).
|
|
2
|
+
export declare const defaultBarStackProps: Record<string, unknown>;
|
|
3
|
+
export declare const BarStack: (props: Record<string, unknown>) => unknown;
|
|
4
|
+
export declare function useStackId(childStackId?: unknown): string | undefined;
|
|
5
|
+
export declare function useBarStackClipPathUrl(index: number): string | undefined;
|
|
6
|
+
export declare const BarStackClipLayer: (props: Record<string, unknown>) => unknown;
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
// Port of cartesian/CartesianAxis.tsx — the axis renderer: axis line, tick
|
|
2
|
+
// lines, tick labels (measured for font metrics via a callback ref), the
|
|
3
|
+
// rendered-ticks store reporter, and the imperative getCalculatedWidth handle
|
|
4
|
+
// YAxis auto-width uses.
|
|
5
|
+
import {
|
|
6
|
+
useState,
|
|
7
|
+
useRef,
|
|
8
|
+
useCallback,
|
|
9
|
+
useImperativeHandle,
|
|
10
|
+
useEffect,
|
|
11
|
+
isValidElement,
|
|
12
|
+
cloneElement,
|
|
13
|
+
} from 'octane';
|
|
14
|
+
import { get } from 'es-toolkit/compat';
|
|
15
|
+
import { clsx } from 'clsx';
|
|
16
|
+
import { Layer } from '../container/Layer.tsrx';
|
|
17
|
+
import { Text, isValidTextAnchor } from '../component/Text.tsrx';
|
|
18
|
+
import {
|
|
19
|
+
CartesianLabelContextProvider,
|
|
20
|
+
CartesianLabelFromLabelProp,
|
|
21
|
+
} from '../component/Label.tsrx';
|
|
22
|
+
import { isNumber, noop } from '../util/DataUtils';
|
|
23
|
+
import { adaptEventsOfChild } from '../util/types.ts';
|
|
24
|
+
import { getTicks } from './getTicks';
|
|
25
|
+
import {
|
|
26
|
+
svgPropertiesNoEvents,
|
|
27
|
+
svgPropertiesNoEventsFromUnknown,
|
|
28
|
+
} from '../util/svgPropertiesNoEvents';
|
|
29
|
+
import { getCalculatedYAxisWidth } from '../util/YAxisUtils';
|
|
30
|
+
import { resolveDefaultProps } from '../util/resolveDefaultProps';
|
|
31
|
+
import { ZIndexLayer } from '../zIndex/ZIndexLayer.tsrx';
|
|
32
|
+
import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
|
|
33
|
+
import { getClassNameFromUnknown } from '../util/getClassNameFromUnknown';
|
|
34
|
+
import { removeRenderedTicks, setRenderedTicks } from '../state/renderedTicksSlice';
|
|
35
|
+
import { useAppDispatch } from '../state/hooks';
|
|
36
|
+
|
|
37
|
+
export const defaultCartesianAxisProps = {
|
|
38
|
+
x: 0,
|
|
39
|
+
y: 0,
|
|
40
|
+
width: 0,
|
|
41
|
+
height: 0,
|
|
42
|
+
viewBox: { x: 0, y: 0, width: 0, height: 0 },
|
|
43
|
+
// The orientation of axis
|
|
44
|
+
orientation: 'bottom',
|
|
45
|
+
// The ticks
|
|
46
|
+
ticks: [],
|
|
47
|
+
stroke: '#666',
|
|
48
|
+
tickLine: true,
|
|
49
|
+
axisLine: true,
|
|
50
|
+
tick: true,
|
|
51
|
+
mirror: false,
|
|
52
|
+
minTickGap: 5,
|
|
53
|
+
// The width or height of tick
|
|
54
|
+
tickSize: 6,
|
|
55
|
+
tickMargin: 2,
|
|
56
|
+
interval: 'preserveEnd',
|
|
57
|
+
zIndex: DefaultZIndexes.axis,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function AxisLine(axisLineProps) {
|
|
61
|
+
const { x, y, width, height, orientation, mirror, axisLine, otherSvgProps } = axisLineProps;
|
|
62
|
+
if (!axisLine) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
let props = { ...otherSvgProps, ...svgPropertiesNoEvents(axisLine), fill: 'none' };
|
|
66
|
+
if (orientation === 'top' || orientation === 'bottom') {
|
|
67
|
+
const needHeight = +(orientation === 'top' && !mirror || orientation === 'bottom' && mirror);
|
|
68
|
+
props = {
|
|
69
|
+
...props,
|
|
70
|
+
x1: x,
|
|
71
|
+
y1: y + needHeight * height,
|
|
72
|
+
x2: x + width,
|
|
73
|
+
y2: y + needHeight * height,
|
|
74
|
+
};
|
|
75
|
+
} else {
|
|
76
|
+
const needWidth = +(orientation === 'left' && !mirror || orientation === 'right' && mirror);
|
|
77
|
+
props = {
|
|
78
|
+
...props,
|
|
79
|
+
x1: x + needWidth * width,
|
|
80
|
+
y1: y,
|
|
81
|
+
x2: x + needWidth * width,
|
|
82
|
+
y2: y + height,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return <line
|
|
86
|
+
{...props}
|
|
87
|
+
className={clsx('recharts-cartesian-axis-line', get(axisLine, 'className'))}
|
|
88
|
+
/>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Calculate the coordinates of endpoints in ticks: `line` for the tick line,
|
|
93
|
+
* `tick` for the tick text.
|
|
94
|
+
*/
|
|
95
|
+
function getTickLineCoord(data, x, y, width, height, orientation, tickSize, mirror, tickMargin) {
|
|
96
|
+
let x1, x2, y1, y2, tx, ty;
|
|
97
|
+
const sign = mirror ? -1 : 1;
|
|
98
|
+
const finalTickSize = data.tickSize || tickSize;
|
|
99
|
+
const tickCoord = isNumber(data.tickCoord) ? data.tickCoord : data.coordinate;
|
|
100
|
+
switch (orientation) {
|
|
101
|
+
case 'top':
|
|
102
|
+
x1 = x2 = data.coordinate;
|
|
103
|
+
y2 = y + +!mirror * height;
|
|
104
|
+
y1 = y2 - sign * finalTickSize;
|
|
105
|
+
ty = y1 - sign * tickMargin;
|
|
106
|
+
tx = tickCoord;
|
|
107
|
+
break;
|
|
108
|
+
case 'left':
|
|
109
|
+
y1 = y2 = data.coordinate;
|
|
110
|
+
x2 = x + +!mirror * width;
|
|
111
|
+
x1 = x2 - sign * finalTickSize;
|
|
112
|
+
tx = x1 - sign * tickMargin;
|
|
113
|
+
ty = tickCoord;
|
|
114
|
+
break;
|
|
115
|
+
case 'right':
|
|
116
|
+
y1 = y2 = data.coordinate;
|
|
117
|
+
x2 = x + +mirror * width;
|
|
118
|
+
x1 = x2 + sign * finalTickSize;
|
|
119
|
+
tx = x1 + sign * tickMargin;
|
|
120
|
+
ty = tickCoord;
|
|
121
|
+
break;
|
|
122
|
+
default:
|
|
123
|
+
x1 = x2 = data.coordinate;
|
|
124
|
+
y2 = y + +mirror * height;
|
|
125
|
+
y1 = y2 + sign * finalTickSize;
|
|
126
|
+
ty = y1 + sign * tickMargin;
|
|
127
|
+
tx = tickCoord;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
line: { x1, y1, x2, y2 },
|
|
132
|
+
tick: { x: tx, y: ty },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function getTickTextAnchor(orientation, mirror) {
|
|
137
|
+
switch (orientation) {
|
|
138
|
+
case 'left':
|
|
139
|
+
return mirror ? 'start' : 'end';
|
|
140
|
+
case 'right':
|
|
141
|
+
return mirror ? 'end' : 'start';
|
|
142
|
+
default:
|
|
143
|
+
return 'middle';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function getTickVerticalAnchor(orientation, mirror) {
|
|
148
|
+
switch (orientation) {
|
|
149
|
+
case 'left':
|
|
150
|
+
case 'right':
|
|
151
|
+
return 'middle';
|
|
152
|
+
case 'top':
|
|
153
|
+
return mirror ? 'start' : 'end';
|
|
154
|
+
default:
|
|
155
|
+
return mirror ? 'end' : 'start';
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function TickItem(props) {
|
|
160
|
+
const { option, tickProps, value } = props;
|
|
161
|
+
let tickItem;
|
|
162
|
+
const combinedClassName = clsx(tickProps.className, 'recharts-cartesian-axis-tick-value');
|
|
163
|
+
if (isValidElement(option)) {
|
|
164
|
+
tickItem = cloneElement(option, { ...tickProps, className: combinedClassName });
|
|
165
|
+
} else if (typeof option === 'function') {
|
|
166
|
+
tickItem = option({ ...tickProps, className: combinedClassName });
|
|
167
|
+
} else {
|
|
168
|
+
let className = 'recharts-cartesian-axis-tick-value';
|
|
169
|
+
if (typeof option !== 'boolean') {
|
|
170
|
+
className = clsx(className, getClassNameFromUnknown(option));
|
|
171
|
+
}
|
|
172
|
+
tickItem = <Text {...tickProps} className={className}>{value}</Text>;
|
|
173
|
+
}
|
|
174
|
+
return tickItem;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function RenderedTicksReporter(props) {
|
|
178
|
+
const { ticks, axisType, axisId } = props;
|
|
179
|
+
const dispatch = useAppDispatch();
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
if (axisId == null || axisType == null) {
|
|
182
|
+
return noop;
|
|
183
|
+
}
|
|
184
|
+
// Filter out irrelevant internal properties before exposing externally
|
|
185
|
+
const tickItems = ticks.map(
|
|
186
|
+
(tick) => ({
|
|
187
|
+
value: tick.value,
|
|
188
|
+
coordinate: tick.coordinate,
|
|
189
|
+
offset: tick.offset,
|
|
190
|
+
index: tick.index,
|
|
191
|
+
}),
|
|
192
|
+
);
|
|
193
|
+
dispatch(setRenderedTicks({ ticks: tickItems, axisId, axisType }));
|
|
194
|
+
return () => {
|
|
195
|
+
dispatch(removeRenderedTicks({ axisId, axisType }));
|
|
196
|
+
};
|
|
197
|
+
}, [dispatch, ticks, axisId, axisType]);
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function Ticks(props) {
|
|
202
|
+
const {
|
|
203
|
+
ticks = [],
|
|
204
|
+
tick,
|
|
205
|
+
tickLine,
|
|
206
|
+
stroke,
|
|
207
|
+
tickFormatter,
|
|
208
|
+
unit,
|
|
209
|
+
padding,
|
|
210
|
+
tickTextProps,
|
|
211
|
+
orientation,
|
|
212
|
+
mirror,
|
|
213
|
+
x,
|
|
214
|
+
y,
|
|
215
|
+
width,
|
|
216
|
+
height,
|
|
217
|
+
tickSize,
|
|
218
|
+
tickMargin,
|
|
219
|
+
fontSize,
|
|
220
|
+
letterSpacing,
|
|
221
|
+
getTicksConfig,
|
|
222
|
+
events,
|
|
223
|
+
axisType,
|
|
224
|
+
axisId,
|
|
225
|
+
ref,
|
|
226
|
+
} = props;
|
|
227
|
+
const finalTicks = getTicks({ ...getTicksConfig, ticks }, fontSize, letterSpacing);
|
|
228
|
+
const axisProps = svgPropertiesNoEvents(getTicksConfig);
|
|
229
|
+
const customTickProps = svgPropertiesNoEventsFromUnknown(tick);
|
|
230
|
+
// Use user-provided textAnchor if available, otherwise calculate from orientation/mirror
|
|
231
|
+
const textAnchor =
|
|
232
|
+
isValidTextAnchor(axisProps.textAnchor)
|
|
233
|
+
? axisProps.textAnchor
|
|
234
|
+
: getTickTextAnchor(orientation, mirror);
|
|
235
|
+
const verticalAnchor = getTickVerticalAnchor(orientation, mirror);
|
|
236
|
+
let tickLinePropsObject = {};
|
|
237
|
+
if (typeof tickLine === 'object') {
|
|
238
|
+
tickLinePropsObject = tickLine;
|
|
239
|
+
}
|
|
240
|
+
const tickLineProps = { ...axisProps, fill: 'none', ...tickLinePropsObject };
|
|
241
|
+
const tickLineCoords = finalTicks.map(
|
|
242
|
+
(entry) => ({
|
|
243
|
+
entry,
|
|
244
|
+
...getTickLineCoord(entry, x, y, width, height, orientation, tickSize, mirror, tickMargin),
|
|
245
|
+
}),
|
|
246
|
+
);
|
|
247
|
+
const tickLines = tickLineCoords.map(({ entry, line: lineCoord }) => {
|
|
248
|
+
return <Layer
|
|
249
|
+
className="recharts-cartesian-axis-tick"
|
|
250
|
+
key={'tick-' + entry.value + '-' + entry.coordinate + '-' + entry.tickCoord}
|
|
251
|
+
>
|
|
252
|
+
{tickLine &&
|
|
253
|
+
<line
|
|
254
|
+
{...tickLineProps}
|
|
255
|
+
{...lineCoord}
|
|
256
|
+
className={clsx('recharts-cartesian-axis-tick-line', get(tickLine, 'className'))}
|
|
257
|
+
/>}
|
|
258
|
+
</Layer>;
|
|
259
|
+
});
|
|
260
|
+
const tickLabels = tickLineCoords.map(({ entry, tick: tickCoord }, i) => {
|
|
261
|
+
const tickProps = {
|
|
262
|
+
verticalAnchor,
|
|
263
|
+
...axisProps,
|
|
264
|
+
textAnchor,
|
|
265
|
+
stroke: 'none',
|
|
266
|
+
fill: stroke,
|
|
267
|
+
...tickCoord,
|
|
268
|
+
index: i,
|
|
269
|
+
payload: entry,
|
|
270
|
+
visibleTicksCount: finalTicks.length,
|
|
271
|
+
tickFormatter,
|
|
272
|
+
padding,
|
|
273
|
+
...tickTextProps,
|
|
274
|
+
angle: tickTextProps?.angle ?? axisProps.angle ?? 0,
|
|
275
|
+
};
|
|
276
|
+
const finalTickProps = { ...tickProps, ...customTickProps };
|
|
277
|
+
return <Layer
|
|
278
|
+
className="recharts-cartesian-axis-tick-label"
|
|
279
|
+
key={'tick-label-' + entry.value + '-' + entry.coordinate + '-' + entry.tickCoord}
|
|
280
|
+
{...adaptEventsOfChild(events, entry, i)}
|
|
281
|
+
>
|
|
282
|
+
{tick &&
|
|
283
|
+
<TickItem
|
|
284
|
+
option={tick}
|
|
285
|
+
tickProps={finalTickProps}
|
|
286
|
+
value={String(
|
|
287
|
+
typeof tickFormatter === 'function' ? tickFormatter(entry.value, i) : entry.value,
|
|
288
|
+
) +
|
|
289
|
+
(unit || '')}
|
|
290
|
+
/>}
|
|
291
|
+
</Layer>;
|
|
292
|
+
});
|
|
293
|
+
return <g className={'recharts-cartesian-axis-ticks recharts-' + axisType + '-ticks'}>
|
|
294
|
+
<RenderedTicksReporter ticks={finalTicks} axisId={axisId} axisType={axisType} />
|
|
295
|
+
{tickLabels.length > 0 &&
|
|
296
|
+
<ZIndexLayer zIndex={DefaultZIndexes.label}>
|
|
297
|
+
<g
|
|
298
|
+
className={'recharts-cartesian-axis-tick-labels recharts-' + axisType + '-tick-labels'}
|
|
299
|
+
ref={ref}
|
|
300
|
+
>{tickLabels}</g>
|
|
301
|
+
</ZIndexLayer>}
|
|
302
|
+
{tickLines.length > 0 &&
|
|
303
|
+
<g
|
|
304
|
+
className={'recharts-cartesian-axis-tick-lines recharts-' + axisType + '-tick-lines'}
|
|
305
|
+
>{tickLines}</g>}
|
|
306
|
+
</g>;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function CartesianAxisComponent(props) {
|
|
310
|
+
const { axisLine, width, height, className, hide, ticks, axisType, axisId, ref, ...rest } = props;
|
|
311
|
+
const [fontSize, setFontSize] = useState('');
|
|
312
|
+
const [letterSpacing, setLetterSpacing] = useState('');
|
|
313
|
+
const tickRefs = useRef(null);
|
|
314
|
+
useImperativeHandle(
|
|
315
|
+
ref,
|
|
316
|
+
() => ({
|
|
317
|
+
getCalculatedWidth: () => {
|
|
318
|
+
return getCalculatedYAxisWidth({
|
|
319
|
+
ticks: tickRefs.current,
|
|
320
|
+
label: props.labelRef?.current,
|
|
321
|
+
labelGapWithTick: 5,
|
|
322
|
+
tickSize: props.tickSize,
|
|
323
|
+
tickMargin: props.tickMargin,
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
}),
|
|
327
|
+
);
|
|
328
|
+
const layerRef = useCallback((el) => {
|
|
329
|
+
if (el) {
|
|
330
|
+
const tickNodes = el.getElementsByClassName('recharts-cartesian-axis-tick-value');
|
|
331
|
+
tickRefs.current = tickNodes;
|
|
332
|
+
const tick = tickNodes[0];
|
|
333
|
+
if (tick) {
|
|
334
|
+
const computedStyle = window.getComputedStyle(tick);
|
|
335
|
+
const calculatedFontSize = computedStyle.fontSize;
|
|
336
|
+
const calculatedLetterSpacing = computedStyle.letterSpacing;
|
|
337
|
+
if (calculatedFontSize !== fontSize || calculatedLetterSpacing !== letterSpacing) {
|
|
338
|
+
setFontSize(calculatedFontSize);
|
|
339
|
+
setLetterSpacing(calculatedLetterSpacing);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}, [fontSize, letterSpacing]);
|
|
344
|
+
if (hide) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
// CartesianAxis allows width or height to be undefined (unlike
|
|
348
|
+
// validateWidthHeight).
|
|
349
|
+
if (width != null && width <= 0 || height != null && height <= 0) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
return <ZIndexLayer zIndex={props.zIndex}>
|
|
353
|
+
<Layer className={clsx('recharts-cartesian-axis', className)}>
|
|
354
|
+
<AxisLine
|
|
355
|
+
x={props.x}
|
|
356
|
+
y={props.y}
|
|
357
|
+
width={width}
|
|
358
|
+
height={height}
|
|
359
|
+
orientation={props.orientation}
|
|
360
|
+
mirror={props.mirror}
|
|
361
|
+
axisLine={axisLine}
|
|
362
|
+
otherSvgProps={svgPropertiesNoEvents(props)}
|
|
363
|
+
/>
|
|
364
|
+
<Ticks
|
|
365
|
+
ref={layerRef}
|
|
366
|
+
axisType={axisType}
|
|
367
|
+
events={rest}
|
|
368
|
+
fontSize={fontSize}
|
|
369
|
+
getTicksConfig={props}
|
|
370
|
+
height={props.height}
|
|
371
|
+
letterSpacing={letterSpacing}
|
|
372
|
+
mirror={props.mirror}
|
|
373
|
+
orientation={props.orientation}
|
|
374
|
+
padding={props.padding}
|
|
375
|
+
stroke={props.stroke}
|
|
376
|
+
tick={props.tick}
|
|
377
|
+
tickFormatter={props.tickFormatter}
|
|
378
|
+
tickLine={props.tickLine}
|
|
379
|
+
tickMargin={props.tickMargin}
|
|
380
|
+
tickSize={props.tickSize}
|
|
381
|
+
tickTextProps={props.tickTextProps}
|
|
382
|
+
ticks={ticks}
|
|
383
|
+
unit={props.unit}
|
|
384
|
+
width={props.width}
|
|
385
|
+
x={props.x}
|
|
386
|
+
y={props.y}
|
|
387
|
+
axisId={axisId}
|
|
388
|
+
/>
|
|
389
|
+
<CartesianLabelContextProvider
|
|
390
|
+
x={props.x}
|
|
391
|
+
y={props.y}
|
|
392
|
+
width={props.width}
|
|
393
|
+
height={props.height}
|
|
394
|
+
lowerWidth={props.width}
|
|
395
|
+
upperWidth={props.width}
|
|
396
|
+
>
|
|
397
|
+
<CartesianLabelFromLabelProp label={props.label} labelRef={props.labelRef} />
|
|
398
|
+
{props.children}
|
|
399
|
+
</CartesianLabelContextProvider>
|
|
400
|
+
</Layer>
|
|
401
|
+
</ZIndexLayer>;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* @deprecated not meant to be used directly in app code — use XAxis or YAxis.
|
|
406
|
+
*/
|
|
407
|
+
export function CartesianAxis(outsideProps) {
|
|
408
|
+
const { ref, ...rest } = outsideProps;
|
|
409
|
+
const props = resolveDefaultProps(rest, defaultCartesianAxisProps);
|
|
410
|
+
return <CartesianAxisComponent {...props} ref={ref} />;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
CartesianAxis.displayName = 'CartesianAxis';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Port of cartesian/GraphicalItemClipPath.tsx — the per-item clipPath used
|
|
2
|
+
// when either axis has allowDataOverflow.
|
|
3
|
+
import { useAppSelector } from '../state/hooks';
|
|
4
|
+
import {
|
|
5
|
+
implicitXAxis,
|
|
6
|
+
implicitYAxis,
|
|
7
|
+
selectXAxisRange,
|
|
8
|
+
selectXAxisSettings,
|
|
9
|
+
selectYAxisRange,
|
|
10
|
+
selectYAxisSettings,
|
|
11
|
+
} from '../state/selectors/axisSelectors';
|
|
12
|
+
import { usePlotArea } from '../hooks';
|
|
13
|
+
|
|
14
|
+
export function useNeedsClip(xAxisId, yAxisId) {
|
|
15
|
+
const xAxis = useAppSelector((state) => selectXAxisSettings(state, xAxisId));
|
|
16
|
+
const yAxis = useAppSelector((state) => selectYAxisSettings(state, yAxisId));
|
|
17
|
+
const needClipX = xAxis?.allowDataOverflow ?? implicitXAxis.allowDataOverflow;
|
|
18
|
+
const needClipY = yAxis?.allowDataOverflow ?? implicitYAxis.allowDataOverflow;
|
|
19
|
+
const needClip = needClipX || needClipY;
|
|
20
|
+
return { needClip, needClipX, needClipY };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function GraphicalItemClipPath(props) @{
|
|
24
|
+
const { xAxisId, yAxisId, clipPathId } = props;
|
|
25
|
+
const plotArea = usePlotArea();
|
|
26
|
+
const { needClipX, needClipY, needClip } = useNeedsClip(xAxisId, yAxisId);
|
|
27
|
+
const xAxisRange = useAppSelector((state) => selectXAxisRange(state, xAxisId, false));
|
|
28
|
+
const yAxisRange = useAppSelector((state) => selectYAxisRange(state, yAxisId, false));
|
|
29
|
+
if (!needClip || !plotArea) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const { x, y, width, height } = plotArea;
|
|
33
|
+
const clipX =
|
|
34
|
+
needClipX && xAxisRange ? Math.min(xAxisRange[0], xAxisRange[1]) : x - width / 2;
|
|
35
|
+
const clipY =
|
|
36
|
+
needClipY && yAxisRange ? Math.min(yAxisRange[0], yAxisRange[1]) : y - height / 2;
|
|
37
|
+
const clipWidth =
|
|
38
|
+
needClipX && xAxisRange ? Math.abs(xAxisRange[1] - xAxisRange[0]) : width * 2;
|
|
39
|
+
const clipHeight =
|
|
40
|
+
needClipY && yAxisRange ? Math.abs(yAxisRange[1] - yAxisRange[0]) : height * 2;
|
|
41
|
+
<clipPath id={'clipPath-' + clipPathId}>
|
|
42
|
+
<rect x={clipX} y={clipY} width={clipWidth} height={clipHeight} />
|
|
43
|
+
</clipPath>
|
|
44
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Extensionless-resolution shim: vendored modules (state/selectors/
|
|
2
|
+
// lineSelectors.js) import `computeLinePoints` from '../../cartesian/Line' —
|
|
3
|
+
// this .ts entry forwards to the .tsrx implementation.
|
|
4
|
+
export { Line, computeLinePoints, defaultLineProps } from './Line.tsrx';
|