grid lines on excluded dates using segmented timeline

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Post Reply
davesnowdon
Posts: 9
Joined: Tue Jul 06, 2010 7:10 pm
antibot: No, of course not.

grid lines on excluded dates using segmented timeline

Post by 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
antibot: No, of course not.

Bug in Jfreechart 1.0.13 DateAxis.refreshTicksHorizontal()

Post by 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
antibot: No, of course not.

Re: grid lines on excluded dates using segmented timeline

Post by 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;
              }
  

zhtrader
Posts: 2
Joined: Mon Apr 04, 2011 11:34 am
antibot: No, of course not.

Re: grid lines on excluded dates using segmented timeline

Post by 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
antibot: No, of course not.

Re: grid lines on excluded dates using segmented timeline

Post by 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...

indiguus
Posts: 1
Joined: Sat Apr 30, 2011 7:31 pm
antibot: No, of course not.

Re: grid lines on excluded dates using segmented timeline

Post by indiguus » Sat Apr 30, 2011 7:34 pm

fantastic, thanks for sharing it.

Post Reply