visx Documentation

Visx | visualization components

21,082 stars TypeScript TypeScript 1 file · ~63,881 tokens #chart#d3#data-visualization#react#svg#visualization#visx#vx
RAW Doc

File: README.md

visx

visx is a collection of reusable low-level visualization components. visx combines the power of d3
to generate your visualization with the benefits of react for updating the DOM.

[!IMPORTANT]
visx v4 is the current stable release and requires React 18 or 19.

bash
npm install @visx/shape

Upgrading from v3? See the visx 4 migration guide.

Usage

Let's make a simple bar graph.

First we'll install the relevant packages:

bash
npm install --save @visx/mock-data @visx/group @visx/shape @visx/scale
javascript
import React from 'react';
import { letterFrequency } from '@visx/mock-data';
import { Group } from '@visx/group';
import { Bar } from '@visx/shape';
import { scaleLinear, scaleBand } from '@visx/scale';

// We'll use some mock data from `@visx/mock-data` for this.
const data = letterFrequency;

// Define the graph dimensions and margins
const width = 500;
const height = 500;
const margin = { top: 20, bottom: 20, left: 20, right: 20 };

// Then we'll create some bounds
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;

// Accessors
const getLetter = (d) => d.letter;
const getFrequency = (d) => d.frequency * 100;

// And then scale the graph by our data
const xScale = scaleBand({
  range: [0, xMax],
  round: true,
  domain: data.map(getLetter),
  padding: 0.4,
});
const yScale = scaleLinear({
  range: [yMax, 0],
  round: true,
  domain: [0, Math.max(...data.map(getFrequency))],
});

// Finally we'll embed it all in an SVG
function BarGraph() {
  return (
    <svg width={width} height={height}>
      {data.map((d) => {
        const letter = getLetter(d);
        const barHeight = yMax - (yScale(getFrequency(d)) ?? 0);
        return (
          <Group key={`bar-${letter}`}>
            <Bar
              x={xScale(letter)}
              y={yMax - barHeight}
              height={barHeight}
              width={xScale.bandwidth()}
              fill="#fc2e1c"
            />
          </Group>
        );
      })}
    </svg>
  );
}

For more examples using visx, check out the gallery.

Motivation

Goal

The goal is to create a library of components you can use to make both your own reusable chart
library or your slick custom one-off chart. visx is largely unopinionated and is meant to be built
upon. Keep your bundle sizes down and use only the packages you need.

How?

Under the hood, visx is using d3 for the calculations and math. If you're creating your own awesome
chart library on top of visx, it's easy to create a component api that hides d3 entirely. Meaning
your team could create charts as easily as using reusable react components.

But why?

Mixing two mental models for updating the DOM is never a good time. Copy and pasting d3 code into
useEffect() is just that. This collection of components lets you easily build your own reusable
visualization charts or library without having to learn d3. No more selections or
enter()/exit()/update().

FAQ

  1. What does visx stand for?

    visx stands for visualization components.

  2. Do you plan on supporting animation/transitions?

    A common criticism of visx is it doesn't have animation baked in, but this was a conscious
    choice. It's a powerful feature to not bake it in.

    Imagine your app already bundles react-motion, adding a hypothetical @visx/animation is
    bloat. Since visx is react, it already supports all react animation libs.

    Charting libraries are like style guides. Each org or app will eventually want full control
    over their own implementation.

    visx makes this easier for everyone. No need to reinvent the wheel each time.

    more info: https://github.com/airbnb/visx/issues/6

  3. Do I have to use every package to make a chart?

    nope! pick and choose the packages you need.

  4. Can I use this to create my own library of charts for my team?

    Please do.

  5. Does visx work with preact?

    yup! alias react + react-dom to preact/compat. For visx v4, configure your package
    manager to satisfy the React 18/19 peer dependency range.

  6. I like using d3.

    Me too.

Thanks

Thanks to Happo for providing the visual regression testing platform that
helps us review UI changes and catch unintended visual regressions.

Development

Please see CONTRIBUTING.md

:v:

MIT


File: ATTRIBUTION.md

Fossa Attribution File


File: CODE_OF_CONDUCT.md

Contributor Covenant Code of Conduct

Airbnb has adopted a Code of Conduct that we expect project participants to adhere to. Please
read the full Code of Conduct text so that you can understand
what actions will and will not be tolerated. Report violations to the maintainers of this project or
to [email protected].

Reports sent to [email protected] are received
by Airbnb's open source code of conductmoderation team, which is composed of Airbnb employees. All
communications are private and confidential.


File: CONTRIBUTING.md

Contributing

Contributions welcome! Please follow the code of conduct.

Overview

Yarn workspaces are used to manage dependencies and
build config across packages in the umbrella visx monorepo, and
lerna is used to manage versioning.

Project structure

text
visx/
  lerna.json
  package.json
  packages/
    visx-package-1/
      src/
      test/
      build/
      package.json
      ...
    visx-package-2/
      ...
    ...

Local development

Run the following to setup your local dev environment:

sh
# Install `yarn`, alternatives at https://yarnpkg.com/en/docs/install
curl -o- -L https://yarnpkg.com/install.sh | bash

# Clone or fork `visx`
git clone [email protected]:airbnb/visx.git # or your fork
cd visx

# install dependencies, and have `yarn` symlink within-`visx` dependencies
yarn

# build packages and generate types for local development
yarn build

Rebuild specific package(s)

Upon modification of a single package you can run the following to rebuild it. Note that you can
specify multiple packages to build this way, and optionally append --watch to continuously watch
for changes.

sh
# build the specified package(s) as cjs + esm versions
# example `PKG=@visx/axis yarn babel:pkg`
PKG=@visx/{package[,package]} yarn babel:pkg

# generate d.ts(definition files) the specified package(s)
# and rebuild any other packages the specified package(s) depend on
# example `PKG=@visx/axis yarn type:pkg`
PKG=@visx/{package[,package]} yarn type:pkg

from the visx monorepo root to re-build the package with your changes.

Running demo pages

You can use the local next.js dev server within packages/visx-demo to view
and iterate on your changes in the gallery. From the packages/visx-demo folder run yarn dev to
start the next server which (if correctly sym-linked) will also watch for changes you make to other
packages (upon re-building them, see above section).

Config generation

visx uses @airbnb/nimbus to generate build configuration for
eslint, prettier, jest, babel, and typescript.


File: lerna.json

{
"packages": [
"packages/*"
],
"version": "4.0.0",
"command": {
"publish": {
"allowBranch": "master"
}
},
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}


File: MIGRATION.md

Upgrading to visx 4

visx 4 is the current major release. It modernizes React support, package entry points, browser
targets, and the published ESM output. For most apps, the upgrade is:

  1. Upgrade all @visx/* packages together to ^4.0.0.
  2. Use React 18 or 19.
  3. Replace deep imports like @visx/shape/lib/shapes/Bar with package-root imports like
    @visx/shape.
  4. If you use TypeScript, install @types/react and, when needed, @types/react-dom using the
    major version that matches your React version.
  5. If you use withBoundingRects, attach its injected nodeRef to the DOM element you want
    measured.
  6. If you rely on generated runtime propTypes, migrate those checks into your app.
  7. If you still need IE11, stay on visx 3.

4.1 (coming soon)

`@visx/kernel` adds shared primitives for first-party hooks

visx 4.1 introduces @visx/kernel, a small shared package for the cross-cutting primitives used by
first-party hooks: structural memoization, accessor normalization, stable callbacks, stable refs,
stable ids, domain computation, number formatting, path-string helpers, Path2D caching, and
structured development warnings.

The package gives first-party hooks a consistent place to normalize user input before doing
package-specific math when that normalization is appropriate. Existing component APIs do not change,
and @visx/kernel does not add rendering opinions.

What you need to do: nothing unless you want to build directly on these low-level primitives.
Existing visx charts continue to work. Future hook APIs may use @visx/kernel internally, but
consumers do not need to install or import it directly unless they opt in.

`@visx/theme` adds shared visual tokens for primitive charts

visx 4.1 introduces @visx/theme, an optional package for sharing chart colors, typography, axis,
grid, and layout defaults across low-level visx charts. The package keeps visx primitives
prop-driven: @visx/axis, @visx/grid, and @visx/shape do not read theme context automatically.

Use the server-compatible root entry when a chart only needs scoped CSS variables:

tsx
import { ThemeScope } from '@visx/theme';

<ThemeScope theme="auto">
  <Chart />
</ThemeScope>;

Use the client entry when chart components need hook-derived props:

tsx
import { ThemeProvider, useAxisStyle, useGridStyle, useColor } from '@visx/theme/react';

theme="auto" is designed for shadcn/ui-style CSS variables such as --chart-1, --background,
--border, and --muted-foreground. It does not install a mode switcher, read the DOM, or update
JS-only layout values when a CSS class changes.

Existing @visx/xychart themes remain supported for XYChart. New primitive charts can reuse the
same visual choices with fromXYChartTheme from @visx/theme.

What you need to do: nothing unless you want to opt in. Existing visx charts continue to work.
Add @visx/theme only when you want shared visual tokens or shadcn/ui-compatible CSS variable
theming for primitive charts.

`@visx/a11y` adds opt-in accessibility helpers for primitive charts

visx 4.1 introduces @visx/a11y, an optional package for adding chart semantics to primitive SVG
charts. It provides server-safe helpers for generated ARIA props, text descriptions, and hidden data
tables, plus a @visx/a11y/react entry for pre-bound chart props, roving keyboard focus, data-table
fallback, and live announcements.

These helpers do not replace the chart render tree or hide non-data elements automatically. If your
chart includes decorative chrome such as grid lines, axis ticks, background rectangles, or clipping
helpers, render those elements with aria-hidden="true" so assistive technology focuses on the
chart title, description, series, data marks, and table fallback.

What you need to do: nothing unless you want to opt in. Existing visx charts continue to work.
Add @visx/a11y only when you want generated chart semantics, keyboard exploration, or a data-table
fallback for primitive charts.

Registry-oriented hooks for primitive charts

visx 4.1 adds the first hook and helper APIs used to build primitive charts for the visx chart
registry. These APIs are additive and live in package roots or explicit React subpaths:

tsx
import {
  getPositiveDomain,
  getResponsiveWidth,
  getZeroBaselineDomain,
  useChartDimensions,
} from '@visx/chart';
import { useAxis } from '@visx/axis/react';
import { useScale } from '@visx/scale/react';
import { arcPath, areaPath, linePath } from '@visx/shape';
import { usePie } from '@visx/shape/react';
import { useColorScale } from '@visx/theme/react';
import { useVoronoi } from '@visx/voronoi/react';

Existing component APIs continue to work. <Axis /> and `` reuse the extracted hook logic
internally, but their public props and rendering behavior are unchanged. Hooks that need React are
exported from /react subpaths; root package imports such as @visx/scale remain available for
non-React code.

What you need to do: nothing unless you want to author hook-based primitive charts. Continue
using existing components as before, or opt into the new hooks from the import paths above.

`@visx/tooltip/floating` adds modern tooltip primitives

visx 4.1 adds an optional Floating UI-backed tooltip surface under the @visx/tooltip/floating
subpath. It includes low-level FloatingTooltip primitives, useFloatingTooltip, config-driven
chart tooltip content, and the useChartTooltip plus ChartTooltip convenience layer for
data-driven chart tooltips.

tsx
import {
  ChartTooltip,
  FloatingTooltip,
  useChartTooltip,
  useFloatingTooltip,
} from '@visx/tooltip/floating';

The new APIs are additive. Existing @visx/tooltip root exports, useTooltip,
useTooltipInPortal, Tooltip, TooltipWithBounds, and withTooltip remain unchanged.

What you need to do: nothing unless you want Floating UI positioning, virtual anchors,
trigger-based interactions, or config-driven chart tooltip content. Continue using the existing
tooltip APIs as before, or opt into the new @visx/tooltip/floating subpath for new tooltip work.

The visx chart registry adds shadcn-compatible chart starters

visx 4.1 introduces a source-first chart registry for installing themed, responsive, accessible
primitive chart components into application code with the shadcn CLI.

sh
npx shadcn@latest add airbnb/visx/line-chart

Registry items are copied into your app as editable source files and depend on public visx packages
such as @visx/a11y, @visx/chart, @visx/responsive, and @visx/theme. The registry itself is
distribution infrastructure and is not a runtime package your app imports.

What you need to do: nothing unless you want drop-in primitive chart starters. Existing visx
charts continue to work. Use registry installs only after the referenced 4.1 visx packages are
published.

From visx 3.x

Upgrade every visx package in your application at the same time. Mixing visx 3 and visx 4 packages
is not recommended because package entry points, peer dependency ranges, and internal package
dependencies changed together.

bash
npm install @visx/shape@^4 @visx/scale@^4

With Yarn, upgrade the visx packages your app depends on to the same major:

bash
yarn up "@visx/*@^4.0.0"

React 18 or 19 is required

React-based @visx/* packages declare react peer dependencies as ^18.0.0 || ^19.0.0. Packages
that depend on react-dom declare the same supported range for their react-dom peer dependency.

What you need to do:

  • React 18 or 19 consumers: no runtime code changes are expected for this peer dependency
    update.
  • React 16 or 17 consumers: stay on visx 3 or upgrade your app to React 18+ before installing
    visx 4.
  • Preact consumers: continue aliasing react and react-dom to preact/compat, and configure
    your package manager to satisfy the React 18/19 peer dependency range.

TypeScript React types are peer dependencies

React-based @visx/* packages now declare @types/react as an optional peer dependency instead of
bundling their own copy. Packages that touch React DOM APIs also declare optional @types/react-dom
peer dependencies.

What you need to do:

  • TypeScript consumers: install @types/react and, when needed, @types/react-dom using the
    major version that matches your React version.
  • Non-TypeScript consumers: no action needed.

Runtime PropTypes were removed

visx packages no longer depend on prop-types, and the build no longer generates runtime
Component.propTypes from TypeScript definitions.

What you need to do:

  • Most consumers do not need to change code.
  • If your app imported prop-types only because a visx package installed it transitively, add
    prop-types as a direct dependency.
  • If your app inspects visx component propTypes at runtime, migrate that validation into your app
    or use TypeScript/static checks instead.

Package root imports are the supported API surface

Every package now publishes an exports field mapping package-root imports to types, import,
and require entries. This improves module resolution in modern bundlers and Node.js, but it also
restricts access to internal paths.

What you need to do: replace deep imports like @visx/foo/lib/bar with package-root imports
like @visx/foo. If a symbol you need is not exported from the package root, open an issue.

Most common component prop types are now exported from package roots as TypeScript-only exports. For
example, prefer importing AxisProps from @visx/axis instead of reaching into internal files.

Modern browser targets

Babel targets were bumped to modern browsers. IE11 and other legacy browsers are no longer
supported.

What you need to do: if you still need IE11, stay on visx 3.

Published ESM output works in strict ESM environments

The published esm/ output now emits explicit .js extensions on relative imports and a nested
esm/package.json with "type": "module". Strict Node ESM consumers such as Vite SSR, Deno, and
edge runtimes should no longer hit ERR_MODULE_NOT_FOUND from extensionless visx ESM imports.

What you need to do: nothing, unless you previously pinned to an older alpha to work around ESM
issues. Upgrade all visx packages to ^4.0.0.

D3 shape and path dependencies were upgraded

visx packages now use d3-shape v3 and d3-path v3 through @visx/vendor. visx preserves its
existing package-level behavior where compatibility shims were needed, but direct D3 imports are now
your app's responsibility.

What you need to do:

  • Most consumers do not need to change code.
  • If your app imports d3-shape or d3-path without declaring them in your own package.json, add
    them as direct dependencies.
  • If your app imports from @visx/vendor/d3-shape or @visx/vendor/d3-path, review the D3 v3 API
    and type changes.

`@visx/bounds` `withBoundingRects` requires `nodeRef`

withBoundingRects no longer falls back to ReactDOM.findDOMNode. The wrapped component receives a
nodeRef prop and must attach it to the DOM element that should be measured. This keeps
@visx/bounds compatible with React 19 and React strict-mode expectations.

What you need to do:

  • If you use withBoundingRects, make sure the wrapped component accepts nodeRef and passes it to
    the measured DOM element.
  • If you use TypeScript, type nodeRef as a React ref for the element you measure.
  • If you already attach nodeRef, no action is needed.
diff
- function Tooltip({ rect, parentRect, children }) {
-   return <div>{children}</div>;
+ type TooltipProps = Omit<WithBoundingRectsProps, 'nodeRef'> & {
+   nodeRef?: React.Ref<HTMLDivElement>;
+ };
+
+ function Tooltip({ rect, parentRect, nodeRef, children }: TooltipProps) {
+   return <div ref={nodeRef}>{children}</div>;
  }

`@visx/responsive` measurement fixes

ParentSize and withParentSize now render a two-div structure to prevent infinite height growth
in flex and grid layouts. useParentSize now uses a callback ref internally and also accepts an
optional externalRef.

What you need to do:

  • Most consumers do not need to change code.
  • If you access parentRef.current from useParentSize, replace it with the returned node.
  • If tests or CSS rely on the exact ParentSize wrapper DOM structure, update them for the nested
    measurement div.

`@visx/xychart` axis loading behavior

BaseAxis no longer renders until at least one data series with non-empty data has been
registered in DataContext. Previously, on initial render the axis could use the fallback
scaleLinear() domain [0, 1], causing tickFormat to receive incorrect intermediate values
before real data loaded.

What you need to do:

  • Most consumers do not need to change code.
  • If you relied on the axis being visible before data loaded, render a placeholder <Axis /> from
    @visx/axis directly with your own scale until your data is ready, then switch to the xychart
    <Axis />.

`@visx/xychart` `withRegisteredData` was removed

The internal withRegisteredData enhancer was removed from @visx/xychart. Series components now
register their data directly instead of using that higher-order component.

What you need to do: most consumers do not need to change code. If you imported
@visx/xychart/lib/enhancers/withRegisteredData directly, migrate to the public xychart series
components and package-root exports.

Lodash is no longer a transitive implementation dependency

@visx/responsive, @visx/text, @visx/xychart, and @visx/shape no longer declare direct
lodash or @types/lodash dependencies. Internal debounce, memoize, and chunk usage has been
replaced with small local helpers. Public visx APIs are intended to behave the same.

What you need to do: if your app imported lodash without declaring it in your own
package.json, add lodash as a direct dependency. It may have worked before only because a visx
package installed it transitively.

Building visx from source requires newer tooling

This note is for contributors or consumers building the visx repo itself. The repository now uses
Yarn 4 via Corepack and requires Node 24 or newer.

What you need to do: if you only install published @visx/* packages, no action is needed. If
you build the repo locally, use Node 24+ and run Yarn through Corepack.

From 4.0.0 alpha releases

Upgrade all @visx/* packages to ^4.0.0. The stable release includes all alpha changes listed
below, plus the final React 18/19 peer dependency range and Dependabot cleanup from the final alpha
publishes.

If you installed 4.0.0-alpha.10, 4.0.0-alpha.12, or 4.0.0-alpha.13, upgrade immediately. Those
alpha releases partially failed and left some packages unpublished or out of sync.

Alpha release history

The notes below are preserved for users who tested the v4 alpha series. Stable upgrade guidance
above supersedes any older alpha-specific instructions.

4.0.0-alpha.17

Internal only: updated transitive brace-expansion lockfile entries to resolve a Dependabot
security alert. No consumer-facing visx API changes are expected.

4.0.0-alpha.16

Internal only: updated demo, test, release, and build-tool dependencies to resolve Dependabot
security alerts. No consumer-facing visx API changes are expected.

4.0.0-alpha.15

React 18 or 19 is now required

React-based @visx/* packages now declare react peer dependencies as ^18.0.0 || ^19.0.0.
Packages that depend on react-dom declare the same supported range for their react-dom peer
dependency. Optional @types/react and, where applicable, @types/react-dom peer dependencies use
the same supported major-version range.

What you need to do:

  • React 18 or 19 consumers: no runtime code changes are expected for this peer dependency
    update.
  • React 16 or 17 consumers: stay on visx v3 or upgrade your app to React 18+ before installing
    visx v4.
  • TypeScript consumers: install @types/react and, when needed, @types/react-dom using the
    major version that matches your React version.
  • Preact consumers: continue aliasing react and react-dom to preact/compat, and configure
    your package manager to satisfy the React 18/19 peer dependency range.

4.0.0-alpha.14

Re-publish of alpha.12 and alpha.13, which partially failed (see below). No intended code changes
relative to alpha.12 — all packages are now published at the same version.

What you need to do: if you installed any @visx/* packages at 4.0.0-alpha.12 or
4.0.0-alpha.13, upgrade to alpha.14 to ensure all packages are in sync.

Lodash removed from package dependencies

@visx/responsive, @visx/text, @visx/xychart, and @visx/shape no longer declare direct
lodash or @types/lodash dependencies. Internal debounce, memoize, and chunk usage has been
replaced with small local helpers. Public visx APIs are intended to behave the same, including the
existing debounce options in @visx/responsive.

What you need to do:

  • Most consumers: nothing — this removes an implementation dependency from visx packages.
  • If your app imported lodash without declaring it in your own package.json: add lodash as
    a direct dependency. It may have worked before only because a visx package installed it
    transitively.

This release also fixes the XYChart docs/demo example so it passes its known width into XYChart.
No consumer code changes are needed for that docs-only fix.

4.0.0-alpha.13 (broken)

⚠️ Do not use this release. An npm provenance transparency log conflict caused lerna publish
to fail partway through. Some packages were never published at this version while the rest were,
resulting in a version mismatch across the monorepo. Use alpha.14 instead.

4.0.0-alpha.12 (broken)

⚠️ Do not use this release. An npm provenance transparency log conflict caused lerna publish
to fail partway through. Some packages were never published at this version while the rest were,
resulting in a version mismatch across the monorepo. Use alpha.14 instead.

4.0.0-alpha.11

Re-publish of alpha.10 which partially failed (see below). No code changes — all packages are now
published at the same version.

What you need to do: if you installed any @visx/* packages at 4.0.0-alpha.10, upgrade to
alpha.11 to ensure all packages are in sync.

4.0.0-alpha.10 (broken)

⚠️ Do not use this release. A sigstore transparency log conflict caused lerna publish to fail
partway through. 18 packages were never published at this version while the rest were, resulting in
a version mismatch across the monorepo. Use alpha.11 instead.

4.0.0-alpha.9

ESM fix now published for all packages

Five packages (@visx/vendor, @visx/point, @visx/scale, @visx/curve, @visx/mock-data) were
stuck on pre-alpha.2 versions and still shipped ESM output without .js extensions or the
esm/package.json "type": "module" marker. This release force-publishes every package so the
alpha.2 ESM fix (#1976) is present across the board.

What you need to do: if you hit ERR_MODULE_NOT_FOUND in strict ESM environments (Vite SSR,
Deno, edge runtimes) with any of those five packages, upgrading to this release resolves it.

4.0.0-alpha.8

`@visx/responsive` useParentSize external ref support

useParentSize now accepts an optional externalRef in its config object. If provided, the hook
forwards the observed DOM node to both its internal state and the external ref, eliminating the need
for a wrapper div when you already have a ref on the container element.

tsx
const myRef = useRef<HTMLDivElement>(null);
const { parentRef, width, height } = useParentSize({ externalRef: myRef });

return <div ref={parentRef}>...</div>;
// myRef.current is also set to the div element

Both RefObject and callback refs are supported.

What you need to do:

  • Most consumers: nothing — this is an additive, non-breaking change. Existing usage without an
    externalRef argument is unchanged.
  • If you were adding a wrapper div to combine your own ref with parentRef: you can now remove
    the wrapper and pass your ref directly via the externalRef option.

4.0.0-alpha.7

`@visx/responsive` ParentSize flex/grid infinite growth fix

ParentSize and withParentSize now render a two-div structure to prevent infinite height growth
in flex and grid layouts (#881,
#1014).

Previously, the component rendered a single wrapper ``. In
flex or grid containers, a child SVG's intrinsic height could grow the wrapper, triggering
ResizeObserver in a feedback loop.

The new structure uses an outer and an inner
that holds the ResizeObserver and children. Since the inner div is absolutely positioned, children's
intrinsic sizes cannot grow the outer container.

What you need to do:

  • Most consumers: nothing — the component API is unchanged and the visual result should be
    identical or better (no more infinite growth).
  • If you rely on the wrapper div's exact DOM structure (e.g., querying it in tests or applying
    CSS that targets a single wrapper div): the wrapper is now two nested divs. className, style,
    and all other HTML attributes still apply to the outer div.
  • If you use the deprecated parentSizeStyles prop: it still works and applies to the outer
    div, but position: relative is prepended to ensure the inner absolutely-positioned measurement
    div works correctly. If you explicitly set position in your custom styles, your value takes
    precedence.
  • If you use withParentSize: the same two-div structure applies. The container div is no
    longer a single ``.

4.0.0-alpha.6

`@visx/responsive` useParentSize callback ref fix

useParentSize now uses a callback ref internally instead of useRef. This fixes a bug where the
hook could permanently report 0×0 dimensions because parentRef.current was null when the
useEffect first ran, and the dependency array never re-fired once the ref attached to the DOM
(#1816).

The returned parentRef is now a callback ref ((node: T | null) => void) instead of a
RefObject<T | null>. A new node property is also returned for direct access to the observed DOM
element.

What you need to do:

  • Most consumers: nothing — `` works with both RefObject and callback
    refs, and ParentSize component users are unaffected.

  • If you access parentRef.current directly: replace with the new node return value.

    diff
    - const { parentRef, width, height } = useParentSize();
    - console.log(parentRef.current);
    + const { parentRef, node, width, height } = useParentSize();
    + console.log(node);

4.0.0-alpha.5

`@visx/xychart` axis rendering fix (breaking)

BaseAxis no longer renders until at least one data series with non-empty data has been
registered in DataContext. Previously, on initial render the axis could use the fallback
scaleLinear() domain [0, 1], causing tickFormat to receive incorrect intermediate values
before real data loaded (#1975).

This is a behavior change: axes that previously rendered immediately (showing 0–1 ticks while
data was loading) will now render null until real data is available.

What you need to do:

  • Most consumers: nothing — this is a bugfix. If you were working around stale tick labels on
    first render, you can remove that workaround.
  • If you relied on the axis being visible before data loaded (e.g., to display a skeleton axis):
    render a placeholder <Axis /> from @visx/axis directly with your own scale until your data is
    ready, then switch to the xychart <Axis />.

Thank you wildseansy for the fix
#1979

4.0.0-alpha.4

Internal only: replaced ts-node with tsx (esbuild-based) for faster TypeScript script execution.
No consumer-facing changes.

4.0.0-alpha.3

`@types/react` and `@types/react-dom` as peer dependencies

React-based @visx/* packages now declare @types/react as a peer dependency instead of
bundling their own copy. That way your app supplies a single version and you avoid duplicate or
conflicting installs.

@visx/bounds, @visx/tooltip, @visx/xychart, and the @visx/visx meta-package all declare
@types/react-dom as an optional peer directly (bounds and tooltip type DOM-touching APIs; xychart
consumes tooltip and so transitively needs react-dom at runtime; the umbrella matches the pattern of
its DOM-touching members).

@visx/brush and @visx/wordcloud also declare @types/react as an optional peer so consumers
installing either package directly get the same type-dependency signal as the rest of the
React-based @visx/* packages.

The peers are marked optional via peerDependenciesMeta, so non-TypeScript consumers will not see
missing-peer warnings.

What you need to do:

  • React 18 or 19 (TypeScript users): add @types/react as a dev dependency matching your React
    version:

    bash
    yarn add -D @types/react

    If you use @visx/bounds, @visx/tooltip, @visx/xychart, or the @visx/visx meta-package,
    also install @types/react-dom:

    bash
    yarn add -D @types/react-dom

    Use the major versions that align with your react / react-dom versions.

  • Non-TypeScript consumers: no action needed.

If you see TypeScript errors about missing react types after upgrading, install the appropriate
@types/react (and @types/react-dom when using @visx/bounds, @visx/tooltip, @visx/xychart,
or @visx/visx) in your application.

4.0.0-alpha.2

Node ESM compatibility fix for published `esm/` output

The published esm/ output now emits explicit .js extensions on relative imports and a nested
esm/package.json with "type": "module". Strict Node ESM consumers (Vite/react-router SSR, Deno,
edge runtimes) previously failed with ERR_MODULE_NOT_FOUND when resolving visx's ESM entry.

What you need to do: nothing — this is a bugfix. If you were pinned to 4.0.0-alpha.1
specifically to avoid a different ESM issue, you can upgrade safely.

4.0.0-alpha.1

Release-plumbing only: prerelease bump configuration and CI permissions for release PR comments. No
consumer-facing changes.

4.0.0-alpha.0

The React 19 cut. This is the release that drops legacy React support and modernizes the build
targets.

React 19 support (automatic JSX transform)

Every @visx/* package now uses the automatic JSX transform and imports React symbols as direct
named imports or type-only imports (no more React.ReactNode namespace access). Peer dependency
ranges were widened to ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0.

What you need to do:

  • React 19 consumers: you should be able to upgrade with no code changes.
  • React 18 / 17 / 16.14+ consumers: still supported, no action needed.
  • React ≤ 16.13: no longer supported — upgrade React first.
  • If you import directly from deep subpaths (e.g. @visx/shape/lib/shapes/Bar), prefer the package
    root (@visx/shape). Deep imports are no longer the blessed API surface and may break in a future
    alpha. Every package now declares exports so Node's module resolver will honor the root entry.

Dropped IE11 support

Babel targets were bumped to modern browsers. IE11 and other legacy browsers are no longer
supported.

What you need to do: if you still need IE11, stay on 3.x.

Package `exports` field

Every package now publishes an exports field mapping . to types, import, and require
entries. This improves module resolution in modern bundlers and Node.js, but does restrict access to
internal paths.

What you need to do: replace any deep imports (@visx/foo/lib/bar) with root imports
(@visx/foo). If a symbol you need isn't re-exported from the root, open an issue.

Lerna v9 / OIDC publishing / resolution cleanup

Internal only — Lerna was upgraded to v9, publishing now uses OIDC trusted publishing, and unused
ansi-* resolutions were removed from the root. No consumer impact.

`@visx/demo` (internal)

Upgraded to React 19, Next.js 15, and @react-spring/web v10. Affects contributors only.


File: package.json

{
"name": "@visx/root",
"license": "MIT",
"version": "0.0.0",
"description": "Low-level visualization components",
"keywords": [
"react",
"d3",
"visualization",
"visx",
"charts"
],
"engines": {
"node": ">=24.0.0",
"yarn": ">=4.0.0"
},
"contributors": [
{
"name": "Harrison Shoff",
"url": "https://github.com/hshoff"
},
{
"name": "Chris Williams",
"url": "https://github.com/williaster"
},
{
"name": "Krist Wongsuphasawat",
"url": "https://github.com/kristw"
}
],
"private": true,
"scripts": {
"build:vendor": "yarn run ts ./packages/visx-vendor/scripts/buildVendor",
"babel": "yarn run babel:cjs && yarn run babel:esm",
"babel:cjs": "lerna exec --ignore '@visx/{demo,vendor}' --parallel -- 'babel --root-mode upward --delete-dir-on-start src/ --out-dir lib --extensions .ts,.tsx'",
"babel:esm": "ESM=true lerna exec --ignore '@visx/{demo,vendor}' --parallel -- 'babel --root-mode upward --delete-dir-on-start src/ --out-dir esm --extensions .ts,.tsx' && node ./scripts/writeEsmPackageJson.js",
"babel:pkg": "lerna exec --scope $PKG -- 'babel --root-mode upward --delete-dir-on-start src/ --out-dir lib --extensions .ts,.tsx' && lerna exec --scope $PKG -- 'ESM=true babel --root-mode upward --delete-dir-on-start src/ --out-dir esm --extensions .ts,.tsx' && node ./scripts/writeEsmPackageJson.js",
"build": "yarn run build:vendor && yarn run babel && yarn run type && yarn run type:kernel-api",
"build:sizes": "yarn run ts ./scripts/computeBuildSizes.ts",
"build:release": "yarn run ts ./scripts/performRelease/index.ts",
"dev:demo": "yarn run docs:generate && yarn workspace @visx/demo dev",
"check:sizes": "yarn run ts ./scripts/compareBuildSizes.ts",
"clean": "rm -rf ./packages/**/{lib,esm}",
"docs:generate": "yarn run ts ./scripts/generateDocs.ts",
"format": "lerna exec --parallel -- 'prettier --write --ignore-path ../../.prettierignore .'",
"lint": "eslint packages/ --quiet",
"lint:fix": "yarn run lint --fix",
"postinstall": "yarn run ts ./scripts/postInstall.ts",
"prepare-release": "git checkout master && git pull --rebase origin master && lerna updated",
"release": "yarn run prepare-release && lerna publish --exact",
"setup": "yarn run build",
"test": "yarn run vitest run",
"test:watch": "yarn run vitest watch",
"vitest": "vitest",
"vitest:ui": "vitest --ui",
"registry:smoke": "yarn workspace @visx/registry smoke:install",
"registry:validate": "yarn workspace @visx/registry validate",
"ts": "tsx --tsconfig ./tsconfig.node.json",
"type": "yarn type:clean && yarn type:build",
"type:build": "lerna exec -- 'tsc --build'",
"type:kernel-api": "tsc -p packages/visx-kernel/test/tsconfig.typecheck.json --pretty false",
"type:clean": "find . -type f -name 'tsconfig.tsbuildinfo' -delete",
"type:pkg": "lerna exec --scope $PKG -- 'tsc --build --verbose'",
"type:update-refs": "yarn run ts ./scripts/updateTsReferences.ts",
"vendor-check": "yarn run ts ./packages/visx-vendor/scripts/flagVendorRequirements.ts"
},
"devDependencies": {
"@babel/cli": "^7.26.4",
"@babel/core": "^7.26.0",
"@babel/eslint-parser": "^7.25.9",
"@babel/preset-env": "^7.29.7",
"@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.26.0",
"@octokit/openapi-types": "18.0.0",
"@octokit/rest": "18.1.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.0",
"@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^13.5.0",
"@types/jsdom": "27.0.0",
"@types/node": "^22.10.2",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^8.18.1",
"@typescript-eslint/parser": "^8.18.1",
"@vitest/coverage-v8": "4.1.8",
"@vitest/eslint-plugin": "^1.4.0",
"@vitest/ui": "4.1.8",
"airbnb-js-shims": "^2.2.1",
"babel-plugin-add-import-extension": "^1.6.0",
"chalk": "4.1.0",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-unicorn": "^45.0.2",
"fast-glob": "3.2.5",
"filesize": "6.1.0",
"jsdom": "27.0.0",
"lerna": "^9.0.7",
"prettier": "^2.8.1",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0",
"timezone-mock": "^1.1.0",
"tsx": "^4.19.0",
"typescript": "^5.7.0",
"vitest": "4.1.8"
},
"packageManager": "[email protected]",
"workspaces": {
"packages": [
"./packages/*"
]
},
"resolutions": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"postcss@npm:8.4.31": "8.5.15",
"caniuse-lite": "^1.0.30001787",
"baseline-browser-mapping": "^2.10.18"
}
}


File: PULL_REQUEST_TEMPLATE.md

:boom: Breaking Changes

:rocket: Enhancements

:memo: Documentation

:bug: Bug Fix

:house: Internal


File: registry.json

{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "visx",
"homepage": "https://github.com/airbnb/visx",
"include": ["packages/visx-registry/registry.json"]
}


File: tsconfig.eslint.json

{
"extends": "./tsconfig.options.json",
"include": [
"scripts//",
"packages/
/src/
/",
"packages/
/test//",
"packages/
/types/
/",
"packages/
/scripts//",
"packages/
/registry/
/",
"vitest.workspace.ts",
"packages/
/vitest.config.ts"
]
}


File: tsconfig.json

{
"extends": "./tsconfig.options.json",
"files": [],
}


File: tsconfig.node.json

{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"composite": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": false,
"jsx": "react",
"lib": ["dom", "esnext"],
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noErrorTruncation": false,
"noImplicitReturns": true,
"noUnusedLocals": true,
"pretty": true,
"removeComments": false,
"resolveJsonModule": true,
"strict": true,
"target": "es2015",
"typeRoots": ["./node_modules/@types", "./types"],
"useDefineForClassFields": false
}
}


File: tsconfig.options.json

{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": false,
"jsx": "react-jsx",
"lib": [
"dom",
"esnext"
],
"module": "esnext",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"pretty": true,
"removeComments": false,
"strict": true,
"target": "es2015",
"useDefineForClassFields": false,
"composite": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"resolveJsonModule": true
}
}


File: .yarnrc.yml

enableGlobalCache: false

nodeLinker: node-modules

logFilters:

  • pattern: "* doesn't provide react ()"
    level: "discard"
  • pattern: "* doesn't provide react-dom ()"
    level: "discard"
  • pattern: "* doesn't provide @react-spring/web ()"
    level: "discard"
  • pattern: "* doesn't provide webpack ()"
    level: "discard"
  • pattern: "Some peer dependencies are incorrectly met*"
    level: "discard"

File: packages/sizes.json

{"visx-a11y":{"esm":28466,"lib":34549},"visx-annotation":{"esm":19693,"lib":23755},"visx-axis":{"esm":14072,"lib":19318},"visx-bounds":{"esm":1495,"lib":1915},"visx-brush":{"esm":42024,"lib":44001},"visx-chart":{"esm":5680,"lib":8613},"visx-chord":{"esm":1907,"lib":2683},"visx-clip-path":{"esm":1522,"lib":2713},"visx-curve":{"esm":351,"lib":2594},"visx-delaunay":{"esm":1475,"lib":2489},"visx-demo":{"esm":0,"lib":0},"visx-drag":{"esm":9078,"lib":11025},"visx-event":{"esm":3571,"lib":5257},"visx-geo":{"esm":8104,"lib":11674},"visx-glyph":{"esm":7243,"lib":11421},"visx-gradient":{"esm":6928,"lib":11581},"visx-grid":{"esm":9631,"lib":12892},"visx-group":{"esm":502,"lib":1030},"visx-heatmap":{"esm":3496,"lib":4564},"visx-hierarchy":{"esm":8687,"lib":13458},"visx-kernel":{"esm":12168,"lib":15402},"visx-legend":{"esm":14929,"lib":20754},"visx-marker":{"esm":3855,"lib":6120},"visx-mock-data":{"esm":325698,"lib":330728},"visx-network":{"esm":3088,"lib":5105},"visx-pattern":{"esm":7400,"lib":10317},"visx-point":{"esm":791,"lib":1901},"visx-react-spring":{"esm":8724,"lib":11009},"visx-registry":{"esm":116,"lib":79},"visx-responsive":{"esm":11775,"lib":14019},"visx-sankey":{"esm":2501,"lib":3894},"visx-scale":{"esm":19357,"lib":31820},"visx-shape":{"esm":52847,"lib":76176},"visx-stats":{"esm":9258,"lib":10690},"visx-text":{"esm":6416,"lib":7990},"visx-theme":{"esm":22587,"lib":31584},"visx-threshold":{"esm":2067,"lib":2758},"visx-tooltip":{"esm":38153,"lib":46550},"visx-vendor":{"esm":2974,"lib":3226},"visx-visx":{"esm":1718,"lib":4399},"visx-voronoi":{"esm":1909,"lib":3235},"visx-wordcloud":{"esm":1996,"lib":2995},"visx-xychart":{"esm":126022,"lib":155810},"visx-zoom":{"esm":12508,"lib":14835}}


File: packages/visx-a11y/Readme.md

@visx/a11y

Accessibility helpers for primitive visx charts without changing the low-level visx primitive model.
The package is split into server-safe entries for generated semantics and a client React entry for
hooks and companion components.

Installation

sh
npm install --save @visx/a11y

Motivation

visx is intentionally low level: primitives take props, compose freely, and stay out of your app's
state model. That is what makes visx useful for unusual charts, custom dashboards, and product
interfaces that do not fit a fixed charting API.

The tradeoff is that primitive charts tend to rebuild the same accessibility layer:

  • chart titles and long descriptions
  • series labels and point value labels
  • hidden data tables for exact values
  • live regions for async chart updates
  • keyboard affordances for chart exploration
  • rules for hiding decorative SVG chrome

That works for one chart. It gets noisy when a registry or dashboard has many charts built from
different visx packages. Small differences creep in, dense charts can produce too much screen reader
output, and teams end up copying local helpers from chart to chart.

@visx/a11y gives those charts a shared semantic layer while keeping the rendering primitives
plain. It does not ship a chart component, impose SVG structure, or hide non-data elements
automatically. Instead, it gives you spreadable props, generated descriptions, table fallbacks, and
small React helpers that you can attach to the primitives you already render.

Primitive-first design

The a11y package is a semantics layer, not a chart framework.

  • visx primitives remain prop-driven.
  • Server helpers are pure functions with no DOM or React hook requirements.
  • The client hook uses React useId() only when id is omitted.
  • Consumers own the SVG render tree, focus ring styling, and decorative element visibility.
  • Data table and announcer components are independently usable.
  • Dense charts degrade to summary descriptions above pointDescriptionThreshold.
  • keyboardNavEnabled controls roving focus for point-by-point chart exploration.

This keeps chart registry items and product charts able to opt in one layer at a time. If a chart
needs custom descriptions, a visible data table, a separate live region, or no interactive keyboard
state yet, the primitive API still supports that.

Basic usage

Use the server entry when a server-rendered chart only needs generated SVG semantics, a text
description, or an HTML table fallback.

tsx
import type { ChartA11yConfig } from '@visx/a11y/server';
import {
  generateChartDescription,
  generateDataTableHTML,
  getChartAriaProps,
} from '@visx/a11y/server';

type Datum = {
  month: string;
  revenue: number;
};

const config: ChartA11yConfig<Datum> = {
  id: 'revenue-chart',
  title: 'Revenue by month',
  chartType: 'line',
  data,
  x: (datum) => datum.month,
  y: (datum) => datum.revenue,
  yLabel: 'Revenue',
  formatY: (value) => `$${value}`,
};

const a11y = getChartAriaProps(config);
const description = generateChartDescription(config);
const tableHtml = generateDataTableHTML(config);

Use useChartA11y from the React entry when chart components need React-bound props and companion
components.

tsx
'use client';

import { useChartA11y } from '@visx/a11y/react';

export function RevenueChart({ data }) {
  const a11y = useChartA11y({
    id: 'revenue-chart',
    title: 'Revenue by month',
    chartType: 'line',
    data,
    x: (datum) => datum.month,
    y: (datum) => datum.revenue,
    yLabel: 'Revenue',
    formatY: (value) => `$${value}`,
  });

  return (
    <>
      <svg {...a11y.svgProps} id={a11y.id}>
        <desc id={a11y.descriptionId}>{a11y.description}</desc>
        {/* chart marks */}
      </svg>
      <a11y.DataTable />
      <a11y.Announcer />
    </>
  );
}

Recipes

Level 1: Chart semantics, description, and table fallback

Start by spreading svgProps, rendering the generated description, and adding the pre-bound data
table and live announcer. This gives the chart an accessible name, a chart-level description, and an
exact-value table fallback without changing the visual chart.

tsx
const a11y = useChartA11y({
  id: 'revenue-chart',
  title: 'Revenue by month',
  chartType: 'line',
  data,
  x: (datum) => datum.month,
  y: (datum) => datum.revenue,
  yLabel: 'Revenue',
  formatY: (value) => `$${value}`,
});

return (
  <>
    <svg {...a11y.svgProps} id={a11y.id}>
      <desc id={a11y.descriptionId}>{a11y.description}</desc>
      <g>
        {data.map((datum) => (
          <circle key={datum.month} />
        ))}
      </g>
    </svg>
    <a11y.DataTable />
    <a11y.Announcer />
  </>
);

Level 2: Series and point semantics

After Level 1 is in place, spread getSeriesProps on each rendered series group and getPointProps
on each rendered data mark. This adds per-series labels and per-point value labels for charts below
the configured pointDescriptionThreshold.

tsx
const a11y = useChartA11y({
  id: 'revenue-chart',
  title: 'Revenue by month',
  chartType: 'line',
  data,
  x: (datum) => datum.month,
  y: (datum) => datum.revenue,
  yLabel: 'Revenue',
  formatY: (value) => `$${value}`,
  series: [{ label: 'Revenue' }],
});

return (
  <>
    <svg {...a11y.svgProps} id={a11y.id}>
      <desc id={a11y.descriptionId}>{a11y.description}</desc>
      <g {...a11y.getSeriesProps(0)}>
        {data.map((datum, index) => (
          <circle key={datum.month} {...a11y.getPointProps(0, index)} />
        ))}
      </g>
    </svg>
    <a11y.DataTable />
    <a11y.Announcer />
  </>
);

Level 3: Keyboard navigation and tooltip bridge

Keep keyboardNavEnabled enabled when a chart should support point-by-point keyboard exploration.
useChartA11y adds roving focus props to each data mark and calls onPointFocus when keyboard
focus moves to a point. Use that callback to mirror the same tooltip, crosshair, or active-point
state that pointer interaction uses.

tsx
const a11y = useChartA11y({
  id: 'revenue-chart',
  title: 'Revenue by month',
  chartType: 'line',
  data,
  x: (datum) => datum.month,
  y: (datum) => datum.revenue,
  yLabel: 'Revenue',
  formatY: (value) => `$${value}`,
  series: [{ label: 'Revenue' }],
  onPointFocus: ({ datum, index, seriesIndex }) => {
    showTooltip({
      datum,
      index,
      seriesIndex,
    });
  },
});

return (
  <svg {...a11y.svgProps} id={a11y.id}>
    <desc id={a11y.descriptionId}>{a11y.description}</desc>
    <g {...a11y.getSeriesProps(0)}>
      {data.map((datum, index) => (
        <circle
          key={datum.month}
          className={a11y.focusedPoint?.index === index ? 'is-keyboard-focused' : undefined}
          {...a11y.getPointProps(0, index)}
        />
      ))}
    </g>
  </svg>
);

Use useChartKeyboardNav directly when a custom chart already owns its generated ARIA semantics but
still wants the same roving-focus behavior, point focus state, and onPointFocus callback.

Keyboard interaction model

When keyboard navigation is enabled, useChartA11y starts in chart mode. The chart root is
tabbable, and data marks become tabbable only while keyboard exploration is active. Navigation is
enabled by default for charts with at least one point and no more than pointDescriptionThreshold
points.

Key Result
Tab Moves focus to or away from the chart root through normal page tab order.
Enter or Space Enters data mode and focuses the first data point, or the last focused point when returning.
ArrowRight Moves to the next point in the current series, wrapping at the end.
ArrowLeft Moves to the previous point in the current series, wrapping at the beginning.
ArrowDown Moves to the next non-empty series and keeps the closest point index.
ArrowUp Moves to the previous non-empty series and keeps the closest point index.
Home Moves to the first point in the current series.
End Moves to the last point in the current series.
Control + Home Moves to the first point in the chart.
Control + End Moves to the last point in the chart.
Escape Exits data mode and returns focus to the chart root.
? or F1 Announces the configured keyboard help text through Announcer.

Decorative chart chrome

@visx/a11y annotates the chart elements it receives through the hook. Consumers are responsible
for hiding decorative chart chrome from assistive technology. Grid lines, axis ticks, background
rects, clipping helpers, and other non-data elements should usually be rendered with
aria-hidden="true" so screen readers focus on the title, description, series, points, and data
table.

tsx
<svg {...a11y.svgProps} id={a11y.id}>
  <rect aria-hidden="true" width={width} height={height} />
  <GridRows aria-hidden="true" scale={yScale} width={innerWidth} />
  <AxisBottom aria-hidden="true" scale={xScale} />
  <g {...a11y.getSeriesProps(0)}>{/* data marks */}</g>
</svg>

File: packages/visx-a11y/package.json

{
"name": "@visx/a11y",
"version": "4.0.0",
"description": "visx chart accessibility helpers",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
},
"./react": {
"types": "./lib/react/index.d.ts",
"import": "./esm/react/index.js",
"require": "./lib/react/index.js"
},
"./server": {
"types": "./lib/server.d.ts",
"import": "./esm/server.js",
"require": "./lib/server.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"visualizations",
"charts",
"accessibility",
"a11y"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-a11y/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-annotation/Readme.md

@visx/annotation

SVG Annotations enable you to label points, thresholds, or regions of a visualization to provide
additional context to for your chart consumer. This package is heavily inspired by
Susie Lu's
react-annotation library.

Each annotation consists of three (optional) parts:

  1. Subject (CircleSubject, LineSubject, more 🔜) – what part of a chart is being annotated
    (point, line, region)

  2. Label – the text component for the annotation. Handles SVG text wrapping using @visx/text,
    and supports title and subtitle customization as well as vertical & horizontal anchors /
    alignment

  3. Connector – line connecting a subject and label

The Annotation or EditableAnnotation component wrappers allow you to compose these components
and simplify their individual positioning:

tsx
<EditableAnnotation
  x={subjectX}
  y={subjectY}
  dx={labelDx} // x offset of label from subject
  dy={labelDy} // y offset of label from subject
  onDragEnd={({ x, y, dx, dy }) => ...}
>
  <Connector />
  <CircleSubject />
  <Label title="Context about this point" subtitle="More deets">
</EditableAnnotation>

Components can also be used in isolation, in which case you must specify exact positions for each
item:

tsx
() => (
  <g>
    <Connector x={subjectX} y={subjectY} dx={labelDx} dy={labelDy} />
    <CircleSubject x={subjectX} y={subjectY} />
    <Label x={subjectX + labelDx} y={subjectY + labelDy} title="...">
  </g>
)

⚠️ `ResizeObserver` dependency

The Label component relies on ResizeObservers for auto-sizing. If you need a polyfill, you can
either polute the window object or inject it cleanly through props:

tsx
import { ResizeObserver } from 'your-favorite-polyfill';

function App() {
  return <Label resizeObserverPolyfill={ResizeObserver} {...} />

Installation

text
npm install --save @visx/annotation

File: packages/visx-annotation/package.json

{
"name": "@visx/annotation",
"version": "4.0.0",
"description": "visx annotation",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@visx/drag": "workspace:",
"@visx/group": "workspace:
",
"@visx/text": "workspace:*",
"classnames": "^2.3.1",
"react-use-measure": "^2.0.4"
},
"devDependencies": {
"@juggle/resize-observer": "^3.3.1",
"@types/react": "^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-annotation/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-drag"
},
{
"path": "../visx-group"
},
{
"path": "../visx-text"
}
]
}


File: packages/visx-annotation/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-axis/Readme.md

@visx/axis

An axis component consists of a line with ticks, tick labels, and an axis label that helps viewers
interpret your graph.

You can use one of the 4 pre-made axes, or you can create your own based on the <Axis /> element.
Note that the @visx/react-spring package exports an AnimatedAxis variant with animated ticks.

Installation

text
npm install --save @visx/axis

File: packages/visx-axis/package.json

{
"name": "@visx/axis",
"version": "4.0.0",
"description": "visx axis",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
},
"./react": {
"types": "./lib/react/index.d.ts",
"import": "./esm/react/index.js",
"require": "./lib/react/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/group": "workspace:",
"@visx/point": "workspace:
",
"@visx/scale": "workspace:",
"@visx/shape": "workspace:
",
"@visx/text": "workspace:*",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-axis/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-point"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-shape"
},
{
"path": "../visx-text"
}
]
}


File: packages/visx-axis/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-bounds/Readme.md

@visx/bounds

text
npm install --save @visx/bounds

`withBoundingRects` HOC

It's often useful to determine whether elements (e.g., tooltips) overflow the bounds of their parent
container and adjust positioning accordingly. The withBoundingRects higher-order component is
meant to simplify this computation by passing in a component's bounding rect as well as its
parent's bounding rect.

Example usage

Example usage with a <Tooltip /> component

tsx
import React from 'react';
import { withBoundingRects, WithBoundingRectsProps } from '@visx/bounds';

type TooltipProps = Omit<WithBoundingRectsProps, 'nodeRef'> & {
  left: number;
  top: number;
  nodeRef?: React.Ref<HTMLDivElement>;
  children?: React.ReactNode;
};

function Tooltip({
  left: initialLeft,
  top: initialTop,
  rect,
  parentRect,
  nodeRef,
  children,
}: TooltipProps) {
  let left = initialLeft;
  let top = initialTop;

  if (rect && parentRect) {
    left = rect.right > parentRect.right ? left - rect.width : left;
    top = rect.bottom > parentRect.bottom ? top - rect.height : top;
  }

  return (
    <div ref={nodeRef} style={{ top, left, ...myTheme }}>
      {children}
    </div>
  );
}

export default withBoundingRects(Tooltip);

File: packages/visx-bounds/package.json

{
"name": "@visx/bounds",
"version": "4.0.0",
"description": "Utilities to make your life with bounding boxes better",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"visualizations",
"charts"
],
"author": "Chris Williams @williaster",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"@types/react-dom": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
}


File: packages/visx-bounds/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-bounds/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-brush/Readme.md

@visx/brush

A brush allows you to select a sub-region of your chart or axis.

Installation

text
npm install --save @visx/brush

File: packages/visx-brush/package.json

{
"name": "@visx/brush",
"version": "4.0.0",
"description": "visx brush",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"d3",
"react",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"dependencies": {
"@visx/drag": "workspace:",
"@visx/event": "workspace:
",
"@visx/group": "workspace:",
"@visx/scale": "workspace:
",
"@visx/shape": "workspace:*",
"classnames": "^2.3.1"
},
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-brush/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-drag"
},
{
"path": "../visx-event"
},
{
"path": "../visx-group"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-shape"
}
]
}


File: packages/visx-brush/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-chart/Readme.md

@visx/chart

Chart-level React hooks and helpers for building primitive visx charts without adopting a chart
framework. The package starts with shared layout and domain helpers that registry-style charts can
use before composing @visx/axis, @visx/scale, @visx/shape, and other low-level primitives.

Installation

sh
npm install --save @visx/chart

Motivation

visx charts are usually assembled from several packages: one package for scales, one for axes, one
for marks, one for interaction, and application code for the SVG frame around them. That composition
is the point, but every primitive chart still tends to rebuild the same chart-level setup:

  • outer SVG dimensions
  • margin defaults
  • inner drawable width and height
  • xMax and yMax aliases used throughout visx examples
  • common numeric domains for primitive chart scales
  • responsive width fallbacks while parent measurement initializes
  • stable layout objects for downstream hooks and components

Those details are small, but they become repetitive in examples, dashboards, and registry items.
@visx/chart gives primitive charts one shared place for that chart-level setup while leaving scale
construction, rendering, interaction, animation, and state ownership in user code.

Primitive-first design

The chart package is a convenience layer, not a chart framework.

  • Hooks return ordinary values that can be passed to any visx primitive.
  • The package does not render SVG elements or own a chart scene graph.
  • Data accessors, scales, axes, marks, events, and animation remain explicit.
  • Layout defaults are normalized, but callers can keep their own sizing system.
  • You can use the chart hooks with one visx package, many visx packages, or custom SVG.

This keeps registry examples compact without hiding the pieces that make visx flexible. If a chart
needs a custom margin model, responsive container, canvas renderer, or no shared layout helper at
all, the primitive API still supports that.

Basic usage

Use useChartDimensions to normalize an outer chart size and margin into the inner drawing area.

tsx
import { Group } from '@visx/group';
import { useChartDimensions } from '@visx/chart';

const margin = { top: 16, right: 16, bottom: 32, left: 40 };

export function ChartFrame({ width, height, children }) {
  const dimensions = useChartDimensions({ width, height, margin });

  return (
    <svg width={dimensions.width} height={dimensions.height}>
      <Group left={dimensions.margin.left} top={dimensions.margin.top}>
        {children(dimensions)}
      </Group>
    </svg>
  );
}

The hook fills missing margin sides with 0, treats non-finite dimensions as 0, and clamps the
inner drawing area to 0 so marks never receive negative layout space.

Numeric domains

Use the domain helpers when a primitive chart needs the usual safe defaults for empty, invalid, or
single-value data.

tsx
import { getPositiveDomain, getZeroBaselineDomain } from '@visx/chart';

const yDomain = getZeroBaselineDomain(data.map((datum) => datum.value));
const stackedYDomain = getPositiveDomain(
  data.map((datum) => datum.desktop + datum.mobile + datum.tablet),
);

getZeroBaselineDomain includes zero and expands equal domains. getPositiveDomain returns a
positive [0, max] domain with an empty fallback of [0, 1]. getPaddedDomain is available for
plots such as scatter charts where the domain should wrap finite values with proportional padding.

Axis ticks

Use the tick helpers when a chart axis may become too dense in responsive layouts.
getVisibleTickValues thins explicit category tick values while preserving the first and last tick
by default, and getAxisTickCount computes a conservative numeric tick count from the available
axis length.

tsx
import { getAxisTickCount, getVisibleTickValues } from '@visx/chart';

const xTickValues = getVisibleTickValues(months, {
  axisLength: dimensions.innerWidth,
  minTickSpacing: 48,
});
const yNumTicks = getAxisTickCount({
  axisLength: dimensions.innerHeight,
  maxTicks: 5,
  minTickSpacing: 48,
});

The helpers only choose visible axis labels. They do not remove data points, bars, bins, or table
fallback rows.

Responsive width fallback

Use getResponsiveWidth when a responsive container may report 0, NaN, or another
non-renderable width while layout measurement initializes.

tsx
import { getResponsiveWidth } from '@visx/chart';

const chartWidth = getResponsiveWidth(measuredWidth, 640);

The helper returns the measured width only when it is finite and greater than 0; otherwise it
returns the fallback width.

Chart config

Use ChartConfig when labels, colors, icons, and theme-specific tokens should live outside the
chart data. This mirrors the way registry charts are usually copied into app code: the data can come
from an API while chart presentation stays colocated with the component.

tsx
import { getChartConfigColor, getChartConfigLabel, type ChartConfig } from '@visx/chart';

const chartConfig = {
  bookings: {
    label: 'Bookings',
    color: 'var(--chart-1)',
  },
  revenue: {
    label: 'Revenue',
    theme: {
      light: 'oklch(0.646 0.222 41.116)',
      dark: 'oklch(0.488 0.243 264.376)',
    },
  },
} satisfies ChartConfig;

const label = getChartConfigLabel(chartConfig, 'bookings');
const color = getChartConfigColor(chartConfig, 'bookings', 'currentColor');

getChartCssVariables can turn a config into --color-* CSS variables for chart shells that want
the same token style as copied registry components.

Working with scales

xMax and yMax are aliases for innerWidth and innerHeight, matching the naming used in many
visx examples.

tsx
import { useChartDimensions } from '@visx/chart';
import { useScale } from '@visx/scale/react';

export function useRevenueScales({ data, width, height }) {
  const dimensions = useChartDimensions({
    width,
    height,
    margin: { top: 16, right: 16, bottom: 32, left: 48 },
  });
  const maxRevenue = Math.max(0, ...data.map((datum) => datum.revenue));

  const xScale = useScale({
    type: 'band',
    domain: data.map((datum) => datum.month),
    range: [0, dimensions.xMax],
    padding: 0.2,
  });

  const yScale = useScale({
    type: 'linear',
    domain: [0, maxRevenue],
    range: [dimensions.yMax, 0],
    nice: true,
  });

  return { dimensions, xScale, yScale };
}

Recipes

Bar chart shell

tsx
import { AxisBottom, AxisLeft } from '@visx/axis';
import { Group } from '@visx/group';
import { Bar } from '@visx/shape';
import { useChartDimensions } from '@visx/chart';
import { useScale } from '@visx/scale/react';

const margin = { top: 16, right: 16, bottom: 32, left: 48 };

export function RevenueBars({ data, width, height }) {
  const dimensions = useChartDimensions({ width, height, margin });
  const maxRevenue = Math.max(0, ...data.map((datum) => datum.revenue));
  const xScale = useScale({
    type: 'band',
    domain: data.map((datum) => datum.month),
    range: [0, dimensions.xMax],
    padding: 0.2,
  });
  const yScale = useScale({
    type: 'linear',
    domain: [0, maxRevenue],
    range: [dimensions.yMax, 0],
    nice: true,
  });

  return (
    <svg width={dimensions.width} height={dimensions.height}>
      <Group left={dimensions.margin.left} top={dimensions.margin.top}>
        {data.map((datum) => {
          const barX = xScale(datum.month) ?? 0;
          const barY = yScale(datum.revenue) ?? 0;

          return (
            <Bar
              key={datum.month}
              x={barX}
              y={barY}
              width={xScale.bandwidth()}
              height={dimensions.yMax - barY}
              fill="currentColor"
            />
          );
        })}
        <AxisBottom top={dimensions.yMax} scale={xScale} />
        <AxisLeft scale={yScale} />
      </Group>
    </svg>
  );
}

Responsive dimensions

useChartDimensions does not measure the DOM. Pair it with your app's layout system or with
@visx/responsive when a chart should fill available space.

tsx
import { getResponsiveWidth } from '@visx/chart';
import { ParentSize } from '@visx/responsive';

export function ResponsiveRevenueBars({ data }) {
  return (
    <ParentSize>
      {({ width }) => (
        <RevenueBars data={data} width={getResponsiveWidth(width, 640)} height={320} />
      )}
    </ParentSize>
  );
}

File: packages/visx-chart/package.json

{
"name": "@visx/chart",
"version": "4.0.0",
"description": "visx chart-level hooks",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"visualizations",
"charts",
"hooks"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/kernel": "workspace:*"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-chart/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-kernel"
}
]
}


File: packages/visx-chord/Readme.md

@visx/chord

Chord diagrams show directed relationships among a group of entities in a radial layout.

Installation

text
npm install --save @visx/chord

File: packages/visx-chord/package.json

{
"name": "@visx/chord",
"version": "4.0.0",
"description": "visx group",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts",
"svg"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@types/d3-chord": "^1.0.9",
"classnames": "^2.3.1",
"d3-chord": "^1.0.4"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-chord/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-chord/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-clip-path/Readme.md

@visx/clip-path

React utilities for defining <clipPath> SVG elements, with or without data, to be clip masks for
other SVG elements by using their clip-path property.

Installation

text
npm install --save @visx/clip-path

File: packages/visx-clip-path/package.json

{
"name": "@visx/clip-path",
"version": "4.0.0",
"description": "visx clip-path",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts",
"svg"
],
"author": "Chris Williams @williaster",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-clip-path/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-clip-path/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-curve/Readme.md

@visx/curve

Installation

text
npm install --save @visx/curve

Overview

The @visx/curve package is a wrapper of the d3-shape curve
functions. A curve is a function that can be passed into other visx objects that draw lines or
paths, such as a LinePath, to change the way the line between points is drawn. Click on the
example below for an interactive way to explore curve aesthetics.

Any function with the prefix curve in d3 can be used through visx like so:

javascript
import { curveCatmullRomOpen } from '@visx/curve';
let line = (<Shape.LinePath curve={curveCatmullRomOpen} />)

// or if you want namespace all Curves under the `Curve`
import * as Curve from `@visx/curve`;
let line = (<Shape.LinePath curve={Curve.curveCatmullRomOpen} />)

Functions

visx d3
curveBasis curveBasis
curveBasisClose curveBasisClosed
curveBasisOpen curveBasisOpen
curveStep curveStep
curveStepAfter curveStepAfter
curveStepBefore curveStepbefore
curveBundle curveBundle
curveLinear curveLinear
curveLinearClosed curveLinearClosed
curveMonotoneX curveMonotoneX
curveMonotoneY curveMonotoneY
curveCardinal curveCardinal
curveCardinalClosed curveCardinalClosed
curveCardinalOpen curveCardinalOpen
curveCatmullRom curveCatmullRom
curveCatmullRomClosed curveCatmullRomClosed
curveCatmullRomOpen curveCatmullRomOpen
curveNatural curveNatural

File: packages/visx-curve/package.json

{
"name": "@visx/curve",
"version": "4.0.0",
"description": "visx curve",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"repository": "https://github.com/airbnb/visx",
"files": [
"lib",
"esm"
],
"keywords": [
"visx",
"react",
"d3",
"visualization",
"chart"
],
"author": "@hshoff",
"license": "MIT",
"dependencies": {
"@visx/vendor": "workspace:*"
},
"publishConfig": {
"access": "public"
}
}


File: packages/visx-curve/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-curve/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-delaunay/Readme.md

@visx/delaunay

Overview

A Voronoi diagram partitions a two-dimensional plane into regions based on a set of input points.
Each unique input point maps to a corresponding region, where each region represents all points
that are closer to the input point than to any other input point
.

Not only are Voronoi diagrams 😍, but they can be used to
improve the interactive experience of a visualization.
This is most often accomplished by overlaying an invisible voronoi grid on top of the visualization
to increase the target area of interaction sites such as points on a scatter plot.

The @visx/delaunay package provides a wrapper around the existing
d3-delaunay package with some react-specific utilities.

Installation

text
npm install --save @visx/delaunay

Usage

The @visx/delaunay package exports a wrapped version of the d3 voronoi and delaunay layouts for flexible usage,
as well as a `` component for rendering Voronoi and Delaunay regions.

js
import { voronoi, Polygon } from '@visx/delaunay';

const points = Array(n).fill(null).map(() => ({
  x: Math.random() * innerWidth,
  y: Math.random() * innerHeight,
}));

// width + height set an extent on the voronoi
// x + y set relevant accessors depending on the shape of your data
const voronoiDiagram = voronoi({
  data: points,
  x: d => d.x,
  y: d => d.y,
  width,
  height,
});

const polygons = Array.from(voronoiDiagram.cellPolygons());

return (
  <svg>
    <Group>
      {polygons.map((polygon) => (
        <Polygon key={...} polygon={polygon} />
      ))}
      {points.map(({ x, y }) => (
        <circle key={...} cx={x} cy={y} />
      )}
    </Group>
  </svg>
)

Additional information about the voronoi diagram API can be found in the
d3-delaunay documentation.


File: packages/visx-delaunay/package.json

{
"name": "@visx/delaunay",
"version": "4.0.0",
"description": "visx delaunay",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@SheaJanke",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@visx/vendor": "workspace:*",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-delaunay/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-delaunay/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-demo/Readme.md

@visx/demo

https://airbnb.io/visx/gallery


File: packages/visx-demo/package.json

{
"name": "@visx/demo",
"version": "4.0.0",
"description": "visx demo",
"repository": "https://github.com/airbnb/visx",
"scripts": {
"build": "next build",
"deploy": "rm -rf out && yarn build && cd out && touch .nojekyll && git init && git add . && git commit -m "Deploy commit" && git remote add origin [email protected]:airbnb/visx.git && git push -f origin master:gh-pages",
"dev": "next",
"preview": "yarn build && cd ./out && npx serve",
"start": "next start"
},
"keywords": [
"visx",
"demo",
"examples"
],
"contributors": [
{
"name": "Harrison Shoff",
"url": "https://github.com/hshoff"
},
{
"name": "Chris Williams",
"url": "https://github.com/williaster"
}
],
"license": "MIT",
"dependencies": {
"@react-spring/web": "^10.0.3",
"@types/d3-scale-chromatic": "^3.1.0",
"@types/nprogress": "^0.2.0",
"@types/prismjs": "^1.16.0",
"@visx/annotation": "workspace:",
"@visx/axis": "workspace:
",
"@visx/bounds": "workspace:",
"@visx/brush": "workspace:
",
"@visx/chord": "workspace:",
"@visx/clip-path": "workspace:
",
"@visx/curve": "workspace:",
"@visx/delaunay": "workspace:
",
"@visx/drag": "workspace:",
"@visx/event": "workspace:
",
"@visx/geo": "workspace:",
"@visx/glyph": "workspace:
",
"@visx/gradient": "workspace:",
"@visx/grid": "workspace:
",
"@visx/group": "workspace:",
"@visx/heatmap": "workspace:
",
"@visx/hierarchy": "workspace:",
"@visx/legend": "workspace:
",
"@visx/marker": "workspace:",
"@visx/mock-data": "workspace:
",
"@visx/network": "workspace:",
"@visx/pattern": "workspace:
",
"@visx/point": "workspace:",
"@visx/react-spring": "workspace:
",
"@visx/responsive": "workspace:",
"@visx/sankey": "workspace:
",
"@visx/scale": "workspace:",
"@visx/shape": "workspace:
",
"@visx/stats": "workspace:",
"@visx/text": "workspace:
",
"@visx/theme": "workspace:",
"@visx/threshold": "workspace:
",
"@visx/tooltip": "workspace:",
"@visx/vendor": "workspace:
",
"@visx/visx": "workspace:",
"@visx/voronoi": "workspace:
",
"@visx/wordcloud": "workspace:",
"@visx/xychart": "workspace:
",
"@visx/zoom": "workspace:*",
"babel-loader": "^8.2.2",
"classnames": "^2.3.1",
"d3-collection": "^1.0.7",
"d3-hierarchy": "^3.1.2",
"d3-scale-chromatic": "^3.1.0",
"d3-shape": "^3.2.0",
"next": "~15.5.18",
"nprogress": "^0.2.0",
"prismjs": "^1.19.0",
"raw-loader": "^4.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-github-button": "^0.1.10",
"react-markdown": "^9.0.1",
"rehype-raw": "^7.0.0",
"topojson-client": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0"
},
"publishConfig": {
"access": "public"
}
}


File: packages/visx-demo/tsconfig.json

{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"module": "esnext",
"moduleResolution": "node",
"composite": true,
"outDir": "lib",
"resolveJsonModule": true,
"rootDir": "src",
"skipLibCheck": true,
"strict": false,
"target": "es5",
"noEmit": true,
"incremental": true
},
"exclude": [
"lib",
"test",
"src/sandboxes//package.json"
],
"include": [
"src/
/.{ts,tsx}",
"../../types/**/
.{ts,tsx}"
],
"references": [
{
"path": "../visx-annotation"
},
{
"path": "../visx-axis"
},
{
"path": "../visx-bounds"
},
{
"path": "../visx-brush"
},
{
"path": "../visx-chord"
},
{
"path": "../visx-clip-path"
},
{
"path": "../visx-curve"
},
{
"path": "../visx-delaunay"
},
{
"path": "../visx-drag"
},
{
"path": "../visx-event"
},
{
"path": "../visx-geo"
},
{
"path": "../visx-glyph"
},
{
"path": "../visx-gradient"
},
{
"path": "../visx-grid"
},
{
"path": "../visx-group"
},
{
"path": "../visx-heatmap"
},
{
"path": "../visx-hierarchy"
},
{
"path": "../visx-legend"
},
{
"path": "../visx-marker"
},
{
"path": "../visx-mock-data"
},
{
"path": "../visx-network"
},
{
"path": "../visx-pattern"
},
{
"path": "../visx-point"
},
{
"path": "../visx-react-spring"
},
{
"path": "../visx-responsive"
},
{
"path": "../visx-sankey"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-shape"
},
{
"path": "../visx-stats"
},
{
"path": "../visx-text"
},
{
"path": "../visx-theme"
},
{
"path": "../visx-threshold"
},
{
"path": "../visx-tooltip"
},
{
"path": "../visx-vendor"
},
{
"path": "../visx-visx"
},
{
"path": "../visx-voronoi"
},
{
"path": "../visx-wordcloud"
},
{
"path": "../visx-xychart"
},
{
"path": "../visx-zoom"
}
]
}


File: packages/visx-demo/vercel.json

{
"version": 2,
"cleanUrls": true
}


File: packages/visx-demo/src/sandboxes/README.md

Examples

This directory contains examples of visx usage.

Each folder is a complete standalone project, and is imported using the Code Sandbox
import from GitHub feature.


File: packages/visx-demo/src/sandboxes/template/package.json

{
"name": "@visx/demo-example",
"description": "Standalone visx demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/responsive": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-annotation/package.json

{
"name": "@visx/demo-annotation",
"description": "Standalone visx annotation demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/annotation": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"annotation"
]
}


File: packages/visx-demo/src/sandboxes/visx-area/package.json

{
"name": "@visx/demo-area",
"description": "Standalone visx area demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/curve": "latest",
"@visx/event": "latest",
"@visx/gradient": "latest",
"@visx/grid": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/tooltip": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"area"
]
}


File: packages/visx-demo/src/sandboxes/visx-axis/package.json

{
"name": "@visx/demo-axis",
"description": "Standalone axis demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/curve": "latest",
"@visx/gradient": "latest",
"@visx/grid": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/react-spring": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"@visx/scale": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"@react-spring/web": "^10.0.3",
"typescript": "^3"
},
"keywords": [
"axis",
"scales",
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-bargroup/package.json

{
"name": "@visx/demo-bargroup",
"description": "Standalone visx grouped bar demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"bargroup"
]
}


File: packages/visx-demo/src/sandboxes/visx-bargroup-horizontal/package.json

{
"name": "@visx/demo-bargroup-horizontal",
"description": "Standalone visx horizontal grouped bar demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"bargroup"
]
}


File: packages/visx-demo/src/sandboxes/visx-bars/package.json

{
"name": "@visx/demo-bars",
"description": "Standalone visx bars demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"bar"
]
}


File: packages/visx-demo/src/sandboxes/visx-barstack/package.json

{
"name": "@visx/demo-barstack",
"description": "Standalone visx stacked bar demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/event": "latest",
"@visx/grid": "latest",
"@visx/group": "latest",
"@visx/legend": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/tooltip": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"barstack"
]
}


File: packages/visx-demo/src/sandboxes/visx-barstack-horizontal/package.json

{
"name": "@visx/demo-barstack-horizontal",
"description": "Standalone visx horizontal stacked bar demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/grid": "latest",
"@visx/group": "latest",
"@visx/legend": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/tooltip": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"barstack"
]
}


File: packages/visx-demo/src/sandboxes/visx-brush/package.json

{
"name": "@visx/demo-brush",
"description": "Standalone visx brush demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/brush": "latest",
"@visx/curve": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/pattern": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"brush",
"interaction"
]
}


File: packages/visx-demo/src/sandboxes/visx-chord/package.json

{
"name": "@visx/demo-chord",
"description": "Standalone visx chord demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/chord": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-curve/package.json

{
"name": "@visx/demo-curve",
"description": "Standalone visx curve demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/curve": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/marker": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"curve",
"interpolate"
]
}


File: packages/visx-demo/src/sandboxes/visx-delaunay-triangulation/package.json

{
"name": "@visx/demo-delaunay-triangulation",
"description": "Standalone visx delaunay triangulation demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/clip-path": "latest",
"@visx/delaunay": "latest",
"@visx/event": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"delaunay",
"triangulation"
]
}


File: packages/visx-demo/src/sandboxes/visx-delaunay-voronoi/package.json

{
"name": "@visx/demo-delaunay-voronoi",
"description": "Standalone @visx/delaunay voronoi demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/clip-path": "latest",
"@visx/delaunay": "latest",
"@visx/event": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"voronoi",
"delaunay"
]
}


File: packages/visx-demo/src/sandboxes/visx-dendrogram/package.json

{
"name": "@visx/demo-dendrogram",
"description": "Standalone visx dendrogram demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/hierarchy": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"hierarchy",
"dendrogram"
]
}


File: packages/visx-demo/src/sandboxes/visx-dots/package.json

{
"name": "@visx/demo-dots",
"description": "Standalone visx scatterplot demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/event": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/tooltip": "latest",
"@visx/voronoi": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"visualization"
]
}


File: packages/visx-demo/src/sandboxes/visx-drag-i/package.json

{
"name": "@visx/demo-drag-i",
"description": "Standalone visx drag demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/drag": "latest",
"@visx/gradient": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"drag"
]
}


File: packages/visx-demo/src/sandboxes/visx-drag-ii/package.json

{
"name": "@visx/demo-drag-ii",
"description": "Standalone visx drag demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/curve": "latest",
"@visx/drag": "latest",
"@visx/gradient": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"drag",
"draw"
]
}


File: packages/visx-demo/src/sandboxes/visx-geo-albers-usa/package.json

{
"name": "@visx/demo-geo-albers-usa",
"description": "Standalone visx geo-albers-usa demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/geo": "latest",
"@visx/responsive": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"topojson-client": "^3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"geojson",
"geo",
"mercator",
"map"
]
}


File: packages/visx-demo/src/sandboxes/visx-geo-albers-usa/us-abbr.json

{
"01": "AL",
"02": "AK",
"60": "AS",
"04": "AZ",
"05": "AR",
"06": "CA",
"08": "CO",
"09": "CT",
"10": "DE",
"12": "FL",
"64": "FM",
"13": "GA",
"66": "GU",
"15": "HI",
"16": "ID",
"17": "IL",
"18": "IN",
"19": "IA",
"20": "KS",
"21": "KY",
"22": "LA",
"23": "ME",
"68": "MH",
"24": "MD",
"25": "MA",
"26": "MI",
"27": "MN",
"28": "MS",
"29": "MO",
"30": "MT",
"31": "NE",
"32": "NV",
"33": "NH",
"34": "NJ",
"35": "NM",
"36": "NY",
"37": "NC",
"38": "ND",
"69": "MP",
"39": "OH",
"40": "OK",
"41": "OR",
"70": "PW",
"42": "PA",
"72": "PR",
"44": "RI",
"45": "SC",
"46": "SD",
"47": "TN",
"48": "TX",
"74": "UM",
"49": "UT",
"50": "VT",
"51": "VA",
"78": "VI",
"53": "WA",
"54": "WV",
"55": "WI",
"56": "WY"
}


File: packages/visx-demo/src/sandboxes/visx-geo-custom/package.json

{
"name": "@visx/demo-geo-custom",
"description": "Standalone visx geo-custom demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/geo": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/vendor": "latest",
"@visx/zoom": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"topojson-client": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"geo",
"maps",
"projection"
]
}


File: packages/visx-demo/src/sandboxes/visx-geo-mercator/package.json

{
"name": "@visx/demo-geo-mercator",
"description": "Standalone visx geo-mercator demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/geo": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"topojson-client": "^3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"geojson",
"geo",
"mercator",
"map"
]
}


File: packages/visx-demo/src/sandboxes/visx-glyph/package.json

{
"name": "@visx/demo-glyph",
"description": "Standalone visx glyph demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/curve": "latest",
"@visx/glyph": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"svg",
"glyph"
]
}


File: packages/visx-demo/src/sandboxes/visx-gradient/package.json

{
"name": "@visx/demo-gradient",
"description": "Standalone visx gradient demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"svg",
"gradient"
]
}


File: packages/visx-demo/src/sandboxes/visx-heatmap/package.json

{
"name": "@visx/demo-heatmap",
"description": "Standalone visx heatmap demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/group": "latest",
"@visx/heatmap": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"heatmap"
]
}


File: packages/visx-demo/src/sandboxes/visx-legend/package.json

{
"name": "@visx/demo-legend",
"description": "Standalone visx legends demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/glyph": "latest",
"@visx/legend": "latest",
"@visx/scale": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"legend"
]
}


File: packages/visx-demo/src/sandboxes/visx-linktypes/package.json

{
"name": "@visx/demo-linktypes",
"description": "Standalone visx link types demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/hierarchy": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"d3-shape": "3.2.0",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"link",
"shape"
]
}


File: packages/visx-demo/src/sandboxes/visx-network/package.json

{
"name": "@visx/demo-network",
"description": "Standalone visx network demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/responsive": "latest",
"@visx/network": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"network"
]
}


File: packages/visx-demo/src/sandboxes/visx-pack/package.json

{
"name": "@visx/demo-pack",
"description": "Standalone visx hierarchy pack demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/group": "latest",
"@visx/hierarchy": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"hierarchy",
"pack"
]
}


File: packages/visx-demo/src/sandboxes/visx-pattern/package.json

{
"name": "@visx/demo-pattern",
"description": "Standalone visx pattern demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/group": "latest",
"@visx/pattern": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-polygons/package.json

{
"name": "@visx/demo-polygons",
"description": "Standalone visx polygons demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"polygon",
"shape"
]
}


File: packages/visx-demo/src/sandboxes/visx-radar/package.json

{
"name": "@visx/demo-radar",
"description": "Standalone visx radar chart demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/point": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"radar"
]
}


File: packages/visx-demo/src/sandboxes/visx-radial-bars/package.json

{
"name": "@visx/demo-radial-bars",
"description": "Standalone visx radial bars demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/text": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"bar"
]
}


File: packages/visx-demo/src/sandboxes/visx-responsive/package.json

{
"name": "@visx/demo-responsive",
"description": "Standalone @visx/responsive demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-sankey/energy.json

{"nodes":[{"name":"Agricultural 'waste'"},{"name":"Bio-conversion"},{"name":"Liquid"},{"name":"Losses"},{"name":"Solid"},{"name":"Gas"},{"name":"Biofuel imports"},{"name":"Biomass imports"},{"name":"Coal imports"},{"name":"Coal"},{"name":"Coal reserves"},{"name":"District heating"},{"name":"Industry"},{"name":"Heating and cooling - commercial"},{"name":"Heating and cooling - homes"},{"name":"Electricity grid"},{"name":"Over generation / exports"},{"name":"H2 conversion"},{"name":"Road transport"},{"name":"Agriculture"},{"name":"Rail transport"},{"name":"Lighting & appliances - commercial"},{"name":"Lighting & appliances - homes"},{"name":"Gas imports"},{"name":"Ngas"},{"name":"Gas reserves"},{"name":"Thermal generation"},{"name":"Geothermal"},{"name":"H2"},{"name":"Hydro"},{"name":"International shipping"},{"name":"Domestic aviation"},{"name":"International aviation"},{"name":"National navigation"},{"name":"Marine algae"},{"name":"Nuclear"},{"name":"Oil imports"},{"name":"Oil"},{"name":"Oil reserves"},{"name":"Other waste"},{"name":"Pumped heat"},{"name":"Solar PV"},{"name":"Solar Thermal"},{"name":"Solar"},{"name":"Tidal"},{"name":"UK land based bioenergy"},{"name":"Wave"},{"name":"Wind"}],"links":[{"source":0,"target":1,"value":124.729},{"source":1,"target":2,"value":0.597},{"source":1,"target":3,"value":26.862},{"source":1,"target":4,"value":280.322},{"source":1,"target":5,"value":81.144},{"source":6,"target":2,"value":35},{"source":7,"target":4,"value":35},{"source":8,"target":9,"value":11.606},{"source":10,"target":9,"value":63.965},{"source":9,"target":4,"value":75.571},{"source":11,"target":12,"value":10.639},{"source":11,"target":13,"value":22.505},{"source":11,"target":14,"value":46.184},{"source":15,"target":16,"value":104.453},{"source":15,"target":14,"value":113.726},{"source":15,"target":17,"value":27.14},{"source":15,"target":12,"value":342.165},{"source":15,"target":18,"value":37.797},{"source":15,"target":19,"value":4.412},{"source":15,"target":13,"value":40.858},{"source":15,"target":3,"value":56.691},{"source":15,"target":20,"value":7.863},{"source":15,"target":21,"value":90.008},{"source":15,"target":22,"value":93.494},{"source":23,"target":24,"value":40.719},{"source":25,"target":24,"value":82.233},{"source":5,"target":13,"value":0.129},{"source":5,"target":3,"value":1.401},{"source":5,"target":26,"value":151.891},{"source":5,"target":19,"value":2.096},{"source":5,"target":12,"value":48.58},{"source":27,"target":15,"value":7.013},{"source":17,"target":28,"value":20.897},{"source":17,"target":3,"value":6.242},{"source":28,"target":18,"value":20.897},{"source":29,"target":15,"value":6.995},{"source":2,"target":12,"value":121.066},{"source":2,"target":30,"value":128.69},{"source":2,"target":18,"value":135.835},{"source":2,"target":31,"value":14.458},{"source":2,"target":32,"value":206.267},{"source":2,"target":19,"value":3.64},{"source":2,"target":33,"value":33.218},{"source":2,"target":20,"value":4.413},{"source":34,"target":1,"value":4.375},{"source":24,"target":5,"value":122.952},{"source":35,"target":26,"value":839.978},{"source":36,"target":37,"value":504.287},{"source":38,"target":37,"value":107.703},{"source":37,"target":2,"value":611.99},{"source":39,"target":4,"value":56.587},{"source":39,"target":1,"value":77.81},{"source":40,"target":14,"value":193.026},{"source":40,"target":13,"value":70.672},{"source":41,"target":15,"value":59.901},{"source":42,"target":14,"value":19.263},{"source":43,"target":42,"value":19.263},{"source":43,"target":41,"value":59.901},{"source":4,"target":19,"value":0.882},{"source":4,"target":26,"value":400.12},{"source":4,"target":12,"value":46.477},{"source":26,"target":15,"value":525.531},{"source":26,"target":3,"value":787.129},{"source":26,"target":11,"value":79.329},{"source":44,"target":15,"value":9.452},{"source":45,"target":1,"value":182.01},{"source":46,"target":15,"value":19.013},{"source":47,"target":15,"value":289.366}]}


File: packages/visx-demo/src/sandboxes/visx-sankey/package.json

{
"name": "@visx/demo-sankey",
"description": "Standalone visx sankey demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18" ,
"@visx/event": "latest",
"@visx/group": "latest",
"@visx/responsive": "latest",
"@visx/sankey": "latest",
"@visx/shape": "latest",
"@visx/tooltip": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"sankey"
]
}


File: packages/visx-demo/src/sandboxes/visx-shape-line-radial/package.json

{
"name": "@visx/demo-shape-line-radial",
"description": "Standalone visx line radial demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/curve": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/grid": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"@react-spring/web": "^10.0.3",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"shape",
"radial",
"line"
]
}


File: packages/visx-demo/src/sandboxes/visx-shape-pie/package.json

{
"name": "@visx/demo-shape-pie",
"description": "Standalone visx pie demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"@react-spring/web": "^10.0.3",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"pie",
"shape",
"donut"
]
}


File: packages/visx-demo/src/sandboxes/visx-shape-splitlinepath/package.json

{
"name": "@visx/demo-shape-splitlinepath",
"description": "Standalone visx splitlinepath demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/curve": "latest",
"@visx/gradient": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"splitline"
]
}


File: packages/visx-demo/src/sandboxes/visx-stacked-areas/package.json

{
"name": "@visx/demo-stacked-areas",
"description": "Standalone visx stacked area demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"stackedarea"
]
}


File: packages/visx-demo/src/sandboxes/visx-stats/package.json

{
"name": "@visx/demo-stats",
"description": "Standalone visx stats demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/pattern": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/stats": "latest",
"@visx/tooltip": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"stats",
"boxplot",
"violin plot"
]
}


File: packages/visx-demo/src/sandboxes/visx-streamgraph/package.json

{
"name": "@visx/demo-streamgraph",
"description": "Standalone visx streamgraph demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/mock-data": "latest",
"@visx/pattern": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/vendor": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"@react-spring/web": "^10.0.3",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"streamgraph",
"react-spring"
]
}


File: packages/visx-demo/src/sandboxes/visx-threshold/package.json

{
"name": "@visx/demo-threshold",
"description": "Standalone visx threshold demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/axis": "latest",
"@visx/curve": "latest",
"@visx/grid": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/shape": "latest",
"@visx/threshold": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"threshold"
]
}


File: packages/visx-demo/src/sandboxes/visx-tooltip/package.json

{
"name": "@visx/demo-tooltip",
"description": "Standalone visx tooltip demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/responsive": "latest",
"@visx/tooltip": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-tree/package.json

{
"name": "@visx/demo-tree",
"description": "Standalone visx tree demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/hierarchy": "latest",
"@visx/responsive": "latest",
"@visx/shape": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"hierarchy",
"tree"
]
}


File: packages/visx-demo/src/sandboxes/visx-treemap/package.json

{
"name": "@visx/demo-treemap",
"description": "Standalone visx treemap demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/group": "latest",
"@visx/hierarchy": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"treemap",
"hierarchy"
]
}


File: packages/visx-demo/src/sandboxes/visx-voronoi/package.json

{
"name": "@visx/demo-voronoi",
"description": "Standalone visx voronoi demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/clip-path": "latest",
"@visx/event": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/voronoi": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"voronoi"
]
}


File: packages/visx-demo/src/sandboxes/visx-wordcloud/package.json

{
"name": "@visx/demo-wordcloud",
"description": "Standalone visx wordcloud demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@visx/responsive":"latest",
"@visx/scale":"latest",
"@visx/text":"latest",
"@visx/wordcloud":"latest",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-xychart/package.json

{
"name": "@visx/demo-xychart",
"description": "Standalone visx xychart demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/curve": "1.0.0",
"@visx/glyph": "latest",
"@visx/mock-data": "latest",
"@visx/pattern": "latest",
"@visx/react-spring": "latest",
"@visx/responsive": "latest",
"@visx/xychart": "latest",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"@react-spring/web": "^10.0.3",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx"
]
}


File: packages/visx-demo/src/sandboxes/visx-zoom-i/package.json

{
"name": "@visx/demo-zoom-i",
"description": "Standalone visx zoom demo.",
"main": "index.tsx",
"private": true,
"dependencies": {
"@babel/runtime": "^7.8.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@visx/clip-path": "latest",
"@visx/event": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
"@visx/zoom": "latest",
"d3-scale-chromatic": "^3.1.0",
"react": "^18",
"react-dom": "^18",
"react-scripts-ts": "3.1.0",
"typescript": "^3"
},
"keywords": [
"visualization",
"d3",
"react",
"visx",
"zoom"
]
}


File: packages/visx-drag/Readme.md

@visx/drag

@visx/drag provides react components and hooks for making items within an interface (or chart)
draggable.

Installation

text
npm install --save @visx/drag

File: packages/visx-drag/package.json

{
"name": "@visx/drag",
"version": "4.0.0",
"description": "visx drag",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@visx/event": "workspace:",
"@visx/point": "workspace:
"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-drag/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-event"
},
{
"path": "../visx-point"
}
]
}


File: packages/visx-drag/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-event/Readme.md

@visx/event

Installation

text
npm install --save @visx/event

Usage

@visx/event exports a utility localPoint that takes an SVG MouseEvent or TouchEvent as
input and returns a { x: number; y: number; } point coordinate (or null in the case the event
has no ownerSVGElement) within the coordinate system of the SVG. This makes placement of
tooltips, finding nearby datum, etc. easier.

Example:

tsx
import { localPoint } from '@visx/event';

<svg>
  <SomeElement
    {...}
    onMouseMove={(event: MouseEvent) => {
      const point = localPoint(event) || { x: 0, y: 0 };
      // use coordinates ...
    }}
  />
  {...}
</svg>

You may optionally pass a reference to the SVG node

tsx
import { useRef } from 'react';
import { localPoint } from '@visx/event';

const svgRef = useRef<SVGSVGElement>(null);

<svg ref={svgRef}>
  <SomeElement
    {...}
    onMouseMove={(event: MouseEvent) => {
      const point = localPoint(svgRef.current, event) || { x: 0, y: 0 };
      // use coordinates ...
    }}
  />
  {...}
</svg>

File: packages/visx-event/package.json

{
"name": "@visx/event",
"version": "4.0.0",
"description": "visx event",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"d3",
"react",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@visx/point": "workspace:*"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-event/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-point"
}
]
}


File: packages/visx-event/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-geo/Readme.md

@visx/geo

The @visx/geo package provides react components for rendering common and custom geographic
projections. `` can be used to render preset projections
(projection='orthographic' | 'albers' | 'albersUsa' | 'mercator' | 'naturalEarth' | 'equalEarth')
along with configurable <Graticule />s lines. Convenience projections such as <Mercator /> are
also exported, along with <CustomProjection /> and <Graticule /> for full customization.

Installation

text
npm install --save @visx/geo

File: packages/visx-geo/package.json

{
"name": "@visx/geo",
"version": "4.0.0",
"description": "visx geo",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts",
"geo"
],
"author": "@nschnierer",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@types/geojson": "",
"@visx/group": "workspace:
",
"@visx/vendor": "workspace:*",
"classnames": "^2.3.1"
},
"devDependencies": {
"@types/react": "^19.0.0",
"@types/topojson-client": "^3.1.5",
"topojson-client": "^3.1.0"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-geo/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-geo/test/topo.json

{
"type": "Topology",
"objects": {
"collection": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"arcs": [[0]],
"id": "poly1"
},
{
"type": "Polygon",
"arcs": [[1]],
"id": "poly2"
}
]
}
},
"arcs": [
[
[3598, 6571],
[-3598, -6571],
[5188, 0],
[-1590, 6571]
],
[
[7823, 9999],
[-2008, -9999],
[4184, 0],
[-2176, 9999]
]
],
"bbox": [-87.2698974609375, 21.616579336740607, -45.2581787109375, 42.68243539838623],
"transform": {
"scale": [0.00420159203420342, 0.002106796285793142],
"translate": [-87.2698974609375, 21.616579336740607]
}
}


File: packages/visx-geo/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-glyph/Readme.md

@visx/glyph

Glyphs are small marks or symbols that you can use in your charts. Example:
https://airbnb.io/visx/glyphs

Installation

text
npm install --save @visx/glyph

File: packages/visx-glyph/package.json

{
"name": "@visx/glyph",
"version": "4.0.0",
"description": "visx glyph",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@visx/group": "workspace:",
"@visx/vendor": "workspace:
",
"classnames": "^2.3.1"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-glyph/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-glyph/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-gradient/Readme.md

@visx/gradient

Inspired by: https://dribbble.com/shots/3380672-Sketch-Gradients-Freebie

Example

js
import { AreaClosed } from '@visx/shape';
import { GradientPinkBlue } from '@visx/gradient';

const GradientArea = () => {
  return (
    <svg>
      <GradientPinkBlue id="gradient" />
      <AreaClosed fill="url('#gradient')" />
    </svg>
  );
};

The Definition Caveat

Like patterns, gradients are "defined." When you render <GradientPinkBlue />, it's rendering a
<linearGradient/>
element inside a <def> in the SVG.

It's often better to think of these as variable definitions rather than true DOM elements. When you
use fill="url('#gradient')" you're referencing the gradient's id: gradient.

Make your own!

In addition to the preset linear gradients, you can make any linear or radial gradient like so:

js
import { LinearGradient, RadialGradient } from '@visx/gradient';

<LinearGradient from="#a18cd1" to="#fbc2eb" />;
<RadialGradient from="#a18cd1" to="#fbc2eb" />;

Installation

text
npm install --save @visx/gradient

File: packages/visx-gradient/package.json

{
"name": "@visx/gradient",
"version": "4.0.0",
"description": "visx gradient",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-gradient/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-gradient/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-grid/Readme.md

@visx/grid

The @visx/grid package lets you create gridlines for charts. <GridRows /> render horizontally,
<GridColumns /> render vertically, or you can use a <Grid /> to get them both at once!

Usage

js
import { Grid } from '@visx/grid';
// or
// import * as Grid from '@visx/grid';
// <Grid.Grid />

const grid = (
  <Grid
    xScale={xScale}
    yScale={yScale}
    width={xMax}
    height={yMax}
    numTicksRows={numTicksForHeight(height)}
    numTicksColumns={numTicksForWidth(width)}
  />
);

Installation

text
npm install --save @visx/grid

File: packages/visx-grid/package.json

{
"name": "@visx/grid",
"version": "4.0.0",
"description": "visx grid",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@visx/curve": "workspace:",
"@visx/group": "workspace:
",
"@visx/point": "workspace:",
"@visx/scale": "workspace:
",
"@visx/shape": "workspace:*",
"classnames": "^2.3.1"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-grid/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-curve"
},
{
"path": "../visx-group"
},
{
"path": "../visx-point"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-shape"
}
]
}


File: packages/visx-grid/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-group/Readme.md

@visx/group

<Group /> provides a simplified API for SVG <g /> elements, which are containers for other SVG
objects. You may pass in a top and left margin (instead of transform={translate(...)}) and a
className.

Installation

text
npm install --save @visx/group

File: packages/visx-group/package.json

{
"name": "@visx/group",
"version": "4.0.0",
"description": "visx group",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"files": [
"lib",
"esm"
],
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts",
"svg"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"classnames": "^2.3.1"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-group/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-group/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-heatmap/Readme.md

@visx/heatmap

A Heatmap is an arrangement of shapes where the data values are represented as colors.

Example

js
<HeatmapRect
  data={data}
  xScale={xScale}
  yScale={yScale}
  colorScale={colorScale}
  opacityScale={opacityScale}
  binWidth={bWidth}
  binHeight={bWidth}
  step={dStep}
  gap={0}
/>

Heatmaps generally require structure that has this shape:

js
[
  {
    bin: 1,
    bins: [
      {
        count: 20,
        bin: 23,
      },
    ],
  },
];

However, you're welcome to use your own structure by defining x, y, z accessors such as:

js
// Example accessors
const x = (d) => d.myBin;
const y = (d) => d.myBins;
const z = (d) => d.myCount;

// Example scale with an accessors
const xScale = scaleLinear({
  range: [0, xMax],
  domain: extent(data, x),
});

Installation

text
npm install --save @visx/heatmap

File: packages/visx-heatmap/package.json

{
"name": "@visx/heatmap",
"version": "4.0.0",
"description": "visx heatmap",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@visx/group": "workspace:*",
"classnames": "^2.3.1"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-heatmap/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
}
]
}


File: packages/visx-heatmap/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-hierarchy/Readme.md

@visx/hierarchy

Many datasets are intrinsically hierarchical. This package contains several react components for
visualizing hierarchical data and largely mirrors
d3-hierarchy.

Many components take the same input hierarchy data root node as defined in as specified in the
d3-hierarchy module. For convenience, this package also
exports the d3-hierarchyutility to generate this format.

js
// equivalent to `import { hierarchy } from 'd3-hierarchy';`
import { hierarchy } from '@visx/hierarchy';

const root = hierarchy({
  name: 'root',
  children: [
    { name: 'child #1' },
    {
      name: 'child #2',
      children: [{ name: 'grandchild #1' }, { name: 'grandchild #2' }, { name: 'grandchild #3' }],
    },
  ],
});

Installation

text
npm install --save @visx/hierarchy

File: packages/visx-hierarchy/package.json

{
"name": "@visx/hierarchy",
"version": "4.0.0",
"description": "visx tree",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"d3",
"react",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@types/d3-hierarchy": "^1.1.6",
"@visx/group": "workspace:*",
"classnames": "^2.3.1",
"d3-hierarchy": "^1.1.4"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-hierarchy/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
}
]
}


File: packages/visx-hierarchy/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-kernel/Readme.md

@visx/kernel

Shared primitives for first-party visx hooks.

@visx/kernel keeps user-input handling consistent across the hooks surface: referential stability,
structural equality, accessor normalization, and shared development warnings live in one package
instead of being reimplemented in each consumer package. It also provides stable id generation for
shared SVG and a11y patterns.

Installation

sh
npm install --save @visx/kernel

Motivation

visx hooks are designed around one idea: hooks own the math, users own the render tree. That means
first-party hooks like useScale, useAxis, and usePie all receive the same kinds of user input:
data arrays, accessors, options objects, dimensions, ids, and callbacks.

Without a shared substrate, each package has to answer the same questions independently:

  • Does this object-shaped input have the same values as last render?
  • Should a string accessor and a simple property function behave the same way?
  • How do we keep callback identity stable while reading fresh state?
  • How do we warn about dirty data with consistent source tags and structured details?
  • How do we generate stable ids for clip paths, gradients, labels, and a11y relationships?

Those are cross-cutting contracts, not chart-specific features. @visx/kernel keeps them small,
audited, and consistent so the hooks surface behaves like one library instead of many similar local
implementations.

Primitive-first design

Kernel is not a chart package. It does not create scales, render axes, lay out marks, or own chart
state. It provides the tiny pieces that make those packages predictable.

  • Hooks return ordinary values and refs.
  • Pure helpers are safe to import on the server.
  • User input is normalized before package-specific work begins.
  • Warning payloads share one shape across packages.
  • Public helpers are added only when multiple first-party packages need the same behavior.

Most applications should use higher-level visx packages directly. Kernel is mainly for first-party
hooks and advanced users building the same kind of low-level primitives.

Basic usage

Stabilize object-shaped inputs

Use useStructuralMemo when an options object should keep the same reference if its shallow values
are unchanged.

tsx
import { useStructuralMemo } from '@visx/kernel';

function ChartFrame({ margin }) {
  const stableMargin = useStructuralMemo(
    {
      top: margin?.top ?? 0,
      right: margin?.right ?? 0,
      bottom: margin?.bottom ?? 0,
      left: margin?.left ?? 0,
    },
    1,
  );

  return <g transform={`translate(${stableMargin.left}, ${stableMargin.top})`} />;
}

Normalize accessors

Use normalizeAccessor when an API accepts either a string key or a function accessor.

ts
import { normalizeAccessor } from '@visx/kernel';

type Datum = { label: string; value: number };

const getValue = normalizeAccessor<Datum, number>('value');
const value = getValue({ label: 'Q1', value: 42 }, 0, []);

Simple property accessors normalize to the same cached function as their string-key equivalent.

ts
const byKey = normalizeAccessor<Datum, number>('value');
const byFunction = normalizeAccessor<Datum, number>((datum) => datum.value);

byKey === byFunction; // true

Compute domains with shared warnings

useDomain normalizes accessors, skips invalid values, stabilizes the returned domain, and emits
structured development warnings for dirty input.

tsx
import { useDomain } from '@visx/kernel';

function RevenueChart({ data }) {
  const domain = useDomain({
    data,
    accessor: 'revenue',
    type: 'linear',
  });

  return <span>{domain.join(' - ')}</span>;
}

Keep callbacks and ids stable

Use useStableCallback when event handlers need stable identity but fresh closed-over values. Use
useStableId for SVG definitions and a11y relationships that must not remount every render.

tsx
import { useLatestRef, useStableCallback, useStableId } from '@visx/kernel';

function InteractiveLayer({ data, onSelect }) {
  const dataRef = useLatestRef(data);
  const clipId = useStableId('scatter-clip');
  const handlePointerMove = useStableCallback((index: number) => {
    onSelect(dataRef.current[index]);
  });

  return (
    <svg>
      <clipPath id={clipId}>
        <rect width={400} height={240} />
      </clipPath>
      <rect clipPath={`url(#${clipId})`} onPointerMove={() => handlePointerMove(0)} />
    </svg>
  );
}

Build and cache path strings

Use createPath when a package needs a small SVG path builder with shared precision behavior. Pass
the resulting string to toPath2D when drawing the same path on Canvas.

ts
import { createPath, toPath2D } from '@visx/kernel';

const d = createPath(2).moveTo(0, 0).lineTo(12.345, 67.89).closePath().toString();
const path = toPath2D(d);

toPath2D(d) returns a real Path2D in browsers. On the server, it returns a minimal object that
stores the path string for cache identity and string inspection; it is not a drawing polyfill.

Format numbers consistently

Use formatNumber when a hook needs a small default formatter without adding a d3-format
dependency.

ts
import { formatNumber } from '@visx/kernel';

const label = formatNumber(1234.56, {
  maximumFractionDigits: 1,
  minimumFractionDigits: 1,
});

Capture warning details

Use setWarnHandler in tests, docs, or integrations that need structured warning payloads.

ts
import { setWarnHandler } from '@visx/kernel';

const restore = setWarnHandler(({ code, details, source }) => {
  console.info(source, code, details);
});

try {
  renderChartWithDirtyData();
} finally {
  restore();
}

File: packages/visx-kernel/package.json

{
"name": "@visx/kernel",
"version": "4.0.0",
"description": "visx shared hook primitives",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"visualizations",
"charts",
"hooks"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
}
}


File: packages/visx-kernel/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-kernel/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-kernel/test/tsconfig.typecheck.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"skipLibCheck": true,
"types": ["node"]
},
"extends": "../../../tsconfig.options.json",
"files": ["api.typecheck.ts"]
}


File: packages/visx-legend/Readme.md

@visx/legend

Legends associate shapes and colors to data, and are associated with scales.

Example

js
import { LegendThreshold } from '@visx/legend';
import { scaleThreshold } from '@visx/scale';

const threshold = scaleThreshold({
  domain: [0.02, 0.04, 0.06, 0.08, 0.1],
  range: ['#f2f0f7', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f'],
});

function MyChart() {
  return (
    <div>
      <svg>{/** chart stuff */}</svg>
      <LegendThreshold
        scale={threshold}
        direction="column-reverse"
        itemDirection="row-reverse"
        labelMargin="0 20px 0 0"
        shapeMargin="1px 0 0"
      />
    </div>
  );
}

Installation

text
npm install --save @visx/legend

File: packages/visx-legend/package.json

{
"name": "@visx/legend",
"version": "4.0.0",
"description": "visx legend",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@visx/group": "workspace:",
"@visx/scale": "workspace:
",
"classnames": "^2.3.1"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-legend/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-scale"
}
]
}


File: packages/visx-legend/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-marker/Readme.md

@visx/marker

Markers are graphical objects attached to a , `<line>`, , or ``
element. MDN <marker>

Installation

text
npm install --save @visx/marker

File: packages/visx-marker/package.json

{
"name": "@visx/marker",
"version": "4.0.0",
"description": "visx marker",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/group": "workspace:",
"@visx/shape": "workspace:
",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-marker/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-shape"
}
]
}


File: packages/visx-marker/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-mock-data/Readme.md

@visx/mock-data

The @visx/mock-data package is here to help you test out your graphs.

Installation

text
npm install --save @visx/mock-data

Generators

Generators can create simple generic data for you like this:

js
import Mock from '@visx/mock-data';
const points = Mock.genRandomNormalPoints();

`Mock.genRandomNormalPoints()`

Returns a series of random normal x,y points.

`Mock.getDateValue(n)`

Generates n date values an hour apart from each other starting with the current time.

Mocks

Mock are essentially a bunch of data dumps that you can use like this:

js
import Mock from '@visx/mock-data';
// or import { cityTemperature } from '@visx/mock-data';
const data = Mock.cityTemperature;

`Mock.appleStock`

js
interface AppleStock {
  date: string;
  close: number;
}

const appleStock: AppleStock[] = [
  { date: '2007-04-24T07:00:00.000Z', close: 93.24 },
  ...
];

`Mock.bitcoinPrice`

js
interface BitcoinPrices {
  currency: string;
  prices: BitcoinPrice[];
}

const bitcoinPrice: BitcoinPrices = {
  currency: 'USD',
  prices: [
    { price: '2486.69', time: '2017-07-03T00:00:00Z' },
    ...
  ]
};

`Mock.browserUsage`

js
const browserUsage: BrowserUsage[] = [
  {
    date: '2015 Jun 15',
    'Google Chrome': '48.09',
    'Internet Explorer': '24.14',
    Firefox: '18.82',
    Safari: '7.46',
    'Microsoft Edge': '0.03',
    Opera: '1.32',
    Mozilla: '0.12',
    'Other/Unknown': '0.01',
  },
  ...
];

`Mock.cityTemperature`

ts
interface CityTemperature {
  date: string;
  'New York': string;
  'San Francisco': string;
  Austin: string;
}

const cityTemperature: CityTemperature[] = [
  {
    date: '20111001',
    'New York': '63.4',
    'San Francisco': '62.7',
    Austin: '72.2',
  },
  ...
];

`Mock.exoplanets`

ts
interface Exoplanets {
  name: string;
  radius: number;
  distance: number | null;
}

const exoplanets: Exoplanets[] = [
  {
    name: 'Jupiter',
    radius: 10.97,
    distance: 0,
  },
  ...
];

`Mock.groupDateValue`

ts
interface GroupDateValue {
  key: string;
  value: string;
  date: string;
}

const groupDateValue: GroupDateValue[] = [
  { key: 'Group1', value: '37', date: '04/23/12' },
  ...
];

`Mock.lesMiserables`

ts
interface LesMiserablesNode {
  id: string;
  group: number;
}

interface LesMiserablesLink {
  source: string;
  target: string;
  value: number;
}

interface LesMiserables {
  nodes: LesMiserablesNode[];
  links: LesMiserablesLink[];
}

const lesMiserables: LesMiserables = {
  nodes: [
    { id: 'Myriel', group: 1 },
    ...
  ],
  links: [
    { source: 'Napoleon', target: 'Myriel', value: 1 },
    ...
  ],
};

`Mock.letterFrequency`

ts
interface LetterFrequency {
  letter: string;
  frequency: number;
}

const letterFrequency: LetterFrequency[] = [
  { letter: 'A', frequency: 0.08167 },
  ...
];

`Mock.shakespeare`

ts
interface Shakespeare {
  id: string;
  parent: string | null;
  size: number | null;
}

const shakespeare: Shakespeare[] = [
  {
    id: 'Shakespeare',
    parent: null,
    size: 0,
  },
  ...
];

Source For Components

`generators/`

`mocks/`


File: packages/visx-mock-data/package.json

{
"name": "@visx/mock-data",
"version": "4.0.0",
"description": "visx mock data",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@types/d3-random": "^2.2.0",
"d3-random": "^2.2.2"
}
}


File: packages/visx-mock-data/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-mock-data/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-network/Readme.md

@visx/network

A simple package to visualize a network or graph layout. Does not currently handle network layout.

Example Usage

js
import { Graph, DefaultLink, DefaultNode } from '@visx/network';
const nodes = [
  { x: 50, y: 20 },
  { x: 200, y: 300 },
  { x: 300, y: 40 },
];

const dataSample = {
  nodes,
  links: [
    { source: nodes[0], target: nodes[1] },
    { source: nodes[1], target: nodes[2] },
    { source: nodes[2], target: nodes[0] },
  ],
};

const MyGraph = () => (
  <Graph graph={dataSample} linkComponent={DefaultLink} nodeComponent={DefaultNode} />
);

Installation

text
npm install --save @visx/network

File: packages/visx-network/package.json

{
"name": "@visx/network",
"version": "4.0.0",
"description": "visx network",
"sideEffects": false,
"repository": "https://github.com/airbnb/visx",
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"keywords": [
"visx",
"data",
"visualizations",
"charts"
],
"author": "@andyfang_dz",
"license": "MIT",
"dependencies": {
"@visx/group": "workspace:*",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-network/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
}
]
}


File: packages/visx-network/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-pattern/Readme.md

@visx/pattern

Inspired by: http://riccardoscalco.github.io/textures/

Example

js
import { AreaClosed } from '@visx/shape';
import { PatternLines } from '@visx/pattern';

const PatternArea = () => {
  return (
    <svg>
      <PatternLines
        id="lines"
        height={5}
        width={5}
        stroke={'black'}
        strokeWidth={1}
        orientation={['diagonal']}
      />
      <AreaClosed fill="url('#lines')" />
    </svg>
  );
};

The Definition Caveat

Like gradients, patterns are "defined." When you put down a , it's putting a [](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Patterns) attribute in the
SVG.

It's often better to think of these as variable definitions rather than true DOM elements. When you
use fill="url('#pattern')" you're referencing the pattern's id: pattern.

Pre-Made Patterns

`PatternsCircles`

js
<PatternCircles id="circles" height={6} width={6} stroke={'black'} strokeWidth={1} />

`PatternsHexagons`

js
<PatternHexagons id="hexagons" height={3} size={8} stroke={'red'} strokeWidth={1} />

`PatternsLines`

js
<PatternLines
  id="lines"
  height={5}
  width={5}
  stroke={'black'}
  strokeWidth={1}
  orientation={['diagonal']}
/>

`PatternsWaves`

js
<PatternWaves id="waves" height={4} width={4} stroke={'blue'} strokeWidth={1} />

Installation

text
npm install --save @visx/pattern

File: packages/visx-pattern/package.json

{
"name": "@visx/pattern",
"version": "4.0.0",
"description": "visx pattern",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualization",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-pattern/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-pattern/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-point/Readme.md

@visx/point

A simple class to represent an x, y coordinate.

Installation

text
npm install --save @visx/point

Example Usage

js
import { Point } from '@visx/point';

const point = new Point({ x: 2, y: 3 });
const { x, y } = point.value(); // Get the coords as an object
const [x, y] = point.toArray(); // or array

Methods

`point.value()`

Returns an { x, y } object with the x and y coordinates.

`point.toArray()`

Returns the coordinates as an array [x, y].


File: packages/visx-point/package.json

{
"name": "@visx/point",
"version": "4.0.0",
"description": "visx point",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"repository": "https://github.com/airbnb/visx",
"files": [
"lib",
"esm"
],
"keywords": [
"visx",
"data",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"publishConfig": {
"access": "public"
}
}


File: packages/visx-point/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-point/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-react-spring/README.md

@visx/react-spring

Although visx is largely unopinioned on animation, there is value in abstracting the complexity +
boilerplate of building animated visx visualization components. This package requires
react-spring as a peerDependency (to be compatible with any usage within your app) and exports
all visx components that depend on react-spring.

react-spring provides performant primitives for animating react
components and is our recommended library for making animated charts. In order to minimize
react-spring as a dependency across other visx packages, we've consolidated components which
depend on it here.

Installation

text
npm install --save react-spring @visx/react-spring

File: packages/visx-react-spring/package.json

{
"name": "@visx/react-spring",
"version": "4.0.0",
"description": "visx primitives that rely on react-spring for animation",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts",
"animation",
"react-spring"
],
"contributors": [
{
"name": "Chris Williams",
"url": "https://github.com/williaster"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@react-spring/web": "^9.7.5 || ^10.0.0",
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@visx/axis": "workspace:",
"@visx/grid": "workspace:
",
"@visx/scale": "workspace:",
"@visx/text": "workspace:
",
"classnames": "^2.3.1"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-react-spring/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-axis"
},
{
"path": "../visx-grid"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-text"
}
]
}


File: packages/visx-react-spring/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-registry/Readme.md

@visx/registry

Source files and validation scripts for the visx shadcn registry. This package is private and has no
runtime API; it exists to ship drop-in chart components through GitHub registry installs.

Motivation

visx is intentionally low level: primitives take props, compose freely, and stay out of your app's
state model. That is what makes visx useful for unusual charts, custom dashboards, and product
interfaces that do not fit a fixed charting API.

The tradeoff is that teams often need a good starting point before they can customize. A line chart,
bar chart, heatmap chart, or treemap chart usually needs the same surrounding work:

  • responsive SVG sizing
  • theme token usage
  • axis and grid styling
  • accessible SVG labels and descriptions
  • hidden data table fallbacks
  • live region wiring
  • installable dependency metadata

That work is valuable, but it is repetitive. @visx/registry packages those starting points as
copyable registry items while keeping the installed output plain React and visx primitives.

Registry-first design

The registry package is distribution infrastructure, not a chart framework.

  • Registry items install into user projects as source files.
  • Installed charts depend on public visx packages, not @visx/registry.
  • Source files live under registry/charts.
  • The repository root registry.json is the public GitHub registry entrypoint.
  • The source registries are committed, but generated public/r item JSON is not.
  • Each chart remains editable after install.

This keeps the installed result compatible with the rest of visx: users can change scales, marks,
themes, accessibility labels, data accessors, and layout directly in their app.

Local development

Add or edit chart source in registry/charts, then update registry.json with the item metadata,
dependencies, source path, and install target.

sh
yarn registry:validate

This validates both the root GitHub registry entrypoint and the package source registry with the
shadcn CLI.

Run the focused registry test suite when changing chart source, metadata, or build scripts:

sh
yarn vitest run --project @visx/registry

Run the install smoke when changing public item names, file targets, dependencies, or exported
component names:

sh
yarn registry:smoke

The smoke test installs every registry item into fresh Next and Vite fixtures with the real shadcn
CLI and typechecks the installed source.

Item structure

Each registry item should have a stable install name and a matching component export.

txt
registry/charts/line-chart/line-chart.tsx
components/charts/line-chart.tsx
export function LineChart()

Use the -chart suffix for chart item names, source files, targets, and exported components. This
keeps registry install names, file names, and generated import names predictable.

GitHub installs

The public registry entrypoint is the repository root registry.json, which includes this package's
source registry:

txt
registry.json
packages/visx-registry/registry.json

After the registry branch lands on the default branch and the referenced visx packages are
published, items can be installed with the shadcn CLI by GitHub address:

sh
npx shadcn@latest add airbnb/visx/line-chart

The local smoke test builds registry item JSON into a temporary directory only so unpublished branch
changes can still be installed into fresh fixtures.

Accessibility and theming

Registry charts should ship with live accessibility wiring from @visx/a11y and theme token usage
from @visx/theme.

Use showLiveRegion={false} when rendering multiple charts on a page that owns a single shared
announcer. The chart should still render its SVG semantics and hidden data table fallback.

Charts should read theme values through visx theme hooks and CSS-ready variables, rather than
hard-coding light and dark mode branches.


File: packages/visx-registry/package.json

{
"name": "@visx/registry",
"version": "4.0.0",
"private": true,
"description": "visx chart registry source files",
"sideEffects": false,
"scripts": {
"build": "yarn run validate",
"smoke:install": "tsx scripts/smokeInstallRegistryItem.ts",
"test": "vitest run",
"validate": "yarn run validate:root && yarn run validate:source",
"validate:root": "shadcn registry validate registry.json --cwd ../..",
"validate:source": "shadcn registry validate"
},
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"visualizations",
"charts",
"registry"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/a11y": "workspace:",
"@visx/axis": "workspace:
",
"@visx/chart": "workspace:",
"@visx/grid": "workspace:
",
"@visx/heatmap": "workspace:",
"@visx/hierarchy": "workspace:
",
"@visx/responsive": "workspace:",
"@visx/scale": "workspace:
",
"@visx/shape": "workspace:",
"@visx/theme": "workspace:
",
"@visx/threshold": "workspace:*",
"react": "^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@types/node": "^22.10.2",
"@types/react": "^19.0.0",
"shadcn": "4.11.0",
"tsx": "^4.19.0",
"typescript": "^5.7.0",
"vitest": "4.1.8"
}
}


File: packages/visx-registry/registry.json

{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "visx",
"homepage": "https://github.com/airbnb/visx",
"items": [
{
"name": "line-chart",
"type": "registry:block",
"title": "Line Chart",
"description": "Themed, responsive, accessible line chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/line-chart/line-chart.tsx",
"type": "registry:component",
"target": "components/charts/line-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "bar-chart",
"type": "registry:block",
"title": "Bar Chart",
"description": "Themed, responsive, accessible bar chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/bar-chart/bar-chart.tsx",
"type": "registry:component",
"target": "components/charts/bar-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "area-chart",
"type": "registry:block",
"title": "Area Chart",
"description": "Themed, responsive, accessible area chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/area-chart/area-chart.tsx",
"type": "registry:component",
"target": "components/charts/area-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "scatter-chart",
"type": "registry:block",
"title": "Scatter Chart",
"description": "Themed, responsive, accessible scatter chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/scatter-chart/scatter-chart.tsx",
"type": "registry:component",
"target": "components/charts/scatter-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "stacked-bar-chart",
"type": "registry:block",
"title": "Stacked Bar Chart",
"description": "Themed, responsive, accessible stacked bar chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/stacked-bar-chart/stacked-bar-chart.tsx",
"type": "registry:component",
"target": "components/charts/stacked-bar-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "multi-series-line-chart",
"type": "registry:block",
"title": "Multi-series Line Chart",
"description": "Themed, responsive, accessible multi-series line chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/multi-series-line-chart/multi-series-line-chart.tsx",
"type": "registry:component",
"target": "components/charts/multi-series-line-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "pie-chart",
"type": "registry:block",
"title": "Pie Chart",
"description": "Themed, responsive, accessible pie chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/chart",
"@visx/responsive",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/pie-chart/pie-chart.tsx",
"type": "registry:component",
"target": "components/charts/pie-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "histogram-chart",
"type": "registry:block",
"title": "Histogram Chart",
"description": "Themed, responsive, accessible histogram chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/histogram-chart/histogram-chart.tsx",
"type": "registry:component",
"target": "components/charts/histogram-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "core"
}
},
{
"name": "grouped-bar-chart",
"type": "registry:block",
"title": "Grouped Bar Chart",
"description": "Themed, responsive, accessible grouped bar chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/grouped-bar-chart/grouped-bar-chart.tsx",
"type": "registry:component",
"target": "components/charts/grouped-bar-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "horizontal-stacked-bar-chart",
"type": "registry:block",
"title": "Horizontal Stacked Bar Chart",
"description": "Themed, responsive, accessible horizontal stacked bar chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/horizontal-stacked-bar-chart/horizontal-stacked-bar-chart.tsx",
"type": "registry:component",
"target": "components/charts/horizontal-stacked-bar-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "stacked-area-chart",
"type": "registry:block",
"title": "Stacked Area Chart",
"description": "Themed, responsive, accessible stacked area chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/stacked-area-chart/stacked-area-chart.tsx",
"type": "registry:component",
"target": "components/charts/stacked-area-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "threshold-chart",
"type": "registry:block",
"title": "Threshold Chart",
"description": "Themed, responsive, accessible threshold chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/axis",
"@visx/chart",
"@visx/grid",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/threshold",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/threshold-chart/threshold-chart.tsx",
"type": "registry:component",
"target": "components/charts/threshold-chart.tsx"
},
{
"path": "registry/charts/bar-chart/chart-ui.tsx",
"type": "registry:component",
"target": "components/charts/chart-ui.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "heatmap-chart",
"type": "registry:block",
"title": "Heatmap Chart",
"description": "Themed, responsive, accessible heatmap chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/chart",
"@visx/heatmap",
"@visx/responsive",
"@visx/scale",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/heatmap-chart/heatmap-chart.tsx",
"type": "registry:component",
"target": "components/charts/heatmap-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "radar-chart",
"type": "registry:block",
"title": "Radar Chart",
"description": "Themed, responsive, accessible radar chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/chart",
"@visx/responsive",
"@visx/scale",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/radar-chart/radar-chart.tsx",
"type": "registry:component",
"target": "components/charts/radar-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "radial-bar-chart",
"type": "registry:block",
"title": "Radial Bar Chart",
"description": "Themed, responsive, accessible radial bar chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/chart",
"@visx/responsive",
"@visx/scale",
"@visx/shape",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/radial-bar-chart/radial-bar-chart.tsx",
"type": "registry:component",
"target": "components/charts/radial-bar-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
},
{
"name": "treemap-chart",
"type": "registry:block",
"title": "Treemap Chart",
"description": "Themed, responsive, accessible treemap chart built from visx primitives.",
"dependencies": [
"@visx/a11y",
"@visx/chart",
"@visx/hierarchy",
"@visx/responsive",
"@visx/scale",
"@visx/theme"
],
"registryDependencies": [],
"files": [
{
"path": "registry/charts/treemap-chart/treemap-chart.tsx",
"type": "registry:component",
"target": "components/charts/treemap-chart.tsx"
}
],
"meta": {
"a11y": true,
"client": true,
"ssr": true,
"tier": "extended"
}
}
]
}


File: packages/visx-registry/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"public",
"registry",
"scripts",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-a11y"
},
{
"path": "../visx-axis"
},
{
"path": "../visx-chart"
},
{
"path": "../visx-grid"
},
{
"path": "../visx-heatmap"
},
{
"path": "../visx-hierarchy"
},
{
"path": "../visx-responsive"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-shape"
},
{
"path": "../visx-theme"
},
{
"path": "../visx-threshold"
}
]
}


File: packages/visx-responsive/Readme.md

@visx/responsive

The @visx/responsive package is here to help you make responsive graphs by providing a collection
of hooks, enhancers and components.

Installation

text
npm install --save @visx/responsive

Hooks

`useScreenSize`

If you would like your graph to adapt to the screen size, you can use the useScreenSize() hook. It
returns current screen width and height and updates the value automatically on browser window
resize. You can optionally pass a config object as an argument to the hook. Config object attributes
are:

  • initialSize - initial size before measuring the screen, defaults to { width: 0, height: 0 }.
  • debounceTime - determines how often the size is updated in milliseconds, defaults to 300.
  • enableDebounceLeadingCall - determines whether the size is updated immediately on first render,
    defaults to true. This is essentially the value of
    options.leading in Lodash's debounce.

Example

tsx
import { useScreenSize } from '@visx/responsive';

const ChartToRender = () => {
  const { width, height } = useScreenSize({ debounceTime: 150 });

  return (
    <svg width={width} height={height}>
      {/* content */}
    </svg>
  );
};

const chartToRender = <ChartToRender myProp="string" />;

`useParentSize`

If you want your graph to adapt to its parent size, you can use useParentSize() hook.
`` uses this hook internally. The hook returns width, height, left, top
properties which describe dimensions of the container which received parentRef ref. You can
optionally pass a config object as an argument to the hook. Config object attributes are:

  • initialSize - initial size before measuring the parent, defaults to
    { width: 0, height: 0, left: 0, top: 0 }.
  • debounceTime - determines how often the size is updated in miliseconds, defaults to 300.
  • enableDebounceLeadingCall - determines whether the size is updated immediately on first render,
    defaults to true. This is essentially the value of
    options.leading in Lodash's debounce.
  • ignoreDimensions - array of dimensions for which an update should be skipped. For example, if
    you pass ['width'], width changes of the component that received parentRef won't be
    propagated. Defaults to [] (all dimensions changes trigger updates).

Example

tsx
import { useParentSize } from '@visx/responsive';

const ChartToRender = () => {
  const { parentRef, width, height } = useParentSize({ debounceTime: 150 });

  return (
    <div ref={parentRef}>
      <svg width={width} height={height}>
        {/* content */}
      </svg>
    </div>
  );
};

const chartToRender = <ChartToRender myProp="string" />;

Enhancers / (HOCs)

`withScreenSize`

If you prefer to use an enhancer, you can use the withScreenSize(). The resulting component will
pass screenWidth and screenHeight props to the wrapped component containing the respective
screen dimensions. You can also optionally pass config props to the wrapped component:

  • debounceTime - determines how often the size is updated in milliseconds, defaults to 300.
  • windowResizeDebounceTime - deprecated, equivalent to the above, kept for backwards compatibility
  • enableDebounceLeadingCall - determines whether the size is updated immediately on first render,
    defaults to true. This is essentially the value of
    options.leading in Lodash's debounce.

Example

tsx
import { withScreenSize, WithScreenSizeProvidedProps } from '@visx/responsive';

interface Props extends WithScreenSizeProvidedProps {
  myProp: string;
}

const MySuperCoolVisxChart = ({ myProp, screenWidth, screenHeight }: Props) => {
  // ...
};

const ChartToRender = withScreenSize(MySuperCoolVisxChart);

const chartToRender = <ChartToRender myProp="string" />;

`withParentSize`

If you prefer to use an enhancer to adapt your graph to its parent component's size, you can use
withParentSize(). The resulting component will pass parentWidth and parentHeight props to the
wrapped component containing the respective parent's dimensions. You can also optionally pass config
props to the wrapped component:

  • initialWidth - initial chart width used before the parent size is determined.
  • initialHeight - initial chart height used before the parent size is determined.
  • debounceTime - determines how often the size is updated in miliseconds, defaults to 300.
  • enableDebounceLeadingCall - determines whether the size is updated immediately on first render,
    defaults to true. This is essentially the value of
    options.leading in Lodash's debounce.

Example

tsx
import { withParentSize, WithParentSizeProvidedProps } from '@visx/responsive';

interface Props extends WithParentSizeProvidedProps {
  myProp: string;
}

const MySuperCoolVisxChart = ({ myProp, parentWidth, parentHeight }: Props) => {
  // ...
};

const ChartWithParentSize = withParentSize(MySuperCoolVisxChart);

const chartToRender = <ChartWithParentSize myProp="string" initialWidth={400} />;

Components

`ParentSize`

You might do the same thing as useParentSize or withParentSize using the ParentSize component.

Example

tsx
import { ParentSize } from '@visx/responsive';

const chartToRender = (
  <ParentSize>
    {(parent) => (
      <MySuperCoolVisxChart
        parentWidth={parent.width}
        parentHeight={parent.height}
        parentTop={parent.top}
        parentLeft={parent.left}
        // this is the referrer to the wrapper component
        parentRef={parent.ref}
        // this function can be called inside MyVisxChart to cause a resize of the wrapper component
        resizeParent={parent.resize}
      />
    )}
  </ParentSize>
);

`ScaleSVG`

You can also create a responsive chart with a specific viewBox with the ScaleSVG component.

Example

tsx
import { ScaleSVG } from '@visx/responsive';

const chartToRender = (
  <ScaleSVG width={400} height={400}>
    <MySuperCoolVXChart />
  </ScaleSVG>
);

⚠️ `ResizeObserver` dependency

useParentSize, ParentSize and withParentSize rely on ResizeObservers for auto-sizing. If you
need a polyfill, you can either pollute the window object or inject it cleanly like this:

tsx
import { ResizeObserver } from 'your-favorite-polyfill';

// hook
useParentSize({ resizeObserverPolyfill: ResizeObserver });

// component
<ParentSize resizeObserverPolyfill={ResizeObserver} {...}>
  {() => {...}}
</ParentSize>

// enhancer
withParentSize(MyComponent, ResizeObserver);

File: packages/visx-responsive/package.json

{
"name": "@visx/responsive",
"version": "4.0.0",
"description": "visx responsive svg",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"devDependencies": {
"@juggle/resize-observer": "^3.3.1"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-responsive/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-responsive/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-sankey/Readme.md

@visx/sankey

Sankey diagrams visualize the directed flow between nodes in an acyclic network. This package
contains react components for visualizing sankey diagrams and largely mirrors
d3-sankey.

Many components take the same input sankey data as defined in as specified in the
d3-sankey module to output a graph of the sankey layout. For
convenience, this package also exports the d3-sankeyutility to
generate this format.

Installation

text
npm install --save @visx/sankey

Usage

The @visx/sankey package exports a wrapped version of d3-sankey for flexible usage, as well as a
<Sankey /> component for rendering the sankey layout.

js
// equivalent to `import { sankey } from 'd3-sankey';`
import { sankey } from '@visx/sankey';

const generator = sankey();
const graph = generator({
  nodes: [{ name: 'node 1' }, { name: 'node 2' }, { name: 'node 3' }],
  links: [
    { source: 0, target: 1, value: 10 },
    { source: 1, target: 2, value: 5 },
  ],
});
js
import { Sankey, sankeyCenter } from '@visx/sankey';

const nodes = [{ name: 'node 1' }, { name: 'node 2' }, { name: 'node 3' }];
const links = [
  { source: 0, target: 1, value: 10 },
  { source: 1, target: 2, value: 5 },
];
const data = { nodes, links };

return (
  <svg>
    <Sankey root={data} nodeAlign={sankeyCenter} size={[100, 100]} />
  </svg>
);

The layout output can also be customized by providing a children function to the <Sankey />
component.

js
import { Sankey, sankeyCenter } from '@visx/sankey';
import { Group } from '@visx/group';
import { BarRounded, LinkHorizontal } from '@visx/group';

const nodes = [{ name: 'node 1' }, { name: 'node 2' }, { name: 'node 3' }];
const links = [
  { source: 0, target: 1, value: 10 },
  { source: 1, target: 2, value: 5 },
];
const data = { nodes, links };

return (
  <svg>
    <Sankey root={data} nodeAlign={sankeyCenter} size={[100, 100]}>
      {({ graph, createPath }) => (
        <>
          <Group>
            {graph.links.map((link, i) => (
              <LinkHorizontal
                key={i}
                data={link}
                path={createPath}
                fill="transparent"
                stroke="#f50057"
                strokeWidth={link.width}
                strokeOpacity={0.5}
              />
            ))}
          </Group>
          <Group>
            {graph.nodes.map(({ y0, y1, x0, x1, name }, i) => (
              <BarRounded
                key={i}
                width={x1 - x0}
                height={y1 - y0}
                x={x0}
                y={y0}
                radius={3}
                fill="#f50057"
                all
              />
            ))}
          </Group>
        </>
      )}
    </Sankey>
  </svg>
);

File: packages/visx-sankey/package.json

{
"name": "@visx/sankey",
"version": "4.0.0",
"description": "visx sankey",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"d3",
"react",
"visualizations",
"charts"
],
"author": "@jacksonhardaker",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@types/d3-sankey": "^0.12.4",
"@visx/group": "workspace:",
"@visx/vendor": "workspace:
",
"classnames": "^2.3.1",
"d3-sankey": "^0.12.3"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-sankey/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-scale/Readme.md

@visx/scale

Installation

sh
npm install --save @visx/scale

Overview of scales

The @visx/scale package aims to provide a wrapper around existing d3 scaling originally defined
in the d3-scale package.

Scales are functions that help you map your data values to the physical pixel size that your graph
requires. For example, let's say you wanted to create a bar chart to show populations per country.
If you were to use a 1-to-1 scale (IE: 1 pixel per y value) your bar for the USA would be about
321.4 million pixels high!

Instead, you can tell visx a function to use that takes a data value (like your population per
country) and quantitatively maps to another dimensional space, like pixels.

For example, we could create a linear scale like this:

js
const graphWidth = 500;
const graphHeight = 200;
const [minX, maxX] = getXMinAndMax();
const [minY, maxY] = getYMinAndMax();

const xScale = Scale.scaleLinear({
  domain: [minX, maxX], // x-coordinate data values
  range: [0, graphWidth], // svg x-coordinates, svg x-coordinates increase left to right
  round: true,
});

const yScale = Scale.scaleLinear({
  domain: [minY, maxY], // y-coordinate data values
  // svg y-coordinates, these increase from top to bottom so we reverse the order
  // so that minY in data space maps to graphHeight in svg y-coordinate space
  range: [graphHeight, 0],
  round: true,
});

// ...

const points = data.map((d, i) => {
  const barHeight = graphHeight - yScale(d.y);
  return <Shape.Bar height={barHeight} y={graphHeight - barHeight} />;
});

Different types of scales

Band scale

Original d3 docs

Example:

js
const scale = Scale.scaleBand({
  /*
    range,
    round,
    domain,
    padding,
    nice = false
  */
});

Linear scale

Original d3 docs

Example:

js
const scale = Scale.scaleLinear({
  /*
    range,
    round,
    domain,
    nice = false,
    clamp = false,
  */
});

Log scale

Original d3 docs

Example:

js
const scale = Scale.scaleLog({
  /*
    range,
    round,
    domain,
    base,
    nice = false,
    clamp = false,
  */
});

Important note: As log(0) = -∞, a log scale domain must be strictly-positive or
strictly-negative; the domain must not include or cross zero.

Radial scale

Original d3 docs

Example:

js
const scale = Scale.scaleRadial({
  /*
    range,
    round,
    domain,
    nice = false,
    clamp = false,
  */
});

Ordinal scale

Original d3 docs

Example:

js
const scale = Scale.scaleOrdinal({
  /*
    range,
    domain,
    unknown,
  */
});

Point scale

Original d3 docs

Example:

js
const scale = Scale.scalePoint({
  /*
    range,
    round,
    domain,
    padding,
    align,
    nice = false,
  */
});

Power scale

Original d3 docs

Example:

js
const scale = Scale.scalePower({
  /*
    range,
    round,
    domain,
    exponent,
    nice = false,
    clamp = false,
  */
});

Square Root scale

Original d3 docs

Example:

js
// No need to set the exponent, It is always 0.5
const scale = Scale.scaleSqrt({
  /*
    range,
    round,
    domain,
    nice = false,
    clamp = false,
  */
});

Time scale

Original d3 docs

Example:

js
const scale = Scale.scaleTime({
  /*
    range,
    round,
    domain,
    nice = false,
    clamp = false,
   */
});

You also can scale time with Coordinated Universal Time via scaleUtc.

Example:

js
const scale = Scale.scaleUtc({
  /*
    range,
    round,
    domain,
    nice = false,
    clamp = false,
   */
});

Color Scales

D3 scales offer the ability to map points to colors. You can use
d3-scale-chromatic in conjunction with visx's
scaleOrdinal to make color scales.

You can install d3-scale-chromatic with npm:

sh
npm install --save d3-scale-chromatic

You create a color scale like so:

js
import { scaleOrdinal } from '@visx/scale';
import { schemeSet1 } from 'd3-scale-chromatic';

const colorScale = scaleOrdinal({
  domain: arrayOfThings,
  range: schemeSet1,
});

This generates a color scale with the following colors:

There are a number of other
categorical color schemes
available, along with other continuous color schemes.


File: packages/visx-scale/package.json

{
"name": "@visx/scale",
"version": "4.0.0",
"description": "visx scale",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
},
"./react": {
"types": "./lib/react/index.d.ts",
"import": "./esm/react/index.js",
"require": "./lib/react/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"authors": [
"@hshoff",
"@kristw"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/vendor": "workspace:*"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
},
"publishConfig": {
"access": "public"
}
}


File: packages/visx-scale/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-scale/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-shape/Readme.md

@visx/shape

Shapes are the core elements of visx. Most of what you see on the screen, like lines, bars, and
areas are all made with shape primitives.

Installation

text
npm install --save @visx/shape

File: packages/visx-shape/package.json

{
"name": "@visx/shape",
"version": "4.0.0",
"description": "visx shape",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
},
"./react": {
"types": "./lib/react/index.d.ts",
"import": "./esm/react/index.js",
"require": "./lib/react/index.js"
}
},
"repository": "https://github.com/airbnb/visx",
"files": [
"lib",
"esm"
],
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"dependencies": {
"@visx/curve": "workspace:",
"@visx/group": "workspace:
",
"@visx/scale": "workspace:",
"@visx/vendor": "workspace:
",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@types/d3-hierarchy": "^1.1.6",
"@types/react": "^19.0.0",
"d3-hierarchy": "^1.1.8"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-shape/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-curve"
},
{
"path": "../visx-group"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-shape/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-stats/Readme.md

@visx/stats

The package provides react components for visualizing distributions, such as Box Plots and Violin
Plots

Installation

text
npm install --save @visx/stats

File: packages/visx-stats/package.json

{
"name": "@visx/stats",
"version": "4.0.0",
"description": "visx stats box violin",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@conglei",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/group": "workspace:",
"@visx/scale": "workspace:
",
"@visx/vendor": "workspace:*",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-stats/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-group"
},
{
"path": "../visx-scale"
},
{
"path": "../visx-vendor"
}
]
}


File: packages/visx-stats/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-text/Readme.md

@visx/text

The @visx/text provides a better SVG <Text> component with the following features

  • Word-wrapping (when width prop is defined)
  • Vertical alignment (verticalAnchor prop)
  • Rotation (angle prop)
  • Scale-to-fit text (scaleToFit prop)

Example

Simple demo to show off a useful feature. Since svg <text> itself does not support
verticalAnchor, normally text rendered at 0,0 would be outside the viewport and thus not
visible. By using <Text> with the verticalAnchor="start" prop, the text will now be visible as
you'd expect.

jsx
import React from 'react';
// note: react@18 syntax
import { createRoot } from 'react-dom/client';
import { Text } from '@visx/text';

const App = () => (
  <svg>
    <Text verticalAnchor="start">Hello world</Text>
  </svg>
);

const root = createRoot(document.getElementById('root'));

root.render(<App />);

Installation

text
npm install --save @visx/text

File: packages/visx-text/package.json

{
"name": "@visx/text",
"version": "4.0.0",
"description": "visx text",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"d3",
"visualization",
"chart"
],
"author": "@techniq",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"classnames": "^2.3.1",
"reduce-css-calc": "^1.3.0"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}


File: packages/visx-text/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": []
}


File: packages/visx-text/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-theme/Readme.md

@visx/theme

Utilities for sharing visual tokens across visx charts without changing the low-level visx primitive
model. The package is split into an RSC-safe root entry for CSS scoping and a client entry for React
hooks.

Installation

sh
npm install --save @visx/theme

Motivation

visx is intentionally low level: primitives take props, compose freely, and stay out of your app's
state model. That is what makes visx useful for unusual charts, custom dashboards, and product
interfaces that do not fit a fixed charting API.

The tradeoff is that every primitive chart tends to rebuild the same styling layer:

  • categorical colors for each series
  • axis strokes, tick labels, and grid lines
  • text colors, font family, and chart surfaces
  • light/dark color branches
  • design-system token plumbing

That works for one chart. It gets noisy when a dashboard has many charts built from different visx
packages. Small differences creep in, dark mode becomes duplicated JavaScript, and teams end up
copying local helpers from chart to chart.

@visx/theme gives those charts a shared visual language while keeping the rendering primitives
plain. It does not make @visx/axis, @visx/grid, or @visx/shape theme-aware. Instead, it gives
you CSS-ready values and small prop helpers that you can pass to the primitives you already use.

Primitive-first design

The theme package is a convenience layer, not a chart framework.

  • visx primitives remain prop-driven.
  • Theme hooks return ordinary strings, numbers, and prop objects.
  • CSS owns resolved colors through custom properties.
  • Explicit chart props and ChartConfig.color overrides always win.
  • Apps own light/dark mode, class names, data attributes, and design-system providers.
  • You can use one hook, the whole provider, or only ThemeScope.

This keeps shadcn/ui integration zero-config for common apps without making shadcn/ui a requirement
or a constraint. If a chart needs a custom palette, a per-series CSS variable, a hand-tuned axis, or
no theme integration at all, the primitive API still supports that.

Basic usage

Use ThemeScope from the root entry when a server component or app layout only needs to provide the
chart CSS variable boundary.

tsx
import { ThemeScope } from '@visx/theme';
import type { ReactNode } from 'react';

export default function DashboardLayout({ children }: { children: ReactNode }) {
  return (
    <ThemeScope theme="auto" className="dashboard-charts">
      {children}
    </ThemeScope>
  );
}

Use ThemeProvider from the client entry when chart components need theme hooks.

tsx
'use client';

import { ThemeProvider } from '@visx/theme/react';
import type { ReactNode } from 'react';

export function ChartShell({ children }: { children: ReactNode }) {
  return <ThemeProvider theme="auto">{children}</ThemeProvider>;
}

theme="auto" does not emit generated variables. It returns CSS-ready var(...) values, so the app
can own the current light or dark mode through classes, data attributes, media queries, or inline
CSS variables.

shadcn/ui variables

The default auto theme reads the same chart variable names commonly used by shadcn/ui:

css
.light {
  --chart-1: #2563eb;
  --chart-2: #16a34a;
  --background: #ffffff;
  --card: #ffffff;
  --border: #e5e7eb;
  --foreground: #0f172a;
  --muted-foreground: #64748b;
}

.dark {
  --chart-1: #60a5fa;
  --chart-2: #4ade80;
  --background: #020617;
  --card: #0f172a;
  --border: #334155;
  --foreground: #f8fafc;
  --muted-foreground: #94a3b8;
}

When the surrounding app flips .light to .dark, CSS variables update the chart colors.
@visx/theme does not install a mode switcher, call matchMedia, or read the DOM.

Auto-mode limitation

CSS-backed tokens update through variables in auto mode:

  • colors
  • categorical colors
  • background, surface, border, and text colors
  • font family

JS-only numeric values cannot update from CSS alone:

  • chart margins
  • axis stroke width and tick length
  • grid stroke width
  • font sizes

Auto mode uses the light theme numeric defaults for those JS-only values. Pass an explicit theme
object from defineTheme when light and dark modes need different layout measurements.

Migrating from `@visx/xychart`

Existing xychart code can keep using XYChartTheme directly. New primitive charts can reuse the
same visual choices with fromXYChartTheme.

tsx
import { XYChart, buildChartTheme } from '@visx/xychart';
import { ThemeScope, fromXYChartTheme } from '@visx/theme';

const legacyTheme = buildChartTheme({
  backgroundColor: '#ffffff',
  colors: ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6'],
  gridColor: '#f3f4f6',
  gridColorDark: '#e5e7eb',
  tickLength: 4,
});

const primitiveTheme = fromXYChartTheme(legacyTheme);

export function Dashboard() {
  return (
    <>
      <XYChart theme={legacyTheme}>{/* existing chart */}</XYChart>
      <ThemeScope theme={primitiveTheme}>{/* new primitive chart */}</ThemeScope>
    </>
  );
}

The adapter is one-way and structural. @visx/theme does not import from @visx/xychart, and there
is no toXYChartTheme adapter.

Recipes

Line chart

tsx
import { AxisBottom } from '@visx/axis';
import { GridRows } from '@visx/grid';
import { LinePath } from '@visx/shape';
import { useAxisStyle, useColor, useGridStyle } from '@visx/theme/react';

export function RevenueLine({ data, xScale, yScale }) {
  const axis = useAxisStyle('bottom');
  const grid = useGridStyle();
  const lineColor = useColor(0);

  return (
    <>
      <GridRows scale={yScale} stroke={grid.stroke} strokeWidth={grid.strokeWidth} />
      <LinePath
        data={data}
        x={(datum) => xScale(datum.date)}
        y={(datum) => yScale(datum.revenue)}
        stroke={lineColor}
        strokeWidth={2}
      />
      <AxisBottom
        scale={xScale}
        stroke={axis.stroke}
        tickLength={axis.tickLength}
        tickStroke={axis.tickStroke}
        tickLabelProps={axis.tickLabelProps}
      />
    </>
  );
}

Bar chart

tsx
import { AxisBottom, AxisLeft } from '@visx/axis';
import { Bar } from '@visx/shape';
import type { ChartConfig } from '@visx/theme';
import { useAxisStyle, useChartConfig } from '@visx/theme/react';

const seriesConfig = {
  desktop: { label: 'Desktop' },
  mobile: { label: 'Mobile' },
} satisfies ChartConfig<'desktop' | 'mobile'>;

export function TrafficBars({ data, xScale, yScale }) {
  const xAxis = useAxisStyle('bottom');
  const yAxis = useAxisStyle('left');
  const { getColor, getLabel } = useChartConfig(seriesConfig, {
    order: ['desktop', 'mobile'],
  });

  return (
    <>
      {data.map((datum) => (
        <Bar
          key={datum.browser}
          x={xScale(datum.browser)}
          y={yScale(datum.desktop)}
          width={xScale.bandwidth()}
          height={yScale(0) - yScale(datum.desktop)}
          fill={getColor('desktop')}
          aria-label={`${getLabel('desktop')} traffic`}
        />
      ))}
      <AxisBottom scale={xScale} {...xAxis} />
      <AxisLeft scale={yScale} {...yAxis} />
    </>
  );
}

Area chart

tsx
import { AxisLeft } from '@visx/axis';
import { AreaClosed } from '@visx/shape';
import { useAxisStyle, useColor, useGridStyle } from '@visx/theme/react';

export function ConversionArea({ data, xScale, yScale }) {
  const axis = useAxisStyle('left');
  const grid = useGridStyle();
  const fill = useColor(1);
  const stroke = useColor('highlight');

  return (
    <>
      <AreaClosed
        data={data}
        x={(datum) => xScale(datum.date)}
        y={(datum) => yScale(datum.conversionRate)}
        yScale={yScale}
        fill={fill}
        fillOpacity={0.18}
        stroke={stroke}
        strokeWidth={2}
      />
      <line x1={0} x2="100%" y1={0} y2={0} stroke={grid.stroke} />
      <AxisLeft
        scale={yScale}
        stroke={axis.stroke}
        tickStroke={axis.tickStroke}
        tickLabelProps={axis.tickLabelProps}
      />
    </>
  );
}

File: packages/visx-theme/package.json

{
"name": "@visx/theme",
"version": "4.0.0",
"description": "visx theme utilities",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
},
"./react": {
"types": "./lib/react/index.d.ts",
"import": "./esm/react/index.js",
"require": "./lib/react/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/airbnb/visx.git"
},
"keywords": [
"visx",
"react",
"visualizations",
"charts",
"theme"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/airbnb/visx/issues"
},
"homepage": "https://github.com/airbnb/visx#readme",
"dependencies": {
"@visx/kernel": "workspace:*"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-theme/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-kernel"
}
]
}


File: packages/visx-theme/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}


File: packages/visx-theme/test/tsconfig.typecheck.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"skipLibCheck": true,
"types": []
},
"extends": "../../../tsconfig.options.json",
"files": ["fromXYChartTheme.typecheck.ts"],
"references": [
{
"path": ".."
},
{
"path": "../../visx-xychart"
}
]
}


File: packages/visx-threshold/Readme.md

@visx/threshold

@visx/threshold allows for creation of Difference Charts in react, which highlight the delta
between two line series.

Installation

text
npm install --save @visx/threshold

File: packages/visx-threshold/package.json

{
"name": "@visx/threshold",
"version": "4.0.0",
"description": "visx threshold",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./esm/index.js",
"require": "./lib/index.js"
}
},
"files": [
"lib",
"esm"
],
"repository": "https://github.com/airbnb/visx",
"scripts": {
"docs": "cd ./docs && ../../../node_modules/.bin/react-docgen --exclude index.js ../src/ | ../../../scripts/buildDocs.sh"
},
"keywords": [
"visx",
"react",
"d3",
"visualizations",
"charts"
],
"author": "@hshoff",
"license": "MIT",
"dependencies": {
"@visx/clip-path": "workspace:",
"@visx/shape": "workspace:
",
"classnames": "^2.3.1"
},
"peerDependencies": {
"@types/react": "^18.0.0 || ^19.0.0",
"react": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@types/react": "^19.0.0"
}
}


File: packages/visx-threshold/tsconfig.json

{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src//*",
"types/
/",
"../../types/**/
"
],
"references": [
{
"path": "../visx-clip-path"
},
{
"path": "../visx-shape"
}
]
}


File: packages/visx-threshold/test/tsconfig.json

{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": ".",
"types": ["vitest/globals"]
},
"extends": "../../../tsconfig.options.json",
"include": ["/*", "../types//", "../../../types/**/"],
"references": [
{
"path": ".."
}
]
}