Spredin

Charting

This is the same document you'll find inside Spredin under Help.

Spredin charts are powered by Apache ECharts. A chart is a floating card bound to a cell range: edit the cells and the chart updates live. You can build and fully customise charts from the UI, from Python, or from an LLM/agent — all three drive the same options, and the raw ECharts option is always reachable as an escape hatch.

Create a chart#

A new chart is named from its data: a chart of one series takes that series' name, as in Excel; one of several has no title until you give it one (Excel shows a placeholder; a script's title wins). It goes beside its table — right of it when it fits in the window, else below — and where neither fits, where it covers the least of the table.

A drag or a resize of the card is one step to undo, and a box in the ⚙ panel changes the chart when you press Enter or leave the box, not at every key.

Chart types#

bar · stackedBar · horizontalBar · line · stepLine · area · stackedArea · pie · donut · rose · scatter · radar · funnel · polarBar · treemap · sunburst · heatmap · boxplot · candlestick

Seven appear as quick-switch icons on the chart card — bar, stacked bar, line, area, stacked area, pie and scatter. All are in the ⚙ panel's Type picker, each with a one-line hint on when to use it. Notes on the extra types:

Detailed editing (the ⚙ panel — Excel-style)#

Click ⚙ (Edit chart) on a chart card for:

Option What it does
Type Switch chart type
Data range Re-bind to a different A1 range
X / Y axis title Axis names
Y min / max Fix the value-axis bounds (blank = automatic, see The automatic value axis below)
Legend Hidden / Top / Bottom / Left / Right
Swap rows / columns Chart the data the other way round (see above)
First row is headers Automatic (text over numbers), Yes or No — say Yes when the headers are numbers, such as years
Swap X / Y axes Turn a bar, line or area chart on its side — categories down the side, values across
Series types (combo) Draw each series as a bar, line or area in one chart; type a column range (B:D) to set several at once
Gridlines Toggle value-axis gridlines
Smooth lines Curved vs. straight line/area
Data labels + format Show values on points/bars/slices; format is an ECharts template ({c} value, {b} name, {d}% percent)
Log scale (Y) Logarithmic value axis
Zoom slider A slider under the chart to zoom into part of a long series
Average line A dashed line at each series' average
Toolbox (save / zoom) Chart buttons to save an image, zoom into a box, see the data as a table, and reset
Empty cells What an empty cell (or #N/A) does to a line or bar: a gap (the default, as in Excel), zero, or connect with a line. A formula that reads an empty cell shows 0 and is plotted at 0; a formula that gives "" counts as an empty cell here.
Dual axis (combo) Plot the last series on a secondary Y (e.g. bars + a %-margin line)
Series colours Comma-separated hex overrides
Advanced (ECharts JSON) A raw ECharts option fragment deep-merged over the generated chart — the full library

Swap X / Y axes, Series types, Zoom slider, Average line, Toolbox and Empty cells appear for bar, line and area charts (stacked and step versions included).

Values look as they do in the cells. The value axis, data labels and tooltips use each column's number format: a $#,##0 column reads $1,507,108, a 0.0% column 12.3% (Excel's "linked to source"). When the series on one axis have different formats, that axis shows plain numbers. With rows and columns swapped, each series is a row, so it takes the format the value columns share, and shows plain numbers when they differ. A data-label format you set in the panel wins over the cells'. The category labels follow the first column's format too, so a column of payments formatted $#,##0 reads $300 along the axis, and a date column reads as the grid shows it — Jul 2025 for a column formatted mmm yyyy, not the date's serial number.

A single column charts as one series over its positions (1, 2, 3…), named by its header, as in Excel.

Box plots follow Excel's box and whisker: the whiskers reach the furthest value within 1.5 × the box's height (the IQR), and anything further out is drawn as a separate point. A box plot summarises columns, so a first column of numbers is a box of its own, unless it reads as row labels (names, or a run like 1, 2, 3 or 2019…2023).

Other niceties: drag the title bar to move, drag the corner to resize, double-click the title to rename, ⤓ exports a PNG (in the desktop app, through the save panel).

The automatic value axis#

With Y min and Y max blank, a line, step-line or scatter chart scales its value axis the way Excel's automatic axis does:

Python / agent API#

# Simple
sheet.chart("A1:E5", "line", "Sales by quarter")

# Excel-style options (snake_case keywords)
sheet.chart("A1:E5", "bar", "Revenue",
            x_title="Quarter", y_title="USD",
            y_min=0, legend_pos="top", labels=True, label_fmt="{c}",
            gridlines=False, colors=["#4f6bed", "#e5604d"])

# Combo (bars + a line on a second axis)
sheet.chart("A1:C13", "bar", "Revenue vs margin", dual_axis=True)

# Change a chart already on the sheet (its id, or its place in sheet.charts())
sheet.update_chart(0, type="line", title="By month", y_min=0)
sheet.clear_charts()   # before re-adding on a re-run: charts are added, never replaced

A chart shows data from its own sheet: to chart another sheet's data, make it there, sheet.book("Data").chart("A1:C9", "bar"). A range that names another sheet raises an error that says so.

Full ECharts power — the echarts= escape hatch#

Anything the structured options don't cover, pass as a raw ECharts option fragment; it is deep-merged over the generated option (objects merge, arrays/scalars replace). This unlocks the whole library — markLine, markArea, dataZoom, visualMap, custom tooltip formatters, multiple grids, etc.

The fragment is saved inside the workbook, so it travels with every copy you send. For that reason it cannot put anything into the page: a string containing < or >, a javascript: link, a title link, and the tooltip's CSS and DOM options are dropped, and a custom tooltip template is drawn on the chart itself rather than as HTML. Templates such as {b}: {c} units and rich-text styles work as usual.

sheet.chart("A1:E5", "line", "With an average line", echarts={
    "tooltip": {"trigger": "axis"},
    "series": [{"markLine": {"data": [{"type": "average", "name": "Avg"}]}}],
    "dataZoom": [{"type": "inside"}],
})

Keyword options map to chart fields (x_title→xTitle, y_title→yTitle, y_min→yMin, y_max→yMax, log_y→logY, dual_axis→dualAxis, legend_pos→legendPos, label_fmt→labelFmt, series_types→seriesTypes, mean_line→meanLine). The others keep their names: legend=False, labels=True, gridlines=False, smooth=True, colors=[…], transpose=True, horizontal=True (swap X / Y), zoom=True, toolbox=True, empty='zero' (or 'gap', 'connect'), and header=True when the series names in the first row are numbers (2023, 2024). echarts= takes any ECharts JSON. An option or value a chart cannot use raises and names what is allowed.

Charts and Excel files#

Notes & limits#