JSPM

  • Created
  • Published
  • Downloads 53
  • Score
    100M100P100Q73212F
  • License MIT

AI-powered CSV analysis, chart generation, and interactive visualization. Parse CSV, detect anomalies, suggest charts, and ask questions about your data using any LLM provider.

Package Exports

  • csv-charts-ai

Readme

csv-charts-ai

AI-powered CSV analysis, chart generation, and interactive visualization. Built on the Vercel AI SDK and Recharts.

Works with any LLM provider — OpenAI, Anthropic, Google, Mistral, Ollama, or any OpenAI-compatible endpoint.

Installation

pnpm add csv-charts-ai ai zod

Peer dependencies: ai, zod (required). react, recharts, lucide-react (optional — only needed for React chart components).

Quick Start

import { parseCSV, analyzeData, suggestQuestions } from "csv-charts-ai";

// 1. Parse CSV string into structured data
const data = parseCSV(`name,age,city,salary
Alice,30,Paris,75000
Bob,25,London,62000
Charlie,35,Berlin,88000`);

// 2. Run full AI analysis (summary + anomalies + charts) in parallel
const result = await analyzeData({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
});

console.log(result.summary.keyInsights);
console.log(`Found ${result.anomalies.length} anomalies`);
console.log(`Generated ${result.charts.length} chart suggestions`);

// 3. Suggest questions the user could ask
const questions = await suggestQuestions({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
});
questions.forEach(q => console.log(`[${q.category}] ${q.question}`));

CSV Parsing

Parse CSV strings into the TabularData format with automatic delimiter detection and column type inference.

import { parseCSV } from "csv-charts-ai";

// Auto-detects delimiter (comma, semicolon, tab, pipe)
const data = parseCSV(csvString);

// Explicit options
const data = parseCSV(csvString, {
  delimiter: ";",
  hasHeader: true,
  skipEmpty: true,
});

console.log(data.headers);   // ["name", "age", "city"]
console.log(data.rowCount);  // 100
console.log(data.columns);   // [{ name: "name", type: "string", index: 0 }, ...]

Type inference detects string, number, date, and boolean columns by sampling values. Handles quoted fields, escaped quotes, multi-line values, and BOM stripping (RFC 4180).

For very large files or exotic encodings, consider using PapaParse and passing the result as TabularData directly.

AI Functions

All AI functions accept either a simple config object or a pre-built LanguageModel from the Vercel AI SDK. All support an optional signal (AbortSignal) for cancellation.

Chart Suggestions

import { suggestCharts } from "csv-charts-ai";

// Simple — OpenAI
const charts = await suggestCharts({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
});

// Custom endpoint — Ollama / vLLM / LM Studio
const charts = await suggestCharts({
  model: { apiKey: "", model: "llama3", baseURL: "http://localhost:11434/v1" },
  data,
});

// Other providers — Anthropic, Google, Mistral
const charts = await suggestCharts({
  model: { apiKey: "sk-ant-...", model: "claude-sonnet-4-20250514", provider: "anthropic" },
  data,
});

// Advanced — any LanguageModel instance
import { anthropic } from "@ai-sdk/anthropic";
const charts = await suggestCharts({
  model: anthropic("claude-sonnet-4-20250514"),
  data,
  language: "French",
});

Custom Chart from Prompt

import { suggestCustomChart } from "csv-charts-ai";

const chart = await suggestCustomChart({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  prompt: "Show me a bar chart of revenue by category",
});

Repair a Broken Chart

import { repairChart } from "csv-charts-ai";

const fixed = await repairChart({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  failedChart: brokenChart,
  columns: ["name", "sales", "date"],
  errorContext: "Column 'revenue' does not exist",
});

Data Summary

import { summarizeData } from "csv-charts-ai";

const result = await summarizeData({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
});

console.log(result.summary);      // "This dataset contains sales records..."
console.log(result.keyInsights);   // ["Revenue peaks in Q4", "Product A leads..."]
console.log(result.dataQuality);   // "Good completeness, 2 missing values in..."

Anomaly Detection

import { detectAnomalies } from "csv-charts-ai";

const anomalies = await detectAnomalies({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  maxRows: 100, // default: 50
});

anomalies.forEach(a =>
  console.log(`[${a.severity}] Row ${a.row}, ${a.column}: ${a.issue}`)
);

Ask Questions About Data

import { askAboutData, streamAskAboutData } from "csv-charts-ai";

// Non-streaming
const answer = await askAboutData({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  question: "What is the average revenue by region?",
  history: [{ prompt: "How many rows?", response: "There are 1000 rows." }],
});

// Streaming
await streamAskAboutData({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  question: "What trends do you see?",
  onChunk: (chunk) => process.stdout.write(chunk),
  onComplete: (full) => console.log("\nDone:", full.length, "chars"),
});

Suggest Questions

import { suggestQuestions } from "csv-charts-ai";

const questions = await suggestQuestions({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  count: 5,
});

questions.forEach(q => console.log(`[${q.category}] ${q.question}`));
// [trend] How has revenue changed month over month?
// [comparison] Which region has the highest average order value?
// [correlation] Is there a relationship between marketing spend and sales?

Full Analysis Pipeline

Runs summary, anomaly detection, and chart suggestions in parallel:

import { analyzeData } from "csv-charts-ai";

const result = await analyzeData({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  detectAnomalies: true,  // default: true
  suggestCharts: true,    // default: true
});

// result.summary   — DataSummaryResult
// result.anomalies — AnomalyResult[]
// result.charts    — ChartConfig[]

Cancellation (AbortSignal)

All AI functions support signal for cancellation — essential for React cleanup and timeouts:

const controller = new AbortController();

const charts = await suggestCharts({
  model: { apiKey: "sk-...", model: "gpt-4o" },
  data,
  signal: controller.signal,
});

// Cancel from elsewhere
controller.abort();

React example:

useEffect(() => {
  const controller = new AbortController();
  analyzeData({ model, data, signal: controller.signal })
    .then(setResult)
    .catch(() => {});
  return () => controller.abort();
}, [data]);

React Components

Requires react, recharts, lucide-react, and Tailwind CSS for styling.

Display Charts

import { ChartDisplay } from "csv-charts-ai";

<ChartDisplay data={data} charts={charts} />

With Theme

import { ChartDisplay, defaultLightTheme } from "csv-charts-ai";

<ChartDisplay data={data} charts={charts} theme={defaultLightTheme} />

Custom Card Wrapper

<ChartDisplay
  data={data}
  charts={charts}
  cardWrapper={({ children, title }) => (
    <div className="my-card">
      <h2>{title}</h2>
      {children}
    </div>
  )}
  onRegenerate={async (chart) => {
    const fixed = await repairChart({ model, failedChart: chart, columns: data.headers, errorContext: "Rendering failed" });
    // update state with fixed chart
  }}
/>

Unstyled Mode (No Tailwind Required)

Pass unstyled to strip all built-in Tailwind classes and style components yourself:

<ChartDisplay
  data={data}
  charts={charts}
  unstyled
  className="my-charts-container"
  chartClassName="my-chart-card"
  titleClassName="my-chart-title"
/>

You can also pass className to any component to add classes alongside the built-in ones:

<ChartDisplay data={data} charts={charts} className="my-extra-class" />

Headless Usage (No React)

The AI functions and CSV parsing work without React — use them in Node.js scripts, APIs, or CLI tools:

import { parseCSV, analyzeData } from "csv-charts-ai";
import { readFileSync } from "fs";

const csv = readFileSync("sales.csv", "utf-8");
const data = parseCSV(csv);

const result = await analyzeData({
  model: { apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4o" },
  data,
});

console.log(result.summary.keyInsights);

Components Reference

Export Description
ChartDisplay Multi-chart container with optional card wrapper and theme
SingleChart Individual chart with toolbar (sort, zoom, trendline, CSV/PNG export)
ChartToolbar Standalone toolbar component
ChartThemeProvider React context for chart theming
defaultDarkTheme / defaultLightTheme Built-in themes

AI Functions Reference

Export Description
suggestCharts(options) Generate 2-4 chart suggestions from data
suggestCustomChart(options) Generate a single chart from a text prompt
repairChart(options) Fix a chart config that failed to render
summarizeData(options) AI-generated data summary with key insights
detectAnomalies(options) Find outliers, missing values, type mismatches
askAboutData(options) Ask natural language questions about data
streamAskAboutData(options) Streaming version of askAboutData
suggestQuestions(options) Suggest interesting questions to ask about the data
analyzeData(options) Full pipeline: summary + anomalies + charts in parallel

Utilities Reference

Export Description
parseCSV(csv, options?) Parse CSV string into TabularData
createModel(config) Create a LanguageModel from an AIConfig
resolveModel(input) Resolve AIConfig or LanguageModel to LanguageModel
summarizeTabularData(data) Generate text summary for AI consumption
getAIErrorMessage(error) Extract user-friendly error messages
processChartData(data, chart) Process and aggregate chart data
processChartDataMultiSeries(data, chart) Multi-series data processing
COLORS Default 8-color palette

Validation Schemas

Export Description
AIConfigSchema Zod schema for validating AI config objects
TabularDataSchema Zod schema for validating TabularData input

Chart Types

bar | line | area | scatter | pie

Multi-series supported via groupBy for bar, line, and area charts.

Aggregation Types

sum | avg | count | min | max | none

Provider Support

Provider Config Extra install
OpenAI { apiKey, model } None (bundled)
Ollama / vLLM / LM Studio { apiKey: "", model, baseURL } None
Mistral (via OpenAI compat) { apiKey, model, baseURL: "https://api.mistral.ai/v1" } None
Anthropic { provider: "anthropic", apiKey, model } @ai-sdk/anthropic
Google { provider: "google", apiKey, model } @ai-sdk/google
Any LanguageModel Pass instance directly Provider SDK

License

MIT