Claude Code for Nivo: Rich SVG and Canvas Charts — Claude Skills 360 Blog
Blog / Frontend / Claude Code for Nivo: Rich SVG and Canvas Charts
Frontend

Claude Code for Nivo: Rich SVG and Canvas Charts

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

Nivo provides a rich set of chart types built on D3 — <ResponsiveBar data={data} keys={["value"]} indexBy="category"> renders bar charts. <ResponsiveLine data={series}> renders line charts. <ResponsiveHeatMap data={matrix} axisTop={...}> renders heatmaps. <ResponsiveTreeMap data={hierarchy} identity="name" value="size"> renders treemaps. <ResponsiveSunburst data={root}> renders multi-level donut charts. <ResponsiveCalendar data={days} from="2024-01-01" to="2024-12-31"> renders GitHub-style activity calendars. <ResponsiveChord data={matrix} keys={labels}> renders chord diagrams. <ResponsiveNetwork data={{ nodes, links }}> renders force-directed networks. Theming: const theme = { background: "#fff", text: { fontSize: 11 }, grid: { line: { stroke: "#f0f0f0" } } }. Motion: motionConfig="gentle". Custom tooltip: tooltip={({ id, value, color }) => <div>{id}: {value}</div>}. All Responsive* variants auto-fill their container. Claude Code generates Nivo heatmaps, sunburst charts, calendar views, and treemaps.

CLAUDE.md for Nivo

## Nivo Stack
- Version: @nivo/core >= 0.87, @nivo/bar, @nivo/line, @nivo/heatmap, @nivo/treemap (install each used)
- Responsive: wrap in <div className="h-[300px]"> and use Responsive* variants
- Theme: const nivoTheme: Theme = { background: "transparent", text: { fontSize: 11, fill: "hsl(var(--muted-foreground))" }, grid: { line: { stroke: "hsl(var(--border))" } }, axis: { ticks: { line: { stroke: "hsl(var(--border))" } } } }
- Tooltip: tooltip={({ datum }) => <div className="bg-popover border rounded-lg px-3 py-2 text-xs shadow-lg">{datum.label}: {datum.value}</div>}
- Motion: motionConfig="gentle" or motionConfig={{ mass: 1, tension: 170, friction: 26 }}

Nivo Bar and Line Charts

// components/charts/NivoDashboard.tsx — Nivo bar and line charts
"use client"
import { ResponsiveBar } from "@nivo/bar"
import { ResponsiveLine } from "@nivo/line"
import type { Theme, BarDatum, LineSvgProps } from "@nivo/core"

const NIVO_THEME: Theme = {
  background: "transparent",
  text: { fontSize: 11, fill: "#6b7280" },
  grid: { line: { stroke: "#f3f4f6", strokeWidth: 1 } },
  axis: {
    domain: { line: { stroke: "transparent" } },
    ticks: { line: { stroke: "#e5e7eb" }, text: { fill: "#6b7280", fontSize: 11 } },
  },
  crosshair: { line: { stroke: "#6366f1", strokeOpacity: 0.3, strokeWidth: 1 } },
  tooltip: {
    container: {
      background: "#fff",
      border: "1px solid #e5e7eb",
      borderRadius: "12px",
      boxShadow: "0 4px 24px rgba(0,0,0,.08)",
      padding: "8px 12px",
      fontSize: 12,
    },
  },
}

// ── Bar chart ────────────────────────────────────────────────────────────────

type BarData = { category: string; [metric: string]: number | string }

interface NivoBarChartProps {
  data: BarData[]
  keys: string[]
  colors?: string[]
  height?: number
  groupMode?: "grouped" | "stacked"
}

export function NivoBarChart({
  data,
  keys,
  colors = ["#6366f1", "#3b82f6", "#22c55e", "#f59e0b"],
  height = 300,
  groupMode = "grouped",
}: NivoBarChartProps) {
  return (
    <div style={{ height }} className="rounded-2xl border bg-card p-4">
      <ResponsiveBar
        data={data as BarDatum[]}
        keys={keys}
        indexBy="category"
        groupMode={groupMode}
        margin={{ top: 16, right: 16, bottom: 48, left: 56 }}
        padding={0.25}
        innerPadding={groupMode === "grouped" ? 4 : 0}
        colors={colors}
        borderRadius={4}
        axisLeft={{
          tickSize: 0,
          tickPadding: 8,
          format: (v) => `${Number(v).toLocaleString()}`,
        }}
        axisBottom={{
          tickSize: 0,
          tickPadding: 8,
        }}
        enableLabel={false}
        enableGridX={false}
        theme={NIVO_THEME}
        motionConfig="gentle"
        animate
      />
    </div>
  )
}

// ── Line chart ───────────────────────────────────────────────────────────────

type LineSeries = { id: string; color: string; data: { x: string; y: number }[] }

interface NivoLineChartProps {
  series: LineSeries[]
  height?: number
  enableArea?: boolean
}

export function NivoLineChart({ series, height = 300, enableArea = false }: NivoLineChartProps) {
  return (
    <div style={{ height }} className="rounded-2xl border bg-card p-4">
      <ResponsiveLine
        data={series}
        margin={{ top: 16, right: 24, bottom: 48, left: 56 }}
        xScale={{ type: "point" }}
        yScale={{ type: "linear", min: "auto", max: "auto", stacked: false }}
        curve="monotoneX"
        colors={series.map((s) => s.color)}
        lineWidth={2}
        pointSize={6}
        pointBorderWidth={2}
        pointBorderColor={{ from: "serieColor" }}
        pointColor="white"
        enableArea={enableArea}
        areaOpacity={0.1}
        enableGridX={false}
        axisLeft={{
          tickSize: 0,
          tickPadding: 8,
          format: (v) => `${Number(v).toLocaleString()}`,
        }}
        axisBottom={{ tickSize: 0, tickPadding: 8 }}
        useMesh
        theme={NIVO_THEME}
        motionConfig="gentle"
        legends={[{
          anchor: "bottom",
          direction: "row",
          justify: false,
          translateX: 0,
          translateY: 48,
          itemWidth: 100,
          itemHeight: 20,
          symbolShape: "circle",
          symbolSize: 8,
          itemTextColor: "#6b7280",
        }]}
      />
    </div>
  )
}

Heatmap and Calendar

// components/charts/NivoHeatmapCalendar.tsx — activity heatmap and calendar
"use client"
import { ResponsiveHeatMap } from "@nivo/heatmap"
import { ResponsiveCalendar } from "@nivo/calendar"

// ── Heatmap (matrix) ─────────────────────────────────────────────────────────

type HeatCell = { x: string; y: number }
type HeatRow = { id: string; data: HeatCell[] }

interface ActivityHeatmapProps {
  data: HeatRow[]
  height?: number
}

export function ActivityHeatmap({ data, height = 280 }: ActivityHeatmapProps) {
  return (
    <div style={{ height }} className="rounded-2xl border bg-card p-4">
      <ResponsiveHeatMap
        data={data}
        margin={{ top: 40, right: 24, bottom: 24, left: 80 }}
        axisTop={{
          tickSize: 0,
          tickPadding: 8,
          tickRotation: -30,
          legend: "",
        }}
        axisLeft={{
          tickSize: 0,
          tickPadding: 8,
        }}
        colors={{ type: "sequential", scheme: "purples" }}
        cellComponent="rect"
        emptyColor="#f9fafb"
        borderRadius={4}
        borderWidth={2}
        borderColor="#fff"
        enableLabels={false}
        animate
        motionConfig="gentle"
        tooltip={({ cell }) => (
          <div className="bg-white border rounded-lg px-3 py-2 text-xs shadow">
            <strong>{cell.serieId}</strong> / {cell.data.x}: <strong>{cell.value ?? "—"}</strong>
          </div>
        )}
      />
    </div>
  )
}

// ── Calendar (GitHub-style) ──────────────────────────────────────────────────

type CalDay = { day: string; value: number }

interface ActivityCalendarProps {
  data: CalDay[]
  from: string // "2024-01-01"
  to: string   // "2024-12-31"
  height?: number
}

export function ActivityCalendar({ data, from, to, height = 180 }: ActivityCalendarProps) {
  return (
    <div style={{ height }} className="rounded-2xl border bg-card p-4">
      <ResponsiveCalendar
        data={data}
        from={from}
        to={to}
        emptyColor="#f3f4f6"
        colors={["#c7d2fe", "#818cf8", "#6366f1", "#4338ca", "#312e81"]}
        margin={{ top: 24, right: 16, bottom: 8, left: 36 }}
        yearSpacing={40}
        monthBorderColor="#fff"
        dayBorderWidth={2}
        dayBorderColor="#fff"
        daySpacing={3}
        legends={[{
          anchor: "bottom-right",
          direction: "row",
          justify: false,
          itemCount: 5,
          itemWidth: 34,
          itemHeight: 36,
          itemsSpacing: 4,
          symbolSize: 20,
        }]}
        tooltip={({ day, value, color }) => (
          <div className="bg-white border rounded-lg px-3 py-2 text-xs shadow">
            <span style={{ color }}>{day}</span>: <strong>{value} contributions</strong>
          </div>
        )}
      />
    </div>
  )
}

Treemap

// components/charts/NivoTreemap.tsx — hierarchical treemap
"use client"
import { ResponsiveTreeMap } from "@nivo/treemap"

type TreeNode = { name: string; value?: number; color?: string; children?: TreeNode[] }

interface NivoTreemapProps {
  data: TreeNode
  height?: number
}

export function NivoTreemap({ data, height = 340 }: NivoTreemapProps) {
  return (
    <div style={{ height }} className="rounded-2xl border bg-card overflow-hidden">
      <ResponsiveTreeMap
        data={data}
        identity="name"
        value="value"
        valueFormat=".02s"
        innerPadding={4}
        outerPadding={8}
        colors={{ scheme: "purples" }}
        borderWidth={2}
        borderColor={{ from: "color", modifiers: [["darker", 0.3]] }}
        labelSkipSize={16}
        label={({ node }) => node.data.name}
        labelTextColor={{ from: "color", modifiers: [["darker", 3]] }}
        parentLabelSize={24}
        parentLabelTextColor={{ from: "color", modifiers: [["darker", 2]] }}
        animate
        motionConfig="gentle"
        tooltip={({ node }) => (
          <div className="bg-white border rounded-lg px-3 py-2 text-xs shadow">
            <strong>{node.data.name}</strong>: {node.formattedValue}
          </div>
        )}
      />
    </div>
  )
}

For the Recharts alternative when a simpler React JSX component API, smaller bundle (no need for all chart types), and more community tutorials are preferred — Recharts covers Bar, Line, Area, Pie, and Scatter charts with less setup while Nivo excels for specialized chart types like heatmaps, treemaps, sunbursts, chord diagrams, and calendars that Recharts doesn’t offer, see the Recharts guide. For the D3.js alternative when the exact visual output and rendering performance must be controlled at every pixel — Nivo wraps D3 internally; drop down to raw D3 only when Nivo’s layout algorithms aren’t customizable enough for a specific visualization, see the D3.js guide. The Claude Skills 360 bundle includes Nivo skill sets covering heatmaps, treemaps, calendars, and chord diagrams. Start with the free tier to try specialized 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 Victory Charts: React Native and Web Charts

Build cross-platform charts with Victory and Claude Code — VictoryChart, VictoryLine, VictoryBar, and VictoryScatter for web and React Native, VictoryPie for donut charts, VictoryArea for stacked areas, VictoryAxis for custom axes, VictoryTooltip and VictoryVoronoiContainer for hover tooltips, VictoryBrushContainer for range selection, VictoryZoomContainer for pan and zoom, VictoryLegend for series labels, custom theme with VictoryTheme, and VictoryStack for grouped bars.

6 min read Jun 25, 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