Charts & Data Visualization

Recharts-based chart library with area, bar, line, pie, and radial charts — all theme-aware, responsive, and composable with dashboard widgets.

Last updated: 2025-02-18

Charts & Data Visualization

Certexi's chart library is built on Recharts with custom Tailwind CSS theming. All charts respond to dark mode, resize fluidly, and compose into dashboard widgets.

certexi.com/app/dashboard/kpi
Loading interactive demo...

KPI dashboard — animated counters, utilization trends, and throughput charts built entirely from library components.

Chart Types

ChartUse CaseComponent
AreaTrends over time (throughput, utilization)AreaChart
BarCategory comparison (zone occupancy, incidents)BarChart
LineMulti-series trends (temperature, weight)LineChart
PieDistribution (asset types, event types)PieChart
RadialSingle-value gauge (compliance score)RadialBarChart
ComposedMixed chart types on one axisComposedChart

Utilization Trend Chart

Track zone utilization over time. The area gradient uses CSS custom properties so it adapts to light and dark themes automatically.

<Card className="w-full">
  <CardHeader className="pb-2">
    <CardTitle className="text-sm">Weekly Utilization Trend</CardTitle>
    <CardDescription>Zone A — Storage</CardDescription>
  </CardHeader>
  <CardContent>
    <div className="space-y-2">
      <div className="flex items-center justify-between text-xs text-muted-foreground">
        <span>Mon</span><span>Tue</span><span>Wed</span><span>Thu</span><span>Fri</span><span>Sat</span><span>Sun</span>
      </div>
      <div className="flex items-end gap-1 h-24">
        <div className="flex-1 bg-blue-500/20 rounded-t" style={{height: '60%'}} />
        <div className="flex-1 bg-blue-500/30 rounded-t" style={{height: '72%'}} />
        <div className="flex-1 bg-blue-500/40 rounded-t" style={{height: '85%'}} />
        <div className="flex-1 bg-blue-500/50 rounded-t" style={{height: '78%'}} />
        <div className="flex-1 bg-blue-500/60 rounded-t" style={{height: '92%'}} />
        <div className="flex-1 bg-blue-500/40 rounded-t" style={{height: '65%'}} />
        <div className="flex-1 bg-blue-500/20 rounded-t" style={{height: '45%'}} />
      </div>
      <div className="flex justify-between text-xs">
        <span className="text-muted-foreground">Avg: 71%</span>
        <Badge variant="outline">Peak: 92%</Badge>
      </div>
    </div>
  </CardContent>
</Card>

Throughput Bar Chart

Daily throughput of transport units processed — compare across days with color-coded status.

<Card className="w-full">
  <CardHeader className="pb-2">
    <CardTitle className="text-sm">Daily Throughput</CardTitle>
    <CardDescription>Transport units processed</CardDescription>
  </CardHeader>
  <CardContent>
    <div className="space-y-1.5">
      <div className="flex items-center gap-2">
        <span className="text-xs w-8 text-muted-foreground">Mon</span>
        <div className="flex-1 h-5 bg-muted rounded overflow-hidden">
          <div className="h-full bg-green-500 rounded" style={{width: '82%'}} />
        </div>
        <span className="text-xs w-8 text-right">164</span>
      </div>
      <div className="flex items-center gap-2">
        <span className="text-xs w-8 text-muted-foreground">Tue</span>
        <div className="flex-1 h-5 bg-muted rounded overflow-hidden">
          <div className="h-full bg-green-500 rounded" style={{width: '91%'}} />
        </div>
        <span className="text-xs w-8 text-right">182</span>
      </div>
      <div className="flex items-center gap-2">
        <span className="text-xs w-8 text-muted-foreground">Wed</span>
        <div className="flex-1 h-5 bg-muted rounded overflow-hidden">
          <div className="h-full bg-amber-500 rounded" style={{width: '68%'}} />
        </div>
        <span className="text-xs w-8 text-right">136</span>
      </div>
      <div className="flex items-center gap-2">
        <span className="text-xs w-8 text-muted-foreground">Thu</span>
        <div className="flex-1 h-5 bg-muted rounded overflow-hidden">
          <div className="h-full bg-green-500 rounded" style={{width: '95%'}} />
        </div>
        <span className="text-xs w-8 text-right">190</span>
      </div>
      <div className="flex items-center gap-2">
        <span className="text-xs w-8 text-muted-foreground">Fri</span>
        <div className="flex-1 h-5 bg-muted rounded overflow-hidden">
          <div className="h-full bg-green-500 rounded" style={{width: '88%'}} />
        </div>
        <span className="text-xs w-8 text-right">176</span>
      </div>
    </div>
  </CardContent>
</Card>

Incident Distribution

Visualize incident categories across the facility as a segmented breakdown.

<Card className="w-72">
  <CardHeader className="pb-2">
    <CardTitle className="text-sm">Incidents by Type</CardTitle>
    <CardDescription>Last 30 days</CardDescription>
  </CardHeader>
  <CardContent className="space-y-3">
    <div className="flex h-4 rounded-full overflow-hidden">
      <div className="bg-red-500" style={{width: '35%'}} />
      <div className="bg-amber-500" style={{width: '25%'}} />
      <div className="bg-blue-500" style={{width: '22%'}} />
      <div className="bg-gray-400" style={{width: '18%'}} />
    </div>
    <div className="grid grid-cols-2 gap-2 text-xs">
      <div className="flex items-center gap-1.5">
        <div className="w-2.5 h-2.5 rounded-full bg-red-500" />
        <span>Weight variance (35%)</span>
      </div>
      <div className="flex items-center gap-1.5">
        <div className="w-2.5 h-2.5 rounded-full bg-amber-500" />
        <span>Missing evidence (25%)</span>
      </div>
      <div className="flex items-center gap-1.5">
        <div className="w-2.5 h-2.5 rounded-full bg-blue-500" />
        <span>Seal mismatch (22%)</span>
      </div>
      <div className="flex items-center gap-1.5">
        <div className="w-2.5 h-2.5 rounded-full bg-gray-400" />
        <span>Other (18%)</span>
      </div>
    </div>
  </CardContent>
</Card>

Architecture

All charts follow the same composition pattern:

Loading diagram…

Gauge / Compliance Score

A radial progress indicator for single-value metrics like compliance percentage.

<Card className="w-48">
  <CardContent className="pt-6 flex flex-col items-center">
    <div className="relative w-28 h-28">
      <svg className="w-full h-full -rotate-90" viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="42" fill="none" stroke="currentColor" strokeWidth="8" className="text-muted" />
        <circle cx="50" cy="50" r="42" fill="none" stroke="currentColor" strokeWidth="8" className="text-green-500" strokeDasharray="264" strokeDashoffset="40" strokeLinecap="round" />
      </svg>
      <div className="absolute inset-0 flex items-center justify-center">
        <span className="text-2xl font-bold">85%</span>
      </div>
    </div>
    <p className="text-sm text-muted-foreground mt-2">Compliance Score</p>
  </CardContent>
</Card>

Usage

import {
  AreaChart, Area, XAxis, YAxis, CartesianGrid,
  Tooltip, ResponsiveContainer
} from 'recharts';

// Wrap in ResponsiveContainer for fluid sizing
<ResponsiveContainer width="100%" height={300}>
  <AreaChart data={utilizationData}>
    <CartesianGrid strokeDasharray="3 3" />
    <XAxis dataKey="date" />
    <YAxis />
    <Tooltip />
    <Area
      type="monotone"
      dataKey="utilization"
      stroke="hsl(var(--primary))"
      fill="hsl(var(--primary) / 0.2)"
    />
  </AreaChart>
</ResponsiveContainer>

Theming

All charts use CSS custom properties from the design system:

TokenUsage
--primaryDefault series color
--destructiveError/alert series
--mutedGrid lines, axis
--foregroundLabels, text
--chart-1 through --chart-5Multi-series palette

Charts automatically adapt when the user toggles dark mode.