AI Assistant
The Pivot Charts assistant lets users inspect a chart’s settings and request changes in plain language. For example, “Switch to horizontal bars” proposes a chart-type change; “Hide the legend” proposes a presentation change. Your application chooses the allowed charts and settings. Changes show a preview before Apply changes updates the existing chart.
Try it without a backend
Section titled “Try it without a backend”Try the Pivot Charts assistant
Choose a suggested request below. This scripted demo runs entirely in your browser, with no backend, model key or model calls. It recognizes only the suggested requests.
Try it: Inspect the settings, then switch to horizontal bars. Cancel changes first, then submit again and Apply changes. Try the title and axis update; open … (More) to hide the legend. The linked Pivot values stay the same.
Reset demo restores the original sample data and clears its conversation. To use your own prompts, follow the API-client setup guide.
The demo uses fixed responses to suggested requests and the real native chart APIs. It does not call a backend or model. It includes the linked Pivot table so you can see that chart presentation changes preserve the report’s values.
What you will connect
Section titled “What you will connect”createPivotChartsAiActions from @revolist/pivot connects an existing PivotChartsPlugin to the shared assistant. The chart plugin still owns validation, data loading, rendering and lifecycle. The assistant does not create a second chart engine.
There are three parts: your active Pivot and chart, the assistant UI, and your authenticated API route that translates a request into a supported result. If you do not have a working chart yet, complete Your First Linked Chart first. Use compatible Pro and Pivot versions exporting AiAssistantPlugin and createPivotChartsAiActions; rebuild stale generated packages when working from source.
1. Register the plugins and containers
Section titled “1. Register the plugins and containers”During grid initialization, before mounting it, add the assistant alongside your existing plugins:
import { PivotPlugin, PivotChartsPlugin, createPivotChartsRenderer,} from '@revolist/pivot';import { AiAssistantPlugin } from '@revolist/revogrid-pro';import '@revolist/revogrid-pro/styles.css';import '@revolist/pivot/styles.css';
grid.plugins = [PivotPlugin, PivotChartsPlugin, AiAssistantPlugin];grid.pivotCharts = { renderer: createPivotChartsRenderer() };// Keep your existing grid.pivot, grid.source and mount setup.// Include any other plugins your application needs.Add these containers to your application template alongside the grid:
<div id="chart-assistant"></div><div id="sales-chart" style="height: 300px"></div>2. Connect the chart and your API client
Section titled “2. Connect the chart and your API client”Run this after the grid has mounted and the initial Pivot report has loaded. This example creates a linked chart in the container above. If your app already has a chart reference, reuse its id when registering the adapter instead of creating a second chart.
import { PivotPlugin, PivotChartsPlugin, createPivotChartsAiActions,} from '@revolist/pivot';import { AiAssistantPlugin, type AiViewInterpreter,} from '@revolist/revogrid-pro';import { apiClient } from './api-client'; // Your authenticated application client.
const interpret: AiViewInterpreter = async (request, { signal }) => { const response = await apiClient.post('/api/ai/pivot-charts', request, { signal }); return response.data; // Axios-style example: return the parsed assistant result.};
export async function connectChartAssistant( grid: HTMLRevoGridElement, assistantHost: HTMLElement, chartHost: HTMLElement, interpret: AiViewInterpreter,) { const plugins = await grid.getPlugins(); const pivot = plugins.find((plugin): plugin is PivotPlugin => plugin instanceof PivotPlugin); const charts = plugins.find((plugin): plugin is PivotChartsPlugin => plugin instanceof PivotChartsPlugin); const assistant = plugins.find(plugin => plugin instanceof AiAssistantPlugin); if (!pivot?.getRuntimeSnapshot() || !charts || !assistant) { throw new Error('Install all three plugins and load the initial Pivot report.'); } const chart = await charts.createChart({ container: chartHost, chartType: 'groupedColumn', linked: true, presentation: { title: 'Sales by region', legendPosition: 'bottom' }, }); grid.aiAssistant = { interpret, mountTo: assistantHost, fields: [], executor: { read: () => ({ sort: [] }), async apply() { throw new Error('Use native chart actions for this assistant.'); }, }, actions: createPivotChartsAiActions(charts, { chartIds: [chart.id], inspect: true, update: { chartTypes: ['groupedColumn', 'groupedBar', 'line'], presentation: true, axes: true, colors: true, }, revision: () => [pivot.getRuntimeSnapshot()?.revision], }), ui: { mode: 'chat', suggestions: ['Inspect the chart settings', 'Switch to horizontal bars'], }, }; return () => { grid.aiAssistant = undefined; chart.destroy(); // This function created this chart; other app charts are preserved. };}
const assistantHost = document.getElementById('chart-assistant');const chartHost = document.getElementById('sales-chart');if (!assistantHost || !chartHost) throw new Error('Missing chart/assistant container.');const disconnect = await connectChartAssistant(grid, assistantHost, chartHost, interpret);// Call disconnect() when this app view unmounts.grid is your existing element. apiClient and /api/ai/pivot-charts belong to your application. Replace them with your real import and route; if your client returns the parsed body directly, return it instead of response.data. Your client supplies its normal session cookie or user bearer token and owns token refresh. Provider credentials stay on the server. See the interpret contract; the Fetch helper remains an optional alternative.
This is an action-only assistant. Top-level fields: [] prevents ordinary grid operations from addressing aggregate rows. Do not enable generic grid data/schema actions against this projection. To let one assistant also change the report, register native Pivot actions separately with their own disclosed fields.
3. Return a native chart action from your backend
Section titled “3. Return a native chart action from your backend”Implement the route used above. Authenticate the caller, enforce your chart/setting policy, and constrain the model to the server-approved schemas in request.actions. createAiViewResponseSchema can construct a response schema after your server validates those descriptors. The top-level request.fields list is intentionally empty: native chart capabilities and allowed chart IDs are described by action schemas.
For a horizontal-bar request, return a JSON body like this, using the actual allowed native chart ID from the descriptor:
{ "kind": "action", "name": "pivotCharts.update", "input": { "chartId": "chart-id-from-your-app", "patch": { "chartType": "groupedBar" } }}The browser validates the result and shows a preview. Apply calls PivotChartsPlugin.updateChart; Cancel preserves the chart. Native compatibility checks still apply, so a permitted chart type may reject data that does not meet its requirements. Errors leave the assistant with feedback rather than silently substituting another chart type.
The reference backend recognizes pivotCharts.inspect and pivotCharts.update. Replace its orders fixture policy with your application’s authorized chart policy. Recognizing a descriptor does not grant access. Return the result object, rather than a raw model response, JSON string or HTTP-client wrapper.
Supported actions and permissions
Section titled “Supported actions and permissions”| Action | Opt-in | Behavior |
|---|---|---|
pivotCharts.inspect | inspect: true | Read the target chart’s projected configuration metadata. No chart values or raw records. |
pivotCharts.update | At least one setting in update | Preview and apply changes to an existing allowed chart. |
chartIds is required: supply one to 20 unique chart IDs. Each operation names exactly one target. Recreate the adapter when your chart catalog or allowlists change. A missing chart is rejected. Optional canInspect(model) and update.canUpdate(model, patch) narrow host permissions; update permission is checked during preparation and immediately before Apply.
| Update option | Accepted patch |
|---|---|
chartTypes | chartType from this explicit list of native chart types. |
presentation: true | title, subtitle, legendPosition, dataLabels, xAxisTitle, yAxisTitle. Strings are limited to 500 characters. |
axes: true | X-axis title; Y-axis title, finite min/max bounds and reverse. Existing axis settings are preserved. |
seriesIds | Nonempty selection from these explicitly allowed native series IDs, at most 50. This replaces the chart’s series selection. |
colors: true | Native paletteMode: index or semantic. Existing measure/member colors are preserved. |
The adapter does not accept arbitrary renderer options, callbacks, datasets, bindings, queries or URLs. It does not create/destroy charts, export files or edit source records. Use application-owned approved recipes for those workflows. It does not add automatic Undo/Redo; chart/report history remains application-owned.
Disclosure, stale previews and remote charts
Section titled “Disclosure, stale previews and remote charts”Inspection returns chart type, linked state, bounded titles/legend/axis metadata, selected series IDs and palette mode. It omits captured datasets, aggregate values, raw records, query predicates, selections and bindings. Titles and series identities can still contain business information. Results remain in the assistant UI unless your application explicitly opts into sending selected evidence back to the model.
Inspection and preview JSON are limited to 16 KiB. Chart inputs and permissions are rechecked before commit. Native getChartRevision(chartId) provides an opaque token that changes when the chart is updated or recreated with the same ID. The revision callback above also protects a preview when its Pivot report changes. Stop is honored before the native update starts; it does not roll back a completed update.
Remote charts retain their native data loader and validation. Inspection does not query your remote dataset. Type and series changes can trigger native chart reloads; your backend continues to own authorization and remote query policy. No complete-dataset analytical totals are inferred from loaded chart categories.
Test before connecting a model
Section titled “Test before connecting a model”Use the embedded demo above to try Inspect, preview, Cancel, Apply and Reset without credentials. In your own app, replace the API-client interpreter with a deterministic function returning one of the action results above, with your actual chart.id. Verify that Cancel preserves the native model, Apply changes it, and changing the report while a preview is open rejects that preview. Then restore your API-client interpreter and test authentication and model interpretation separately.
See testing without a model and API and lifecycle for additional integration guidance.