DateAxis : Convert minutes to mm:ss

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
axel
Posts: 21
Joined: Fri Aug 10, 2007 12:37 pm

DateAxis : Convert minutes to mm:ss

Post by axel » Tue Apr 29, 2008 9:01 am

Hi everybody,

I'm trying to display a chart with a time axis presenting durations in minutes and seconds ( "mm:ss" ).

I got data from a dataset where durations are in minutes, with a double format (eg: 4.52), and I would like to convert these minutes to mm:ss for the display in the chart.

I tried the following but it doesn't work

Code: Select all

DateAxis timeAxis=new DateAxis( "Duration (mm:ss)");         
timeAxis.setTickUnit( new DateTickUnit(DateTickUnit.MINUTE, 1, new SimpleDateFormat( "mm:ss" ) ) );
If someone could have an idea to help me, it would be much appreciated !

Many thanks in advance,

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Post by david.gilbert » Tue Apr 29, 2008 4:43 pm

Does the 4.52 mean 4:52am? Or 4 minutes and 31.2 seconds? Or something else? Whatever it is, you'll need to either convert it to "milliseconds since 1-Jan-1970" so that you can use the Java DateFormat classes, or write a custom NumberFormat class that can produce strings in the form "mm:ss" for the numbers you pass to it.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

axel
Posts: 21
Joined: Fri Aug 10, 2007 12:37 pm

Post by axel » Tue Apr 29, 2008 5:28 pm

Hi David

Many thanks for your answer.

Correct, 4.52 means 4 minutes and 31.2 seconds.

In this case the best solution is to write a custom NumberFormat class ?

axel
Posts: 21
Joined: Fri Aug 10, 2007 12:37 pm

Post by axel » Wed Apr 30, 2008 3:05 pm

Another question :oops:

I write a custom NumberFormat class, named MinuteSecondFormat as follows

Code: Select all

public class MinuteSecondFormat extends NumberFormat {

    private double minutes;
    private double secondes;

    public MinuteSecondFormat(double duree) {
        minutes = Math.floor(duree);
        secondes = Math.round((duree-Math.floor(duree))*60);
    }

    @Override
    public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
        toAppendTo.append(minutes+"'"+secondes);
        return toAppendTo;
    }

    @Override
    public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
        toAppendTo.append(minutes+"'"+secondes);
        return toAppendTo;
    }

    @Override
    public Number parse(String source, ParsePosition parsePosition) {
        double val=Double.valueOf(source).doubleValue();
        return val;
    } 
}
I use it in the generation of the chart like this

Code: Select all

NumberAxis rangeAxis = new NumberAxis(ylabel);
rangeAxis.setNumberFormatOverride(MinuteSecondFormat.getInstance());
but nothing changes in the output....

Has someone an idea ?

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

Post by skunk » Wed Apr 30, 2008 4:29 pm

Did you remember to call

Code: Select all

plot.setRangeAxis(rangeAxis);
after you customized it?

axel
Posts: 21
Joined: Fri Aug 10, 2007 12:37 pm

Post by axel » Wed Apr 30, 2008 4:45 pm

No, in fact I use

Code: Select all

CategoryPlot plot = (new CategoryPlot(data, domainAxis, rangeAxis, renderer));

Taqua
JFreeReport Project Leader
Posts: 698
Joined: Fri Mar 14, 2003 3:34 pm
Contact:

Post by Taqua » Wed Apr 30, 2008 5:58 pm

Just a very stupid question:

Who is creating the jfreechart-dataset with those minutes/seconds in there? If the answer is "you", then why are you messing around with a custom numberformat instead of creating the dataset in a correct way?

For instance instead of providing floating-point minutes, you could equally easily provide Java-timestamps (minute * 60 * 1000) and then you could use the standard built in date-formats.

axel
Posts: 21
Joined: Fri Aug 10, 2007 12:37 pm

Post by axel » Wed Apr 30, 2008 7:17 pm

Of course, I thought of it !
But the data is coming from a database, and it's more difficult to change everything in it.

My chart is absolutely readable with floating-point minutes, but it would be a little more readable with the custom format I try to implement

RoyW
Posts: 93
Joined: Wed Apr 23, 2008 7:42 pm
Contact:

Post by RoyW » Thu May 01, 2008 3:50 pm

Here is a rough version of a formatter, it seems to work for charts but I wouldn't use it elsewhere

Code: Select all

public class MinuteSecondFormat extends NumberFormat
{
   public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos)
   {
      //We are assuming that we don't display hours and we are not using "pos"
      int mins = (int) Math.floor(number);
      int secs = (int) Math.round((number-mins)*60);

      toAppendTo.append(mins)
              .append(":")
              .append(secs < 10 ? "0" : "")
              .append(secs);
      return toAppendTo;
   }

   public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos)
   {
      return format((double) number, toAppendTo, pos);
   }

   public Number parse(String source, ParsePosition parsePosition)
   {
      //This is incorrect, it needs to parse "hh:mm"
      return Double.parseDouble(source);
   }
}
To use

Code: Select all

NumberAxis rangeAxis = new NumberAxis(ylabel); 
rangeAxis.setNumberFormatOverride(new MinuteSecondFormat()); 

Locked