@devmm/puredocs-excel-charts
v1.2.0
Published
Chart support for @devmm/puredocs-excel
Readme
@devmm/puredocs-excel-charts
Chart support for
@devmm/puredocs-excel. Generates valid OOXML chart parts (column, bar, line, area, pie, doughnut, radar, scatter, bubble) and embeds them into a workbook — no dependency other than the core package.
Install
npm install @devmm/puredocs-excel @devmm/puredocs-excel-charts@devmm/puredocs-excel is a peer dependency.
Quick start
import { Workbook } from '@devmm/puredocs-excel';
import { ExcelChart, ExcelChartType, ChartLegendPosition } from '@devmm/puredocs-excel-charts';
const wb = Workbook.create();
const sheet = wb.addWorksheet('Sales');
sheet.getRange('A1:B5').setValues([
['Month', 'Revenue'],
['Jan', 120], ['Feb', 150], ['Mar', 130], ['Apr', 180],
]);
ExcelChart.create(ExcelChartType.ColumnClustered)
.setAnchor({ from: 'D2', to: 'K20' })
.setTitle('Monthly Revenue')
.addSeries({ name: 'Sales!$B$1', values: 'Sales!$B$2:$B$5', categories: 'Sales!$A$2:$A$5' })
.configureValueAxis(a => { a.numberFormat = '#,##0'; a.title = 'VND'; })
.configureLegend(l => { l.position = ChartLegendPosition.Bottom; })
.showDataLabels({ value: true })
.addTo(sheet);
await wb.saveToFile('./report.xlsx');Ranges must be absolute and sheet-qualified, e.g.
Sheet1!$B$2:$B$5.
Chart types
ExcelChart.create(type) accepts any ExcelChartType:
| Family | Types |
|---|---|
| Column / Bar | ColumnClustered, ColumnStacked, BarClustered, BarStacked |
| Line | Line, LineMarkers |
| Area | Area |
| Pie | Pie, Doughnut |
| Radar | Radar, RadarMarkers, RadarFilled |
| XY | Scatter, ScatterLines, ScatterSmooth, Bubble |
Series data by family:
| Family | categories | values | bubbleSize |
|---|---|---|---|
| Column/Bar/Line/Area/Pie/Doughnut/Radar | X labels | Y values | — |
| Scatter | X values | Y values | — |
| Bubble | X values | Y values | bubble sizes |
API
ExcelChart.create(type): ExcelChart
Static factory. All configuration methods are fluent (return this).
| Method | Description |
|---|---|
| setAnchor(anchor) | Position: { from: 'D2', to: 'K20' } or { fromRow, fromCol, toRow, toCol } (0-based) |
| setTitle(text) | Chart title |
| addSeries(series) | Add a data series (see ChartSeries) |
| configureLegend(fn) | fn(legend) → set legend.position (ChartLegendPosition) |
| configureCategoryAxis(fn) | fn(axis) → set title / numberFormat / min / max / majorGridlines |
| configureValueAxis(fn) | Same, for the primary value axis |
| configureSecondaryValueAxis(fn) | Same, for the secondary value axis (combo charts) |
| setSecondaryType(type) | Chart type for secondaryAxis series (default Line) |
| showDataLabels(config?) | Toggle labels: { value?, category?, series?, percent? } (default { value: true }) |
| setGapWidth(n) | Bar/column gap width (%) |
| setHoleSize(pct) | Doughnut hole size (10–90) |
| addTo(sheet) | Attach to a Worksheet |
ChartSeries
interface ChartSeries {
name?: string; // ref (contains '!') or literal
values: string; // Y range (absolute, sheet-qualified)
categories?: string; // X range / labels
bubbleSize?: string; // bubble charts only
color?: ExcelColor | string; // '#RRGGBB' or ExcelColor
secondaryAxis?: boolean; // plot on the secondary axis (combo)
trendline?: ChartTrendline; // regression line
pointColors?: (ExcelColor | string)[]; // per-data-point colours
}ChartTrendline
interface ChartTrendline {
type: TrendlineType; // Linear | Exponential | Logarithmic | MovingAverage | Polynomial | Power
order?: number; // Polynomial order (2–6)
period?: number; // MovingAverage period
displayEquation?: boolean;
displayRSquared?: boolean;
}Examples
Multi-series column with data labels
ExcelChart.create(ExcelChartType.ColumnClustered)
.setTitle('Revenue vs Cost')
.addSeries({ name: 'Sales!$B$1', values: 'Sales!$B$2:$B$5', categories: 'Sales!$A$2:$A$5' })
.addSeries({ name: 'Sales!$C$1', values: 'Sales!$C$2:$C$5', categories: 'Sales!$A$2:$A$5' })
.showDataLabels({ value: true })
.addTo(sheet);Pie with per-slice colours and percentages
ExcelChart.create(ExcelChartType.Pie)
.setTitle('Revenue share')
.addSeries({
values: 'Sales!$B$2:$B$5',
categories: 'Sales!$A$2:$A$5',
pointColors: ['#4472C4', '#ED7D31', '#A5A5A5', '#FFC000'],
})
.showDataLabels({ percent: true })
.addTo(sheet);Doughnut
ExcelChart.create(ExcelChartType.Doughnut)
.setHoleSize(60)
.addSeries({ values: 'Sales!$B$2:$B$5', categories: 'Sales!$A$2:$A$5' })
.addTo(sheet);Scatter with a linear trendline
import { TrendlineType } from '@devmm/puredocs-excel-charts';
ExcelChart.create(ExcelChartType.Scatter)
.setTitle('Cost vs Revenue')
.addSeries({
name: 'corr',
categories: 'Sales!$C$2:$C$5', // X
values: 'Sales!$B$2:$B$5', // Y
trendline: { type: TrendlineType.Linear, displayEquation: true, displayRSquared: true },
})
.configureCategoryAxis(a => { a.title = 'Cost'; })
.configureValueAxis(a => { a.title = 'Revenue'; })
.addTo(sheet);Bubble
ExcelChart.create(ExcelChartType.Bubble)
.addSeries({
categories: 'Data!$A$2:$A$6', // X
values: 'Data!$B$2:$B$6', // Y
bubbleSize: 'Data!$C$2:$C$6',
})
.addTo(sheet);Combo chart (column + line on a secondary axis)
ExcelChart.create(ExcelChartType.ColumnClustered)
.setTitle('Revenue vs Margin')
.addSeries({ name: 'Data!$B$1', values: 'Data!$B$2:$B$6', categories: 'Data!$A$2:$A$6' })
.addSeries({ name: 'Data!$D$1', values: 'Data!$D$2:$D$6', categories: 'Data!$A$2:$A$6',
secondaryAxis: true, color: '#ED7D31' })
.setSecondaryType(ExcelChartType.LineMarkers)
.configureValueAxis(a => { a.title = 'VND'; a.numberFormat = '#,##0'; })
.configureSecondaryValueAxis(a => { a.title = 'Margin %'; a.numberFormat = '0"%"'; })
.addTo(sheet);Multiple charts on one sheet
Call .addTo(sheet) several times — all charts are aggregated into a single drawing
part automatically:
ExcelChart.create(ExcelChartType.ColumnClustered).setAnchor({ from: 'E1', to: 'L16' })
.addSeries({ values: 'S!$B$2:$B$5', categories: 'S!$A$2:$A$5' }).addTo(sheet);
ExcelChart.create(ExcelChartType.Line).setAnchor({ from: 'E18', to: 'L33' })
.addSeries({ values: 'S!$B$2:$B$5', categories: 'S!$A$2:$A$5' }).addTo(sheet);Notes & limitations
- Ranges are not validated against the worksheet; pass correct absolute refs.
- Charts are write-only in this version — they are not read back when loading a file.
- Not yet supported: error bars, 3D views. See
DESIGN.mdfor the roadmap.
License
MIT © TVE
