Integrated Charts (Enterprise)
apex-grid-enterprise turns the grid's current view or a selected cell range into an ApexCharts chart. Use the declarative <apex-grid-chart> companion element for a live, self-updating chart, or the imperative renderChart / createRangeChart methods for full control. The chart model is derived by intent: a selected cell range wins, otherwise the current view (the flat grid, or a grouping/pivot aggregate). ApexCharts is dynamically imported, so it only loads when a chart is actually drawn.
The <apex-grid-chart> element
Bind a chart element to a grid by setting its grid property. It renders the grid's current chart model and redraws automatically when the view changes (grouping, pivot, data, or selection):
import 'apex-grid-enterprise/define';
const grid = document.querySelector('apex-grid-enterprise');
const chart = document.createElement('apex-grid-chart');
chart.grid = grid;
chart.source = 'auto'; // selection if present, else the view
document.querySelector('#chart-slot').appendChild(chart);
| Property | Type | Description |
|---|---|---|
grid | ApexGridEnterprise | The grid to chart |
source | 'auto' | 'selection' | 'view' | Which model to chart: selection if present else view ('auto'), or force one |
type | ChartType | 'auto' | Chart type, or let the grid recommend one ('auto') |
definition | ChartDefinition | Column-to-chart mapping: category, measures, and aggregation |
format | ChartFormat | Format overlay: colors, number format, axis titles, analytics overlays |
theme | 'grid' | 'light' | 'dark' | Palette source; 'grid' syncs to the grid theme |
crossFilter | boolean | Turn the chart into a cross-filter surface |
mode | 'inline' | 'dialog' | Render in place ('inline') or in a dialog ('dialog', default) |
It fires apex-chart-created ({ chart, type }) after rendering and apex-chart-type-changed ({ type }) when the built-in gallery changes type. Note: unlike the other companion elements it renders in light DOM, because ApexCharts injects global styles.
View-bound live companion
With source="view" the panel charts the whole current view and redraws automatically as you sort, filter, or edit the grid, with no cell selection required. Under the hood it reads getViewChartModel(), which works on any grid (not just a grouped or pivoted one):
chart.source = 'view';
chart.type = 'column'; // gallery-switchable; 'auto' picks a recommended type
Chart types
ChartType is 'column' | 'bar' | 'line' | 'area' | 'pie' | 'donut' | 'scatter' | 'radar' | 'combo' (plus 'auto' to let the grid recommend one). 'column' and 'bar' distinguish vertical vs horizontal. The panel's type gallery is grouped (cartesian / circular / statistical) with Auto shown as a "Suggested" badge.
Imperative rendering
Render into any container element and get back the ApexCharts instance:
// chart the current view (respects grouping/pivot/sort/filter)
const chart = await grid.renderChart(document.querySelector('#c'), { type: 'column' });
// chart the current cell range selection
const rangeChart = await grid.createRangeChart(document.querySelector('#c2'), { type: 'line' });
RenderChartOptions includes type (a ChartType or 'auto') and comboTypes (per-series types for a 'combo' chart).
Chart models
For custom rendering pipelines, get the underlying ChartModel (categories + series) without rendering:
| Method | Returns |
|---|---|
getChartModel() | Model for the current auto source |
getViewChartModel() | Model derived from the current view (grouping/pivot) |
getRangeChartModel() | Model derived from the current range selection |
getCrossFilterModel() | { categoryKey, model } for cross-filtering |
import { chartModelToApexOptions, recommendChartType } from 'apex-grid-enterprise';
const model = grid.getViewChartModel();
const type = recommendChartType(model); // pick a sensible type
const options = chartModelToApexOptions(model, { type }); // → ApexCharts options
recommendChartType(model) returns a ChartType heuristic; chartModelToApexOptions(model, options) is a pure transform to an ApexCharts options object (no ApexCharts dependency at call time).
Data mapping
A ChartDefinition controls which column is the category, which columns are the measures, and how rows aggregate per category. Every field is optional: the empty default keeps the automatic mapping (first non-numeric column is the category, every numeric column a series, summed per category), so a mapping UI can seed itself from the default and override only what changes.
chart.definition = {
category: 'region', // column key for the X axis
measures: ['revenue', 'deals'], // column keys plotted as series
aggregation: 'sum', // 'sum' | 'avg' | 'count' | 'min' | 'max' | 'median'
// or a per-measure map: { revenue: 'sum', deals: 'avg' }
secondaryMeasures: ['deals'], // draw these on a secondary (opposite) value axis
};
The panel surfaces this in a Data popover: a category picker, a checkbox per numeric column (with a per-series 2nd axis toggle), and the aggregation. The columns it offers come from grid.getChartFields() ({ key, label, numeric }[]), so a custom mapping UI can read the same list; buildValueAxes() builds the dual-axis layout. Each getter (getViewChartModel, getRangeChartModel, getChartModel) also accepts an optional ChartDefinition.
Calculated fields
A calculated field plots a series from a formula over the other columns, with no extra grid column. The formula uses the enterprise formula engine with A1 references, where the letters map to the numeric columns in display order (A1 = first numeric column, B1 = second, …; the row is always 1 — one aggregated value per column per category):
chart.definition = {
category: 'department',
measures: ['salary'],
calculatedFields: [{ name: 'Bonus %', formula: 'B1 / A1 * 100' }],
secondaryMeasures: ['Bonus %'], // a calc field can sit on the secondary axis (by its name)
};
Each field is evaluated per category over the aggregated values (aggregate-then-evaluate, i.e. the ratio of totals, the convention in Excel PivotTable calculated fields and Power BI measures). isValidChartFormula(formula) and computeCalculatedSeries(...) are exported for building your own UI.
Format popover
The toolbar's Format popover surfaces the options users change most often, layered over apexOptions so it only touches the keys you set. All are available programmatically via the format property (ChartFormat):
chart.format = {
colors: ['#2563eb', '#16a34a'], // per-series, in series order
legend: true,
dataLabels: false,
gridlines: true,
numberFormat: 'currency', // 'none' | 'currency' | 'percent' | 'thousands'
axisTitles: { x: 'Department', y: 'Salary (USD)' },
referenceLine: 100000, // dashed target/threshold on the value axis
referenceBand: { from: 80000, to: 100000 }, // shaded target range
trendline: true, // least-squares trend overlay on the first series
forecast: 3, // project N future periods as a continuation line
forecastBand: true, // add a ~95% prediction band around the forecast
};
trendline, forecast, and forecastBand are also exposed as the pure functions linearTrend(), linearForecast(), and linearForecastBand(), and ChartFormat ↔ ApexCharts translation as formatToApexOptions(), so you can drive them without the panel.
Export
The toolbar's Export menu (and the matching methods) save the chart as a raster PNG, a scalable SVG, or copy it to the clipboard as an image:
await chart.exportImage('png'); // or 'svg'
await chart.copyImage(); // PNG to the clipboard
Save and restore
toJSON() returns a plain-JSON ChartConfig (type, source, mapping, format, heading, cross-filter, and any frozen snapshot) that an app can persist anywhere and reapply with restore(). apexOptions is excluded (it is author code and may hold functions), so bind it and grid separately.
const config = chart.toJSON(); // JSON-safe; JSON.stringify(chart) works too
localStorage.setItem('myChart', JSON.stringify(config));
// later
chart.grid = grid;
chart.restore(JSON.parse(localStorage.getItem('myChart')));
Multiple charts and entry points
The enterprise grid adds a "Create chart" toolbar button that opens the panel in a dialog. Each click mints an independent chart panel, so several charts (each a frozen snapshot of the data at creation) can sit side by side without disturbing one another. Other ways to start a chart:
- On a selection a floating Chart button appears over the grid, and Alt+F1 charts the current cell range from the keyboard.
- On a grouped / pivoted view the right-click menu offers "Chart this view"; with a plain selection it offers "Chart range".
- A dialog chart's heading auto-titles from the mapping ("Revenue by Region") and is double-click-to-rename.
Charting a pivot
Because <apex-grid-chart> follows the view, it redraws when you change pivotOn/groupBy. Both the grid and the chart element listen to the apex-view-changed event.
Cross-filtering
Set crossFilter (the property or the cross-filter attribute) on <apex-grid-chart> to turn the chart into a filter surface: clicking a chart category filters the grid to that value, and clicking it again clears the filter.
<apex-grid-chart cross-filter></apex-grid-chart>
chart.crossFilter = true;
chart.selectCategory(0); // programmatic equivalent of clicking the first segment
The chart reads the grid's full, unfiltered data, so every category stays on the chart instead of collapsing to the filtered subset. The filter is applied with a self-contained, type-independent equality operation, so it matches regardless of the category column's declared type. Turning crossFilter off (or disconnecting the panel) drops any filter it applied. For custom pipelines, getCrossFilterModel() returns { categoryKey, model }.
React example
import { useEffect, useRef } from 'react'
import 'apex-grid-enterprise/define'
export default function ChartedGrid() {
const gridRef = useRef<any>(null)
const chartRef = useRef<any>(null)
useEffect(() => {
const grid = gridRef.current
grid.columns = columns
grid.data = data
grid.groupBy = ['region']
grid.aggregations = { revenue: ['sum'] }
chartRef.current.grid = grid
chartRef.current.source = 'view'
chartRef.current.type = 'column'
}, [])
return (
<div>
<apex-grid-enterprise ref={gridRef} style={{ height: 360 }} />
<apex-grid-chart ref={chartRef} mode="inline" />
</div>
)
}