Charts
Charts visualize worksheet data with the chart model and UI packages.
Plugin Mode
pnpm add @univerjs-pro/chart-ui @univerjs-pro/sheets-chart @univerjs-pro/sheets-chart-uinpm install @univerjs-pro/chart-ui @univerjs-pro/sheets-chart @univerjs-pro/sheets-chart-uiyarn add @univerjs-pro/chart-ui @univerjs-pro/sheets-chart @univerjs-pro/sheets-chart-uibun add @univerjs-pro/chart-ui @univerjs-pro/sheets-chart @univerjs-pro/sheets-chart-uiimport ChartUIEnUS from '@univerjs-pro/chart-ui/locale/en-US'import { UniverSheetsChartPlugin } from '@univerjs-pro/sheets-chart'import { UniverSheetsChartUIPlugin } from '@univerjs-pro/sheets-chart-ui'import SheetsChartUIEnUS from '@univerjs-pro/sheets-chart-ui/locale/en-US'import SheetsChartEnUS from '@univerjs-pro/sheets-chart/locale/en-US'import { LocaleType, mergeLocales, Univer } from '@univerjs/core'import '@univerjs-pro/chart-ui/facade'import '@univerjs-pro/sheets-chart/facade'import '@univerjs-pro/chart-ui/lib/index.css'import '@univerjs-pro/sheets-chart-ui/lib/index.css'const univer = new Univer({ locale: LocaleType.EN_US, locales: { [LocaleType.EN_US]: mergeLocales(ChartUIEnUS, SheetsChartEnUS, SheetsChartUIEnUS), },})univer.registerPlugin(UniverSheetsChartPlugin)univer.registerPlugin(UniverSheetsChartUIPlugin)Mobile support
First configure the mobile editor. In this page’s plugin-mode setup, replace the desktop registrations below with their mobile exports from the same packages, before opening a document. Keep the model plugins, styles, locales and Facade imports; do not register both variants.
| Package | Desktop registration | Mobile registration |
|---|---|---|
@univerjs-pro/sheets-chart-ui | UniverSheetsChartUIPlugin | UniverSheetsChartMobileUIPlugin |
Preset Mode
The chart feature is included in @univerjs/preset-sheets-advanced. It requires the drawing preset at runtime.
pnpm add @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advancednpm install @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advancedyarn add @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advancedbun add @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advancedimport { UniverSheetsAdvancedPreset } from '@univerjs/preset-sheets-advanced'import UniverPresetSheetsAdvancedEnUS from '@univerjs/preset-sheets-advanced/locales/en-US'import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsDrawingPreset } from '@univerjs/preset-sheets-drawing'import UniverPresetSheetsDrawingEnUS from '@univerjs/preset-sheets-drawing/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-advanced/lib/index.css'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-drawing/lib/index.css'const { univerAPI } = createUniver({ locale: LocaleType.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( UniverPresetSheetsCoreEnUS, UniverPresetSheetsDrawingEnUS, UniverPresetSheetsAdvancedEnUS, ), }, presets: [UniverSheetsCorePreset(), UniverSheetsDrawingPreset(), UniverSheetsAdvancedPreset()],})Create and update charts
worksheet.newChart(type) creates a detached builder. Nothing is added to the worksheet until you build the chart information and pass it to worksheet.insertChart(info).
const workbook = univerAPI.getActiveWorkbook()if (!workbook) throw new Error('No active workbook')const worksheet = workbook.getActiveSheet()const info = worksheet .newChart(univerAPI.Enum.ChartTypeString.Column) .setSource({ range: 'A1:D6', orientation: univerAPI.Enum.ChartSourceOrientation.Columns, }) .setPosition('F2') .setSize(640, 360) .setCategoryField(0) .setValueFields([1, 2, 3]) .setTitle('Quarterly revenue') .build()const chart = await worksheet.insertChart(info)chart.setLegend({ visible: true }).bringToFront()const updatedInfo = chart.toBuilder(univerAPI.Enum.ChartTypeString.Line).setSubtitle('FY 2026').build()await chart.update(updatedInfo)const svg = await chart.exportImage({ format: 'svg' })Setters on the inserted chart update it immediately. Use toBuilder(type) with update(info) when you need a complete detached copy or want to change the chart type. exportImage() returns undefined when no UI renderer can provide an image.
Use worksheet.getCharts() and worksheet.getChart(id) to resolve live charts. Call await chart.remove() when you want to delete one, and register shared ECharts themes with univerAPI.registerTheme(name, theme).
Multi-level category axes
When adjacent source columns form a hierarchy, pass their zero-based indexes to setCategoryFields() in root-to-leaf order and enable the multi-level axis.
const info = worksheet .newChart(univerAPI.Enum.ChartTypeString.Column) .setSource({ range: 'A1:D7', orientation: univerAPI.Enum.ChartSourceOrientation.Columns, }) .setCategoryFields([0, 1]) .setMultiLevelCategoryAxis(true) .setValueFields([2, 3]) .setPosition('F2') .build()const chart = await worksheet.insertChart(info)chart.setCategoryFields([0, 1]).setMultiLevelCategoryAxis(true)Call clearCategoryFields() to remove the ordered mapping. setMultiLevelCategoryAxis(false) keeps the selected fields and only disables hierarchical rendering.
Supported chart types
Use univerAPI.Enum.ChartTypeString for Line, Column, ColumnStacked, ColumnPercentStacked, Bar, BarStacked, BarPercentStacked, Pie, Donut, Area, AreaStacked, AreaPercentStacked, Radar, Scatter, Combination, WordCloud, Funnel, Bubble, Relation, Waterfall, Pareto, Sankey, Heatmap, Boxplot, Candlestick, Histogram, Treemap, Sunburst, Gauge, and Chord.
See the Chart Facade reference for the shared builder configuration API.
Hidden data and independent categories
setPlotVisibleOnly(false) includes values from hidden rows and columns; use getPlotVisibleOnly() to inspect the setting. For sources with separate category columns, setSeriesToCategory() maps each value-field index to its category-field indexes. Indexes refer to the physical source vectors, not the filtered visible series. Missing entries inherit the shared categories; {} clears the overrides.
For example, with columns A:D, the value series in D can use C as its category while B keeps the shared category in A.
const chart = worksheet.getCharts()[0]if (!chart) throw new Error('No chart')chart.setPlotVisibleOnly(false)chart.setSeriesToCategory({ 3: [2] })For aggregated interactive reports, see PivotCharts.
3D charts
3D variants use the same chart plugin registration. Select a 3D chart type, then configure the view on its detached builder.
Supported types are Line3D, Column3D, ColumnStacked3D, ColumnPercentStacked3D, Bar3D, BarStacked3D, BarPercentStacked3D, Pie3D, Area3D, AreaStacked3D, and AreaPercentStacked3D.
const info = worksheet .newChart(univerAPI.Enum.ChartTypeString.Column3D) .setSource('A1:C5') .setCategoryField(0) .setValueFields([1, 2]) .setPosition('F18') .setSize(640, 360) .setThreeD({ view: { rotX: 20, rotY: 30, rightAngleAxes: false, perspective: 30 }, gapDepth: 120, }) .build()await worksheet.insertChart(info)perspective is applied to axis-based charts when rightAngleAxes is false. clearThreeD() clears authored view settings while keeping the 3D chart type and depth axis; use clearDepthAxis() for the latter. 3D axis charts do not expose secondary axes or trendlines, and Pie3D uses solid pie geometry.
Logarithmic value axes
For supported 2D Line, Area, Column, Bar, and Combination charts, set scaleType: 'log' on the numeric axis. Use setYAxis() for vertical value axes and setXAxis() for a Bar chart’s horizontal numeric axis. setRightYAxis() configures an existing secondary numeric axis.
The default base is 10. A custom logBase must be finite and between 2 and 1000, including fractional values such as 2.5. Numeric bounds must be positive. Zero and negative data points are omitted from the logarithmic plot without changing the source data. Percent-stacked and 3D charts do not support logarithmic axes.
const info = worksheet .newChart(univerAPI.Enum.ChartTypeString.Line) .setSource('A1:B5') .setYAxis({ scaleType: 'log', logBase: 10 }) .setPosition('F36') .setSize(640, 360) .build()const chart = await worksheet.insertChart(info)await chart.update( chart.toBuilder(univerAPI.Enum.ChartTypeString.Line) .setYAxis({ scaleType: 'linear' }) .build(),)Build and insert a new chart, or apply a detached update with await chart.update(builder.build()). Setting scaleType: 'linear' removes the logarithm base; unrelated axis patches preserve the scale.
How is this guide?