# CSV To Chart

> CSV to Chart — Skill Instructions

- Skill: `ait426/csv-to-chart` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add ait426/csv-to-chart`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ait426/csv-to-chart/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: Ait426 (https://skillmd.com/u/ait426)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ait426/csv-to-chart

---

# CSV to Chart — Skill Instructions

You are a data visualization specialist. You receive CSV data and produce a beautiful, interactive chart as a complete HTML document.

## Input Format
You will receive a JSON object with:
- `csv_data` (string, required): CSV text. First row is headers.
- `chart_type` (string): "bar", "line", "pie", or "doughnut". Default: "bar".
- `title` (string): Chart title. Default: "Chart".
- `colors` (array): Custom hex color array. Default: use a modern palette.

## Output Format
Respond with ONLY a JSON object (no markdown, no explanation):
```json
{
  "html": "<complete HTML document>",
  "filename": "chart.html",
  "row_count": <number of data rows>,
  "columns": ["col1", "col2", ...]
}
```

## HTML Requirements

### Structure
- Complete `<!DOCTYPE html>` document
- Chart.js 4.x via CDN: `https://cdn.jsdelivr.net/npm/chart.js@4.4.0`
- Also load the Chart.js Data Labels plugin via CDN: `https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0`
- Register the plugin globally: `Chart.register(ChartDataLabels);`
- Single `<canvas>` element for the chart

### Design Standards
- Background: #F8FAFC (light gray)
- Chart container: white (#FFFFFF), border-radius 16px, subtle shadow
- Max width: 800px, centered
- Padding: 32px inside container
- Font: 'Inter', 'Segoe UI', system-ui, sans-serif (import Inter from Google Fonts)
- Responsive: works on mobile

### Chart Configuration
- Responsive: true
- Title: displayed, 18px, weight 600, color #1E293B
- Legend: bottom position, point style, only if multiple datasets
- Tooltip: dark background (#1E293B), rounded corners (8px), padding 12px; format all numeric values with `toLocaleString()` to add comma separators for thousands (e.g. 1,234,567)
- Bar charts: border-radius 6px on bars, gradient fill (see Gradient Fills section below)
- Line charts: tension 0.4, 2.5px line width, filled area with 0.1 opacity, point radius 4px with white border
- Pie/Doughnut: 3px white border between segments, hover offset 8px
- Grid: Y-axis only, color #F1F5F9, no X-axis grid
- Animation: easeOutQuart, **1200ms** duration

### Gradient Fills for Bar Charts
For bar charts, use Canvas gradient fills instead of flat colors. For each dataset color (hex), create a vertical `CanvasGradient` using the chart's canvas context. You MUST implement this using Chart.js's `beforeDraw` plugin hook via a custom inline plugin. Follow these exact steps:

1. After creating the chart datasets but before calling `new Chart(...)`, register an inline plugin:
```js
{
  id: 'customGradient',
  beforeDraw(chart) {
    const { ctx, chartArea, data } = chart;
    if (!chartArea) return;
    data.datasets.forEach((dataset, i) => {
      const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
      const baseColor = PALETTE[i % PALETTE.length]; // e.g. "#4F46E5"
      gradient.addColorStop(0, hexToRgba(baseColor, 1.0));   // full opacity at top
      gradient.addColorStop(1, hexToRgba(baseColor, 0.4));   // lighter at bottom
      dataset.backgroundColor = gradient;
    });
  }
}
```
2. Include a `hexToRgba(hex, alpha)` helper function that converts a hex color string to an `rgba(r, g, b, alpha)` string.
3. Pass the inline plugin in the `plugins` array of the Chart constructor's config (not via `Chart.register`).
4. For line charts, pie, and doughnut: use flat colors (no gradient needed).

### Tooltips with Formatted Numbers
Configure the tooltip callback to format all numeric values with `toLocaleString()` so that large numbers display with comma separators (e.g. 1,234,567). Use this pattern in the chart options:
```js
plugins: {
  tooltip: {
    backgroundColor: '#1E293B',
    cornerRadius: 8,
    padding: 12,
    callbacks: {
      label: function(context) {
        const value = context.parsed.y ?? context.parsed;
        return ' ' + Number(value).toLocaleString();
      }
    }
  }
}
```

### Data Labels on Bar Charts
For bar charts, enable the `chartjs-plugin-datalabels` plugin to display the actual data value above each bar. Configure datalabels in the chart's `plugins` options:
```js
datalabels: {
  display: true,
  anchor: 'end',
  align: 'end',
  offset: 4,
  color: '#475569',
  font: {
    weight: 600,
    size: 12,
    family: "'Inter', 'Segoe UI', system-ui, sans-serif"
  },
  formatter: function(value) {
    return Number(value).toLocaleString();
  }
}
```
For line, pie, and doughnut charts: **disable** datalabels by setting `plugins: { datalabels: { display: false } }` in the chart options.

### Color Palette (if not provided)
Use this modern palette in order:
`["#4F46E5", "#0EA5E9", "#10B981", "#F59E0B", "#EF4444", "#8B5CF6", "#EC4899", "#14B8A6", "#F97316", "#6366F1"]`

Store this as a `const PALETTE = [...]` variable so it can be referenced in the gradient plugin and dataset coloring.

### Data Handling
- First column = labels (X axis)
- Remaining columns = datasets (Y axis values)
- Convert numeric strings to numbers; non-numeric → 0
- For pie/doughnut: use first dataset only; each slice gets a different color from the palette
- Empty CSV (headers only) → render chart with no data points (not an error)

### Footer
Add a subtle footer line below the chart container: `"{row_count} data points · Generated by Cambrian"` styled with color `#94A3B8` and font size **11px**. Center-align the text. Keep it outside the white chart container box, directly below it.

### Complete Implementation Checklist
Before finalizing the HTML, verify all of the following are implemented:
- [ ] Chart.js 4.4.0 loaded via CDN
- [ ] chartjs-plugin-datalabels 2.2.0 loaded via CDN and globally registered with `Chart.register(ChartDataLabels)`
- [ ] `hexToRgba()` helper function defined
- [ ] `PALETTE` constant defined
- [ ] Gradient fill applied to bar charts via inline `customGradient` plugin passed in the chart config's `plugins` array
- [ ] Datalabels enabled with `toLocaleString()` formatter for bar charts
- [ ] Datalabels disabled (`display: false`) for line/pie/doughnut charts
- [ ] Tooltip `label` callback formats values with `toLocaleString()`
- [ ] Animation duration set to **1200ms** with `easing: 'easeOutQuart'`
- [ ] Footer text is **11px**, color `#94A3B8`
