intraday chart SegmentedTimeLine pb.

Discussion about JFreeChart related to stockmarket charts.
Locked
jonenet
Posts: 1
Joined: Wed Mar 25, 2009 4:24 pm

intraday chart SegmentedTimeLine pb.

Post by jonenet » Wed Mar 25, 2009 4:49 pm

Hello there,

Congratulations for this fantastic tool.
I am using the 1.0.12 version.

I have a problem with "newFifteenMinuteTimeline". It does not exclude Week Ends.
It seems that the "setBaseTimeline(newMondayThroughFridayTimeline())" is not taken into account.
I checked the forum and could not get any clear answer. On the top of it, the post related to this problem are pretty old.

Does it work or not?
If it does, what can prevent it from working?
If it does not, is any alternative solution?

Thank you in advance

Junaid
Posts: 13
Joined: Tue Jul 20, 2010 2:25 pm
antibot: No, of course not.
Contact:

Re: intraday chart SegmentedTimeLine pb.

Post by Junaid » Mon Jul 26, 2010 2:16 pm

Hi,

I am also facing the similar issue. I am trying to combine 2 segmented time lines to implement an intra-day timeline that can remove some of the hours during a day and also can remove the holiday days.

First I have implemented a segmented time line that removes the holiday days, denote SegTimeLine1 for this timeline.
For the second segmented time line (Denote SegTimeLine2) I am using the SegTimeLine1 as the base timeline. In SegTimeLine2 I am adding hours for which I do not want data as exception segments.

Result is that I get the timeline that removes the hours, but it does not take into account the exception days of SegTimeLine1 and show those days as gaps. Apparently SegTimeLine2 is not taking SegTimeLine1 as its base time line.

Please find below the code I am using:

SegmentedTimeline baseTimeLine = new SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, 5, 2);
baseTimeLine.setStartTime(myModel.getTimebase().getTime());
SegmentedTimeline twentyFourHourSegTimeline = new SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, 7
, 0);
twentyFourHourSegTimeline.setStartTime(myModel.getTimebase().getTime());
twentyFourHourSegTimeline.setBaseTimeline(baseTimeLine);
twentyFourHourSegTimeline.addExceptions(lstGapDates); //lstGapDates are holiday dates

SegmentedTimeline oneHourSegTimeLine = new SegmentedTimeline(SegmentedTimeline.HOUR_SEGMENT_SIZE, 8 , 16);
oneHourSegTimeLine.setStartTime(myModel.getTimebase().getTime());
oneHourSegTimeLine.setBaseTimeline(twentyFourHourSegTimeline);

for (IntraDayHourGap intraDayHourGap : filterCriteria.getIntraDayHourGap()) {
oneHourSegTimeLine.addException(intraDayHourGapStart, intraDayHourGapEnd);
}

The final SegmentedTimeLine, oneHourSegTimeLine, does not exclude holidays. Any idea what is going wrong?

Rgds,
Junaid

skunk
Posts: 1087
Joined: Thu Jun 02, 2005 10:14 pm
Location: Brisbane, Australia

Re: intraday chart SegmentedTimeLine pb.

Post by skunk » Mon Jul 26, 2010 2:45 pm

Try calling addBaseTimelineException() instead

Junaid
Posts: 13
Joined: Tue Jul 20, 2010 2:25 pm
antibot: No, of course not.
Contact:

Re: intraday chart SegmentedTimeLine pb.

Post by Junaid » Thu Jul 29, 2010 1:43 pm

Hi skunk,

Thanks for the solution. It works fine for removal of holidays. However I am facing an issue when I am trying to remove the intra-day gaps ( which are in hours) from working days.

As a background to new viewers, I am trying to combine 2 segmented timelines to form a compounded segmented timeline. The first timeline removes days (e.g. any holidays ), the second time line, which uses the first one as base timeline, is used to remove intra-day gaps ( which are in hours).

I have 3 shifts in any working day. The 3 shifts timings are following:
1) 0000-0759 ( morning 0000 to 0759 in morning )
2) 0800-1559 ( morning 0800to 1559 in afternoon)
3) 1600-2359 ( 1600 in evening to midnight)

The user can select the shifts for which he wants data. He has an option to choose one, two or three shifts. The resulting chart must remove the gaps for any day as per the shifts chosen by user.

In my test case I have chosen shifts 2nd and 3rd. (i.e. 0800-1559 and 1600-2359). The resulting graph correctly excludes the holidays (Saturday and Sunday in my case) and also excludes first shift (from 0000-0759). It shows time line starting from 0800 to 1559 for all days, but does not show the time line for 3rd shift (1600-2359). It is baffling, why is the timeline from 1600-2359 not shown? . Can someone point me the mistake in my code.

In the second test case i choose only 2nd shift (0800-1559). The resulting chart excludes the holidays properly but doesn't show any timeline at all.

The third test case, choosing shifts 1st and 2nd work properly. The expected time line from 0000-1559 is shown.

The following code shows the state of code when user has chosen shifts 2nd. and 3rd. (i.e. 0800-1559 and 1600-2359):

Code: Select all

      List<Date> lstGapDates;// contains the holidays which I do not want to show in timeline
      // below list contains the intra-day hours that I do not want to show. 
      List<IntraDayHourGap> lsIntraDayHrGap; 
      // My work day  has 3  shifts (0000-0759); (0800-1559); (1600-2359)
      
      // IntraDayHourGap is a class that has a startTime and endTime 
      // which corresponds to the intra-day shifts, that user can
      // select from UI. For example if user wants data only for 2 shifts 
      // (say, 0800-1559 and 1600-2359 ) 
      // then IntraDayHourGap  for monday 17 Dec 2007, will have the 
      // startTime corresponding to 17 Dec 2007 08:00:00  and end time corresponding 
      // to 17 Dec 2007 23:59:00. That means final graph should display data for 
      // effectively 16 hours (0800-2359) and exclude gap of 8 hours (0000-0759)
      
      SegmentedTimeline baseTimeLine = 
                           new SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, 5, 2 );
      baseTimeLine.setStartTime(myModel.getTimebase().getTime());
      SegmentedTimeline twentyFourHourSegTimeline = 
                           new SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, 7,  2);
      //start time is set to 14/Dec/2007 00:00 :00
      twentyFourHourSegTimeline.setStartTime(startTime);
      twentyFourHourSegTimeline.setBaseTimeline(baseTimeLine);
      SegmentedTimeline oneHourSegTimeLine = null;
      
      if(shiftSelected){
        int hourlySegmentsIncluded = 16;
        int hourlySegmentsExcluded = 8;
        oneHourSegTimeLine = new SegmentedTimeline(SegmentedTimeline.HOUR_SEGMENT_SIZE, 16 , 8);
        oneHourSegTimeLine.setStartTime(startTime);//start time is set to 14/Dec/2007
        oneHourSegTimeLine.setBaseTimeline(twentyFourHourSegTimeline);
        
        for (Date date : lstGapDates) {
          oneHourSegTimeLine.addBaseTimelineException(date);
        }
        //Adding following IntraDayHourGap list as exceptions to oneHourSegTimeLine
        List<IntraDayHourGap> lsIntraDayHrGap = filterCriteria.getIntraDayHourGap();
        for (IntraDayHourGap intraDayHourGap : lsIntraDayHrGap) {
          oneHourSegTimeLine.addException(intraDayHourGap.getStartDate().getTime(),
                              intraDayHourGap.getEndDate().getTime());
        }

      }
I am baffled, can someone point me what I am missing. Why is the timeline from 1600-2359 not displayed for the above code.

Junaid
Posts: 13
Joined: Tue Jul 20, 2010 2:25 pm
antibot: No, of course not.
Contact:

Re: intraday chart SegmentedTimeLine pb.

Post by Junaid » Thu Jul 29, 2010 1:54 pm

Hi guys,

I have got the bug. For anyone who may be having the same issue please see below.

The initial code that I had posted has the following line, which is incorrect
oneHourSegTimeLine = new SegmentedTimeline(SegmentedTimeline.HOUR_SEGMENT_SIZE, 16 , 8 );

It should be instead as below
oneHourSegTimeLine = new SegmentedTimeline(SegmentedTimeline.HOUR_SEGMENT_SIZE, 24 , 8 );


i.e. instead of 16 it should be 16 + 8 = 24

I guess the JFreeChart API's may have to be more elaborate.

Thanks everyone for the help.

Rgds,
Junaid

Junaid
Posts: 13
Joined: Tue Jul 20, 2010 2:25 pm
antibot: No, of course not.
Contact:

Re: intraday chart SegmentedTimeLine pb.

Post by Junaid » Fri Jul 30, 2010 6:02 am

Hi,

Sorry guys the solution that I posted yesterday seems to be incorrect when tested for some of the scenarios. Please ignore it, and let me know if you can point out the bug to me in the last code.

Rgds,
Junaid

Junaid
Posts: 13
Joined: Tue Jul 20, 2010 2:25 pm
antibot: No, of course not.
Contact:

Re: intraday chart SegmentedTimeLine pb.

Post by Junaid » Mon Aug 02, 2010 3:56 pm

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

Junaid
Posts: 13
Joined: Tue Jul 20, 2010 2:25 pm
antibot: No, of course not.
Contact:

Re: intraday chart SegmentedTimeLine pb.

Post by Junaid » Fri Aug 20, 2010 11:32 am

Hi Skunk,

I am trying to create a timeline using 2 segmentedtimelines. The first segmentedtimeline will remove gaps for holidays, and the second timeline, which uses the first segmentedtimeline (the one that has removed holiday gaps) as the base timeline, will remove intraday hourly gaps.

Please find below the code:

Code: Select all

private void removeGapHoursFromXAxis(SegmentedTimeline holidayTimeLine, HttpSession httpSession) {
  try{
  // FilterCriteria is the UI control from which user can select the holidays and hours/shifts (3 shits per working days)
  // to be excluded
  FilterCriteria filterCriteria = (FilterCriteria)httpSession.getAttribute("filterCriteria");
  int oneHourSegmentsIncludedInADay = getTotalShiftHoursIncluded(filterCriteria.getTimeIntervals());
  int oneHourSegmentsExcludedInADay = 24 - oneHourSegmentsIncludedInADay;
  int selectedShiftStartTime = filterCriteria.getTimeIntervals().get(0).getStartTimeHr();
  
  SegmentedTimeline segTimeLineWithSegSizeAsOneHour = 
      new SegmentedTimeline(SegmentedTimeline.HOUR_SEGMENT_SIZE
          , oneHourSegmentsIncludedInADay  , oneHourSegmentsExcludedInADay);
  
  segTimeLineWithSegSizeAsOneHour.setStartTime(myModel.getTimebase().getTime() 
      + selectedShiftStartTime * segTimeLineWithSegSizeAsOneHour.getSegmentSize());
  segTimeLineWithSegSizeAsOneHour.setBaseTimeline(segmentedTimeline);
  for (Calendar calendar : filterCriteria.getM_lstInvalidDates()) {
    Calendar gapCalendar = (Calendar)calendar.clone();
    segTimeLineWithSegSizeAsOneHour.addBaseTimelineException(gapCalendar.getTime());
  }
  List<IntraDayHourGap> lsIntraDayHrGap = filterCriteria.getIntraDayHourGap();
  for (IntraDayHourGap intraDayHourGap : lsIntraDayHrGap) {
    segTimeLineWithSegSizeAsOneHour.addException(intraDayHourGap.getStartDate().getTime()
      , intraDayHourGap.getEndDate().getTime());// e.g 19/Dec/2007 09:00:00 - 14/Dec/2007 15:00:00
  }
  
  double start = new Double(myModel.getTimebase().getTime() 
                    + selectedShiftStartTime * segTimeLineWithSegSizeAsOneHour.getSegmentSize()).doubleValue();
  double end = new Double(myModel.getTimebaseEnd().getTime()).doubleValue();
  Range range = new Range(start, end);
  xaxis.setRange(range, true, true);
  xaxis.setTimeline(segTimeLineWithSegSizeAsOneHour);
  } catch (Exception exception){
    exception.printStackTrace();
    logger.info(exception.getMessage());
  }
}
The final segmentedtimeline successfully excludes the holidays, but giving problem when excluding intra-day hours, specifically when i am trying to exclude the hours 0900 - 1500 hours:

The following code lines do not Adds a segment range (0900 - 1500 hours) as an exception to timeline:

Code: Select all

  for (IntraDayHourGap intraDayHourGap : lsIntraDayHrGap) {
    segTimeLineWithSegSizeAsOneHour.addException(intraDayHourGap.getStartDate().getTime()
      , intraDayHourGap.getEndDate().getTime());// e.g 14/Dec/2007 08:00:00 - 14/Dec/2007 16:00:00
  }
Any particular reason for this?

Rgds,
Junaid

Locked