How to Work with Astryx Chart Components and Vega Integration

Use VegaChart from @astryxdesign/vega for declarative Vega/Vega‑Lite specs, or specialized components like SankeyChart and RadialChart from @astryxdesign/lab for built‑in layout, accessibility, and data‑table fallbacks.

Astryx provides two distinct paths for building visualizations: a thin React wrapper around the Vega runtime for full spec control, and higher‑level chart primitives with automatic accessibility features. Both approaches follow Tier‑1 architecture principles where a single root component owns the rendering lifecycle and supplies context to children. This guide walks through the implementation details, practical patterns, and key source files in the facebook/astryx repository.

Two Integration Paths for Astryx Charts

The library organizes its visualization capabilities across separate packages based on your needs.

Path Use Case Primary Component Package
Declarative Vega/Vega‑Lite Render any custom spec with full Vega ecosystem compatibility VegaChart @astryxdesign/vega
Higher‑level primitives Production‑ready charts with responsive layout, accessibility, and minimal configuration SankeyChart, RadialChart, ThreeDChart @astryxdesign/lab

Both paths share core design principles: accessibility first (every chart exposes role="img" with overridable aria-label), non‑reactive data loading (initial data is loaded once; updates use the runtime API), and single‑root lifecycle ownership.

VegaChart: Deep Vega Integration

VegaChart in [packages/vega/src/VegaChart.tsx](https://github.com/facebook/astryx/blob/main/packages/vega/src/VegaChart.tsx) provides complete access to the Vega runtime through a React‑friendly API.

How VegaChart Processes Specifications

The component inspects spec.$schema to determine whether compilation is needed:

  1. Schema validationparseSchema ([src/schema.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/schema.ts)) parses the URL and identifies Vega‑Lite vs. native Vega.
  2. Compilation — Vega‑Lite specs are processed through compile(spec, compileOptions).spec.
  3. Parsing — The resulting Vega spec passes through vega.parse(vegaSpec, parseConfig, parseOptions).
  4. View instantiation — A new View(runtime, viewOptions) is created and bound to the container <div>.
  5. Data hydration — Initial datasets load via view.data(name, tuples) before the first render.
  6. Async executionview.runAsync() triggers rendering, followed by onReady or onError callbacks.

All configuration objects map directly to underlying Vega APIs, allowing fine‑tuned control without leaving the Astryx abstraction.

Rendering Vega‑Lite Bar Charts

import {VegaChart} from '@astryxdesign/vega';

const spec = {
  $schema: 'https://vega.github.io/schema/vega-lite/v5.json',
  mark: 'bar',
  data: {name: 'table'},
  encoding: {
    x: {field: 'category', type: 'ordinal'},
    y: {field: 'value', type: 'quantitative'}
  }
};

function App() {
  return (
    <VegaChart
      spec={spec}
      data={{table: [
        {category: 'A', value: 30},
        {category: 'B', value: 55}
      ]}}
      onReady={view => {
        // Attach signal listeners or update data dynamically
        view.addSignalListener('click', (_, value) => {
          console.log('clicked', value);
        });
      }}
    />
  );
}

Critical pattern: The data prop is not reactive. After mount, updates must use the view instance received in onReady via view.data() and view.runAsync().

Customizing Vega View Options

<VegaChart
  spec={vegaSpec}
  viewOptions={{
    logLevel: 1,                     // Debug logging
    tooltip: (handler, event) => {   // Custom tooltip implementation
      // Custom handler logic
    },
    background: '#fafafa'
  }}
  compileOptions={{
    config: {mark: {tooltip: true}}
  }}
/>

The viewOptions object in [src/types.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/types.ts) exposes all Vega View constructor parameters, while compileOptions configures Vega‑Lite compilation behavior.

Higher‑Level Chart Components

The @astryxdesign/lab package provides purpose‑built components with automatic layout computation and accessibility features.

SankeyChart for Flow Visualizations

SankeyChart ([packages/lab/src/Sankey/SankeyChart.tsx](https://github.com/facebook/astryx/blob/main/packages/lab/src/Sankey/SankeyChart.tsx)) manages flow layout through computeLayout and distributes positions via SankeyProvider context.

import {
  SankeyChart,
  SankeyNode,
  SankeyLink,
  SankeyGrid,
  SankeyLabel
} from '@astryxdesign/lab';

const nodes = [
  {id: 'a', label: 'Source A'},
  {id: 'b', label: 'Source B'},
  {id: 'c', label: 'Target C'}
];

const links = [
  {source: 'a', target: 'c', value: 10},
  {source: 'b', target: 'c', value: 20}
];

function RevenueFlow() {
  return (
    <SankeyChart
      nodes={nodes}
      links={links}
      minColumnWidth={200}
      label="Revenue flow by channel"
    >
      <SankeyGrid />
      <SankeyLink />
      <SankeyNode />
      <SankeyLabel />
    </SankeyChart>
  );
}

Key behaviors:

  • Responsive width — expands to container; horizontal scrolling activates when columns × minColumnWidth exceeds available space
  • Accessible scrolling — scrollable regions receive proper accessible names
  • Data table fallback — for ≤ 100 links, a visually hidden HTML table with "From / To / Value" columns supports screen readers

RadialChart: Spider and Pie Modes

RadialChart ([packages/lab/src/Radial/RadialChart.tsx](https://github.com/facebook/astryx/blob/main/packages/lab/src/Radial/RadialChart.tsx)) automatically selects spider mode when axes are provided, otherwise operating in pie/donut mode.

import {
  RadialChart,
  RadialAxis,
  RadialArea,
  RadialGrid
} from '@astryxdesign/lab';

const data = [
  {model: 'A', speed: 7, handling: 5, comfort: 6},
  {model: 'B', speed: 6, handling: 8, comfort: 7}
];

function PerformanceRadar() {
  return (
    <RadialChart
      data={data}
      axes={['speed', 'handling', 'comfort']}
      height={400}
      label="Vehicle performance comparison"
    >
      <RadialGrid rings={5} />
      <RadialArea dataKey="model" color="#4a90e2" />
      <RadialAxis />
    </RadialChart>
  );
}

Spider mode calculations:

  • angleByAxis map computes angular position for each axis
  • Per‑axis domains drive radial scale calculations

Pie mode calculations:

  • Values are aggregated and converted to slice start/end angles
  • Optional padAngle creates separation between slices

Both modes include automatic data table generation when total data points fall below the MAX_TABLE_POINTS threshold (6 points in the example above).

ThreeDChart for WebGL Visualizations

The 3‑D family in packages/lab/src/ThreeD/ follows identical Tier‑1 patterns. ThreeDChart ([ThreeDChart.tsx](https://github.com/facebook/astryx/blob/main/packages/lab/src/ThreeD/ThreeDChart.tsx)) exposes ThreeDProvider context for projection matrices and camera interaction handling.

Data Update Patterns

Astryx charts use initial data loading rather than reactive updates. This design choice prevents expensive recomputation on every render.

Approach Method Use Case
Vega runtime view.data(name, newTuples).runAsync() Dynamic data streaming, filtering, or updates
Re‑mount component Change key prop Complete spec or configuration change

Vega Runtime Update Example

<VegaChart
  spec={spec}
  onReady={view => {
    // Store view reference for external updates
    window.chartView = view;
  }}
/>

// Later, from an event handler or data fetch:
window.chartView.data('table', newData);
window.chartView.runAsync();

Source File Reference

Component File Path Purpose
VegaChart [packages/vega/src/VegaChart.tsx](https://github.com/facebook/astryx/blob/main/packages/vega/src/VegaChart.tsx) Root component, Vega View lifecycle management
Type definitions [packages/vega/src/types.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/types.ts) VegaChart props, spec types, callback signatures
Schema parsing [packages/vega/src/schema.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/schema.ts) $schema URL parsing, library detection
Vega‑Lite configuration [packages/vega/src/vegaLiteConfig.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/vegaLiteConfig.ts) Reusable config object builders
SankeyChart [packages/lab/src/Sankey/SankeyChart.tsx](https://github.com/facebook/astryx/blob/main/packages/lab/src/Sankey/SankeyChart.tsx) Flow layout, responsive scrolling, accessibility
RadialChart [packages/lab/src/Radial/RadialChart.tsx](https://github.com/facebook/astryx/blob/main/packages/lab/src/Radial/RadialChart.tsx) Spider/pie mode, angular calculations
ThreeDChart [packages/lab/src/ThreeD/ThreeDChart.tsx](https://github.com/facebook/astryx/blob/main/packages/lab/src/ThreeD/ThreeDChart.tsx) Projection math, camera context

Summary

  • Choose VegaChart when you need full Vega/Vega‑Lite spec compatibility and direct runtime access; the component automatically compiles Vega‑Lite and exposes the View instance via onReady
  • Choose @astryxdesign/lab components for production scenarios requiring responsive layout, accessibility compliance, and minimal configuration
  • Update data via runtime APIs rather than props; initial data is loaded once during mount, and subsequent changes use view.data() and view.runAsync()
  • Leverage built‑in accessibility — every Astryx chart exposes role="img", accepts aria-label, and generates hidden data tables for small datasets

Frequently Asked Questions

How does VegaChart detect whether a spec is Vega or Vega‑Lite?

VegaChart calls parseSchema from [src/schema.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/schema.ts) to inspect spec.$schema. If the URL contains vega-lite, the component runs vegaLite.compile() before parsing; otherwise it passes the spec directly to vega.parse().

Can I update chart data without re‑mounting the component?

Yes. Capture the view instance in the onReady callback, then call view.data(name, newTuples) followed by view.runAsync(). The data prop is intentionally non‑reactive to prevent performance overhead on every render.

What accessibility features are built into Astryx charts?

All charts render with role="img" and accept an aria-label prop. For datasets with ≤ 100 points (links in Sankey, rows×axes in Radial), a visually hidden <table> is automatically generated containing the raw data for screen‑reader users. Scrollable regions in SankeyChart receive additional accessible naming.

Where should I configure Vega‑Lite compilation options?

Pass a compileOptions prop to VegaChart. This object is forwarded directly to vegaLite.compile(spec, compileOptions). You can also use [vegaLiteConfig.ts](https://github.com/facebook/astryx/blob/main/packages/vega/src/vegaLiteConfig.ts) helpers to build reusable configuration objects.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →