Jump to content
We've recently updated our Privacy Statement, available here ×

iReport timeseries chart does not touch zero point


vasu_murthy

Recommended Posts

Hi,
I am using time series charts in iReports designer 3.0.0 to display time in X-axis , count of rows in Y-axis and Series expression to show in various colors.
The issue i am facing is that, if i query the database for 3 days time period and it returns quite a number of rows as follows:
Day 1 -- 3 rows
Day 2 -- 0 rows
Day 3 -- 5 rows

The line drawn by the time Series chart now directly plots from Day 1 to Day 3, i.e., from value 3 to 5 in Y-axis.
Ideally the line should start at point 3 on Day 1, touch zero on Day 2 and then reach 5 on Day 3.
But the way currently the time Series chart behaves is, zero points are ignored in between two non-zero points. In my example it should touch zero point on Day 2 even though my query did not return any rows on that day.
The way the time Series chart plot now joins Day 1 value (3) with Day 3 value (5) and it gives a false impression that Day 2 Y-axis value might be 4, which should have been zero.
Please let me know if you faced this kind of scenario and do I need to provide any more details on the issue.

Thanks
Vasu

Link to comment
Share on other sites

  • 1 year later...
  • Replies 3
  • Created
  • Last Reply

Top Posters In This Topic

I think the problem isn't that day 2 has a value of 0, its day 2 has no entry, I had a similar problem drawing a chart of sparse data. The only solution I found was using a JRChartCustomizer to add the missing periods with a zero value.
 

Code:
package utils;import java.util.Date;import org.jfree.chart.JFreeChart;import org.jfree.chart.plot.XYPlot;import org.jfree.data.time.Day;import org.jfree.data.time.Hour;import org.jfree.data.time.Minute;import org.jfree.data.time.Month;import org.jfree.data.time.Second;import org.jfree.data.time.TimeSeries;import org.jfree.data.time.TimeSeriesCollection;import org.jfree.data.time.Week;import org.jfree.data.time.Year;import net.sf.jasperreports.engine.JRAbstractChartCustomizer;import net.sf.jasperreports.engine.JRChart;/** * This is a Jasper Reports chart customizer for time series chart that will fill in * missing time periods in the dataset with 0 value entries. For example if your plotting * the number of hits to a website by hour and there were 10 hits at midnight and 10 hits * at 6 am, but no hits from 1 am to 5 am by default the time series chart will draw a strait * line from the midnight plot point to the 6 am plot point, if you want the line to drop to * zero this class can be set in the chart element customizerClass attribute and Jasper Reports * will call it before generating the chart. *  * NOTE: this has dependencies on the jrxml file that a startDateInternal and endDateInternal * property exists that holds the start and end date to be plotted. *  * @author ron@nellymoser.com * */public class JRTimeSeriesCustomizerEmptyDateFiller extends JRAbstractChartCustomizer {	public void customize(JFreeChart chart, JRChart jasperChart) {		Date startDate = (Date) getParameterValue("startDateInternal", true);		Date endDate = (Date) getParameterValue("endDateInternal", true);				if (chart.getPlot() != null && chart.getPlot() instanceof XYPlot) {			XYPlot plot = (XYPlot) chart.getPlot();			for (int i = 0; i < plot.getDatasetCount(); i++) {				Object genericDataSet = plot.getDataset(i);				if (genericDataSet != null && genericDataSet instanceof TimeSeriesCollection) {					TimeSeriesCollection tsc = (TimeSeriesCollection) genericDataSet;					for (Object genericTimeSeries : tsc.getSeries()) {						if (genericTimeSeries != null && genericTimeSeries instanceof TimeSeries) {							TimeSeries timeSeries = (TimeSeries) genericTimeSeries;							fillInMissingPeriods(timeSeries, startDate, endDate, timeSeries.getTimePeriodClass());						}					}				}			}		}	}		// TODO: it would be more effecient to move the while inside each if statement so the if is only executed	// once instead of each period from start to end.	private void fillInMissingPeriods(TimeSeries timeSeries, Date startDate, Date endDate, Class<?> period) {		Date dateIndex = startDate;		while (dateIndex.before(endDate)) {			if (Day.class.equals(period)) {				dateIndex = DateUtils.startOfDay(dateIndex);				if (timeSeries.getDataItem(new Day(dateIndex)) == null) {					timeSeries.add(new Day(dateIndex), 0.0d);				}				dateIndex = DateUtils.addDays(dateIndex, 1);			} else if (Hour.class.equals(period)) {				dateIndex = DateUtils.startOfHour(dateIndex);				if (timeSeries.getDataItem(new Hour(dateIndex)) == null) {					timeSeries.add(new Hour(dateIndex), 0.0d);				}				dateIndex = DateUtils.addHours(dateIndex, 1);			} else if (Minute.class.equals(period)) {				dateIndex = DateUtils.startOfMinute(dateIndex);				if (timeSeries.getDataItem(new Minute(dateIndex)) == null) {					timeSeries.add(new Minute(dateIndex), 0.0d);				}				dateIndex = DateUtils.addMinutes(dateIndex, 1);			} else if (Second.class.equals(period)) {				dateIndex = DateUtils.startOfSecond(dateIndex);				if (timeSeries.getDataItem(new Second(dateIndex)) == null) {					timeSeries.add(new Second(dateIndex), 0.0d);				}				dateIndex = DateUtils.addSeconds(dateIndex, 1);			} else if (Week.class.equals(period)) {				dateIndex = DateUtils.startOfWeek(dateIndex);				if (timeSeries.getDataItem(new Week(dateIndex)) == null) {					timeSeries.add(new Week(dateIndex), 0.0d);				}				dateIndex = DateUtils.addDays(dateIndex, 7);			} else if (Month.class.equals(period)) {				dateIndex = DateUtils.startOfMonth(dateIndex);				if (timeSeries.getDataItem(new Month(dateIndex)) == null) {					timeSeries.add(new Month(dateIndex), 0.0d);				}				dateIndex = DateUtils.addMonths(dateIndex, 1);			} else if (Year.class.equals(period)) {				dateIndex = DateUtils.startOfYear(dateIndex);				if (timeSeries.getDataItem(new Year(dateIndex)) == null) {					timeSeries.add(new Year(dateIndex), 0.0d);				}				dateIndex = DateUtils.addYears(dateIndex, 1);			} else {				// un-expected time period				throw new Exception("The supplied time period " + period.getName() + " is unsupported, use Second, Minute, Hour, Day, Week, Month, and Year.");			}		}	}}
Link to comment
Share on other sites

  • 2 months later...

Hello rreganjr,

I'm really interested in your customizer class but I get errors compiling it on my system (see messages below).

 

I can't find the DateUtils class anywhere. Can you tell me to find it ? If it's custom made can you send it to me ?

 

Thanks,

 

Mixcom

Code:
JRTimeSeriesCustomizerEmptyDateFiller.java:62: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfDay(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:66: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addDays(dateIndex, 1);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:68: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfHour(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:72: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addHours(dateIndex, 1);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:74: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfMinute(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:78: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addMinutes(dateIndex, 1);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:80: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfSecond(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:84: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addSeconds(dateIndex, 1);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:86: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfWeek(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:90: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addDays(dateIndex, 7);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:92: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfMonth(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:96: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addMonths(dateIndex, 1);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:98: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.startOfYear(dateIndex);                           ^JRTimeSeriesCustomizerEmptyDateFiller.java:102: cannot find symbolsymbol  : variable DateUtilslocation: class utils.JRTimeSeriesCustomizerEmptyDateFiller               dateIndex = DateUtils.addYears(dateIndex, 1);
Link to comment
Share on other sites

Hi Mixcom,

I also working on a similiar issue, however it seems that many functions in  java.util.Date have been deprecated. I have found a similar DateUtils functionality in org.apache.commons.lang.time.DateUtils, howver it is still missing several functions.

I am still working on a solution however, not sure as of yet.

 

Thanks

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...