Unfortunately, the code grew pretty large. I tried to compress it to the main commands:
Basically, my data is stored in objects named trends, the graph is an XYPlot with a TimeSeriesCollection, each dataset holding exactly one series. The domainaxis is of type DateAxis while I use a custom extension of NumberAxis for the range axis. Maybe there lies the problem? I've posted the code before in this forum. It is again attached here. The main purpose of the extension was, that the tickunits actually all start at 0 but I wanted them to start at the bottom of my Valueaxis...
Code: Select all
//get current curve
trend = trends[i];
set = new Integer(trend.getSet());
trendID = new Integer(trend.getID());
//get DataSet and Renderer for this Trend or create new ones:
dataset = (TimeSeriesCollection) this.datasets.get(trendID);
renderer = (XYItemRenderer) this.renderer.get(trendID);
if (dataset == null) {
//--> create dataset
dataset = new TimeSeriesCollection();
this.datasets.put(trendID, dataset);
}
if (renderer == null) {
//--> create renderer
renderer = new StandardXYItemRenderer(StandardXYItemRenderer.LINES);
this.renderer.put(trendID, renderer);
}
//set color.
renderer.setPaint(trend.getColor());
//Set larger stroke
renderer.setStroke(selectedStroke);
// ---> Create series and fill it with data
TimeSeries series = new TimeSeries(trend.getTagName(), Millisecond.class);
for(int j=0; j<trend.getLength(); ++j){
series.addOrUpdate(trend.getTimeData(j),trend.doubleValue(j));
}
//Each Dataset has only one series. As we have just created a new one, remove the old!
dataset.removeAllSeries();
//Add new series to dataset of this trend
dataset.addSeries(series);
// Set or create the graph's range axis.
NumberAxis rangeAxis = (NumberAxis) this.rangeAxes.get(trendID);
rangeAxis.setRange(trend.getStartY(), trend.getEndY());
((CustomTickNumberAxis)rangeAxis).setLowestVisibleTickValue(new Double(trend.getStartY()));
double range = rangeAxis.getUpperBound() - rangeAxis.getLowerBound();
if (range < 10)
rangeAxis.setTickUnit(new NumberTickUnit(range / 10.0, doubleFormatter));
else
rangeAxis.setTickUnit(new NumberTickUnit(range / 10.0, intFormatter));
// Set this axis at the current next free position
rangeAxis.setLabel(""+trend.getSet());
((CustomTickNumberAxis)rangeAxis).setMarkerPaint(trend.getColor());
((CustomTickNumberAxis)rangeAxis).setSet(trend.getSet());
plot.setRangeAxis(count, rangeAxis);
plot.setRangeAxisLocation(count, AxisLocation.BOTTOM_OR_LEFT);
domainAxis = (DateAxis) this.domainAxes.get(trendID);
double end = trend.getEndX();
double finalTick = ((end-start) / 1000) / 11;
DateTickUnit tick = new DateTickUnit(DateTickUnit.SECOND, (int)finalTick);
domainAxis.setTickUnit(tick);
domainAxis.setRange(start, end);
//take values of the trend.
// getTimeData(int) accesses a Millisecond[].
long startX = trend.getTimeData(0).getFirstMillisecond();
long endX = trend.getTimeData(trend.getLength()-1).getFirstMillisecond();
adjustDomainAxis(domainAxis, startX, endX);
plot.setDomainAxis(count, domainAxis);
plot.setDomainAxisLocation(count, AxisLocation.BOTTOM_OR_RIGHT);
plot.getRangeAxis(count).setVisible(true);
plot.getDomainAxis(count).setVisible(true);
// .. then some annotations are added that I left out here ..
plot.setDataset(count, dataset);
plot.setRenderer(count, renderer);
plot.mapDatasetToRangeAxis(count, count);
plot.mapDatasetToDomainAxis(count, count);
And here for the custom NumberAxis that is used (see setLowestVisibleTickUnit above.) :
Code: Select all
public static class CustomTickNumberAxis extends org.jfree.chart.axis.NumberAxis {
/**
* Holds value of property lowestVisibleTickValue.
* The lowest visible tick unit is the bottom anchor for a vertical
* number axis.
* NOTE: Make sure this value is >= the lowerBound of the NumberAxis, as
* otherwise it will be ignored as it cannot be displayed correctly.
* See {@link #calculateLowestVisibleTickValue}.
*/
private Double lowestVisibleTickValue;
/**
* Calculates the value of the lowest visible tick on the axis or
* returns any previously specified. See {@link #lowestVisibleTickValue}.
* If the specified value is smaller than the lower bound of the axis, the
* default method (see {@link NumberAxis#calculateLowestVisibleTickValue})
* is used.
* @return The value of the lowest visible tick on the axis.
*/
protected double calculateLowestVisibleTickValue() {
if (lowestVisibleTickValue != null && lowestVisibleTickValue.doubleValue() >= getRange().getLowerBound()) {
return lowestVisibleTickValue.doubleValue();
} else
return super.calculateLowestVisibleTickValue();
}
/**
* Getter for property lowestVisibleTickValue.
* @return Value of property lowestVisibleTickValue.
*/
public Double getLowestVisibleTickValue() {
return this.lowestVisibleTickValue;
}
/**
* Setter for property lowestVisibleTickValue.
* @param lowestVisibleTickValue New value of property lowestVisibleTickValue.
*/
public void setLowestVisibleTickValue(Double lowestVisibleTickValue) {
this.lowestVisibleTickValue = lowestVisibleTickValue;
}
}
regards,
Christopher
P.S.: Ok, I just rechecked, the problem still appears if I'm using the normal NumberAxis... In that case it happens more frequently, that the lowest and highest tick value are left out...