reportium
v0.8.0
Published
React BI reporting module inspired by Evidence - embeddable without standalone server
Maintainers
Readme
Reportium
React BI reporting module inspired by Evidence - embeddable without standalone server.
Features
- SQL-First: Write SQL queries directly in your React components
- DuckDB-Powered: Fast, in-browser analytics with DuckDB WASM
- Reactive Queries: Automatic re-execution when dependencies change
- Built-in Charts: LineChart, BarChart, AreaChart, PieChart, ScatterChart, Sparkline, and more
- Data Components: DataTable, Value, BigValue, Delta for KPIs
- Data Loading: Support for CSV, JSON, and Parquet files
- Type-Safe: Full TypeScript support with generics
- Cached: Integrated with TanStack Query for intelligent caching
- Semantic Layer: AI-native BI with schema-first semantic models
- Natural Language Queries: Ask questions in plain English (useNLQ hook)
- Smart Charts: Automatic visualization recommendations based on data
- MDX Components: Styled markdown rendering with configurable spacing presets
- Report Sections: PDF/print-optimized layout components with page break handling
- AI-Generated Reports: Comprehensive BI report generation with MCP integration
Installation
npm install reportiumPeer Dependencies
npm install react react-dom @tanstack/react-query tailwindcssQuick Start
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { DuckDBProvider, useQuery, LineChart } from 'reportium';
const queryClient = new QueryClient();
function SalesDashboard() {
const { data, isLoading } = useQuery({
queryKey: ['sales'],
sql: 'SELECT date, revenue FROM sales ORDER BY date',
});
if (isLoading) return <div>Loading...</div>;
return (
<LineChart
data={data}
x="date"
y="revenue"
title="Revenue Trend"
/>
);
}
function App() {
return (
<QueryClientProvider client={queryClient}>
<DuckDBProvider>
<SalesDashboard />
</DuckDBProvider>
</QueryClientProvider>
);
}Built-in Chart Components
All charts accept data and mapping props directly:
import {
LineChart, BarChart, AreaChart, PieChart, ScatterChart,
Sparkline, FunnelChart, Histogram, HeatMap, BoxPlot, SankeyChart
} from 'reportium';
// Line Chart
<LineChart data={data} x="date" y="revenue" title="Revenue" />
// Bar Chart
<BarChart data={data} x="category" y="count" />
// Area Chart
<AreaChart data={data} x="date" y={['revenue', 'cost']} stacked />
// Pie Chart
<PieChart data={data} name="category" value="amount" />
// Scatter Chart
<ScatterChart data={data} x="price" y="quantity" />
// Sparkline (inline mini chart)
<Sparkline data={data} value="revenue" />
// Funnel Chart
<FunnelChart data={data} name="stage" value="count" />
// Histogram
<Histogram data={data} value="amount" bins={10} />
// Heat Map
<HeatMap data={data} x="day" y="hour" value="count" />
// Box Plot
<BoxPlot data={data} category="region" value="revenue" />
// Sankey Diagram
<SankeyChart data={data} source="from" target="to" value="flow" />Data Components
Display KPIs and metrics:
import { Value, BigValue, Delta, DataTable } from 'reportium';
// Simple value display
<Value value={1234.56} format="currency" />
// Big KPI display
<BigValue
value={42500}
title="Total Revenue"
format="currency"
trend={12.5}
/>
// Delta/change indicator
<Delta value={15.3} format="percent" />
// Interactive data table
<DataTable
data={data}
columns={['name', 'revenue', 'growth']}
sortable
paginated
/>MDX Components
Styled markdown components for professional report rendering:
import {
MDXComponents,
MDXComponentsPrint,
MDXComponentsCompact,
createMDXComponents,
SPACING_PRESETS
} from 'reportium';
// Default readable spacing
<MDXProvider components={MDXComponents}>
<MyMDXContent />
</MDXProvider>
// Print-optimized with wider spacing
<MDXProvider components={MDXComponentsPrint}>
<MyReport />
</MDXProvider>
// Compact for dense dashboards
<MDXProvider components={MDXComponentsCompact}>
<MyDashboard />
</MDXProvider>
// Custom configuration
const customComponents = createMDXComponents({
proseStyle: 'print',
useThemeVariables: true,
});Spacing Presets
| Preset | Use Case | Line Height |
|--------|----------|-------------|
| compact | Dense dashboards, data-heavy views | 1.5 |
| readable | Screen viewing (default) | 1.75 |
| print | PDF generation, printed reports | 1.8 |
Report Sections
Components optimized for PDF/print output with page break handling:
import { ReportSection, ReportCard, AnalysisSection } from 'reportium';
// Basic section with break-inside-avoid
<ReportSection title="Key Findings" breakInsideAvoid>
<p>Analysis content goes here...</p>
</ReportSection>
// Card-styled section
<ReportCard title="Revenue Analysis">
<BigValue value={42500} title="Total" />
</ReportCard>
// Pre-styled analysis sections
<AnalysisSection type="findings" title="Key Findings">
<ul>
<li>Revenue increased 15%</li>
<li>Customer retention improved</li>
</ul>
</AnalysisSection>
<AnalysisSection type="recommendations" title="Recommendations">
<ol>
<li>Expand to new markets</li>
<li>Increase marketing spend</li>
</ol>
</AnalysisSection>Analysis Section Types
| Type | Style | Use Case |
|------|-------|----------|
| findings | Blue left border | Key discoveries |
| recommendations | Green left border | Action items |
| summary | Gray background | Executive summaries |
| details | Plain | Detailed analysis |
Core Hooks
useQuery
Main SQL query hook with caching and automatic re-fetching:
const { data, isLoading, error, refetch } = useQuery<SalesRow>({
queryKey: ['sales', region],
sql: 'SELECT * FROM sales WHERE region = ?',
params: [region],
staleTime: 5000,
refetchInterval: 10000,
});useReactiveQuery
Reactive queries with template variable syntax:
const [minAge, setMinAge] = useState(18);
const { data } = useReactiveQuery({
queryKey: ['filtered-users'],
sql: 'SELECT * FROM users WHERE age >= ${minAge}',
variables: { minAge },
});useChart
Transform data to ECharts options (for custom charts):
const chartOption = useChart({
data,
mapping: { x: 'date', y: ['revenue', 'cost'] },
type: 'line',
title: 'Sales Performance',
smooth: true,
});useDataSource
Load external data sources:
const { isLoaded, error } = useDataSource({
url: 'https://example.com/data.csv',
tableName: 'sales',
type: 'csv',
refetchInterval: 60000,
});useNLQ (Natural Language Queries)
Process natural language questions into SQL:
import { useNLQ } from 'reportium';
const { processQuery, isProcessing, lastResult } = useNLQ();
// Ask a question
const result = await processQuery("Show total revenue by region last quarter");
// Result includes:
// - sql: Generated SQL query
// - chartRecommendation: Suggested visualization
// - entities: Extracted measures, dimensions, filtersuseSemanticQuery
Type-safe semantic queries without writing SQL:
import { useSemanticQuery } from 'reportium';
const { data, isLoading, generatedSQL } = useSemanticQuery({
model: 'sales',
measures: [{ name: 'revenue', aggregation: 'sum' }],
groupBy: ['region'],
filters: [{ column: 'status', operator: 'eq', value: 'completed' }],
orderBy: [{ column: 'revenue', direction: 'desc' }],
limit: 10,
});Utilities
Formatting
import { formatNumber, formatCurrency, formatPercent, formatDate, formatBytes, formatDuration } from 'reportium';
formatNumber(1234.5); // "1,234.5"
formatCurrency(1234.5); // "$1,234.50"
formatPercent(0.156); // "15.6%"
formatDate(new Date()); // "2024-01-15"
formatBytes(1536000); // "1.46 MB"
formatDuration(3665); // "1h 1m 5s"Data Transformation
import { groupBy, pivot, sortBy, filterData, aggregateColumn, percentile, calculateHistogramBins, calculateBoxPlotStats } from 'reportium';
// Group data
const grouped = groupBy(data, 'category');
// Pivot table
const pivoted = pivot(data, 'date', 'category', 'revenue');
// Sort
const sorted = sortBy(data, 'revenue', 'desc');
// Filter
const filtered = filterData(data, { region: 'US' });
// Aggregate
const total = aggregateColumn(data, 'revenue', 'sum');
// Statistical
const p95 = percentile(data.map(d => d.value), 95);
const bins = calculateHistogramBins(data, 'value', 10);
const boxStats = calculateBoxPlotStats(data, 'value');Semantic Layer
Define semantic models for AI-powered analytics:
import { SemanticProvider, defineSemanticModel, column, measure } from 'reportium';
// Define a semantic model
const salesModel = defineSemanticModel({
name: 'sales',
label: 'Sales Transactions',
tableName: 'sales',
columns: [
column({ name: 'revenue', label: 'Revenue', semanticType: 'currency' }),
column({ name: 'region', label: 'Region', semanticType: 'category' }),
column({ name: 'date', label: 'Order Date', semanticType: 'date' }),
],
measures: [
measure({ name: 'total_revenue', expression: 'revenue', aggregation: 'sum', semanticType: 'currency' }),
],
});
// Wrap your app
function App() {
return (
<DuckDBProvider>
<SemanticProvider schema={{ models: [salesModel] }} autoInfer>
<Dashboard />
</SemanticProvider>
</DuckDBProvider>
);
}With autoInfer enabled, Reportium automatically discovers semantic types from your data - no schema definition required for quick exploration.
AI-Generated Reports
Reportium integrates with MCP (Model Context Protocol) servers to generate comprehensive BI reports from natural language queries. The demos showcase professional report generation with:
- Executive Summaries: 2-3 sentence overview of key findings
- Key Metrics: KPIGrid with important numbers
- Analysis Sections: Detailed narrative explaining the data
- Visualizations: Charts with contextual explanations
- Findings & Insights: Bullet-pointed discoveries
- Recommendations: Actionable next steps
See the vSphere Demo and TrustCenter Demo for complete implementations.
Data Sources
- CSV files
- JSON files
- Parquet files
- Direct data arrays
- HTTP endpoints
Documentation
- Hooks Usage Guide
- Quick Reference
- Semantic BI Plan
- Schema Builder Guide
- Inference Engine Guide
- Chart Recommender Guide
- Examples
Examples
- Basic Demo - Simple dashboard example with Playwright E2E tests
- vSphere Demo - Infrastructure monitoring with MCP and AI-generated BI reports
- TrustCenter Demo - Security compliance dashboard with AI-generated BI reports
Changelog
0.8.0
- Add MDXComponents with spacing presets (compact, readable, print)
- Add ReportSection, ReportCard, AnalysisSection for PDF/print optimization
- Enhance vSphere and TrustCenter demos with comprehensive BI report generation
- Add chart usage guidelines and BI report style guidelines to demos
- Improve AI output quality with maxSteps/maxTokens configuration
0.7.0
- Add semantic BI layer with NLQ orchestration
- Add comprehensive NLQ test suite (352 tests)
- Add Playwright E2E tests for examples
0.6.0
- Add statistical chart types (Histogram, BoxPlot, HeatMap)
- Add SankeyChart for flow visualization
- Add FunnelChart for conversion analysis
License
BSL-1.1 (Business Source License)
See LICENSE for details. Converts to Apache 2.0 after 4 years.
