grid lines on excluded dates using segmented timeline

A free public discussion forum for the JFreeChart class library.

grid lines on excluded dates using segmented timeline

Postby davesnowdon » Fri Mar 11, 2011 8:00 pm

I'm charting data using a segmented timeline (SegmentedTimeline.newMondayThroughFridayTimeline()) to avoid gaps in the chart due to weekends.

However this means that grid lines that would have fallen on an excluded date are not shown (eg 1st Jan 2011). So I get grid lines displayed for every month except Aug 2010, Jan 2011 etc

When setting the tick unit I tried changing from this:
Code: Select all
axis.setTickUnit(new DateTickUnit(DateTickUnitType.MONTH, 1));

to this:
Code: Select all
axis.setTickUnit(new DateTickUnit(DateTickUnitType.MONTH, 1, DateTickUnitType.DAY, 2, new SimpleDateFormat()));

as the documentation for DateTickUnit hints that using rollMultiple provides a way around this.

However, this just seems to cause JFreeChart to enter an infinite loop when rendering the chart.

I've looked at the source code for DateTickUnit and googled around but have not found a solution. Is there a known workaround?

thanks

Dave
davesnowdon
 
Posts: 9
Joined: Tue Jul 06, 2010 7:10 pm

Bug in Jfreechart 1.0.13 DateAxis.refreshTicksHorizontal()

Postby davesnowdon » Mon Mar 14, 2011 2:32 pm

On further investigation this looks like a bug in DateAxis.refreshTicksHorizontal() in JFreeChart version 1.0.13

The method tests for whether the current tick date is excluded (line 1646) and if so rolls the date forward (line 1703)
Code: Select all
            if (!isHiddenValue(tickDate.getTime())) {
...
           }
            else {
                tickDate = unit.rollDate(tickDate, this.timeZone);
                continue;
            }


However, the next iteration of the loop then calls correctTickDateForPosition() which sets the tick date back to the date before it was rolled forward:
Code: Select all
            // could add a flag to make the following correction optional...
            tickDate = correctTickDateForPosition(tickDate, unit,
                    this.tickMarkPosition);


The code then loops until killed.

Surely other people using SegmentedTimeLine would have hit the same issue so I'm surprised that I couldn't find anything on this via google.

Dave
davesnowdon
 
Posts: 9
Joined: Tue Jul 06, 2010 7:10 pm

Re: grid lines on excluded dates using segmented timeline

Postby davesnowdon » Mon Mar 14, 2011 3:51 pm

I have made a quick and dirty fix to DateAxis that appears to fix the problem.
Is there an official address to send patches to?

FWIW Here's a diff of my changes below:

Code: Select all
*** DateAxis.java.orig   2009-04-20 10:23:40.000000000 +0100
--- DateAxis.java   2011-03-14 14:34:22.000000000 +0000
***************
*** 1620,1629 ****
          Date tickDate = calculateLowestVisibleTickValue(unit);
          Date upperDate = getMaximumDate();
 
          while (tickDate.before(upperDate)) {
              // could add a flag to make the following correction optional...
!             tickDate = correctTickDateForPosition(tickDate, unit,
!                     this.tickMarkPosition);
 
              long lowestTickTime = tickDate.getTime();
              long distance = unit.addToDate(tickDate, this.timeZone).getTime()
--- 1620,1632 ----
          Date tickDate = calculateLowestVisibleTickValue(unit);
          Date upperDate = getMaximumDate();
 
+         boolean hasRolled = false;
          while (tickDate.before(upperDate)) {
              // could add a flag to make the following correction optional...
!             if (!hasRolled) {
!                tickDate = correctTickDateForPosition(tickDate, unit,
!                      this.tickMarkPosition);
!             }
 
              long lowestTickTime = tickDate.getTime();
              long distance = unit.addToDate(tickDate, this.timeZone).getTime()
***************
*** 1680,1685 ****
--- 1683,1689 ----
                  Tick tick = new DateTick(tickDate, tickLabel, anchor,
                          rotationAnchor, angle);
                  result.add(tick);
+                 hasRolled = false;
 
                  long currentTickTime = tickDate.getTime();
                  tickDate = unit.addToDate(tickDate, this.timeZone);
***************
*** 1701,1706 ****
--- 1705,1711 ----
              }
              else {
                  tickDate = unit.rollDate(tickDate, this.timeZone);
+                 hasRolled = true;
                  continue;
              }
 
davesnowdon
 
Posts: 9
Joined: Tue Jul 06, 2010 7:10 pm

Re: grid lines on excluded dates using segmented timeline

Postby zhtrader » Mon Apr 04, 2011 2:08 pm

thanks for posting this solution/workaround, it solved my problem :D
zhtrader
 
Posts: 2
Joined: Mon Apr 04, 2011 11:34 am

Re: grid lines on excluded dates using segmented timeline

Postby zhtrader » Mon Apr 04, 2011 3:53 pm

may I be cheeky? given that you are obviously quite skilled in working out problems with the dateaxis class, would you like to have a look at a problem that a lot of (financial chart) users are having with combining 2 segmented timelines (1. for monday through friday and another for a certain timeperiod during day when stocks/futures/etc. are traded)? the problems is that setting the basetimeline (in this case monday through friday, i.e. exclude weekend days) has no effect. just do a search on basetimeline and you will see a lot of posts related to this problem...
zhtrader
 
Posts: 2
Joined: Mon Apr 04, 2011 11:34 am

Re: grid lines on excluded dates using segmented timeline

Postby indiguus » Sat Apr 30, 2011 7:34 pm

fantastic, thanks for sharing it.
indiguus
 
Posts: 1
Joined: Sat Apr 30, 2011 7:31 pm


Return to JFreeChart - General

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 7 guests