Victory logo

Victory

An ecosystem of composable React components for building interactive data visualizations on web and mobile.

npm install victory
11.2K325.2K/weekv37.3.62.17 MBMIT100 issues
Last updated: 2025-01-15
Star history chart for FormidableLabs/victory

TL;DR

Victory is a collection of modular React components designed for building interactive data visualizations with a consistent API across web and mobile.

It leverages D3 for layout calculations while fully delegating rendering to React, making it the premier choice for cross-platform development teams.

Why Victory?

Victory stands out by strictly adhering to React's component-based philosophy, treating every part of a chart—from axes to individual data points—as a composable component.

  • Component-Based Composition: Charts are built like Lego blocks using isolated components (VictoryChart, VictoryLine, VictoryAxis), offering granular control without a monolithic configuration object.
  • First-Class React Native Support: Unlike many libraries where mobile is an afterthought, Victory offers near-identical APIs for React Native, allowing significant code reuse between platforms.
  • Declarative Animations: Complex data transitions and entrance animations are handled via simple props, abstracting away the heavy lifting of D3 interpolations.
  • ** robust Theming System:** A powerful VictoryTheme API allows you to define global visualization design systems (colors, fonts, spacing) once and apply them universally.
  • Interactive Containers: Advanced interactions like zooming, panning, and Voronoi tooltips are managed through specialized container components like VictoryZoomContainer, keeping logic separate from presentation.

Code Snippet

Victory charts are composed of children within a wrapper. This example shows a line chart with axes, a specific theme, and basic entrance animation.

import React from 'react';
import { VictoryChart, VictoryLine, VictoryTheme, VictoryAxis } from 'victory';

const data = [
  { quarter: 1, earnings: 13000 },
  { quarter: 2, earnings: 16500 },
  { quarter: 3, earnings: 14250 },
  { quarter: 4, earnings: 19000 }
];

export const MyChart = () => (
  <VictoryChart
    // Apply a pre-defined or custom theme to all child components
    theme={VictoryTheme.material}
    domainPadding={20}
  >
    <VictoryAxis
      // render x-axis with custom tick formatting
      tickValues={[1, 2, 3, 4]}
      tickFormat={["Q1", "Q2", "Q3", "Q4"]}
    />
    <VictoryAxis
      dependentAxis
      // render y-axis with currency formatting
      tickFormat={(x) => `$${x / 1000}k`}
    />
    <VictoryLine
      data={data}
      x="quarter"
      y="earnings"
      style={{
        data: { stroke: "#c43a31" },
        parent: { border: "1px solid #ccc"}
      }}
      animate={{
        duration: 2000,
        onLoad: { duration: 1000 }
      }}
    />
  </VictoryChart>
);

The <VictoryChart> acts as a coordinator, automatically calculating domains and scales for its children (VictoryLine, VictoryAxis) based on the provided data.

Pros and Cons

No library is perfect; understanding the trade-offs is key to selecting the right tool.

Pros

  • Cross-Platform Parity: The architecture allows you to share the vast majority of your charting logic between web (SVG) and mobile (React Native) applications.
  • Modular Architecture: You only import the specific chart types you need (VictoryBar, VictoryPie), which fits perfectly into modern bundler optimization strategies.
  • Design System Friendly: The theming engine is robust enough to support complex corporate branding requirements without fighting CSS specificity.

Cons

  • SVG Performance Limits: Because it renders SVG nodes in the DOM, performance degrades noticeably with large datasets (e.g., thousands of points) compared to Canvas-based solutions.
  • Verbose Styling: Styling individual elements often requires deep nested objects in props rather than standard CSS classes, which can feel clunky.
  • Manual Layout Tuning: Preventing label overlap or positioning legends often requires manual "magic number" padding adjustments rather than automatic layout engines.

Comparison with Other Charting Libraries

The table below outlines the positioning differences between Victory and other popular React charting libraries:

LibraryDesign PhilosophyBest ForPain Points
VictoryCross-Platform Modular
Composable components that wrap D3, emphasizing code reuse between Web and Native.
Cross-Platform Apps
Teams maintaining both React and React Native codebases.
SVG Performance
Struggles with high-frequency real-time data or massive datasets.
RechartsSimple & Composable
Similar component-based API but focused purely on easy web implementation.
Dashboards
Standard admin dashboards needing quick, reliable charts.
Customization Limits
Harder to break out of the default behaviors for highly custom visualizations.
VisxLow-Level Primitives
Unopinionated collection of visualization primitives (shapes, scales) rather than full charts.
Custom Bespoke Viz
Complex, non-standard visualizations where you need total control.
Steep Learning Curve
Requires understanding D3 concepts; significant boilerplate to build a basic chart.

Verdict: When to Adopt

Choose Victory if your primary requirement is maintaining a consistent visualization language across both React and React Native applications. It is the strongest contender for "write once, render everywhere" in the charting space. However, if you are building a high-frequency trading terminal or visualizing massive datasets solely for the web, consider a Canvas-based alternative like visx or react-canvas.