0
# Base Axis Component
1
2
The flexible base `Axis` component provides complete control over axis orientation and behavior. Use this component when you need custom orientations, advanced styling, or when the pre-built components don't meet your specific requirements.
3
4
## Component
5
6
```typescript { .api }
7
function Axis<Scale extends AxisScale>(props: AxisProps<Scale>): JSX.Element;
8
9
interface AxisProps<Scale extends AxisScale> extends SharedAxisProps<Scale> {
10
orientation?: OrientationType;
11
}
12
13
type OrientationType = "top" | "left" | "right" | "bottom";
14
```
15
16
The `Axis` component extends `SharedAxisProps` with an additional `orientation` prop that determines axis direction and default styling.
17
18
## Basic Usage
19
20
```typescript
21
import { Axis, Orientation } from '@visx/axis';
22
import { scaleLinear } from '@visx/scale';
23
24
const scale = scaleLinear({
25
range: [0, 400],
26
domain: [0, 100],
27
});
28
29
<Axis
30
scale={scale}
31
orientation={Orientation.bottom}
32
left={50}
33
top={300}
34
label="X Values"
35
stroke="#333"
36
tickStroke="#333"
37
tickLabelProps={{
38
fill: '#333',
39
fontSize: 11,
40
textAnchor: 'middle',
41
}}
42
/>
43
```
44
45
## Orientation Options
46
47
The `orientation` prop accepts values from the `Orientation` constant:
48
49
```typescript { .api }
50
const Orientation: {
51
readonly top: "top";
52
readonly left: "left";
53
readonly right: "right";
54
readonly bottom: "bottom";
55
};
56
```
57
58
### Orientation Behavior
59
60
Each orientation automatically configures:
61
62
- **Tick positioning**: Where ticks appear relative to the axis line
63
- **Label positioning**: Default placement of tick labels
64
- **Axis direction**: Whether the axis is horizontal or vertical
65
66
```typescript
67
// Horizontal axes
68
<Axis orientation={Orientation.top} scale={xScale} /> // Ticks above, labels above ticks
69
<Axis orientation={Orientation.bottom} scale={xScale} /> // Ticks below, labels below ticks
70
71
// Vertical axes
72
<Axis orientation={Orientation.left} scale={yScale} /> // Ticks left, labels left of ticks
73
<Axis orientation={Orientation.right} scale={yScale} /> // Ticks right, labels right of ticks
74
```
75
76
## Advanced Customization
77
78
### Custom Renderer Function
79
80
Use the `children` prop to provide a custom renderer function for complete control over axis rendering:
81
82
```typescript
83
<Axis
84
scale={scale}
85
orientation={Orientation.bottom}
86
>
87
{(axisProps) => (
88
<g className="custom-axis">
89
{/* Custom axis line */}
90
<line
91
x1={axisProps.axisFromPoint.x}
92
y1={axisProps.axisFromPoint.y}
93
x2={axisProps.axisToPoint.x}
94
y2={axisProps.axisToPoint.y}
95
stroke="blue"
96
strokeWidth={2}
97
/>
98
99
{/* Custom ticks */}
100
{axisProps.ticks.map((tick, i) => (
101
<g key={i} className="custom-tick">
102
<line
103
x1={tick.from.x}
104
y1={tick.from.y}
105
x2={tick.to.x}
106
y2={tick.to.y}
107
stroke="red"
108
/>
109
<text
110
x={tick.from.x}
111
y={tick.from.y + 15}
112
textAnchor="middle"
113
fill="red"
114
>
115
{tick.formattedValue}
116
</text>
117
</g>
118
))}
119
</g>
120
)}
121
</Axis>
122
```
123
124
### Custom Tick Component
125
126
Override individual tick rendering:
127
128
```typescript
129
<Axis
130
scale={scale}
131
orientation={Orientation.bottom}
132
tickComponent={({ x, y, formattedValue }) => (
133
<g>
134
<circle cx={x} cy={y - 5} r={3} fill="red" />
135
<text x={x} y={y + 15} textAnchor="middle" fill="red">
136
{formattedValue}
137
</text>
138
</g>
139
)}
140
/>
141
```
142
143
### Custom Ticks Component
144
145
Override the entire tick rendering system:
146
147
```typescript
148
<Axis
149
scale={scale}
150
orientation={Orientation.left}
151
ticksComponent={(ticksProps) => (
152
<g className="custom-ticks">
153
{ticksProps.ticks.map((tick, i) => (
154
<g key={i}>
155
<rect
156
x={tick.from.x - 20}
157
y={tick.from.y - 5}
158
width={15}
159
height={10}
160
fill="lightblue"
161
/>
162
<text
163
x={tick.from.x - 25}
164
y={tick.from.y + 3}
165
textAnchor="end"
166
fontSize={10}
167
>
168
{tick.formattedValue}
169
</text>
170
</g>
171
))}
172
</g>
173
)}
174
/>
175
```
176
177
## Renderer Props Interface
178
179
When using custom renderers, you receive `AxisRendererProps`:
180
181
```typescript { .api }
182
interface AxisRendererProps<Scale extends AxisScale> extends SharedAxisProps<Scale> {
183
// Computed axis line endpoints
184
axisFromPoint: { x: number; y: number };
185
axisToPoint: { x: number; y: number };
186
187
// Axis configuration
188
horizontal: boolean;
189
orientation: OrientationType;
190
191
// Tick configuration
192
tickPosition: (value: ScaleInput<Scale>) => AxisScaleOutput;
193
tickSign: 1 | -1;
194
ticks: ComputedTick<Scale>[];
195
}
196
197
interface ComputedTick<Scale extends AxisScale> {
198
value: ScaleInput<Scale>;
199
index: number;
200
from: { x: number; y: number };
201
to: { x: number; y: number };
202
formattedValue: string | undefined;
203
}
204
```
205
206
## Complex Examples
207
208
### Multi-axis Chart
209
210
```typescript
211
function ComplexChart() {
212
const xScale = scaleLinear({ range: [0, 400], domain: [0, 100] });
213
const yScale = scaleLinear({ range: [300, 0], domain: [0, 50] });
214
const y2Scale = scaleLinear({ range: [300, 0], domain: [0, 1000] });
215
216
return (
217
<svg width={500} height={350}>
218
{/* Primary Y axis */}
219
<Axis
220
scale={yScale}
221
orientation={Orientation.left}
222
left={40}
223
label="Primary Y"
224
stroke="#333"
225
/>
226
227
{/* Secondary Y axis */}
228
<Axis
229
scale={y2Scale}
230
orientation={Orientation.right}
231
left={440}
232
label="Secondary Y"
233
stroke="#666"
234
tickStroke="#666"
235
tickLabelProps={{ fill: '#666' }}
236
/>
237
238
{/* X axis */}
239
<Axis
240
scale={xScale}
241
orientation={Orientation.bottom}
242
top={300}
243
left={40}
244
label="X Values"
245
stroke="#333"
246
/>
247
</svg>
248
);
249
}
250
```
251
252
### Custom Angle Orientation
253
254
```typescript
255
// Custom diagonal axis using transform
256
<Axis
257
scale={scale}
258
orientation={Orientation.bottom}
259
tickTransform="rotate(-45)"
260
tickLabelProps={{
261
textAnchor: 'end',
262
dx: '-0.5em',
263
dy: '-0.25em'
264
}}
265
/>
266
```
267
268
### Responsive Axis
269
270
```typescript
271
function ResponsiveAxis({ width, data }) {
272
const scale = scaleLinear({
273
range: [0, width],
274
domain: extent(data),
275
});
276
277
// Adjust tick count based on width
278
const numTicks = Math.max(2, Math.floor(width / 80));
279
280
return (
281
<Axis
282
scale={scale}
283
orientation={Orientation.bottom}
284
numTicks={numTicks}
285
tickLabelProps={{
286
fontSize: width < 400 ? 10 : 12,
287
}}
288
/>
289
);
290
}
291
```