AI-Powered Chart
- Basic Usage
- Data Conventions
- Custom Data Conversion
- Persisting Chart State
- Reconnecting After Deserialization
- Multiple Charts
ChartAIController creates and updates a Chart visualization based on natural-language requests. Given a DatabaseProvider, the controller exposes tools that let the LLM inspect the database schema, write SQL queries for one or more series, and update the Highcharts configuration independently of the data.
The controller exposes five tools:
-
get_database_schema— describes the tables, columns, and SQL dialect. -
get_chart_state— returns the current Highcharts configuration and the queries powering the chart. -
update_chart_data_source— validates and queues SQL queries, one per series. -
update_chart_configuration— queues a Highcharts configuration update, such as chart type, axes, tooltip, legend, or per-series styling. -
get_plot_options_schema— returns the JSON schema for a specific chart type’s plot options, allowing the LLM to discover available styling properties.
Data and configuration are kept separate: series data comes from SQL queries, while visual appearance comes from the configuration. Both are queued during the LLM turn and applied atomically in onRequestCompleted().
Basic Usage
Create a Chart, construct a controller, and wire it to the orchestrator:
Source code
Java
Chart chart = new Chart();
MessageInput messageInput = new MessageInput();
DatabaseProvider databaseProvider = new JdbcDatabaseProvider(dataSource);
ChartAIController controller = new ChartAIController(chart, databaseProvider);
AIOrchestrator.builder(provider, ChartAIController.getSystemPrompt())
.withInput(messageInput)
.withController(controller)
.build();
add(messageInput, chart);Example prompts:
-
"Plot monthly revenue for the last year as a column chart."
-
"Show revenue by region as a pie chart."
-
"Compare 2025 and 2026 quarterly sales side-by-side with a legend."
-
"Turn this into an area chart and add a 'Revenue (USD)' y-axis title."
|
Tip
|
Recommended System Prompt
ChartAIController.getSystemPrompt() returns a recommended system prompt that instructs the LLM to inspect state before making changes and to keep data and configuration separate.
|
Data Conventions
The default converter recognizes specific column aliases when mapping SQL results to Highcharts series. All reserved names are prefixed with _ to avoid colliding with real data columns. Common patterns include:
-
Basic charts — line, column, bar, area, pie, and spline charts take two columns: category and value. No special aliases are required.
-
Multi-series — add a
_seriescolumn to group rows into separate named series. -
Scatter and bubble —
_x,_y, and optionally_zfor bubble size. -
Range (
arearange,columnrange) —_low,_high, and optionally_x. -
OHLC and candlestick —
_x,_open,_high,_low,_close. -
Heatmap —
_x,_y,_value. -
Gantt, Timeline, Treemap, Organization, Sankey, and Waterfall — use the dedicated name-based aliases documented in the tool description.
Any pattern that produces a DataSeriesItem also accepts an optional _color column for per-point coloring. The full list of aliases is defined in the ColumnNames class.
Custom Data Conversion
The built-in DefaultDataConverter handles the common patterns. To take full control — for example, to post-process rows, merge data from multiple queries into a single series, or apply custom formatting — implement DataConverter and register it with setDataConverter():
Source code
Java
public class CurrencyDataConverter implements DataConverter {
@Override
public List<Series> convertToSeries(List<Map<String, Object>> data) {
DataSeries series = new DataSeries();
for (Map<String, Object> row : data) {
String name = (String) row.get("category");
Number value = (Number) row.get("value");
series.add(new DataSeriesItem(name, roundToCents(value)));
}
return List.of(series);
}
}
controller.setDataConverter(new CurrencyDataConverter());The converter receives the raw rows from DatabaseProvider.executeQuery() and returns one or more Series instances.
Persisting Chart State
ChartState captures both the SQL queries and the Highcharts configuration. Register a state change listener to persist the state automatically after each successful AI request:
Source code
Java
controller.addStateChangeListener(state ->
sessionStore.save(sessionId, state));
// Restore on a new session
ChartState saved = sessionStore.load(sessionId);
if (saved != null) {
controller.restoreState(saved);
}Listeners do not fire when restoreState() is called. The queries and configuration are also stored on the Chart component, so they survive session serialization automatically.
Reconnecting After Deserialization
ChartAIController is not serializable. After session restore, create a new controller and pass it to the orchestrator’s reconnector together with the new provider:
Source code
Java
ChartAIController controller = new ChartAIController(chart, databaseProvider);
ChartState saved = sessionStore.load(sessionId);
if (saved != null) {
controller.restoreState(saved);
}
orchestrator.reconnect(provider)
.withController(controller)
.apply();Multiple Charts
ChartAIController manages a single chart. To expose several charts to the same orchestrator — for example in a dashboard — implement a custom AIController that builds its tool list from ChartAITools.createAll() with a ChartAITools.Callbacks implementation that returns a stable ID per chart.