Skip to content

Controls and Localization

Show only the controls your users need. Built-in controls can be enabled, disabled or hidden, and their labels can be translated.

Start from the chart with standard controls. Then hide one optional section and check that the remaining workflow is still clear. Use Layout to choose report fields and Display for visual settings.

Interactive example

Chart controls

Compare the controls available under different chart authoring policies.

The example loads when visible.

Try it: leave Chart UI policy selected, choose Enable customization, then Open chart workspace. The example starts with customization hidden. In the workspace, Layout chooses fields and measures; Display changes appearance. The Chart and Data view buttons switch between the plot and its table.

Pivot Charts separate portable model presentation from renderer-wide styling. Use presentation and chartOptions when the choice must persist with one chart. Configure createPivotChartsRenderer when an application needs a shared palette, typography, tooltip, or export pipeline.

The Layout and Display inspectors group related controls into collapsible sections. Layout starts with ordered row and column fields and checkbox measure selection; sorting, ranking, member filters, and the Pivot connection are separate sections. Valid query edits update automatically. Display starts with labels and legend, with appearance, axes, colors, navigation, interaction, and references available in their own sections. Collapsing a section preserves its draft edits. Switching tabs also preserves Display drafts and expanded sections. Presentation, colors, annotations and query edits update automatically. Incomplete numeric or reference edits stay local with validation feedback until valid. Color controls use the shared Pro palette and native color chooser, without a free-text color field. Automatic restores the default color where supported. Reset colors preserves combination layer and axis assignments, including changes still being processed.

The picker captions and swatch names are customizable through localeText.colors.picker.customColor and localeText.colors.picker.colorLabels. Each existing color control policy continues to hide or disable its picker. Apply policy and translation keys are accepted; the inspector no longer renders those actions.

The whole-layout Reset action is hidden by default. To expose it, set pivotChartsUi.controls['query.reset'] = 'enabled'.

Rename section titles with localeText.inspector. Hide or disable a whole section with pivotChartsUi.controls['inspector.<section>']; existing leaf control policies continue to apply. Section IDs are source, fields, sort, filters, connection, presentation, appearance, axes, colors, navigation, interaction, and annotations.

grid.pivotChartsUi = {
localeText: {
inspector: { fields: 'Fields to compare', annotations: 'Notes and targets' },
},
controls: {
'inspector.navigation': 'hidden',
'inspector.axes': 'disabled',
},
};

Existing chartOptions.heading, colors.heading, annotations.heading, navigation.heading, and interaction.heading overrides remain section-title fallbacks. An explicit inspector title takes precedence.

Pivot Charts consume the report’s committed aggregate values. Configure numeric/scalar eligibility, counts and execution pins in the Pivot aggregation contract. Chart normalization, formatting or a shared dataset shape does not establish identical local/server results or increase arithmetic precision. A remote provider must supply complete aggregates under its backend policy, not averages or distinct totals reconstructed from a visible page.

For an embedded chart mounted with controls: 'standard', set pivotChartsUi.settingsMountTo to an application-owned element to place the configurator in a drawer. The chart fills its original container. The application owns opening and closing the drawer; destroying the chart removes its controls from the target. Chart dialogs retain their own settings panel.

pivotCharts.localeText supports deep partial overrides for dialog actions, status and errors, breadcrumbs, gallery tabs/families, all chart names and descriptions, compatibility reasons, chart options, data controls and table, legend overflow, tooltips, accessibility text, context actions, themes, totals, and number formatting.

grid.pivotCharts = {
renderer: createPivotChartsRenderer(),
localeText: {
actions: {
exportChart: 'Exportar',
downloadPdf: 'Transferir PDF',
viewData: 'Ver dados',
viewChart: 'Ver gráfico',
},
chartTypes: {
groupedColumn: 'Colunas agrupadas',
boxPlot: 'Diagrama de caixa',
},
renderer: {
formatNumber: (value) =>
new Intl.NumberFormat('pt-PT').format(value),
},
},
};

pivotCharts.localeText supplies shared chart and renderer text. pivotChartsUi.localeText supplies UI overrides, merged deeply over that text. Both properties are reactive: replacing either configuration updates existing chart dialogs and embedded chart panels. Partial overrides retain all other labels, descriptions, option labels, accessible names, and formatter functions.

grid.pivotCharts = {
renderer,
localeText: {
controls: { totals: 'Totales' },
dataTable: { categoryHeader: 'Categoría', emptyValue: 'Sin valor' },
renderer: { formatNumber: value => numberFormatter.format(value) },
},
};
grid.pivotChartsUi = {
localeText: {
context: {
heading: 'Detalles de los datos',
close: 'Cerrar detalles',
rows: 'Filas',
columns: 'Columnas',
frame: (categories, series) => `${categories} categorías · ${series} métricas`,
formatFilterValue: value => String(value),
},
actions: { chartLabel: 'Gráfico', dataLabel: 'Tabla', viewData: 'Ver datos', viewChart: 'Ver gráfico' },
chartOptions: { labels: { strokeWidth: 'Grosor de línea' } },
gallery: { tabs: { chart: 'Gráfico', data: 'Datos', customize: 'Estilo' } },
},
controls: {
'context.note': 'hidden',
'controls.keepLinked': 'hidden',
'controls.totals': 'disabled',
'tabs.chart': 'hidden',
'chartTypes.pie': 'hidden',
'chartOptions.showGridLines': 'hidden',
'chartOptions.strokeWidth': 'disabled',
annotations: 'hidden',
'export.pdf': 'disabled',
},
dataGrid: {
sorting: true,
range: true,
resize: true,
columnGrouping: true,
rowSize: 36,
categoryColumn: { name: 'Categoría', size: 220 },
seriesColumn: series => ({ name: series.measure?.label ?? series.label, size: 180 }),
filter: false,
},
};

controls accepts enabled, disabled, or hidden. Unspecified controls are enabled when their data and renderer capabilities permit them. Hidden controls are not rendered; disabled controls remain visible and cannot be activated. A parent restriction wins over an enabled child. For example, disabling navigation also disables navigation.enabled, even if the child is explicitly enabled. A UI policy never enables an unsupported renderer capability or removes a loading/read-only restriction.

The close policy also gates Escape, and drill.navigate gates Alt+Left and Home in the chart area. Re-enabling these controls restores their shortcuts.

For the transient data-details popup, context.close controls its close button; Escape and clicking outside still dismiss the popup. Restrict context or context.heading to disable access. Restricting the details or export trigger also closes its already-open popup or menu. Disabled tabs stay visible; if no tab is enabled, no settings panel is active. Hiding every tab removes the sidebar.

Visible numeric option values can be localized independently of the numeric API:

grid.pivotChartsUi = {
localeText: {
chartOptions: {
formatValue: (value, key, step) => new Intl.NumberFormat('de-DE', {
maximumFractionDigits: step < 1 ? 2 : 0,
}).format(value),
},
},
};

formatValue(value, key, step) affects range-value captions. Option updates still use numbers. Omit it to retain the default step-based decimal formatting.

The policy changes available UI actions. It does not rewrite the chart model, disable model-defined rendering behavior, or restrict programmatic API calls. Use ref.update(...) to configure chart behavior, and the UI policy to control which settings users may change. Disable reset actions too when their broader scope is inappropriate for your application.

For a chart type whose catalog definition advertises navigation, configure its rendered toolbar and plot gestures through the chart model:

ref.update({
navigation: {
enabled: true,
navigator: true,
crosshair: true,
tooltipMode: 'shared',
actions: {
zoomIn: 'enabled',
zoomOut: 'disabled',
reset: 'hidden',
},
gestures: { wheel: false, pan: true, pinch: false },
},
});

Each action accepts enabled, disabled, or hidden; omitted actions default to enabled. Disabled actions cannot activate through pointer or keyboard input. Plot gestures require enabled: true, and each omitted gesture defaults to allowed. Navigator handles and its range band remain independent of that flag. Action policies alone do not create a toolbar; toolbar availability still follows the enabled, navigator, and viewport configuration.

A supplied navigation record replaces the previous record, including its nested action and gesture policies. Omitting it from an update preserves the current configuration; supplying {} restores defaults. These policies survive model serialization and restoration. Unsupported chart types reject a nonempty navigation record with a localizable error.

Use localeText.navigation to rename toolbar actions, navigator accessible names, instructions, and range summaries. Visible button text is independent of its accessible action name:

const localeText = {
navigation: {
zoomInButtonText: 'Zoom in',
zoomOutButtonText: 'Zoom out',
panLeftButtonText: 'Earlier',
panRightButtonText: 'Later',
resetViewportButtonText: 'Reset',
formatNavigatorValue: (value, scale, handle, defaultText) =>
`${handle}: ${defaultText}`,
},
};

Translated text is measured and shortened with an ellipsis when space is limited. If no text prefix fits, the button shows its distinct default action glyph instead. The full text remains in the button title, and accessible action names remain independently configurable. Default glyph buttons retain their compact geometry. formatNavigatorValue customizes slider aria-valuetext; value matches numeric aria-valuenow (epoch milliseconds for time, a boundary ordinal for categories). The category end boundary is exclusive, while its defaultText names the last included category. Numeric slider bounds and behavior remain unchanged. localeText.renderer.invalidNavigation and navigationUnsupported(chartType) customize validation messages. These renderer/model policies also work through the standalone charts API, without a RevoGrid host.

ID or prefixControlled UI
settingsEntire settings sidebar; hiding it gives the chart the full width
tabs.chart, tabs.data, tabs.customizeIndividual settings tabs; selection and arrow navigation skip unavailable tabs
inspector, inspector.<section>All collapsible inspector sections, or one section listed above; restrictions cascade to its controls
gallery, chartTypes.<type>Gallery and individual chart types, including recommendations
data, query, relationship.x/y/sizeData settings, independent query editor, and relationship bindings
query.rows/columns/filtersHierarchy and member-filter editors
controls.<key>Individual presentation/data controls: title, subtitle, description, legend, dataLabels, xAxisTitle, yAxisTitle, totals, drillSyncMode, keepLinked, valueSeries, theme
presentation, customizePresentation controls or all customization settings
chartOptions.<key>Each catalog option, including its reset action
chartOptions.resetAllReset all chart options
axes.y.<field>, axes.ySecondary.<field>Primary/secondary axis scale, min, max, title, unit, notation and precision
axes.seriesLayer, axes.seriesAxisCombination series layers and axis assignment
navigation, interaction, annotations, colorsWhole feature groups; individual controls use the same prefix
actions.viewData, dataViewChart/data switch or the data view itself; hiding an active data view returns to the chart
dataView.sorting/selection/resize/filteringNative data-grid interaction features
context, context.heading, context.closeData details popup, trigger and close action
context.overview/rows/columns/totals/filters/localFilters/noteIndividual information groups within the popup
export, export.png/pdf/svg/csv, actions.exportChartExport menu, formats and trigger
drill, drill.navigate, drill.retryDrill navigation controls
actions.retry, actions.closeChart retry and close actions

Import PIVOT_CHART_UI_CONTROLS, PivotChartUiControlId, PivotChartUiControlState, PivotChartsUiConfig, and PivotChartDataGridConfig from @revolist/pivot or @revolist/pivot/charts for the concrete control inventory and public types. Each rendered control also exposes its stable ID in data-pivot-chart-control; IDs are independent of translated labels.

The current-frame RevoGrid is always read-only. Its source and formatting stay owned by the chart. dataGrid exposes sorting, selection (range), resizing, focus, clipboard, row/column sizes, theme, and category/series column names, sizes, bounds, sortability, and pinning. Global sorting restrictions win over a column’s sortable: true setting.

Column-axis members use native grouped headers: Q1 › Revenue becomes a Q1 group with a Revenue child column. Nested paths and multiple measures share their adjacent parent groups without changing series order. Standalone series without a column path retain their flat names. Values-on-rows layouts use the last column member as the leaf name. columnGrouping: false restores full flat series labels; groupLabel(label, series, level) overrides group names, and seriesColumn overrides leaf names. Groups use semantic member keys, so equal display names do not merge distinct members. Labels come from the dataset; display text is never split to infer a hierarchy.

Sorting and Pro filtering are enabled by default. Category columns offer text conditions and series columns offer numeric conditions against raw values, independent of formatted cell text. The native filter popup is supplied by AdvanceFilterPlugin. Pass RevoGrid’s ColumnFilterConfig through dataGrid.filter, including its localization captions and filter names. Setting filter: false, or disabling dataView.filtering, removes filtering. RevoGrid’s native filter-localization contract is retained rather than introducing a second set of filter strings. categoryColumn.filter and seriesColumn(...).filter can select Pro filter types (such as ['selection']) or disable individual column filters. Global filtering and sorting restrictions win over column overrides. Sorting/filtering affect only the current data grid; they do not change the chart dataset, Pivot report, or exports. They refresh against new frame values and reset when the series schema changes.

The data view uses localeText.dataTable for its accessible name, category header, missing values, and sort actions/announcements. Series names come from the dataset and may be overridden with seriesColumn. Numbers use the supplied formatted dataset values or localeText.renderer.formatNumber.

Function overrides cover dynamic strings as well as fixed labels. In addition to number and data-table formatting, context.frame, context.more, and context.formatFilterValue customize data details. Annotation target/path text and the UTC input hint use annotations.targetLabel, annotations.pathLabel, and annotations.utcPlaceholder.

For a stacked-axis tick whose mathematical value exceeds JavaScript’s finite number range, renderer.formatScaledNumber(value, multiplier) formats the value without requiring their product to fit in a number. The default uses scientific notation, such as 2.697 × 10^308. Override this callback through pivotCharts.localeText to control the complete plotted label. Ordinary representable ticks continue to use renderer.formatNumber. Shared renderer formatters belong in pivotCharts.localeText; pivotChartsUi.localeText overrides inspector and data-view UI text without replacing the plot/export locale.

Radar’s category prerequisite message is customizable with renderer.minimumCategoriesRequired(chartTypeLabel, minimum). Both radar types require three non-total categories; empty frames retain the no-data view.

Use query.formatMemberValue for member-picker values and context.formatFieldLabel for row and column dimension headings and filter headings in data details. The latter receives the configured dimension label when available, otherwise the field name. Their defaults are String(value) and the unchanged resolved field label.

Generated inspector labels also expose formatter callbacks: query.formatMeasureLabel(prop, aggregator) controls the fallback caption when a measure has no configured label, colors.measureLabel(prop, aggregator) controls measure-color captions, colors.memberPathLabel(path) formats member paths, and annotations.coordinateLabel(label, path) formats category reference choices. Configured field and measure names remain application data; rename those in the Pivot configuration.

grid.pivotChartsUi = {
localeText: {
query: { formatMemberValue: value => `Member: ${String(value)}` },
context: { formatFieldLabel: label => `Field: ${label}` },
},
};

A zero-grid chart created with createStandalonePivotChart accepts the same localeText options for its renderer and export text. It does not render the settings sidebar or data-details popup, so UI policies belong to PivotChartsUiPlugin; standalone behavior is configured through the controller’s model/update API and renderer capabilities.

Numeric color-map keys expose localeText.colors.formatValueMapValue(value, role) for the complete displayed number. role is minimum, midpoint, or maximum. An explicit callback is used unchanged, including localized small or long values. When omitted, keys use renderer.formatNumber with the existing compact scientific fallback for small values or long labels. For example:

import type { PivotChartsLocaleTextOptions } from '@revolist/pivot';
const localeText: PivotChartsLocaleTextOptions = {
colors: {
formatValueMapValue: (value, role) => `${role}: ${new Intl.NumberFormat('de-DE').format(value)}`,
},
};

The toolbar’s short captions use actions.chartLabel and actions.dataLabel; actions.viewChart and actions.viewData name their accessible actions. Configure the buttons independently with controls['actions.viewChart'] and controls['actions.viewData']. dataView controls the entire view switch. gallery.tabs.chart/data caption overrides remain fallbacks when the corresponding short caption is not supplied.

Every native dropdown choice supports <controlId>.options.<value>, for example:

grid.pivotChartsUi = {
controls: {
'controls.totals.options.all': 'hidden',
'controls.totals.options.grand': 'disabled',
'query.sortDirection.options.desc': 'disabled',
},
};

These policies configure the editor, without rewriting the chart model. A hidden current choice retains its selected value and label but cannot be chosen from the menu. Parent restrictions and existing capability restrictions still apply. For dynamic choices, use the option’s native value, exposed alongside its full ID in data-pivot-chart-control.

Automatic category grouping and authored axis formatting are also translatable:

grid.pivotCharts = {
renderer,
localeText: {
renderer: {
otherCategoryLabel: 'Autres',
groupedCategoryLabel: (label, index) => `${label} (groupe ${index})`,
formatAxisTick: (value, format) => new Intl.NumberFormat('fr-FR', format).format(value),
formatTimeAxisTick: (epochMilliseconds, dateOnly) =>
new Intl.DateTimeFormat('fr-FR', dateOnly
? { dateStyle: 'medium', timeZone: 'UTC' }
: { dateStyle: 'short', timeStyle: 'short', timeZone: 'UTC' }).format(epochMilliseconds),
},
},
};

Axis formatter callbacks also receive the built-in text as their last argument, so an application can selectively override formats. User-authored titles, field and series labels, units and notes remain application data; use their existing model, column-label and formatter APIs to translate them. Backend diagnostic text can be mapped through status.formatError and drill.formatError.

See appearance and formatting, navigation and the UI API.