Dynamic Charts by Prompt

Generate interactive Chart.js dashboards from natural language prompts, powered by Anthropic Claude and streamed in real time.

Next.js 15 · Chart.js · AI-Powered

How It Works

User types prompt API streams to Claude JSONL response json-render parses Chart.js dashboard

Type a natural language description of the data you want to visualize. The system streams an AI-generated component tree that renders as an interactive, drag-and-drop dashboard with charts and metric cards.

Tech Stack

Layer Technology
Framework Next.js 15 (App Router, Turbopack) + React 19
AI Vercel AI SDK v6 + Anthropic Claude
Rendering @json-render/core + @json-render/react + @json-render/shadcn
Charts Chart.js 4 + react-chartjs-2 + chartjs-plugin-zoom
Styling Tailwind CSS v4
Validation Zod

Chart Types

Line Chart

Time series and trend data. Supports multiple datasets with independent y-axes.

Bar Chart

Categorical comparisons. Supports grouped and stacked configurations.

Pie Chart

Proportional data as a full circle. Best for parts of a whole (up to ~7 segments).

Doughnut Chart

Hollow center variant of pie chart. Display a summary metric in the center.

Area Chart

Line chart with filled area. Good for volume or cumulative values over time.

Radar Chart

Multivariate data on radial axes. Compare entities across several dimensions.

Architecture

Request Flow

  1. Client (page.tsx) — Uses useUIStream from @json-render/react to manage the streaming connection. Sends POST to /api/generate.
  2. API Route (api/generate/route.ts) — Builds a system prompt via catalog.prompt(), calls streamText with the Anthropic provider, streams the response back.
  3. AI Response — Claude generates JSONL describing a component tree. Each line is a UI component with props and data.
  4. Rendering (dashboard-renderer.tsx) — Receives the parsed tree, maps component names to React components via the registry, renders Chart.js charts in a resizable grid.

SSR Considerations

Dependency Issue Solution
chartjs-plugin-zoom Accesses window Dynamic import with ssr: false
@json-render/shadcn Includes React context Use /catalog subpath in server code
@json-render/react Uses React context Use /schema subpath in server code

Key Files

File Responsibility
src/app/page.tsx Client entry, streaming UI
src/app/api/generate/route.ts AI streaming endpoint
src/lib/catalog.ts json-render catalog definition
src/lib/registry.tsx Client-side component registry
src/lib/chart-schemas.ts Zod schemas for chart props
src/lib/chartjs-setup.ts Chart.js plugin registration
src/components/dashboard-renderer.tsx Dynamic renderer (no SSR)

Component Catalog

Chart Components

All chart components live in src/components/charts/. They accept Chart.js configuration as props and render via react-chartjs-2.

Layout Components

Schema Definitions

Chart props are validated using Zod schemas in src/lib/chart-schemas.ts. Each chart type has a schema defining labels, datasets, colors, and chart-specific options.

Data Query API

data-query.ts

Core data querying logic. Parses and executes data queries from the AI-generated component tree, transforms raw data into Chart.js-compatible formats, handles filtering, grouping, and aggregation.

data-context.tsx

React context provider that distributes data throughout the component tree. Provides shared state, loading/error states, and refresh capabilities.

use-chart-data.ts

Custom hook for chart components to consume data from the context. Returns processed Chart.js-ready data, loading state, and refresh function.

chart-utils.ts

Helper functions for color palette generation, dataset formatting, axis configuration, and responsive breakpoints.

sample-data.ts

Markdown tables included in the system prompt. Gives Claude example data formats to work with when generating dashboards.

Adding New Chart Types

1

Create component in src/components/charts/

2

Add Zod schema in chart-schemas.ts

3

Register in catalog.ts

4

Register in registry.tsx

1. Create the Component

// src/components/charts/new-chart.tsx
'use client';

import { Chart } from 'react-chartjs-2';

interface NewChartProps {
  labels: string[];
  datasets: Array<{
    label: string;
    data: number[];
    backgroundColor?: string;
  }>;
}

export function NewChart({ labels, datasets }: NewChartProps) {
  return (
    <Chart
      type="newType"
      data={{ labels, datasets }}
      options={{ responsive: true, maintainAspectRatio: false }}
    />
  );
}

2. Define the Schema

// In src/lib/chart-schemas.ts
export const newChartSchema = z.object({
  labels: z.array(z.string()),
  datasets: z.array(z.object({
    label: z.string(),
    data: z.array(z.number()),
    backgroundColor: z.string().optional(),
  })),
});

3. Register in Catalog

// In src/lib/catalog.ts
components: {
  // ... existing
  NewChart: {
    description: 'Description of when to use this chart',
    schema: newChartSchema,
  },
}

4. Register in Registry

// In src/lib/registry.tsx
import { NewChart } from '@/components/charts/new-chart';

components: {
  // ... existing
  NewChart: NewChart,
}

5. Register Chart.js Elements (if needed)

// In src/lib/chartjs-setup.ts
import { NewController, NewElement } from 'chart.js';
Chart.register(NewController, NewElement);