Claude
Skills
Sign in
Back

data-visualizer

Included with Lifetime
$97 forever

Expert in creating charts, dashboards, and data visualizations using modern libraries

Generaldata-vizchartsdashboardsd3rechartsanalytics

What this skill does


# Data Visualizer Skill

I help you build beautiful, interactive data visualizations and dashboards.

## What I Do

**Chart Creation:**

- Line charts, bar charts, pie charts
- Area charts, scatter plots, heatmaps
- Complex visualizations (Sankey, treemaps, network graphs)

**Dashboard Building:**

- KPI cards and metrics
- Real-time data dashboards
- Interactive filters and drill-downs
- Responsive layouts

**Data Presentation:**

- Data storytelling
- Color schemes and accessibility
- Animation and interactions
- Export capabilities

## Library Selection Guide

### Recharts (Recommended for React)

**Best for:**

- Quick, simple charts
- React/Next.js projects
- Standard chart types
- Responsive design

**Example:**

```typescript
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts'

const data = [
  { month: 'Jan', revenue: 4000, expenses: 2400 },
  { month: 'Feb', revenue: 3000, expenses: 1398 },
  { month: 'Mar', revenue: 2000, expenses: 9800 },
]

function RevenueChart() {
  return (
    <LineChart width={600} height={300} data={data}>
      <CartesianGrid strokeDasharray="3 3" />
      <XAxis dataKey="month" />
      <YAxis />
      <Tooltip />
      <Legend />
      <Line type="monotone" dataKey="revenue" stroke="#8884d8" />
      <Line type="monotone" dataKey="expenses" stroke="#82ca9d" />
    </LineChart>
  )
}
```

---

### Chart.js (Recommended for Vue/Angular)

**Best for:**

- Framework-agnostic
- Simple API
- Good documentation
- Standard chart types

**Example:**

```typescript
import { Chart } from 'chart.js/auto'

const ctx = document.getElementById('myChart')
const chart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    datasets: [
      {
        label: 'Sales',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: 'rgba(54, 162, 235, 0.5)'
      }
    ]
  },
  options: {
    responsive: true,
    plugins: {
      legend: { position: 'top' },
      title: { display: true, text: 'Monthly Sales' }
    }
  }
})
```

---

### D3.js (Advanced)

**Best for:**

- Custom visualizations
- Complex interactions
- Full control over rendering
- Data-driven documents

**When to use:**

- Need custom chart type
- Complex data transformations
- Advanced interactions
- Publication-quality graphics

**Example:**

```typescript
import * as d3 from 'd3'

function createBarChart(data: Array<{ name: string; value: number }>) {
  const width = 600
  const height = 400
  const margin = { top: 20, right: 20, bottom: 30, left: 40 }

  const svg = d3.select('#chart').append('svg').attr('width', width).attr('height', height)

  const x = d3
    .scaleBand()
    .domain(data.map(d => d.name))
    .range([margin.left, width - margin.right])
    .padding(0.1)

  const y = d3
    .scaleLinear()
    .domain([0, d3.max(data, d => d.value)])
    .range([height - margin.bottom, margin.top])

  svg
    .selectAll('rect')
    .data(data)
    .join('rect')
    .attr('x', d => x(d.name))
    .attr('y', d => y(d.value))
    .attr('height', d => y(0) - y(d.value))
    .attr('width', x.bandwidth())
    .attr('fill', 'steelblue')

  // Add axes
  svg
    .append('g')
    .attr('transform', `translate(0,${height - margin.bottom})`)
    .call(d3.axisBottom(x))

  svg.append('g').attr('transform', `translate(${margin.left},0)`).call(d3.axisLeft(y))
}
```

---

## Dashboard Patterns

### Pattern 1: KPI Dashboard

**Use case:** Executive dashboard with key metrics

```typescript
// components/KPIDashboard.tsx
import { Card } from '@/components/ui/card'

interface KPICardProps {
  title: string
  value: string | number
  change: number
  trend: 'up' | 'down'
}

function KPICard({ title, value, change, trend }: KPICardProps) {
  const trendColor = trend === 'up' ? 'text-green-600' : 'text-red-600'
  const trendIcon = trend === 'up' ? '↑' : '↓'

  return (
    <Card className="p-6">
      <h3 className="text-sm font-medium text-gray-600">{title}</h3>
      <div className="mt-2 flex items-baseline">
        <p className="text-3xl font-semibold">{value}</p>
        <span className={`ml-2 text-sm ${trendColor}`}>
          {trendIcon} {Math.abs(change)}%
        </span>
      </div>
    </Card>
  )
}

export default function Dashboard() {
  return (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
      <KPICard title="Total Revenue" value="$45,231" change={12.5} trend="up" />
      <KPICard title="Active Users" value="2,350" change={-5.2} trend="down" />
      <KPICard title="Conversion Rate" value="3.24%" change={8.1} trend="up" />
      <KPICard title="Avg Order Value" value="$158" change={2.3} trend="up" />
    </div>
  )
}
```

---

### Pattern 2: Real-Time Dashboard

**Use case:** Live data monitoring

```typescript
// components/RealtimeDashboard.tsx
'use client'

import { useEffect, useState } from 'react'
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'

interface DataPoint {
  time: string
  value: number
}

export default function RealtimeDashboard() {
  const [data, setData] = useState<DataPoint[]>([])

  useEffect(() => {
    // Fetch initial data
    fetch('/api/metrics/realtime')
      .then(res => res.json())
      .then(setData)

    // Subscribe to real-time updates
    const eventSource = new EventSource('/api/metrics/stream')

    eventSource.onmessage = (event) => {
      const newDataPoint = JSON.parse(event.data)

      setData(prev => {
        const updated = [...prev, newDataPoint]
        // Keep last 20 data points
        return updated.slice(-20)
      })
    }

    return () => eventSource.close()
  }, [])

  return (
    <div className="p-6 bg-white rounded-lg shadow">
      <h2 className="text-xl font-bold mb-4">Live Traffic</h2>
      <ResponsiveContainer width="100%" height={300}>
        <LineChart data={data}>
          <XAxis dataKey="time" />
          <YAxis />
          <Tooltip />
          <Line
            type="monotone"
            dataKey="value"
            stroke="#8884d8"
            strokeWidth={2}
            dot={false}
            isAnimationActive={false}
          />
        </LineChart>
      </ResponsiveContainer>
    </div>
  )
}
```

**API Route for SSE:**

```typescript
// app/api/metrics/stream/route.ts
export async function GET(req: Request) {
  const encoder = new TextEncoder()

  const stream = new ReadableStream({
    async start(controller) {
      const interval = setInterval(async () => {
        const value = Math.floor(Math.random() * 100)
        const time = new Date().toLocaleTimeString()

        const data = `data: ${JSON.stringify({ time, value })}\n\n`
        controller.enqueue(encoder.encode(data))
      }, 1000)

      // Cleanup on close
      req.signal.addEventListener('abort', () => {
        clearInterval(interval)
        controller.close()
      })
    }
  })

  return new Response(stream, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive'
    }
  })
}
```

---

### Pattern 3: Interactive Dashboard with Filters

```typescript
// components/SalesDashboard.tsx
'use client'

import { useState } from 'react'
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'

type Period = '7d' | '30d' | '90d'
type Region = 'all' | 'us' | 'eu' | 'asia'

export default function SalesDashboard() {
  const [period, setPeriod] = useState<Period>('30d')
  const [region, setRegion] = useState<Region>('all')

  const { data, loading } = useSalesData({ period, region })

  return (
    <div className="space-y-6">
      {/* Filters */}
      <div className="flex gap-4">
        <select
          value={period}
          onChange={(e) => setPeriod(e.target.value as Period)}
          className="px-4 py-2 border rounded"
        >
          <option value="7d">Last 7 days</option>
          <option value="30d">Last 30 days</option>
          <option value="90d">L
Files: 3
Size: 20.2 KB
Complexity: 30/100
Category: General

Related in General