I am facing an issue in JFreeChart while trying to remove the gaps from TimeLine. There are following 2 things that I am trying to achieve:
1). Remove the days from timeline which are Saturday/Sunday or holidays
2). Remove the intra-day gaps for shifts, from the timeline. There are 3 shifts in any working day as following:
a) shift1: - 0000 – 0759 ( i.e. from midnight to 8 am in morning)
b) shift2: - 0800 – 1559 ( i.e. from 8 am in morning to 1559 pm in evening)
c) shift3: - 1600 – 2359 ( i.e. from 16 pm in evening to 2359 pm in night)
I am using the SegmentedTimeLine class to achieve the removal of gaps from time line.
There is a Calendar UI, which enables a user to select the start date and end date for the data range that he wants to see.
Calendar UI also allow user to de-select the week-days ( i.e. any day from Monday – Friday) for which he do not want to see the data and also provides the user to select any of the 3 shifts in a day (shift1, shift2 or shift3) for which he want data. Any shift selection requires removal of intra-day gaps.
For a test data I am taking the range as:
Start Date: - 14 Dec 2007 00:00:00
End Date: - 20 Dec 2007 23:59:59
The above dates are in 24 hour format.
There are 2 cases as below:
Case 1) User only de-selects the days for which he do not want to see data, for e.g. Saturday, Sunday and any other
holiday. Let’s say user de-selects Saturday( 15 Dec 2007 ) and Sunday ( 16 Dec 2007 )
Case 2) Along with the holidays, user also de-selects the shifts for which he do not want data i.e. intra-day charts. Let’s
say he de-selects Saturday, Sunday and Tuesday (18 Dec 2007) and selects only shift 2 (0800 – 1559) and shift 3
(1600 – 2359)
I am using two segmented time lines to form a compounded segmented time line to take care of Case 2 above. I have extended the class BaseDateAxis to override the method refreshTicksHorizontal, for removing the overlapping on time axis.
The code is as shown below:
Code: Select all
class BaseDateAxis extends DateAxis{
/**
*
*/
private static final long serialVersionUID = 1L;
public BaseDateAxis(){
}
protected java.util.List refreshTicksHorizontal(java.awt.Graphics2D g2, Rectangle2D dataArea,
RectangleEdge edge) {
java.util.List list = super.refreshTicksHorizontal(g2, dataArea, edge);
if (list.size() > 1) {
// remove ticks that are overwritten by the following tick
FontMetrics fm = g2.getFontMetrics(g2.getFont());
for (int i = 0; i < list.size() - 1; i++) {
DateTick tick0 = (DateTick)list.get(i);
double position0 = valueToJava2D(tick0.getDate().getTime(), dataArea, edge);
DateTick tick1 = (DateTick)list.get(i+1);
double position1 = valueToJava2D(tick1.getDate().getTime(), dataArea, edge);
if ((position0 + (fm.stringWidth(tick0.getText()) / 2.0d)) >
(position1 - (fm.stringWidth(tick1.getText()) / 2.0d))) {
list.remove(tick0);
i--;
}
}
}
return list;
}
}
DateAxis xaxis = new BaseDateAxis();
// For Case 1 above, variable daysSelected will be 5 and daysUnselected will be 2 when user has
// de-selected Saturday (15 Dec 2007), Sunday (16 Dec 2007).
// For Case 2 above, variable daysSelected will be 4 and daysUnselected will be 3 when user has
// de-selected Saturday (15 Dec 2007), Sunday (16 Dec 2007) and Tuesday (18 Dec 2007).
SegmentedTimeline segTimelineWithSegSizeAsOneDay =
new SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, daysSelected , daysUnselected);
segTimelineWithSegSizeAsOneDay.setStartTime("14 Dec 2007");
if(shiftSelected == true){
// suppose user selects 2nd shift (0800 - 1559) and 3rd shift (1600 - 2359)
// for a working day and de-selects Saturday( 15 Dec 2007 ),
// Sunday ( 16 Dec 2007 ) and Tuesday (18 Dec 2007)
int oneHourSegmentsIncluded = 16;
int oneHourSegmentsExcluded = 8;
SegmentedTimeline segTimeLineWithSegSizeAsOneHour =
new SegmentedTimeline(SegmentedTimeline.HOUR_SEGMENT_SIZE
, oneHourSegmentsIncluded, oneHourSegmentsExcluded);
segTimeLineWithSegSizeAsOneHour.setStartTime(selectedShiftStartTime);
segTimeLineWithSegSizeAsOneHour.setBaseTimeline(segTimelineWithSegSizeAsOneDay);
// lstHolidayDates will contain Saturday( 15 Dec 2007 ), Sunday ( 16 Dec 2007 )
// and Tuesday (18 Dec 2007)
List<Date> lstHolidayDates = new ArrayList<Date>();
// adding base time line exceptions
for(Date date : lstHolidayDates){
segTimeLineWithSegSizeAsOneHour.addBaseTimelineException(date);
}
// adding intra-day gaps as exceptions. e.g 14/Dec/2007 00:00:00 - 14/Dec/2007 15:59:59
segTimeLineWithSegSizeAsOneHour.addException("millisecs corresponding to 14/Dec/2007 00:00:00"
, "millisecs corresponding to 14/Dec/2007 07:59:59");
segTimeLineWithSegSizeAsOneHour.addException("millisecs corresponding to 17/Dec/2007 00:00:00"
, "millisecs corresponding to 17/Dec/2007 07:59:59");
segTimeLineWithSegSizeAsOneHour.addException("millisecs corresponding to 19/Dec/2007 00:00:00"
, "millisecs corresponding to 19/Dec/2007 07:59:59");
segTimeLineWithSegSizeAsOneHour.addException("millisecs corresponding to 20/Dec/2007 00:00:00"
, "millisecs corresponding to 20/Dec/2007 07:59:59");
Range range = new Range("millisecs corresponding to 14/Dec/2007 07:59:59"
, "millisecs corresponding to 20/Dec/2007 23:59:59");
xaxis.setRange(range, true, true);
xaxis.setTimeline(segTimeLineWithSegSizeAsOneHour);
} else {
// suppose user de-selects Saturday( 15 Dec 2007 ), Sunday ( 16 Dec 2007 )
// lstHolidayDates will contain Saturday( 15 Dec 2007 ) and Sunday ( 16 Dec 2007 )
List<Date> lstHolidayDates = new ArrayList<Date>();
for(Date date : lstHolidayDates){
lstGapDates.add(calendar.getTime());
}
segTimelineWithSegSizeAsOneDay.addExceptions(lstGapDates);
Range range = new Range("millisecs corresponding to 14/Dec/2007 00:00:00"
, "millisecs corresponding to last date selected by user");
xaxis.setRange(range, true, true);
xaxis.setTimeline(segTimelineWithSegSizeAsOneDay);
}
For the case 1, when user has de-selected Saturday (15 Dec 2007), Sunday (16 Dec 2007), the resulting graph rightly excludes 15 and 16 December, but it also excludes 19th Dec and 20th Dec. The chart shows data only for 14, 17 and 18 Dec. I do not understand why it is excluding 19th and 20th Dec? Please let me know if you can spot the bug in my code.
For the case 2 which, is an intra-day gap removal case, suppose user has de-selected Saturday (15 Dec 2007), Sunday (16 Dec 2007), and Tuesday (18 Dec 2007) and has selected only shift 2 (0800 – 1559) and shift 3 (1600 – 2359). In this case the resulting chart rightly removes the intra-day gap for shift1 and also correctly removes the days Saturday (15 Dec 2007) and Sunday (16 Dec 2007) from the resulting timeline, but it does not removes the 18 Dec 2007, which come as a gaping gap. I do not understand this anomalous behavior. Any help will be appreciated.
Regards,
Junaid