Visx
Expert guidance for building low-level, composable React visualizations with visx
You are an expert in creating data visualizations with visx (formerly vx), a collection of low-level visualization primitives for React by Airbnb.
## Key Points
- **Gradients and Patterns**: Use `@visx/gradient` and `@visx/pattern` to fill shapes with linear gradients, radial gradients, or SVG patterns.
- **Drag and Zoom**: Use `@visx/drag` and `@visx/zoom` for interactive pan/zoom behaviors.
- **Geo and Maps**: Use `@visx/geo` with projections to render geographic data.
- **Threshold Charts**: Use `@visx/threshold` to highlight the area between two series.
- Install only the `@visx/*` packages you actually use; the library is designed for tree-shaking at the package level.
- Compute scales outside the render return or memoize them to avoid recalculating on every render.
- Use `<ParentSize>` for responsive charts rather than hard-coding width and height.
- Forgetting to account for margins when calculating `xMax` and `yMax`, which causes axes and shapes to overflow or clip.
- Importing from a monolithic `visx` package that does not exist; each primitive is its own scoped package (`@visx/shape`, `@visx/scale`, etc.).
## Quick Example
```bash
npm install @visx/shape @visx/scale @visx/axis @visx/group @visx/responsive @visx/tooltip
```
```jsx
import { ParentSize } from "@visx/responsive";
<ParentSize>
{({ width, height }) => <MyChart width={width} height={height} />}
</ParentSize>
```skilldb get data-visualization-skills/VisxFull skill: 151 linesvisx — Data Visualization
You are an expert in creating data visualizations with visx (formerly vx), a collection of low-level visualization primitives for React by Airbnb.
Overview
visx is a set of modular, low-level visualization packages that combine the power of D3 with the React component model. Unlike higher-level charting libraries, visx does not provide pre-built chart components. Instead, it provides primitives (scales, shapes, axes, legends, tooltips, patterns, gradients) that you compose to build exactly the visualization you need. Use visx when you want full creative control over your visualization in React without writing raw D3 DOM manipulation.
Setup & Configuration
Install only the packages you need:
npm install @visx/shape @visx/scale @visx/axis @visx/group @visx/responsive @visx/tooltip
Basic bar chart setup:
import { scaleBand, scaleLinear } from "@visx/scale";
import { Bar } from "@visx/shape";
import { Group } from "@visx/group";
import { AxisBottom, AxisLeft } from "@visx/axis";
const data = [
{ label: "A", value: 30 },
{ label: "B", value: 80 },
{ label: "C", value: 45 },
];
const width = 600;
const height = 400;
const margin = { top: 20, right: 20, bottom: 40, left: 40 };
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
const xScale = scaleBand({ domain: data.map(d => d.label), range: [0, xMax], padding: 0.4 });
const yScale = scaleLinear({ domain: [0, Math.max(...data.map(d => d.value))], range: [yMax, 0] });
function MyChart() {
return (
<svg width={width} height={height}>
<Group left={margin.left} top={margin.top}>
{data.map(d => (
<Bar
key={d.label}
x={xScale(d.label)}
y={yScale(d.value)}
width={xScale.bandwidth()}
height={yMax - yScale(d.value)}
fill="teal"
/>
))}
<AxisBottom top={yMax} scale={xScale} />
<AxisLeft scale={yScale} />
</Group>
</svg>
);
}
Core Patterns
Line Charts with LinePath
import { LinePath } from "@visx/shape";
import { curveMonotoneX } from "@visx/curve";
<LinePath
data={data}
x={d => xScale(d.label) + xScale.bandwidth() / 2}
y={d => yScale(d.value)}
stroke="steelblue"
strokeWidth={2}
curve={curveMonotoneX}
/>
Tooltips
import { useTooltip, TooltipWithBounds } from "@visx/tooltip";
const { showTooltip, hideTooltip, tooltipData, tooltipLeft, tooltipTop } = useTooltip();
// On mouse events:
// showTooltip({ tooltipData: d, tooltipLeft: x, tooltipTop: y });
{tooltipData && (
<TooltipWithBounds left={tooltipLeft} top={tooltipTop}>
{tooltipData.label}: {tooltipData.value}
</TooltipWithBounds>
)}
Responsive Containers
import { ParentSize } from "@visx/responsive";
<ParentSize>
{({ width, height }) => <MyChart width={width} height={height} />}
</ParentSize>
Advanced Features
- Gradients and Patterns: Use
@visx/gradientand@visx/patternto fill shapes with linear gradients, radial gradients, or SVG patterns. - Drag and Zoom: Use
@visx/dragand@visx/zoomfor interactive pan/zoom behaviors. - Geo and Maps: Use
@visx/geowith projections to render geographic data. - Threshold Charts: Use
@visx/thresholdto highlight the area between two series.
Best Practices
- Install only the
@visx/*packages you actually use; the library is designed for tree-shaking at the package level. - Compute scales outside the render return or memoize them to avoid recalculating on every render.
- Use
<ParentSize>for responsive charts rather than hard-coding width and height.
Core Philosophy
visx exists because Airbnb needed the creative freedom of D3 inside the component model of React, without the DOM ownership conflicts that arise from combining them directly. D3 wants to own DOM manipulation; React wants to own DOM manipulation. visx resolves this by wrapping D3's math and layout primitives (scales, shapes, curves, projections) as React components while leaving the actual rendering to React's virtual DOM. You get D3's power for computation and React's model for rendering.
visx is deliberately low-level. It does not provide a <BarChart /> component because the library's philosophy is that the best visualization for your data is one you compose from primitives, not one you configure from a prop sheet. This means more code for a simple bar chart compared to Recharts or Nivo, but dramatically more flexibility when you need a chart that does not exist in any library's catalog. visx is the right choice when your visualization is unique enough that a pre-built component would require extensive escape hatches.
The modular package architecture (@visx/shape, @visx/scale, @visx/axis, etc.) reflects the philosophy that you should only pay for what you use. Each package is independently versioned and installable, and there is no monolithic visx import. This keeps bundle sizes small but requires you to know which package provides which primitive. The package names are intuitive -- shapes in @visx/shape, scales in @visx/scale -- but you must import from each one explicitly.
Anti-Patterns
-
Forgetting margin calculations: Not subtracting margins from the SVG width and height when computing
xMaxandyMaxfor scales. This causes axes, bars, and lines to overflow the intended drawing area and clip against the SVG boundary. -
Importing a nonexistent monolithic package: Attempting
import { Bar, scaleLinear } from "visx", which does not exist. visx is a collection of scoped packages; every import must specify the sub-package (e.g.,@visx/shape,@visx/scale). -
Recomputing scales on every render: Defining scales inside the render function without memoization, causing D3 scale objects to be recreated on every render cycle. This wastes computation and can cause subtle animation issues. Memoize scales with
useMemoand appropriate dependency arrays. -
Hardcoding SVG dimensions instead of using ParentSize: Setting fixed
widthandheighton the<svg>element rather than using<ParentSize>to measure the container. This produces charts that do not adapt to different screen sizes or container layouts. -
Using D3 DOM manipulation alongside visx: Reaching for
d3.select()to manipulate SVG elements that are rendered by React/visx. This creates a dual-ownership conflict where D3 and React fight over the same DOM nodes, leading to stale renders, lost state, and hard-to-debug visual glitches.
Common Pitfalls
- Forgetting to account for margins when calculating
xMaxandyMax, which causes axes and shapes to overflow or clip. - Importing from a monolithic
visxpackage that does not exist; each primitive is its own scoped package (@visx/shape,@visx/scale, etc.).
Install this skill directly: skilldb add data-visualization-skills
Related Skills
Chart Js
Expert guidance for building responsive charts quickly with Chart.js
D3
Expert guidance for building custom, data-driven visualizations with D3.js
Echarts
Expert guidance for building feature-rich interactive charts with Apache ECharts
Nivo
Expert guidance for building rich, themed data visualizations in React with Nivo
Observable Plot
Expert guidance for building concise, exploratory data visualizations with Observable Plot
Plotly
Expert guidance for building interactive, publication-quality charts with Plotly.js