Claude Code for Victory Charts: React Native and Web Charts — Claude Skills 360 Blog
Blog / Frontend / Claude Code for Victory Charts: React Native and Web Charts
Frontend

Claude Code for Victory Charts: React Native and Web Charts

Published: June 25, 2027
Read time: 6 min read
By: Claude Skills 360

Victory provides a cross-platform charting library that works in both React web and React Native — <VictoryChart> is the container for all chart primitives. <VictoryLine data={data} x="date" y="value"> draws line charts. <VictoryBar data={data}> draws bar charts. <VictoryPie data={data} x="label" y="amount"> draws pie charts. <VictoryArea> fills below a line. <VictoryScatter> draws scatter plots. <VictoryAxis tickFormat={(t) => format(t)} dependentAxis> configures axes. <VictoryTooltip> with <VictoryVoronoiContainer> shows hover tooltips. <VictoryBrushContainer brushDimension="x"> handles range selection. VictoryTheme.material or a custom theme object styles all elements. <VictoryStack> stacks bars or areas. animate={{ duration: 400, easing: "quadInOut" }} animates transitions. For React Native: import { VictoryChart } from "victory-native" — same API, SVG rendered via react-native-svg. Claude Code generates Victory charts, donut charts, and brushable dashboards.

CLAUDE.md for Victory Charts

## Victory Charts Stack
- Version: victory >= 37, victory-native >= 41 (for React Native)
- Web: import { VictoryChart, VictoryLine, VictoryBar, VictoryPie, VictoryAxis, VictoryTooltip, VictoryVoronoiContainer } from "victory"
- React Native: import { VictoryChart, ... } from "victory-native" — requires react-native-svg >= 15
- Theme: <VictoryChart theme={VictoryTheme.clean}> or custom theme object
- Tooltip: <VictoryChart containerComponent={<VictoryVoronoiContainer voronoiDimension="x" labels={({ datum }) => datum.y} labelComponent={<VictoryTooltip />} />}>
- Animate: animate={{ duration: 300, onLoad: { duration: 400 } }} on each primitive
- Colors: colorScale={["#6366f1","#f43f5e","#22c55e"]}

Dashboard Charts Component

// components/charts/VictoryDashboard.tsx — multi-chart Victory dashboard
"use client"
import {
  VictoryChart,
  VictoryLine,
  VictoryBar,
  VictoryAxis,
  VictoryTooltip,
  VictoryVoronoiContainer,
  VictoryLegend,
  VictoryTheme,
  VictoryArea,
  VictoryStack,
  VictoryBrushContainer,
  type VictoryStyleObject,
} from "victory"
import { useState } from "react"

type DataPoint = { x: string; y: number }
type SeriesData = { name: string; data: DataPoint[]; color: string }

const STROKE_STYLES: VictoryStyleObject = {
  data: { strokeWidth: 2, fillOpacity: 0.15 },
}

interface MetricLineChartProps {
  series: SeriesData[]
  height?: number
}

export function MetricLineChart({ series, height = 280 }: MetricLineChartProps) {
  const [selectedDomain, setSelectedDomain] = useState<{ x?: [string, string] } | null>(null)

  return (
    <div className="rounded-2xl border bg-card p-4">
      {/* Main chart */}
      <VictoryChart
        height={height}
        padding={{ top: 20, right: 24, bottom: 50, left: 56 }}
        theme={VictoryTheme.clean}
        containerComponent={
          <VictoryVoronoiContainer
            voronoiDimension="x"
            labels={({ datum }) => `${datum.y.toLocaleString()}`}
            labelComponent={
              <VictoryTooltip
                style={{ fontSize: 10 }}
                flyoutStyle={{ fill: "white", stroke: "#e5e7eb", strokeWidth: 1, borderRadius: 6 }}
                flyoutPadding={{ top: 4, bottom: 4, left: 8, right: 8 }}
              />
            }
          />
        }
      >
        <VictoryAxis
          tickFormat={(t: string) => t}
          style={{
            tickLabels: { fontSize: 10, fill: "#6b7280" },
            axis: { stroke: "#e5e7eb" },
            grid: { stroke: "#f3f4f6" },
          }}
        />
        <VictoryAxis
          dependentAxis
          tickFormat={(t: number) => `${(t / 1000).toFixed(0)}k`}
          style={{
            tickLabels: { fontSize: 10, fill: "#6b7280" },
            axis: { stroke: "transparent" },
            grid: { stroke: "#f3f4f6", strokeDasharray: "4,4" },
          }}
        />

        {series.map((s) => (
          <VictoryLine
            key={s.name}
            data={s.data}
            style={{ data: { stroke: s.color, strokeWidth: 2 } }}
            animate={{ duration: 400 }}
          />
        ))}

        <VictoryLegend
          x={0}
          y={height - 35}
          orientation="horizontal"
          gutter={24}
          style={{ labels: { fontSize: 10, fill: "#6b7280" } }}
          data={series.map((s) => ({ name: s.name, symbol: { fill: s.color } }))}
        />
      </VictoryChart>
    </div>
  )
}

interface StackedBarChartProps {
  categories: string[]
  groups: { name: string; data: number[]; color: string }[]
  height?: number
}

export function StackedBarChart({ categories, groups, height = 260 }: StackedBarChartProps) {
  const seriesData = groups.map((g) => ({
    ...g,
    points: g.data.map((y, i) => ({ x: categories[i], y })),
  }))

  return (
    <div className="rounded-2xl border bg-card p-4">
      <VictoryChart
        height={height}
        padding={{ top: 16, right: 16, bottom: 40, left: 48 }}
        domainPadding={{ x: 20 }}
        theme={VictoryTheme.clean}
      >
        <VictoryAxis
          style={{ tickLabels: { fontSize: 10, fill: "#6b7280" }, axis: { stroke: "#e5e7eb" } }}
        />
        <VictoryAxis
          dependentAxis
          tickFormat={(t: number) => `${t.toLocaleString()}`}
          style={{ tickLabels: { fontSize: 10, fill: "#6b7280" }, axis: { stroke: "transparent" }, grid: { stroke: "#f3f4f6", strokeDasharray: "4,4" } }}
        />

        <VictoryStack>
          {seriesData.map((s) => (
            <VictoryBar
              key={s.name}
              data={s.points}
              style={{ data: { fill: s.color, fillOpacity: 0.85 } }}
              animate={{ duration: 300 }}
            />
          ))}
        </VictoryStack>

        <VictoryLegend
          x={0}
          y={height - 32}
          orientation="horizontal"
          gutter={20}
          style={{ labels: { fontSize: 10, fill: "#6b7280" } }}
          data={groups.map((g) => ({ name: g.name, symbol: { fill: g.color } }))}
        />
      </VictoryChart>
    </div>
  )
}

Donut Chart

// components/charts/DonutChart.tsx — VictoryPie donut with center label
"use client"
import { VictoryPie, VictoryLabel } from "victory"

type Slice = { label: string; value: number; color: string }

interface DonutChartProps {
  data: Slice[]
  title?: string
  subtitle?: string
  size?: number
}

export function DonutChart({ data, title, subtitle, size = 280 }: DonutChartProps) {
  const total = data.reduce((sum, d) => sum + d.value, 0)

  return (
    <div className="rounded-2xl border bg-card p-4">
      <div className="relative" style={{ width: size, height: size, margin: "0 auto" }}>
        <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
          <VictoryPie
            standalone={false}
            width={size}
            height={size}
            data={data.map((d) => ({ x: d.label, y: d.value }))}
            colorScale={data.map((d) => d.color)}
            innerRadius={size * 0.28}
            padAngle={2}
            animate={{ duration: 500 }}
            style={{
              labels: { display: "none" },
            }}
          />
          {/* Center label */}
          {title && (
            <VictoryLabel
              textAnchor="middle"
              verticalAnchor="middle"
              x={size / 2}
              y={size / 2 - 8}
              text={title}
              style={{ fontSize: 24, fontWeight: 700, fill: "#111" }}
            />
          )}
          {subtitle && (
            <VictoryLabel
              textAnchor="middle"
              verticalAnchor="middle"
              x={size / 2}
              y={size / 2 + 18}
              text={subtitle}
              style={{ fontSize: 12, fill: "#6b7280" }}
            />
          )}
        </svg>
      </div>

      {/* Legend */}
      <div className="mt-3 space-y-2">
        {data.map((slice) => (
          <div key={slice.label} className="flex items-center justify-between text-sm">
            <div className="flex items-center gap-2">
              <span className="size-3 rounded-sm flex-shrink-0" style={{ backgroundColor: slice.color }} />
              <span className="text-muted-foreground">{slice.label}</span>
            </div>
            <div className="flex items-center gap-3">
              <span className="font-medium">{slice.value.toLocaleString()}</span>
              <span className="text-xs text-muted-foreground w-10 text-right">
                {((slice.value / total) * 100).toFixed(1)}%
              </span>
            </div>
          </div>
        ))}
      </div>
    </div>
  )
}

For the Recharts alternative when a more familiar JSX component API tightly integrated with React state (not a standalone SVG render), built-in responsive container, and wider community examples are preferred — Recharts is the most popular React charting library for web-only apps while Victory’s primary advantage is the same API running in React Native, see the Recharts guide. For the D3.js alternative when completely custom SVG geometries, physics-based force layouts, geographic projections, or maximum control over every rendering detail is needed — D3 is the foundation Victory is built on, offering the lowest-level primitives while Victory provides pre-built chart components, see the D3.js guide. The Claude Skills 360 bundle includes Victory skill sets covering cross-platform charts, donut charts, and stacked bar charts. Start with the free tier to try React Native chart generation.

Keep Reading

Frontend

Claude Code for Chart.js Advanced: Custom Plugins and Mixed Charts

Advanced Chart.js patterns with Claude Code — chart.register() for tree-shaking, mixed chart types combining bar and line, custom plugin API with beforeDraw and afterDatasetsDraw hooks, ScriptableContext for computed colors, ChartDataLabels plugin for value labels, chartjs-plugin-zoom for pan and zoom, custom gradient fills via ctx.createLinearGradient, ChartJS annotation plugin for threshold lines, streaming data with chartjs-plugin-streaming, and react-chartjs-2 with useRef and chart instance.

6 min read Jun 27, 2027
Frontend

Claude Code for Nivo: Rich SVG and Canvas Charts

Build rich data visualizations with Nivo and Claude Code — ResponsiveLine and ResponsiveBar for adaptive charts, ResponsiveHeatMap for matrix data, ResponsiveTreeMap for hierarchal data, ResponsiveSunburst for nested proportions, ResponsiveChord for relationship diagrams, ResponsiveCalendar for activity heat maps, ResponsiveNetwork for force graphs, NivoTheme for consistent styling, tooltip customization with sliceTooltip, and motion config for spring animations.

6 min read Jun 26, 2027
Frontend

Claude Code for Luxon: Modern Date and Time Handling

Handle dates and times with Luxon and Claude Code — DateTime.now() and DateTime.fromISO(), DateTime.fromFormat() with custom parsing tokens, plus() and minus() for duration math, diff() between two DateTimes, startOf() and endOf() for range boundaries, setLocale() for locale-aware formatting, toRelative() for relative time strings, toISO() and toFormat() for output, Interval for date ranges, Duration for exact amounts, IANAZone for timezone conversion, and Settings.defaultLocale.

5 min read Jun 24, 2027

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free