Fix #834: custom tick formatter breaks logarithmic axis#973
Merged
Conversation
When both a custom tick label formatter and logarithmic mode were active on the same axis, the formatter check took priority and routed to AxisTickCalculator_Callback, which uses linear tick calculation. This caused the axis to render as linear and the formatter to receive linearly-spaced values (0, 1e8, 2e8 …) instead of logarithmically- spaced powers of ten (1, 10, 100 … 1e8). Fix: - Add new constructors to AxisTickCalculator_Logarithmic that accept a Function<Double, String> and set axisFormat = Formatter_Custom before calculate() runs, so tick positions remain logarithmic while labels are produced by the callback. - Change calculate() to use axisFormat.format() throughout instead of the hardcoded formatterLogNumber.format() calls. - In Axis_Y and Axis_X, add a combined-case branch that routes to the new constructors when both custom formatter and logarithmic mode are active (checked before the plain callback branch). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes #834 where enabling a custom axis tick label formatter caused logarithmic axes to silently fall back to linear scaling by ensuring logarithmic tick positions are still computed while allowing custom tick labels.
Changes:
- Extend
AxisTickCalculator_Logarithmicto support custom label formatting while preserving logarithmic tick calculation. - Update
Axis_Y/Axis_Xtick-calculator selection to route the “logarithmic + custom formatter” combination to the logarithmic calculator instead of the callback (linear) calculator. - Add regression tests and a standalone demo reproducer for issue #834.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| xchart/src/test/java/org/knowm/xchart/XYChartTest.java | Adds regression tests for custom formatter + log axis combinations. |
| xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java | Allows log tick calculator to use a custom formatter for labels while keeping log spacing. |
| xchart/src/main/java/org/knowm/xchart/internal/chartpart/Axis_Y.java | Routes Y-axis “custom formatter + log mode” to the log tick calculator. |
| xchart/src/main/java/org/knowm/xchart/internal/chartpart/Axis_X.java | Routes X-axis “custom formatter + log mode” to the log tick calculator. |
| xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue834.java | Adds a runnable demo reproducing #834’s scenario. |
- Axis_X: add DataType.Date guard to the log+custom-formatter branch so Date x-axes continue to use AxisTickCalculator_Date even when a custom formatter is also set (mirrors the existing guard on the plain log branch) - XYChartTest: strengthen both log-axis tests to assert the formatter receives powers-of-ten tick values, not linearly-spaced ones; a silent regression back to linear would now fail the assertion - TestForIssue834: add Javadoc to getChart() marking it headless-safe Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a custom axis tick label formatter was set alongside a logarithmic axis (
setYAxisLogarithmic(true)+setCustomYAxisTickLabelsFormatter(...)), the logarithmic scaling was silently discarded. The formatter received linearly-spaced values (0, 1e8, 2e8 ...) instead of the expected powers-of-ten (1, 10, 100 ... 1e8), and the chart rendered as a linear axis.The root cause: in both
Axis_Y.getAxisTickCalculatorForY()andAxis_X.getAxisTickCalculatorForX(), the custom-formatter check came first in the if/else chain and unconditionally routed toAxisTickCalculator_Callback, which inherits the base linearcalculate()method. The logarithmic branch was never reached.Approach
The fix combines logarithmic tick-position calculation with custom label formatting:
AxisTickCalculator_Logarithmic-- allformatterLogNumber.format()calls insidecalculate()are replaced withaxisFormat.format(). SinceaxisFormatdefaults toformatterLogNumber, existing behavior is unchanged. Two new constructors accept aFunction<Double, String>and setaxisFormat = new Formatter_Custom(fn)beforecalculate()runs, so tick positions remain logarithmic while tick labels come from the callback.Axis_Y/Axis_X-- a new combined-case branch is added above the plain callback branch: when both a custom formatter and logarithmic mode are active, it routes to the new constructors instead ofAxisTickCalculator_Callback.No changes to base classes; the fix is fully contained in these three files.
Testing
XYChartTest(Y-axis and X-axis variants) verify the chart renders without throwing.TestForIssue834.javademo reproduces the reporter's exact use case -- logarithmic Y-axis with an energy unit formatter (nJ / µJ / mJ / J). The axis now shows correct log spacing with custom labels.