I have multiple charts, line charts, as well as stacked area charts.
We allow users to zoom on the x-axis (domain axis), and we want to use auto-range for the y-axis (range axis).
While auto-range works fine for line charts, it does not work correctly for the stacked area charts.
Basically, the code looks like this:
Code: Select all
xyPlot.getDomainAxis().setRange(lowerBound, upperBound);
xyPlot.getRangeAxis().setUpperMargin(0.05);
xyPlot.getRangeAxis().setAutoRange(true);
And this works fine for line charts, and I will list why:
Line charts use an XYLineAndShapeRenderer, which inherit from AbstractXYItemRender, which in turn inherits from AbstractRenderer.
The AbstractRenderer defines the property dataBoundsIncludeVisibleSeriesOnly:
Code: Select all
/**
* A flag that controls whether or not the renderer will include the
* non-visible series when calculating the data bounds.
*
* @since 1.0.13
*/
private boolean dataBoundsIncludesVisibleSeriesOnly = true;
Code: Select all
/**
* Returns the range of values the renderer requires to display all the
* items from the specified dataset.
*
* @param dataset the dataset ({@code null} permitted).
* @param includeInterval include the interval (if any) for the dataset?
*
* @return The range ({@code null} if the dataset is {@code null}
* or empty).
*
* @since 1.0.13
*/
protected Range findRangeBounds(XYDataset dataset, boolean includeInterval) {
if (dataset == null) {
return null;
}
if (getDataBoundsIncludesVisibleSeriesOnly()) {
List visibleSeriesKeys = new ArrayList();
int seriesCount = dataset.getSeriesCount();
for (int s = 0; s < seriesCount; s++) {
if (isSeriesVisible(s)) {
visibleSeriesKeys.add(dataset.getSeriesKey(s));
}
}
// the bounds should be calculated using just the items within
// the current range of the x-axis...if there is one
Range xRange = null;
XYPlot p = getPlot();
if (p != null) {
ValueAxis xAxis = null;
int index = p.getIndexOf(this);
if (index >= 0) {
xAxis = this.plot.getDomainAxisForDataset(index);
}
if (xAxis != null) {
xRange = xAxis.getRange();
}
}
if (xRange == null) {
xRange = new Range(Double.NEGATIVE_INFINITY,
Double.POSITIVE_INFINITY);
}
return DatasetUtils.findRangeBounds(dataset,
visibleSeriesKeys, xRange, includeInterval);
}
return DatasetUtils.findRangeBounds(dataset, includeInterval);
}
Yet, things look differently for StackedXYAreaRenderer and StackedXYAreaRenderer2, which are used in stacked area charts.
Both are also child classes of AbstractXYItemRender, but they override findRangeBounds in such a fashion that dataBoundsIncludeVisibleSeriesOnly is not taken into account anymore.
This leads to the problem that data points that are outside of the currently visible chart part are taken into account for bounds calculation even if they shouldn't.
For example, if the highest visible y-point in a zoomed stacked area chart is 1, but somewhere outside the currently visible range there is a y-point of 10, the auto-range would still scale the y-axis to 10.
This is my first time writing on this forum and I do not know how this is handled in other cases...
I think this is a bug that should be fixed (and should not be that hard to fix).
Is it the best to also open an issue on the GitHub page?
Best wishes,
M