AI-powered, natural-language analytics for Pivot tables in React. Drive sorting, filtering, calculations, and formatting with plain English via Syncfusion’s AI AssistView and a secure Node/Express gateway to OpenAI.
Meta: React + Vite + TypeScript frontend with Syncfusion PivotView and AI AssistView, backed by an Express API proxy to OpenAI with per-visitor token budgeting.
Optional hero image: A screenshot of the Pivot table with the AI Assist panel open, captioned “Ask AI to sort, filter, and calculate — instantly.”
- Problem: Configuring complex Pivot operations with UI clicks is time‑consuming and error‑prone. ❗
- Solution: An AI chat assistant lets you “tell” the Pivot what to do (e.g., “Sort Country descending,” “Show France and Germany,” “Average Sold”). 💡
- What’s unique: ✨
- Tightly couples Syncfusion’s
PivotViewwithAIAssistViewfor grounded UI changes. - Secure server-side OpenAI access with per-visitor token budgeting and reset windows.
- Ready-to-run Vite + TypeScript + React 19 development experience.
Real-world uses:
- 📊 Self-serve analytics portals
- 📈 BI dashboards with conversational pivots
- 🧭 Guided data exploration/demos and PoCs
- 🗣️ Natural language control of Pivot operations (sort/filter/aggregate/format).
- 💬 Prebuilt prompt suggestions for one‑click examples.
- 🔧 Live toolbar integration adds an “AI Assist” action to the Pivot.
- 🧾 Response templating for AI outputs in the AssistView.
- 🔒 Secure backend proxy to OpenAI; never expose API keys to the browser.
- ⏱️ Per-visitor token limits and hourly reset to manage usage.
- ⚙️ Vite HMR dev loop, React 19, TypeScript 5.9, ESLint 9.
- 🌐 Easily configurable API base URL via
VITE_API_BASE_URL.
- Languages/Frameworks: React 19, TypeScript 5.9, Vite 7, Express 4
- Syncfusion React components:
@syncfusion/ej2-react-pivotview@syncfusion/ej2-react-interactive-chat(AI AssistView)@syncfusion/ej2-react-popups
- Backend:
openai@4.50.0,dotenv,cors,date-fns - Node.js: >= 18 (recommended 18/20+)
- Browsers: Modern evergreen (Chromium, Firefox, Safari)
Prerequisites: ✅
- Node.js >= 18 and npm
- An OpenAI API key
- Backend API (Express)
- Location: server
- Create
.env:
# server/.env
OPENAI_API_KEY=sk-...
# Optional: override model (default: gpt-4o-mini)
OPENAI_MODEL=gpt-4o-mini
# Optional: CORS origin for frontend
CORS_ORIGIN=http://localhost:5173- Install & run:
cd server
npm install
npm start- Server runs on
http://localhost:3000(default). Confirm the terminal log.
- Frontend (Vite + React)
- Location: assistive-pivot
- Create
.env(or.env.local) to point at the backend:
# assistive-pivot/.env
VITE_API_BASE_URL=http://localhost:3000- Install & run:
cd assistive-pivot
npm install
npm run dev- Open the URL shown by Vite (commonly
http://localhost:5173).
Troubleshooting:
- CORS errors: Ensure
CORS_ORIGINmatches the Vite URL. - 403 token limit: Tokens reset on an hourly window per visitor ID.
- 500/AI errors: Verify
OPENAI_API_KEYand network access.
- Start both backend (port 3000) and frontend (Vite dev server).
- In the app, click the toolbar’s “AI Assist” button.
- Try prompts such as:
- “Sort Country field by descending”
- “Show only data from France and Germany”
- “Change the Sold field aggregation from sum to avg”
- “Clear filtering”
First success checkpoint: The Pivot updates as requested. Next steps: Add new prompt suggestions or wire your own data.
- Frontend:
- Syncfusion
PivotViewrenders the analytics grid/chart. - Syncfusion
AIAssistViewprovides the chat surface and prompt execution. - Prompts trigger
fetchAI(...)(viaserverAIRequest) with the current Pivot’s state.
- Syncfusion
- Backend:
- Express
/api/chatvalidates the request, checks token budget per visitor, and forwards chat messages to OpenAI. - Token store (
user_tokens.json) uses a lightweight, file-based budget with hourly resets.
- Express
Data Flow:
- User prompt in AssistView
- Frontend gathers Pivot state
- POST to
/api/chatwithvisitorId+ messages - Server consults token store, then calls OpenAI
- Server returns AI content; frontend applies to Pivot props
- assistive-pivot/ — React + Vite app
- src/frontend/ai-assistive-pivot.tsx — AssistView + Pivot wiring
- src/assistive-pivot.tsx — Demo wrapper, toolbar and layout
- src/model/sf-ai-schema.ts — AI response schema helpers
- src/backend/ai-service.ts —
serverAIRequestand visitor fingerprint - src/datasource.ts — Sample Pivot dataset
- src/App.tsx, src/main.tsx — App entry
- server/ — Express + OpenAI proxy
- server.js — REST API, token checks, error handling
- ai-model.js — OpenAI Chat Completions call
- token-store.js — File-based token budgeting
- test/token-store.test.js — Node tests for token store
- AI Assist integration
- ai-assistive-pivot.tsx sets up:
- Toolbar button to open AI dialog
- Prompt suggestions footer
- Response template for AI messages
promptRequesthandler callingfetchAI(...)with current Pivot state
- ai-assistive-pivot.tsx sets up:
- Pivot operations via props
dataSourceSettingscontrols rows, columns, values, filters, and conditional formatting- AI responses translate to targeted prop changes on Pivot
- Token budgeting
- Default: 50,000 tokens per visitor per hour
- Exempt visitors: configured in
EXEMPT_VISITOR_IDS(for demos/tests) - Persists to server/user_tokens.json
Frontend:
VITE_API_BASE_URL— API base (defaulthttp://localhost:3000)
Backend (.env):
OPENAI_API_KEY— requiredOPENAI_MODEL— defaults togpt-4o-miniCORS_ORIGIN— default*, set to your Vite origin in dev
Token store (edit in server/token-store.js):
TOKEN_RESET_INTERVAL_HOURS— default 1DEFAULT_TOKENS— default 50,000EXEMPT_VISITOR_IDS— Array of visitor IDs bypassing deductions
- Call the backend API directly
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"visitorId": "dev-visitor",
"messages": {
"messages": [
{"role":"system","content":"You help configure a Syncfusion Pivot grid."},
{"role":"user","content":"Sort Country descending"}
]
}
}'- Use the frontend helper (ai-service.ts)
import { serverAIRequest } from '../backend/ai-service';
const response = await serverAIRequest({
messages: {
messages: [
{ role: 'system', content: 'Guide Pivot changes.' },
{ role: 'user', content: 'Show only France and Germany' }
]
},
temperature: 0.3
});
// Apply response to Pivot props as needed- Add a new prompt suggestion (ai-assistive-pivot.tsx)
const suggestions = [
"Sort Country field by descending",
"Show only data from France and Germany",
"Change the Sold field aggregation from sum to avg",
"Clear filtering",
"Highlight Amount > 250000 in red" // new suggestion
];- Vite HMR enables fast feedback in dev.
- Keep prompts concise to reduce token usage and latency.
- Limit returned content to minimal deltas; avoid verbose explanations where not needed.
- Serve the API and app close to each other to reduce network hops.
POST /api/chat
- Request body:
visitorId(string) — required per-visitor budgeting keymessages(object) — OpenAI Chat API-compatible payload holder:{ messages: Array<{ role, content }> }- Optional tuning:
temperature,topP,maxTokens,frequencyPenalty,presencePenalty,stopSequences
- Response 200:
{ "response": "<model content string>" }
- Response 403 (budget exceeded):
{ "error": "You have reached your token limit..." }
- Response 400/500:
{ "error": "<message>" }
- CORS blocked
- Set
CORS_ORIGINin server.envto your Vite URL (e.g.,http://localhost:5173)
- Set
- Token limit reached
- You’ll see a banner and a 403 with reset time; try again after the window resets
- “Failed to generate text”
- Verify
OPENAI_API_KEYand internet access; inspect server logs
- Verify
- Frontend can’t reach API
- Check
VITE_API_BASE_URLand that the server is listening on the expected port
- Check
- Server tests:
cd server
npm test- Framework: Node’s built-in
node:test - What’s covered: token store initialization, deduction logic, exempt users
- Branch from
main, keep PRs focused and small. - Code style: ESLint 9 + TypeScript.
- Frontend:
cd assistive-pivot
npm run lint
npm run build- Backend:
cd server
npm start
npm test- 📖 Syncfusion Documentation - Complete EJ2 React documentation
- 💬 Syncfusion Forums - Active community support
- 🎥 Video Tutorials - Learn from Syncfusion team
- 📚 Code Examples - 1000+ examples gallery
- 🐛 GitHub Issues - Report bugs and suggest features
Built with the technologies developers love:
React 19 ⚡ | Webpack 5 📦 | Syncfusion EJ2 🎨 | Node.js 🚀
If you find this project helpful, please:
- ⭐ Star this repository
- 🔄 Share with your team
- 📢 Mention in your portfolio
- 💬 Contribute improvements
This project is licensed under Syncfusion Evaluation License.
Usage Rights:
- ✅ Free for evaluation and development
- ✅ Educational and learning purposes
- ✅ Internal team projects
- ❌ Production deployment (requires commercial license)
- ❌ Redistribution without commercial license
For commercial licensing, contact Syncfusion Sales
Thank you for exploring this Fitness Tracker Dashboard! We hope this helps you:
- 🏆 Master modern React development
- 🔧 Learn advanced patterns with Syncfusion
- 🎓 Understand micro-frontend architecture
- 💡 Build better applications
Made with ❤️ using Syncfusion EJ2
Version: 1.0.0 | Last Updated: January 2026 | Status: ✅ Production Ready