CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-visx--axis

React axis components for data visualization with D3 scale integration, providing pre-built orientations and flexible customization options.

Pending
Overview
Eval results
Files

base-axis.mddocs/

Base Axis Component

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.

Component

function Axis<Scale extends AxisScale>(props: AxisProps<Scale>): JSX.Element;

interface AxisProps<Scale extends AxisScale> extends SharedAxisProps<Scale> {
  orientation?: OrientationType;
}

type OrientationType = "top" | "left" | "right" | "bottom";

The Axis component extends SharedAxisProps with an additional orientation prop that determines axis direction and default styling.

Basic Usage

import { Axis, Orientation } from '@visx/axis';
import { scaleLinear } from '@visx/scale';

const scale = scaleLinear({
  range: [0, 400],
  domain: [0, 100],
});

<Axis
  scale={scale}
  orientation={Orientation.bottom}
  left={50}
  top={300}
  label="X Values"
  stroke="#333"
  tickStroke="#333"
  tickLabelProps={{
    fill: '#333',
    fontSize: 11,
    textAnchor: 'middle',
  }}
/>

Orientation Options

The orientation prop accepts values from the Orientation constant:

const Orientation: {
  readonly top: "top";
  readonly left: "left";
  readonly right: "right";
  readonly bottom: "bottom";
};

Orientation Behavior

Each orientation automatically configures:

  • Tick positioning: Where ticks appear relative to the axis line
  • Label positioning: Default placement of tick labels
  • Axis direction: Whether the axis is horizontal or vertical
// Horizontal axes
<Axis orientation={Orientation.top} scale={xScale} />    // Ticks above, labels above ticks
<Axis orientation={Orientation.bottom} scale={xScale} /> // Ticks below, labels below ticks

// Vertical axes  
<Axis orientation={Orientation.left} scale={yScale} />   // Ticks left, labels left of ticks
<Axis orientation={Orientation.right} scale={yScale} />  // Ticks right, labels right of ticks

Advanced Customization

Custom Renderer Function

Use the children prop to provide a custom renderer function for complete control over axis rendering:

<Axis
  scale={scale}
  orientation={Orientation.bottom}
>
  {(axisProps) => (
    <g className="custom-axis">
      {/* Custom axis line */}
      <line
        x1={axisProps.axisFromPoint.x}
        y1={axisProps.axisFromPoint.y}
        x2={axisProps.axisToPoint.x}
        y2={axisProps.axisToPoint.y}
        stroke="blue"
        strokeWidth={2}
      />
      
      {/* Custom ticks */}
      {axisProps.ticks.map((tick, i) => (
        <g key={i} className="custom-tick">
          <line
            x1={tick.from.x}
            y1={tick.from.y}
            x2={tick.to.x}
            y2={tick.to.y}
            stroke="red"
          />
          <text
            x={tick.from.x}
            y={tick.from.y + 15}
            textAnchor="middle"
            fill="red"
          >
            {tick.formattedValue}
          </text>
        </g>
      ))}
    </g>
  )}
</Axis>

Custom Tick Component

Override individual tick rendering:

<Axis
  scale={scale}
  orientation={Orientation.bottom}
  tickComponent={({ x, y, formattedValue }) => (
    <g>
      <circle cx={x} cy={y - 5} r={3} fill="red" />
      <text x={x} y={y + 15} textAnchor="middle" fill="red">
        {formattedValue}
      </text>
    </g>
  )}
/>

Custom Ticks Component

Override the entire tick rendering system:

<Axis
  scale={scale}
  orientation={Orientation.left}
  ticksComponent={(ticksProps) => (
    <g className="custom-ticks">
      {ticksProps.ticks.map((tick, i) => (
        <g key={i}>
          <rect
            x={tick.from.x - 20}
            y={tick.from.y - 5}
            width={15}
            height={10}
            fill="lightblue"
          />
          <text
            x={tick.from.x - 25}
            y={tick.from.y + 3}
            textAnchor="end"
            fontSize={10}
          >
            {tick.formattedValue}
          </text>
        </g>
      ))}
    </g>
  )}
/>

Renderer Props Interface

When using custom renderers, you receive AxisRendererProps:

interface AxisRendererProps<Scale extends AxisScale> extends SharedAxisProps<Scale> {
  // Computed axis line endpoints
  axisFromPoint: { x: number; y: number };
  axisToPoint: { x: number; y: number };
  
  // Axis configuration
  horizontal: boolean;
  orientation: OrientationType;
  
  // Tick configuration
  tickPosition: (value: ScaleInput<Scale>) => AxisScaleOutput;
  tickSign: 1 | -1;
  ticks: ComputedTick<Scale>[];
}

interface ComputedTick<Scale extends AxisScale> {
  value: ScaleInput<Scale>;
  index: number;
  from: { x: number; y: number };
  to: { x: number; y: number };
  formattedValue: string | undefined;
}

Complex Examples

Multi-axis Chart

function ComplexChart() {
  const xScale = scaleLinear({ range: [0, 400], domain: [0, 100] });
  const yScale = scaleLinear({ range: [300, 0], domain: [0, 50] });
  const y2Scale = scaleLinear({ range: [300, 0], domain: [0, 1000] });

  return (
    <svg width={500} height={350}>
      {/* Primary Y axis */}
      <Axis
        scale={yScale}
        orientation={Orientation.left}
        left={40}
        label="Primary Y"
        stroke="#333"
      />
      
      {/* Secondary Y axis */}
      <Axis
        scale={y2Scale}
        orientation={Orientation.right}
        left={440}
        label="Secondary Y"
        stroke="#666"
        tickStroke="#666"
        tickLabelProps={{ fill: '#666' }}
      />
      
      {/* X axis */}
      <Axis
        scale={xScale}
        orientation={Orientation.bottom}
        top={300}
        left={40}
        label="X Values"
        stroke="#333"
      />
    </svg>
  );
}

Custom Angle Orientation

// Custom diagonal axis using transform
<Axis
  scale={scale}
  orientation={Orientation.bottom}
  tickTransform="rotate(-45)"
  tickLabelProps={{
    textAnchor: 'end',
    dx: '-0.5em',
    dy: '-0.25em'
  }}
/>

Responsive Axis

function ResponsiveAxis({ width, data }) {
  const scale = scaleLinear({
    range: [0, width],
    domain: extent(data),
  });
  
  // Adjust tick count based on width
  const numTicks = Math.max(2, Math.floor(width / 80));
  
  return (
    <Axis
      scale={scale}
      orientation={Orientation.bottom}
      numTicks={numTicks}
      tickLabelProps={{
        fontSize: width < 400 ? 10 : 12,
      }}
    />
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-visx--axis

docs

base-axis.md

index.md

prebuilt-axes.md

tile.json