You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
itle: Feature Request – Secondary Y-Axis Support for Charts
Hello GridCraft Development Team,
I am currently testing GridCraft as an alternative to Microsoft Excel, particularly for environmental monitoring and water quality data analysis.
I have successfully created charts with dates on the horizontal axis and multiple data series.
However, I have not been able to find an option to assign different data series to independent vertical axes.
Requested feature: Secondary Y-Axis support
It would be very useful to have the ability to:
Assign individual data series to either the primary or secondary Y-axis.
Configure independent scales, minimum and maximum values, and units for each axis.
Create combination charts, for example columns for conductivity and lines for pH.
Maintain full compatibility with Microsoft Excel XLSX files, including editable charts and secondary axes.
Practical example: Water quality monitoring
X-axis: Date
Primary Y-axis: Conductivity (0–3,000 µS/cm)
Secondary Y-axis: pH (6–10)
Conductivity: Column chart
pH: Line chart
This functionality is particularly important for scientific, industrial and environmental monitoring applications, where parameters have very different measurement scales.
Could you please confirm whether secondary Y-axis support is already available in GridCraft or whether it is planned for a future release?
Hi Mike, not a maintainer, just another Excel user testing GridCraft on Windows. I tried your exact example (conductivity as columns on the primary axis 0 to 3,000, pH as a line on a secondary axis 6 to 10, titles on both).
What already worked: GridCraft reads an Excel combo chart with a secondary axis and draws it correctly, columns on the left axis and the pH line on its own right-hand axis.
A way to build it inside GridCraft: the Format pane's Series section now has a chart type picker and a "Secondary axis" box per series (or chart.formatSelection {series, secondary, type} for scripts).
Fixed axis scales: Minimum, Maximum and Major unit for both vertical axes, plus the secondary axis title, in a new Axes section of the Format pane. They are read from and written to the XLSX, so a round trip through GridCraft no longer sends your axes back to Automatic (before the PR, Excel reopened the file with 0 to 2,500 and 0 to 9 and no pH title).
Checked by opening the results in Excel for Microsoft 365: series types, axis groups, bounds, units and titles all come back as set. Log scale, minor units and the horizontal axis options are not in this PR.
Fixes it. The reporter's chart can now be built in GridCraft: conductivity as columns on 0–3,000, pH as a line on a secondary axis 6–10 with its own title. Excel reads it back exactly as set, and a combo with fixed bounds made in Excel survives a round trip through GridCraft. There are a few problems around the edges, listed below.
Setup: PR head 67217f7, merged locally into main at a1c8454 (the conflicts needed some resolving, see Merging), Windows 11. Checked with:
gridcraft-cli from the PR and from main;
the PR's tests and a temporary render probe;
Excel for Microsoft 365 through COM. A combo with fixed bounds was built in Excel and saved to a scratch folder, and the GridCraft-written files were opened in Excel.
Case
main
PR
chart.formatSelection {"series":1,"secondary":true,"type":"line"} on a column chart
accepted, but the chart stays a plain column chart
combo: series 1 columns on axis 1, series 2 a line on axis 2 (read back in Excel)
chart.set {"yMin":0,"yMax":3000,"yUnit":500,"y2Min":6,"y2Max":10,"y2Title":"pH"}, saved, opened in Excel
ignored
Excel shows 0–3000 by 500 and 6–10 titled "pH"
Excel-made combo with these bounds, opened and saved by GridCraft, reopened in Excel
bounds become automatic (0–3500 and 0–10), "pH" title lost
0–3000 by 500 and 6–10, "pH" kept
yMin ≥ yMax, yUnit 0, a missing series
—
refused with a clear message
Problems:
A fixed major unit that gives more than 50 steps only labels the first 50. apply_fixed accepts up to 1,000 steps, but Scale::ticks stops at 50. On a 0–1,000 axis, unit 1 draws labels and gridlines only from 0 to 50, and unit 10 only up to 500; the rest of the axis has none.
let step = match fixed.major_unit.filter(|u| u.is_finite() && *u > 0.0 && span / *u <= 1000.0){
A fixed Minimum above the automatic maximum is silently dropped. With data 100…1,000 and yMin 2000, the axis stays 0–1,200. The value is stored and saved, but has no effect on screen.
The pane's new labels ("Axes", "Vertical axis", "Secondary vertical axis", "Minimum:", "Major unit:", "Secondary axis", …) are not passed through the translation tables. This is minor.
Merging: conflicts with main at a1c8454 in crates/chart/src/tests.rs, crates/engine/src/cmd/insert.rs, crates/engine/src/tests.rs, crates/xlsx/src/chart.rs, crates/xlsx/src/chartex.rs, crates/xlsx/src/tests/mod.rs and docs/chart-parity.md. After resolving:
main's new XLSX tests (chart_book_names.rs, multilevel_category_roundtrip.rs) need the three new Chart fields;
the PR's axis_roundtrip.rs needs main's Series::quartiles.
Activity
Combo chart with secondary axis rendered by GridCraft (storytold#1267)
storytold#1267 screenshots
storytold#1267 screenshots
richard1912 commentedon Oct 14, 2026
Hi Mike, not a maintainer, just another Excel user testing GridCraft on Windows. I tried your exact example (conductivity as columns on the primary axis 0 to 3,000, pH as a line on a secondary axis 6 to 10, titles on both).
What already worked: GridCraft reads an Excel combo chart with a secondary axis and draws it correctly, columns on the left axis and the pH line on its own right-hand axis.
What was missing, and what PR #1290 adds:
chart.formatSelection {series, secondary, type}for scripts).Checked by opening the results in Excel for Microsoft 365: series types, axis groups, bounds, units and titles all come back as set. Log scale, minor units and the horizontal axis options are not in this PR.
iluebbe commentedon Oct 23, 2026
#1290 checked
Fixes it. The reporter's chart can now be built in GridCraft: conductivity as columns on 0–3,000, pH as a line on a secondary axis 6–10 with its own title. Excel reads it back exactly as set, and a combo with fixed bounds made in Excel survives a round trip through GridCraft. There are a few problems around the edges, listed below.
Setup: PR head 67217f7, merged locally into
mainat a1c8454 (the conflicts needed some resolving, see Merging), Windows 11. Checked with:gridcraft-clifrom the PR and frommain;mainchart.formatSelection {"series":1,"secondary":true,"type":"line"}on a column chartchart.set {"yMin":0,"yMax":3000,"yUnit":500,"y2Min":6,"y2Max":10,"y2Title":"pH"}, saved, opened in ExcelyMin≥yMax,yUnit0, a missing seriesProblems:
apply_fixedaccepts up to 1,000 steps, butScale::ticksstops at 50. On a 0–1,000 axis, unit 1 draws labels and gridlines only from 0 to 50, and unit 10 only up to 500; the rest of the axis has none.gridcraft/crates/chart/src/axis.rs
Line 25 in 67217f7
gridcraft/crates/chart/src/axis.rs
Line 149 in 67217f7
yMin2000, the axis stays 0–1,200. The value is stored and saved, but has no effect on screen.gridcraft/crates/chart/src/axis.rs
Line 145 in 67217f7
0,5becomes 5.gridcraft/crates/ui-egui/src/panes.rs
Line 250 in 67217f7
main(08902d9, fix(xlsx): combination-chart import loses the first group's series types #1014). The two versions conflict, andmain's loop no longer has thegivariable the PR's lines use.Merging: conflicts with
mainat a1c8454 incrates/chart/src/tests.rs,crates/engine/src/cmd/insert.rs,crates/engine/src/tests.rs,crates/xlsx/src/chart.rs,crates/xlsx/src/chartex.rs,crates/xlsx/src/tests/mod.rsanddocs/chart-parity.md. After resolving:main's new XLSX tests (chart_book_names.rs,multilevel_category_roundtrip.rs) need the three newChartfields;axis_roundtrip.rsneedsmain'sSeries::quartiles.It also overlaps with other open chart PRs:
Chartfields and edits the same<c:scaling>writer and reader, so mostChartliterals conflict.nice_scale(lo, hi, force_zero)call.Scale::tickssnapping.chart.setparameter line.useandpub uselines inrender.rsandchart/src/lib.rs(trivial).Tests (merged with
main, with the additions above):cargo test -p gridcraft-chart42 passed.-p gridcraft-model: 23 passed.-p gridcraft-xlsx: 254 passed, including the newaxis_roundtriptests.-p gridcraft-engine --lib: 391 passed.-p gridcraft-ui-egui --lib: 151 passed.cargo clippy -p gridcraft-chart -p gridcraft-xlsx -p gridcraft-engine -p gridcraft-model -p gridcraft-ui-egui --all-targets -- -D warningsandcargo fmt --all -- --checkare clean. Not run: the ui-egui integration tests.