@octanejs/recharts 0.1.16 → 0.1.18
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/package.json +4 -4
- package/src/animation/CSSTransitionAnimate.tsrx +142 -0
- package/src/cartesian/Area.tsrx +1096 -0
- package/src/cartesian/Area.tsrx.d.ts +340 -0
- package/src/cartesian/AreaRevealShape.tsrx +202 -0
- package/src/cartesian/CartesianGrid.tsrx +643 -0
- package/src/cartesian/CartesianGrid.tsrx.d.ts +219 -0
- package/src/cartesian/ErrorBar.tsrx +322 -0
- package/src/cartesian/ErrorBar.tsrx.d.ts +131 -0
- package/src/cartesian/Funnel.tsrx +833 -0
- package/src/cartesian/Funnel.tsrx.d.ts +274 -0
- package/src/cartesian/ReferenceLine.tsrx +452 -0
- package/src/cartesian/ReferenceLine.tsrx.d.ts +178 -0
- package/src/cartesian/Scatter.tsrx +1076 -0
- package/src/cartesian/Scatter.tsrx.d.ts +351 -0
- package/src/cartesian/ZAxis.tsrx +148 -0
- package/src/cartesian/ZAxis.tsrx.d.ts +102 -0
- package/src/chart/AreaChart.tsrx +22 -0
- package/src/chart/AreaChart.tsrx.d.ts +12 -0
- package/src/chart/ComposedChart.tsrx +22 -0
- package/src/chart/ComposedChart.tsrx.d.ts +12 -0
- package/src/chart/FunnelChart.tsrx +22 -0
- package/src/chart/FunnelChart.tsrx.d.ts +12 -0
- package/src/chart/PieChart.tsrx +31 -0
- package/src/chart/PieChart.tsrx.d.ts +31 -0
- package/src/chart/PolarChart.tsrx +121 -0
- package/src/chart/RadarChart.tsrx +53 -0
- package/src/chart/RadarChart.tsrx.d.ts +31 -0
- package/src/chart/RadialBarChart.tsrx +31 -0
- package/src/chart/RadialBarChart.tsrx.d.ts +31 -0
- package/src/chart/Sankey.tsrx +1542 -0
- package/src/chart/Sankey.tsrx.d.ts +253 -0
- package/src/chart/ScatterChart.tsrx +22 -0
- package/src/chart/ScatterChart.tsrx.d.ts +12 -0
- package/src/chart/SunburstChart.tsrx +495 -0
- package/src/chart/SunburstChart.tsrx.d.ts +146 -0
- package/src/chart/types.ts +19 -0
- package/src/component/Cursor.tsrx +157 -0
- package/src/component/DefaultLegendContent.tsrx +288 -0
- package/src/component/DefaultLegendContent.tsrx.d.ts +125 -0
- package/src/component/DefaultTooltipContent.tsrx +215 -0
- package/src/component/DefaultTooltipContent.tsrx.d.ts +87 -0
- package/src/component/Legend.tsrx +302 -0
- package/src/component/Legend.tsrx.d.ts +88 -0
- package/src/component/ResponsiveContainer.ts +1 -22
- package/src/component/ResponsiveContainer.tsrx +171 -0
- package/src/component/ResponsiveContainer.tsrx.d.ts +81 -0
- package/src/component/Tooltip.tsrx +425 -0
- package/src/component/Tooltip.tsrx.d.ts +246 -0
- package/src/component/TooltipBoundingBox.tsrx +135 -0
- package/src/context/CellsContext.ts +12 -0
- package/src/context/legendPayloadContext.tsrx +11 -0
- package/src/context/useTooltipAxis.ts +20 -0
- package/src/index.d.ts +236 -0
- package/src/index.ts +67 -0
- package/src/polar/Pie.tsrx +1224 -0
- package/src/polar/Pie.tsrx.d.ts +436 -0
- package/src/polar/PolarAngleAxis.tsrx +554 -0
- package/src/polar/PolarAngleAxis.tsrx.d.ts +215 -0
- package/src/polar/PolarGrid.tsrx +317 -0
- package/src/polar/PolarGrid.tsrx.d.ts +117 -0
- package/src/polar/PolarRadiusAxis.tsrx +463 -0
- package/src/polar/PolarRadiusAxis.tsrx.d.ts +209 -0
- package/src/polar/Radar.tsrx +696 -0
- package/src/polar/Radar.tsrx.d.ts +215 -0
- package/src/polar/RadialBar.tsrx +887 -0
- package/src/polar/RadialBar.tsrx.d.ts +340 -0
- package/src/state/ReportPolarOptions.tsrx +11 -0
- package/src/state/selectors/areaSelectors.ts +257 -0
- package/src/state/selectors/funnelSelectors.ts +86 -0
- package/src/state/selectors/pieSelectors.ts +134 -0
- package/src/state/selectors/polarGridSelectors.ts +43 -0
- package/src/state/selectors/polarScaleSelectors.ts +159 -0
- package/src/state/selectors/polarSelectors.ts +198 -0
- package/src/state/selectors/radarSelectors.ts +228 -0
- package/src/state/selectors/radialBarSelectors.ts +511 -0
- package/src/state/selectors/scatterSelectors.ts +168 -0
- package/src/util/FunnelUtils.tsrx +19 -0
- package/src/util/RadialBarUtils.tsrx +29 -0
- package/src/util/ScatterUtils.tsrx +34 -0
- package/src/util/cursor/getCursorPoints.ts +45 -0
- package/src/util/cursor/getCursorRectangle.ts +28 -0
- package/src/util/cursor/getRadialCursorPoints.ts +31 -0
- package/src/util/payload/getUniqPayload.ts +28 -0
- package/src/util/scale/CartesianScaleHelper.ts +71 -0
- package/src/util/tooltip/translate.ts +168 -0
- package/src/util/types.ts +3 -0
- package/src/util/useElementOffset.ts +147 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import * as React from 'octane';
|
|
2
|
+
import { FunctionComponent, ReactElement, ReactNode, SVGProps, useEffect, useMemo } from 'octane';
|
|
3
|
+
import maxBy from 'es-toolkit/compat/maxBy';
|
|
4
|
+
import minBy from 'es-toolkit/compat/minBy';
|
|
5
|
+
|
|
6
|
+
import { clsx } from 'clsx';
|
|
7
|
+
import { Text } from '../component/Text';
|
|
8
|
+
import { PolarLabelContextProvider, PolarLabelFromLabelProp } from '../component/Label';
|
|
9
|
+
import { Layer } from '../container/Layer';
|
|
10
|
+
import { polarToCartesian } from '../util/PolarUtils';
|
|
11
|
+
import {
|
|
12
|
+
adaptEventsOfChild,
|
|
13
|
+
RenderableAxisProps,
|
|
14
|
+
Coordinate,
|
|
15
|
+
PolarViewBoxRequired,
|
|
16
|
+
PresentationAttributesAdaptChildEvent,
|
|
17
|
+
TickItem,
|
|
18
|
+
AxisDomain,
|
|
19
|
+
ScaleType,
|
|
20
|
+
AxisDomainTypeInput,
|
|
21
|
+
EvaluatedAxisDomainType,
|
|
22
|
+
TickProp,
|
|
23
|
+
BaseTickContentProps,
|
|
24
|
+
AxisTick,
|
|
25
|
+
} from '../util/types';
|
|
26
|
+
import { addRadiusAxis, RadiusAxisSettings, removeRadiusAxis } from '../state/polarAxisSlice';
|
|
27
|
+
import { NiceTicksAlgorithm } from '../state/cartesianAxisSlice';
|
|
28
|
+
import { useAppDispatch, useAppSelector } from '../state/hooks';
|
|
29
|
+
import { selectPolarAxisScale, selectPolarAxisTicks } from '../state/selectors/polarScaleSelectors';
|
|
30
|
+
import { selectPolarViewBox } from '../state/selectors/polarAxisSelectors';
|
|
31
|
+
import { defaultPolarRadiusAxisProps } from './defaultPolarRadiusAxisProps';
|
|
32
|
+
import {
|
|
33
|
+
svgPropertiesNoEvents,
|
|
34
|
+
svgPropertiesNoEventsFromUnknown,
|
|
35
|
+
} from '../util/svgPropertiesNoEvents';
|
|
36
|
+
import { RequiresDefaultProps, resolveDefaultProps } from '../util/resolveDefaultProps';
|
|
37
|
+
import { ZIndexable, ZIndexLayer } from '../zIndex/ZIndexLayer';
|
|
38
|
+
import { RechartsScale } from '../util/scale/RechartsScale';
|
|
39
|
+
import type { CustomScaleDefinition } from '../util/scale/CustomScaleDefinition';
|
|
40
|
+
import { usePolarChartLayout } from '../context/chartLayoutContext';
|
|
41
|
+
import { noop } from '../util/DataUtils';
|
|
42
|
+
import { getAxisTypeBasedOnLayout } from '../util/getAxisTypeBasedOnLayout';
|
|
43
|
+
import { getClassNameFromUnknown } from '../util/getClassNameFromUnknown';
|
|
44
|
+
|
|
45
|
+
type TickOrientation = 'left' | 'right' | 'middle';
|
|
46
|
+
|
|
47
|
+
export interface PolarRadiusAxisProps<DataPointType = any, DataValueType = any> extends Omit<
|
|
48
|
+
RenderableAxisProps<DataPointType, DataValueType>,
|
|
49
|
+
'axisLine' | 'angle' | 'type' | 'tickSize' | 'domain' | 'scale' | 'tick'
|
|
50
|
+
>, ZIndexable {
|
|
51
|
+
/**
|
|
52
|
+
* Determines how the axis line is drawn. Options:
|
|
53
|
+
* - `true`: the axis line is drawn with default props;
|
|
54
|
+
* - `false`: the axis line is not visible;
|
|
55
|
+
* - `object`: passed as props to SVG `<line>` element representing the axis line.
|
|
56
|
+
*
|
|
57
|
+
* @example <PolarRadiusAxis axisLine={false} />
|
|
58
|
+
* @example <PolarRadiusAxis axisLine={{ stroke: 'red', strokeWidth: 2 }} />
|
|
59
|
+
* @defaultValue true
|
|
60
|
+
*/
|
|
61
|
+
axisLine?: boolean | SVGProps<SVGLineElement>;
|
|
62
|
+
/**
|
|
63
|
+
* The angle of the whole axis: the line, ticks and labels, everything.
|
|
64
|
+
*
|
|
65
|
+
* This is different from other graphical elements where angle usually means
|
|
66
|
+
* the angle of text. Here, it means the angle of everything.
|
|
67
|
+
*
|
|
68
|
+
* @defaultValue 0
|
|
69
|
+
*/
|
|
70
|
+
angle?: number;
|
|
71
|
+
/**
|
|
72
|
+
* The type of axis.
|
|
73
|
+
*
|
|
74
|
+
* `category`: Treats data as distinct values.
|
|
75
|
+
* Each value is in the same distance from its neighbors, regardless of their actual numeric difference.
|
|
76
|
+
*
|
|
77
|
+
* `number`: Treats data as continuous range.
|
|
78
|
+
* Values that are numerically closer are placed closer together on the axis.
|
|
79
|
+
*
|
|
80
|
+
* `auto`: the type is inferred based on the chart layout.
|
|
81
|
+
*
|
|
82
|
+
* @defaultValue auto
|
|
83
|
+
*/
|
|
84
|
+
type?: AxisDomainTypeInput;
|
|
85
|
+
/**
|
|
86
|
+
* The orientation of axis text.
|
|
87
|
+
* @defaultValue right
|
|
88
|
+
*/
|
|
89
|
+
orientation?: TickOrientation;
|
|
90
|
+
/**
|
|
91
|
+
* Specify the domain of axis when the axis is a number axis.
|
|
92
|
+
*
|
|
93
|
+
* If undefined, then the domain is calculated based on the data and dataKeys.
|
|
94
|
+
*
|
|
95
|
+
* The length of domain should be 2, and we will validate the values in domain.
|
|
96
|
+
*
|
|
97
|
+
* Each element in the array can be a number, 'auto', 'dataMin', 'dataMax', a string like 'dataMin - 20', 'dataMax + 100',
|
|
98
|
+
* or a function that accepts a single argument and returns a number.
|
|
99
|
+
*
|
|
100
|
+
* If any element of domain is set to be 'auto', comprehensible scale ticks will be calculated, and the final domain of axis is generated by the ticks.
|
|
101
|
+
* If a function, receives '[dataMin, dataMax]', and must return a computed domain as '[min, max]'.
|
|
102
|
+
*
|
|
103
|
+
* @example <PolarRadiusAxis type="number" domain={['dataMin', 'dataMax']} />
|
|
104
|
+
* @example <PolarRadiusAxis type="number" domain={[0, 'dataMax']} />
|
|
105
|
+
* @example <PolarRadiusAxis type="number" domain={['auto', 'auto']} />
|
|
106
|
+
* @example <PolarRadiusAxis type="number" domain={[0, 'dataMax + 1000']} />
|
|
107
|
+
* @example <PolarRadiusAxis type="number" domain={['dataMin - 100', 'dataMax + 100']} />
|
|
108
|
+
* @example <PolarRadiusAxis type="number" domain={[dataMin => (0 - Math.abs(dataMin)), dataMax => (dataMax * 2)]} />
|
|
109
|
+
* @example <PolarRadiusAxis type="number" domain={([dataMin, dataMax]) => { const absMax = Math.max(Math.abs(dataMin), Math.abs(dataMax)); return [-absMax, absMax]; }} />
|
|
110
|
+
* @example <PolarRadiusAxis type="number" domain={[0, 100]} allowDataOverflow />
|
|
111
|
+
*/
|
|
112
|
+
domain?: AxisDomain;
|
|
113
|
+
/**
|
|
114
|
+
* Scale function determines how data values are mapped to visual values.
|
|
115
|
+
* In other words, decided the mapping between data domain and coordinate range.
|
|
116
|
+
*
|
|
117
|
+
* If undefined, or 'auto', the scale function is created internally according to the type of axis and data.
|
|
118
|
+
*
|
|
119
|
+
* You can define a custom scale, either as a string shortcut to a d3 scale, or as a complete scale definition object.
|
|
120
|
+
*
|
|
121
|
+
* @defaultValue auto
|
|
122
|
+
* @example <PolarRadiusAxis scale="log" />
|
|
123
|
+
* @example
|
|
124
|
+
* import { scaleLog } from 'd3-scale';
|
|
125
|
+
* const scale = scaleLog().base(Math.E);
|
|
126
|
+
* <PolarRadiusAxis scale={scale} />
|
|
127
|
+
*/
|
|
128
|
+
scale?: | ScaleType
|
|
129
|
+
| CustomScaleDefinition
|
|
130
|
+
| CustomScaleDefinition<string>
|
|
131
|
+
| CustomScaleDefinition<number>
|
|
132
|
+
| CustomScaleDefinition<Date>;
|
|
133
|
+
/**
|
|
134
|
+
* The customized event handler of click on the ticks of this axis
|
|
135
|
+
*/
|
|
136
|
+
onClick?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
137
|
+
/**
|
|
138
|
+
* The customized event handler of mousedown on the ticks of this axis
|
|
139
|
+
*/
|
|
140
|
+
onMouseDown?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
141
|
+
/**
|
|
142
|
+
* The customized event handler of mouseup on the ticks of this axis
|
|
143
|
+
*/
|
|
144
|
+
onMouseUp?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
145
|
+
/**
|
|
146
|
+
* The customized event handler of mousemove on the ticks of this axis
|
|
147
|
+
*/
|
|
148
|
+
onMouseMove?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
149
|
+
/**
|
|
150
|
+
* The customized event handler of mouseover on the ticks of this axis
|
|
151
|
+
*/
|
|
152
|
+
onMouseOver?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
153
|
+
/**
|
|
154
|
+
* The customized event handler of mouseout on the ticks of this axis
|
|
155
|
+
*/
|
|
156
|
+
onMouseOut?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
157
|
+
/**
|
|
158
|
+
* The customized event handler of mouseenter on the ticks of this axis
|
|
159
|
+
*/
|
|
160
|
+
onMouseEnter?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
161
|
+
/**
|
|
162
|
+
* The customized event handler of mouseleave on the ticks of this axis
|
|
163
|
+
*/
|
|
164
|
+
onMouseLeave?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
165
|
+
/**
|
|
166
|
+
* Allow the ticks of axis to be decimals or not.
|
|
167
|
+
*
|
|
168
|
+
* @defaultValue false
|
|
169
|
+
*/
|
|
170
|
+
allowDecimals?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Controls how Recharts calculates "nice" tick values for this axis.
|
|
173
|
+
* Options: `'none'`, `'auto'`, `'adaptive'`, `'snap125'`.
|
|
174
|
+
* See {@link NiceTicksAlgorithm} for a full description of each option.
|
|
175
|
+
*
|
|
176
|
+
* @defaultValue 'auto'
|
|
177
|
+
*/
|
|
178
|
+
niceTicks?: NiceTicksAlgorithm;
|
|
179
|
+
/**
|
|
180
|
+
* @defaultValue 0
|
|
181
|
+
*/
|
|
182
|
+
radiusAxisId?: string | number;
|
|
183
|
+
/**
|
|
184
|
+
* Defines how the individual label text is rendered.
|
|
185
|
+
* This controls the settings for individual ticks; on a typical axis, there are multiple ticks, depending on your data.
|
|
186
|
+
*
|
|
187
|
+
* If you want to customize the overall axis label, use the `label` prop instead.
|
|
188
|
+
*
|
|
189
|
+
* Options:
|
|
190
|
+
* - `false`: Do not render any tick labels.
|
|
191
|
+
* - `true`: Render tick labels with default settings.
|
|
192
|
+
* - `object`: An object of props to be merged into the internally calculated tick props.
|
|
193
|
+
* - `ReactElement`: A custom React element to be used as the tick label.
|
|
194
|
+
* - `function`: A function that returns a React element for custom rendering of tick labels.
|
|
195
|
+
*
|
|
196
|
+
* @defaultValue true
|
|
197
|
+
*/
|
|
198
|
+
tick?: TickProp<BaseTickContentProps>;
|
|
199
|
+
ticks?: ReadonlyArray<AxisTick>;
|
|
200
|
+
/**
|
|
201
|
+
* Z-Index of this component and its children. The higher the value,
|
|
202
|
+
* the more on top it will be rendered.
|
|
203
|
+
* Components with higher zIndex will appear in front of components with lower zIndex.
|
|
204
|
+
* If undefined or 0, the content is rendered in the default layer without portals.
|
|
205
|
+
*
|
|
206
|
+
* @since 3.4
|
|
207
|
+
* @defaultValue 500
|
|
208
|
+
* @see {@link https://recharts.github.io/en-US/guide/zIndex/ Z-Index and layers guide}
|
|
209
|
+
*/
|
|
210
|
+
zIndex?: number;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
type AxisSvgProps =
|
|
214
|
+
Omit<PresentationAttributesAdaptChildEvent<any, SVGTextElement>, 'scale' | 'type'>;
|
|
215
|
+
|
|
216
|
+
export type Props<DataPointType = any, DataValueType = any> =
|
|
217
|
+
AxisSvgProps & PolarRadiusAxisProps<DataPointType, DataValueType>;
|
|
218
|
+
|
|
219
|
+
type PropsWithDefaults<DataPointType = any, DataValueType = any> =
|
|
220
|
+
RequiresDefaultProps<Props<DataPointType, DataValueType>, typeof defaultPolarRadiusAxisProps>;
|
|
221
|
+
|
|
222
|
+
type InsideProps =
|
|
223
|
+
Omit<PropsWithDefaults, 'scale'> & PolarViewBoxRequired & {
|
|
224
|
+
scale: RechartsScale;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const AXIS_TYPE = 'radiusAxis';
|
|
228
|
+
|
|
229
|
+
function SetRadiusAxisSettings(props: Omit<RadiusAxisSettings, 'type'> & {
|
|
230
|
+
type: AxisDomainTypeInput;
|
|
231
|
+
}): null {
|
|
232
|
+
const dispatch = useAppDispatch();
|
|
233
|
+
const layout = usePolarChartLayout();
|
|
234
|
+
const settings: RadiusAxisSettings | undefined = useMemo(() => {
|
|
235
|
+
const { type: typeFromProps, ...rest } = props;
|
|
236
|
+
const evaluatedType: EvaluatedAxisDomainType | undefined = getAxisTypeBasedOnLayout(
|
|
237
|
+
layout,
|
|
238
|
+
'radiusAxis',
|
|
239
|
+
typeFromProps,
|
|
240
|
+
);
|
|
241
|
+
if (evaluatedType == null) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
return { ...rest, type: evaluatedType };
|
|
245
|
+
}, [props, layout]);
|
|
246
|
+
useEffect(() => {
|
|
247
|
+
if (settings == null) {
|
|
248
|
+
return noop;
|
|
249
|
+
}
|
|
250
|
+
dispatch(addRadiusAxis(settings));
|
|
251
|
+
return () => {
|
|
252
|
+
dispatch(removeRadiusAxis(settings));
|
|
253
|
+
};
|
|
254
|
+
}, [dispatch, settings]);
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Calculate the coordinate of tick
|
|
260
|
+
* @param coordinate The radius of tick
|
|
261
|
+
* @param angle from props
|
|
262
|
+
* @param cx from chart
|
|
263
|
+
* @param cy from chart
|
|
264
|
+
* @return (x, y)
|
|
265
|
+
*/
|
|
266
|
+
const getTickValueCoord = (
|
|
267
|
+
{ coordinate }: TickItem,
|
|
268
|
+
angle: number,
|
|
269
|
+
cx: number,
|
|
270
|
+
cy: number,
|
|
271
|
+
): Coordinate => {
|
|
272
|
+
return polarToCartesian(cx, cy, coordinate, angle);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const getTickTextAnchor = (orientation: TickOrientation): string => {
|
|
276
|
+
let textAnchor;
|
|
277
|
+
|
|
278
|
+
switch (orientation) {
|
|
279
|
+
case 'left':
|
|
280
|
+
textAnchor = 'end';
|
|
281
|
+
break;
|
|
282
|
+
case 'right':
|
|
283
|
+
textAnchor = 'start';
|
|
284
|
+
break;
|
|
285
|
+
default:
|
|
286
|
+
textAnchor = 'middle';
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return textAnchor;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const getViewBox = (
|
|
294
|
+
angle: number,
|
|
295
|
+
cx: number,
|
|
296
|
+
cy: number,
|
|
297
|
+
ticks: ReadonlyArray<TickItem>,
|
|
298
|
+
): PolarViewBoxRequired => {
|
|
299
|
+
const maxRadiusTick = maxBy(ticks, (entry: TickItem) => entry.coordinate || 0);
|
|
300
|
+
const minRadiusTick = minBy(ticks, (entry: TickItem) => entry.coordinate || 0);
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
cx,
|
|
304
|
+
cy,
|
|
305
|
+
startAngle: angle,
|
|
306
|
+
endAngle: angle,
|
|
307
|
+
innerRadius: minRadiusTick?.coordinate || 0,
|
|
308
|
+
outerRadius: maxRadiusTick?.coordinate || 0,
|
|
309
|
+
clockWise: false,
|
|
310
|
+
};
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const renderAxisLine = (props: InsideProps, ticks: ReadonlyArray<TickItem>): ReactElement => {
|
|
314
|
+
const { cx, cy, angle, axisLine, ...others } = props;
|
|
315
|
+
const extent: [number, number] = ticks.reduce(
|
|
316
|
+
(result: [number, number], entry: TickItem): [number, number] => [
|
|
317
|
+
Math.min(result[0], entry.coordinate),
|
|
318
|
+
Math.max(result[1], entry.coordinate),
|
|
319
|
+
],
|
|
320
|
+
[Infinity, -Infinity],
|
|
321
|
+
);
|
|
322
|
+
const point0 = polarToCartesian(cx, cy, extent[0], angle);
|
|
323
|
+
const point1 = polarToCartesian(cx, cy, extent[1], angle);
|
|
324
|
+
|
|
325
|
+
const axisLineProps = {
|
|
326
|
+
...svgPropertiesNoEvents(others),
|
|
327
|
+
fill: 'none',
|
|
328
|
+
...svgPropertiesNoEvents(axisLine),
|
|
329
|
+
x1: point0.x,
|
|
330
|
+
y1: point0.y,
|
|
331
|
+
x2: point1.x,
|
|
332
|
+
y2: point1.y,
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// @ts-expect-error wrong SVG element type
|
|
336
|
+
return <line className="recharts-polar-radius-axis-line" {...axisLineProps} />;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const renderTickItem = (
|
|
340
|
+
option: Props['tick'],
|
|
341
|
+
tickProps: any,
|
|
342
|
+
value: string | number,
|
|
343
|
+
): ReactNode => {
|
|
344
|
+
let tickItem;
|
|
345
|
+
|
|
346
|
+
if (React.isValidElement(option)) {
|
|
347
|
+
tickItem = React.cloneElement(option, tickProps);
|
|
348
|
+
} else if (typeof option === 'function') {
|
|
349
|
+
tickItem = option(tickProps);
|
|
350
|
+
} else {
|
|
351
|
+
tickItem = <Text
|
|
352
|
+
{...tickProps}
|
|
353
|
+
className="recharts-polar-radius-axis-tick-value"
|
|
354
|
+
>{value}</Text>;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return tickItem;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
const renderTicks = (props: InsideProps, ticks: ReadonlyArray<TickItem>): ReactElement => {
|
|
361
|
+
const { angle, tickFormatter, stroke, tick, ...others } = props;
|
|
362
|
+
const textAnchor = getTickTextAnchor(props.orientation);
|
|
363
|
+
const axisProps = svgPropertiesNoEvents(others);
|
|
364
|
+
const customTickProps = svgPropertiesNoEventsFromUnknown(tick);
|
|
365
|
+
|
|
366
|
+
const items = ticks.map((entry, i) => {
|
|
367
|
+
const coord = getTickValueCoord(entry, props.angle, props.cx, props.cy);
|
|
368
|
+
const tickProps = {
|
|
369
|
+
textAnchor,
|
|
370
|
+
transform: `rotate(${90 - angle}, ${coord.x}, ${coord.y})`,
|
|
371
|
+
...axisProps,
|
|
372
|
+
stroke: 'none',
|
|
373
|
+
fill: stroke,
|
|
374
|
+
...customTickProps,
|
|
375
|
+
index: i,
|
|
376
|
+
...coord,
|
|
377
|
+
payload: entry,
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
return <Layer
|
|
381
|
+
className={clsx('recharts-polar-radius-axis-tick', getClassNameFromUnknown(tick))}
|
|
382
|
+
key={`tick-${entry.coordinate}`}
|
|
383
|
+
{...adaptEventsOfChild(props, entry, i)}
|
|
384
|
+
>{renderTickItem(
|
|
385
|
+
tick,
|
|
386
|
+
tickProps,
|
|
387
|
+
tickFormatter ? tickFormatter(entry.value, i) : entry.value,
|
|
388
|
+
)}</Layer>;
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
return <Layer className="recharts-polar-radius-axis-ticks">{items}</Layer>;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
export const PolarRadiusAxisWrapper: FunctionComponent<PropsWithDefaults> = (
|
|
395
|
+
defaultsAndInputs: PropsWithDefaults,
|
|
396
|
+
) => {
|
|
397
|
+
const { radiusAxisId } = defaultsAndInputs;
|
|
398
|
+
|
|
399
|
+
const viewBox = useAppSelector(selectPolarViewBox);
|
|
400
|
+
const scale = useAppSelector((state) => selectPolarAxisScale(state, 'radiusAxis', radiusAxisId));
|
|
401
|
+
const ticks = useAppSelector(
|
|
402
|
+
(state) => selectPolarAxisTicks(state, 'radiusAxis', radiusAxisId, false),
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
if (viewBox == null || !ticks || !ticks.length || scale == null) {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const props: InsideProps = {
|
|
410
|
+
...defaultsAndInputs,
|
|
411
|
+
scale,
|
|
412
|
+
...viewBox,
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const { tick, axisLine } = props;
|
|
416
|
+
|
|
417
|
+
return <ZIndexLayer zIndex={props.zIndex}>
|
|
418
|
+
<Layer className={clsx('recharts-polar-radius-axis', AXIS_TYPE, props.className)}>
|
|
419
|
+
{axisLine && renderAxisLine(props, ticks)}
|
|
420
|
+
{tick && renderTicks(props, ticks)}
|
|
421
|
+
<PolarLabelContextProvider {...getViewBox(props.angle, props.cx, props.cy, ticks)}>
|
|
422
|
+
<PolarLabelFromLabelProp label={props.label} />
|
|
423
|
+
{props.children}
|
|
424
|
+
</PolarLabelContextProvider>
|
|
425
|
+
</Layer>
|
|
426
|
+
</ZIndexLayer>;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* @provides PolarLabelContext
|
|
431
|
+
* @consumes PolarViewBoxContext
|
|
432
|
+
*/
|
|
433
|
+
export function PolarRadiusAxis<DataPointType = any, DataValueType = any>(
|
|
434
|
+
outsideProps: Props<DataPointType, DataValueType>,
|
|
435
|
+
) {
|
|
436
|
+
const props: PropsWithDefaults<DataPointType, DataValueType> = resolveDefaultProps(
|
|
437
|
+
outsideProps,
|
|
438
|
+
defaultPolarRadiusAxisProps,
|
|
439
|
+
);
|
|
440
|
+
return <>
|
|
441
|
+
<SetRadiusAxisSettings
|
|
442
|
+
domain={props.domain}
|
|
443
|
+
id={props.radiusAxisId}
|
|
444
|
+
scale={props.scale}
|
|
445
|
+
type={props.type}
|
|
446
|
+
dataKey={props.dataKey}
|
|
447
|
+
unit={undefined}
|
|
448
|
+
name={props.name}
|
|
449
|
+
allowDuplicatedCategory={props.allowDuplicatedCategory}
|
|
450
|
+
allowDataOverflow={props.allowDataOverflow}
|
|
451
|
+
reversed={props.reversed}
|
|
452
|
+
includeHidden={props.includeHidden}
|
|
453
|
+
allowDecimals={props.allowDecimals}
|
|
454
|
+
niceTicks={props.niceTicks ?? 'auto'}
|
|
455
|
+
ticks={props.ticks}
|
|
456
|
+
tickCount={props.tickCount}
|
|
457
|
+
tick={props.tick}
|
|
458
|
+
/>
|
|
459
|
+
<PolarRadiusAxisWrapper {...props} />
|
|
460
|
+
</>;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
PolarRadiusAxis.displayName = 'PolarRadiusAxis';
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as React from 'octane';
|
|
2
|
+
import { FunctionComponent, SVGProps } from 'octane';
|
|
3
|
+
import {
|
|
4
|
+
RenderableAxisProps,
|
|
5
|
+
PresentationAttributesAdaptChildEvent,
|
|
6
|
+
AxisDomain,
|
|
7
|
+
ScaleType,
|
|
8
|
+
AxisDomainTypeInput,
|
|
9
|
+
TickProp,
|
|
10
|
+
BaseTickContentProps,
|
|
11
|
+
AxisTick,
|
|
12
|
+
} from '../util/types';
|
|
13
|
+
import { NiceTicksAlgorithm } from '../state/cartesianAxisSlice';
|
|
14
|
+
import { defaultPolarRadiusAxisProps } from './defaultPolarRadiusAxisProps';
|
|
15
|
+
import { RequiresDefaultProps } from '../util/resolveDefaultProps';
|
|
16
|
+
import { ZIndexable } from '../zIndex/ZIndexLayer';
|
|
17
|
+
import { CustomScaleDefinition } from '../util/scale/CustomScaleDefinition';
|
|
18
|
+
type TickOrientation = 'left' | 'right' | 'middle';
|
|
19
|
+
export interface PolarRadiusAxisProps<DataPointType = any, DataValueType = any>
|
|
20
|
+
extends
|
|
21
|
+
Omit<
|
|
22
|
+
RenderableAxisProps<DataPointType, DataValueType>,
|
|
23
|
+
'axisLine' | 'angle' | 'type' | 'tickSize' | 'domain' | 'scale' | 'tick'
|
|
24
|
+
>,
|
|
25
|
+
ZIndexable {
|
|
26
|
+
/**
|
|
27
|
+
* Determines how the axis line is drawn. Options:
|
|
28
|
+
* - `true`: the axis line is drawn with default props;
|
|
29
|
+
* - `false`: the axis line is not visible;
|
|
30
|
+
* - `object`: passed as props to SVG `<line>` element representing the axis line.
|
|
31
|
+
*
|
|
32
|
+
* @example <PolarRadiusAxis axisLine={false} />
|
|
33
|
+
* @example <PolarRadiusAxis axisLine={{ stroke: 'red', strokeWidth: 2 }} />
|
|
34
|
+
* @defaultValue true
|
|
35
|
+
*/
|
|
36
|
+
axisLine?: boolean | SVGProps<SVGLineElement>;
|
|
37
|
+
/**
|
|
38
|
+
* The angle of the whole axis: the line, ticks and labels, everything.
|
|
39
|
+
*
|
|
40
|
+
* This is different from other graphical elements where angle usually means
|
|
41
|
+
* the angle of text. Here, it means the angle of everything.
|
|
42
|
+
*
|
|
43
|
+
* @defaultValue 0
|
|
44
|
+
*/
|
|
45
|
+
angle?: number;
|
|
46
|
+
/**
|
|
47
|
+
* The type of axis.
|
|
48
|
+
*
|
|
49
|
+
* `category`: Treats data as distinct values.
|
|
50
|
+
* Each value is in the same distance from its neighbors, regardless of their actual numeric difference.
|
|
51
|
+
*
|
|
52
|
+
* `number`: Treats data as continuous range.
|
|
53
|
+
* Values that are numerically closer are placed closer together on the axis.
|
|
54
|
+
*
|
|
55
|
+
* `auto`: the type is inferred based on the chart layout.
|
|
56
|
+
*
|
|
57
|
+
* @defaultValue auto
|
|
58
|
+
*/
|
|
59
|
+
type?: AxisDomainTypeInput;
|
|
60
|
+
/**
|
|
61
|
+
* The orientation of axis text.
|
|
62
|
+
* @defaultValue right
|
|
63
|
+
*/
|
|
64
|
+
orientation?: TickOrientation;
|
|
65
|
+
/**
|
|
66
|
+
* Specify the domain of axis when the axis is a number axis.
|
|
67
|
+
*
|
|
68
|
+
* If undefined, then the domain is calculated based on the data and dataKeys.
|
|
69
|
+
*
|
|
70
|
+
* The length of domain should be 2, and we will validate the values in domain.
|
|
71
|
+
*
|
|
72
|
+
* Each element in the array can be a number, 'auto', 'dataMin', 'dataMax', a string like 'dataMin - 20', 'dataMax + 100',
|
|
73
|
+
* or a function that accepts a single argument and returns a number.
|
|
74
|
+
*
|
|
75
|
+
* If any element of domain is set to be 'auto', comprehensible scale ticks will be calculated, and the final domain of axis is generated by the ticks.
|
|
76
|
+
* If a function, receives '[dataMin, dataMax]', and must return a computed domain as '[min, max]'.
|
|
77
|
+
*
|
|
78
|
+
* @example <PolarRadiusAxis type="number" domain={['dataMin', 'dataMax']} />
|
|
79
|
+
* @example <PolarRadiusAxis type="number" domain={[0, 'dataMax']} />
|
|
80
|
+
* @example <PolarRadiusAxis type="number" domain={['auto', 'auto']} />
|
|
81
|
+
* @example <PolarRadiusAxis type="number" domain={[0, 'dataMax + 1000']} />
|
|
82
|
+
* @example <PolarRadiusAxis type="number" domain={['dataMin - 100', 'dataMax + 100']} />
|
|
83
|
+
* @example <PolarRadiusAxis type="number" domain={[dataMin => (0 - Math.abs(dataMin)), dataMax => (dataMax * 2)]} />
|
|
84
|
+
* @example <PolarRadiusAxis type="number" domain={([dataMin, dataMax]) => { const absMax = Math.max(Math.abs(dataMin), Math.abs(dataMax)); return [-absMax, absMax]; }} />
|
|
85
|
+
* @example <PolarRadiusAxis type="number" domain={[0, 100]} allowDataOverflow />
|
|
86
|
+
*/
|
|
87
|
+
domain?: AxisDomain;
|
|
88
|
+
/**
|
|
89
|
+
* Scale function determines how data values are mapped to visual values.
|
|
90
|
+
* In other words, decided the mapping between data domain and coordinate range.
|
|
91
|
+
*
|
|
92
|
+
* If undefined, or 'auto', the scale function is created internally according to the type of axis and data.
|
|
93
|
+
*
|
|
94
|
+
* You can define a custom scale, either as a string shortcut to a d3 scale, or as a complete scale definition object.
|
|
95
|
+
*
|
|
96
|
+
* @defaultValue auto
|
|
97
|
+
* @example <PolarRadiusAxis scale="log" />
|
|
98
|
+
* @example
|
|
99
|
+
* import { scaleLog } from 'd3-scale';
|
|
100
|
+
* const scale = scaleLog().base(Math.E);
|
|
101
|
+
* <PolarRadiusAxis scale={scale} />
|
|
102
|
+
*/
|
|
103
|
+
scale?:
|
|
104
|
+
| ScaleType
|
|
105
|
+
| CustomScaleDefinition
|
|
106
|
+
| CustomScaleDefinition<string>
|
|
107
|
+
| CustomScaleDefinition<number>
|
|
108
|
+
| CustomScaleDefinition<Date>;
|
|
109
|
+
/**
|
|
110
|
+
* The customized event handler of click on the ticks of this axis
|
|
111
|
+
*/
|
|
112
|
+
onClick?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
113
|
+
/**
|
|
114
|
+
* The customized event handler of mousedown on the ticks of this axis
|
|
115
|
+
*/
|
|
116
|
+
onMouseDown?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
117
|
+
/**
|
|
118
|
+
* The customized event handler of mouseup on the ticks of this axis
|
|
119
|
+
*/
|
|
120
|
+
onMouseUp?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
121
|
+
/**
|
|
122
|
+
* The customized event handler of mousemove on the ticks of this axis
|
|
123
|
+
*/
|
|
124
|
+
onMouseMove?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
125
|
+
/**
|
|
126
|
+
* The customized event handler of mouseover on the ticks of this axis
|
|
127
|
+
*/
|
|
128
|
+
onMouseOver?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
129
|
+
/**
|
|
130
|
+
* The customized event handler of mouseout on the ticks of this axis
|
|
131
|
+
*/
|
|
132
|
+
onMouseOut?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
133
|
+
/**
|
|
134
|
+
* The customized event handler of mouseenter on the ticks of this axis
|
|
135
|
+
*/
|
|
136
|
+
onMouseEnter?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
137
|
+
/**
|
|
138
|
+
* The customized event handler of mouseleave on the ticks of this axis
|
|
139
|
+
*/
|
|
140
|
+
onMouseLeave?: (data: any, index: number, e: React.MouseEvent) => void;
|
|
141
|
+
/**
|
|
142
|
+
* Allow the ticks of axis to be decimals or not.
|
|
143
|
+
*
|
|
144
|
+
* @defaultValue false
|
|
145
|
+
*/
|
|
146
|
+
allowDecimals?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Controls how Recharts calculates "nice" tick values for this axis.
|
|
149
|
+
* Options: `'none'`, `'auto'`, `'adaptive'`, `'snap125'`.
|
|
150
|
+
* See {@link NiceTicksAlgorithm} for a full description of each option.
|
|
151
|
+
*
|
|
152
|
+
* @defaultValue 'auto'
|
|
153
|
+
*/
|
|
154
|
+
niceTicks?: NiceTicksAlgorithm;
|
|
155
|
+
/**
|
|
156
|
+
* @defaultValue 0
|
|
157
|
+
*/
|
|
158
|
+
radiusAxisId?: string | number;
|
|
159
|
+
/**
|
|
160
|
+
* Defines how the individual label text is rendered.
|
|
161
|
+
* This controls the settings for individual ticks; on a typical axis, there are multiple ticks, depending on your data.
|
|
162
|
+
*
|
|
163
|
+
* If you want to customize the overall axis label, use the `label` prop instead.
|
|
164
|
+
*
|
|
165
|
+
* Options:
|
|
166
|
+
* - `false`: Do not render any tick labels.
|
|
167
|
+
* - `true`: Render tick labels with default settings.
|
|
168
|
+
* - `object`: An object of props to be merged into the internally calculated tick props.
|
|
169
|
+
* - `ReactElement`: A custom React element to be used as the tick label.
|
|
170
|
+
* - `function`: A function that returns a React element for custom rendering of tick labels.
|
|
171
|
+
*
|
|
172
|
+
* @defaultValue true
|
|
173
|
+
*/
|
|
174
|
+
tick?: TickProp<BaseTickContentProps>;
|
|
175
|
+
ticks?: ReadonlyArray<AxisTick>;
|
|
176
|
+
/**
|
|
177
|
+
* Z-Index of this component and its children. The higher the value,
|
|
178
|
+
* the more on top it will be rendered.
|
|
179
|
+
* Components with higher zIndex will appear in front of components with lower zIndex.
|
|
180
|
+
* If undefined or 0, the content is rendered in the default layer without portals.
|
|
181
|
+
*
|
|
182
|
+
* @since 3.4
|
|
183
|
+
* @defaultValue 500
|
|
184
|
+
* @see {@link https://recharts.github.io/en-US/guide/zIndex/ Z-Index and layers guide}
|
|
185
|
+
*/
|
|
186
|
+
zIndex?: number;
|
|
187
|
+
}
|
|
188
|
+
type AxisSvgProps = Omit<
|
|
189
|
+
PresentationAttributesAdaptChildEvent<any, SVGTextElement>,
|
|
190
|
+
'scale' | 'type'
|
|
191
|
+
>;
|
|
192
|
+
export type Props<DataPointType = any, DataValueType = any> = AxisSvgProps &
|
|
193
|
+
PolarRadiusAxisProps<DataPointType, DataValueType>;
|
|
194
|
+
type PropsWithDefaults<DataPointType = any, DataValueType = any> = RequiresDefaultProps<
|
|
195
|
+
Props<DataPointType, DataValueType>,
|
|
196
|
+
typeof defaultPolarRadiusAxisProps
|
|
197
|
+
>;
|
|
198
|
+
export declare const PolarRadiusAxisWrapper: FunctionComponent<PropsWithDefaults>;
|
|
199
|
+
/**
|
|
200
|
+
* @provides PolarLabelContext
|
|
201
|
+
* @consumes PolarViewBoxContext
|
|
202
|
+
*/
|
|
203
|
+
export declare function PolarRadiusAxis<DataPointType = any, DataValueType = any>(
|
|
204
|
+
outsideProps: Props<DataPointType, DataValueType>,
|
|
205
|
+
): React.JSX.Element;
|
|
206
|
+
export declare namespace PolarRadiusAxis {
|
|
207
|
+
var displayName: string;
|
|
208
|
+
}
|
|
209
|
+
export {};
|