Menu

#556 TimeSeries: wrong date format values

closed-fixed
General (896)
7
2014-08-17
2005-10-19
m.hilpert
No

I have the following case wher I have just 2 dates and a
custom date format ("MMM yyyy"). The resulting chart
(viwed at 800x600 frame size) shows the label "Dez
2003" four times instead of "Dez 2003" one time
and "Jan 2004" one time:

/**
* This chart uses a date axis for X and shows a bug
with the automatic label generation. Instead of
generating 2 Labels for
* the 2 different dates, it generates 4 labels with the
same text value ("Dez 2003") of the first time series date
(2003-12-31)
* ignoring the second time series date (2004-01-31).
*
* Tested with JFreeChart 1.0.0-rc1
*
* @return JFreeChart.
*/
private JFreeChart testDateAxis1() {
JFreeChart result = null;

TimeSeriesCollection ds = new
TimeSeriesCollection();
TimeSeries ts = new TimeSeries("series1",
Month.class);
SimpleDateFormat sdf = new SimpleDateFormat
("yyyy-MM-dd");
sdf.setLenient(false); //strict parsing
ts.add(new Month(sdf.parse("2003-12-31", new
ParsePosition(0))), new BigDecimal(100.0));
ts.add(new Month(sdf.parse("2004-01-31", new
ParsePosition(0))), new BigDecimal(106.0));
ds.addSeries(ts);

result = ChartFactory.createTimeSeriesChart
("Time Series Chart", "X", "Y", ds, true, false, false);

//set date format that causes the trouble:
XYPlot xyPlot = result.getXYPlot();
DateAxis da = (DateAxis) xyPlot.getDomainAxis();
DateFormat df = da.getDateFormatOverride();
df = new SimpleDateFormat("MMM yyyy");
da.setDateFormatOverride(df);

return result;
}//testDateAxis1()

Discussion

  • m.hilpert

    m.hilpert - 2005-10-19
    • labels: --> General
    • priority: 5 --> 7
     
  • m.hilpert

    m.hilpert - 2005-10-19

    Output chart showing wrong labels

     
  • Kipper

    Kipper - 2005-10-21

    Logged In: YES
    user_id=1365076

    I think the problem is that you are misusing the DateFormat:
    you can better achieve what you wish by creating a custom
    "TickUnitSource" and setting it on your DateAxis. Have a
    look at the code in
    "DateAxis.createStandardDateTickUnits(Timezone)" to see how
    TickUnitSource works.

    The tick unit source contains the "natural" increments: a
    number of DateTickUnits, each with a formatter, and
    crucially, the unit (DAY, MONTH, YEAR) and number specifying
    how many days, months, years...

    If you provide just the formatter, there is no way for the
    framework to see what kind of precision the formatter
    provides: it is just a text formatter. You know it is
    accurate to monthly increments, but the framework can't
    figure that out. In your case, the framework has figured out
    that it can fit 2-week interval labels on your axis, and
    does so, but you force it to print only the months, and so
    you get repeated labels.

    Solution is: DateTickUnits do provide the level of
    precision, and the framework can access this.

    The TickUnitSource is a collection of (Date)TickUnits and is
    handy because the framework will then choose the most
    fine-grained timeunit that will fit on the axis, without the
    labels overlapping.

    If you are sure you always want one-month intervals, you can
    also create a:

    > DateTickUnit myUnit = new DateTickUnit(DateTickUnit.MONTH,
    1, new SimpleDateFormatter());

    and set it on your DateAxis with:

    > DateAxis.setTickUnit(myUnit, true, true);

    Hope this helps. I don't think what you report is a bug though.

     
  • m.hilpert

    m.hilpert - 2005-10-28

    Logged In: YES
    user_id=667728

    > DateTickUnit myUnit = new DateTickUnit
    (DateTickUnit.MONTH,
    1, new SimpleDateFormatter());
    and set it on your DateAxis with:
    > DateAxis.setTickUnit(myUnit, true, true);
    Hope this helps. I don't think what you report is a bug though.

    YOur workaround doesn't work (for all cases). Because by
    setting it fixed to 1 month, all labels will overlapp if you have
    too many labels, so the automatic won't work anymore.

     
  • Kipper

    Kipper - 2005-10-28

    Logged In: YES
    user_id=1365076

    I wasn't sure whether the framework would check that, and
    unfortunately I guess it doesn't.

    I suggested you look at "TickUnitSource", and this certainly
    does look at how much space is available to each label and
    automatically picks the one that fits best. Unfortunately,
    it's relationship with SegmentedTimeline can be described as
    disfunctional at best: I'm currently busy trying to fix the
    labelling when you use SegmentedTimeline, because I get
    overlaps there too.

     
  • David Gilbert

    David Gilbert - 2005-11-03
    • assigned_to: nobody --> mungady
    • status: open --> closed-wont-fix
     
  • David Gilbert

    David Gilbert - 2005-11-03

    Logged In: YES
    user_id=112975

    The setDateFormatOverride() method only overrides the tick
    label format, it doesn't override the tick size. So you
    have to be careful not to specify an inappropriate format
    (i.e. one that won't differentiate between two dates that
    are a single tick unit apart).

    A better approach would be to use a custom tick unit
    collection for the axis that doesn't include any units less
    than one month (so this will become the minimum tick size):

    DateAxis axis = (DateAxis) plot.getDomainAxis();

    // customise the standard tick units...
    DateFormat f1 = new SimpleDateFormat("MMM yyyy");
    DateFormat f2 = new SimpleDateFormat("yyyy");
    TickUnits standardUnits = new TickUnits();
    standardUnits.add(new
    DateTickUnit(DateTickUnit.MONTH, 1, f1));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.MONTH, 2, f1));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.MONTH, 3, f1));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.MONTH, 4, f1));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.MONTH, 6, f1));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.YEAR, 1, f2));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.YEAR, 2, f2));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.YEAR, 5, f2));
    standardUnits.add(new
    DateTickUnit(DateTickUnit.YEAR, 10, f2));
    axis.setStandardTickUnits(standardUnits);

    Regards,

    Dave Gilbert
    JFreeChart Project Leader

     
  • m.hilpert

    m.hilpert - 2006-11-21
    • status: closed-wont-fix --> closed-fixed
     
  • m.hilpert

    m.hilpert - 2006-11-21

    Logged In: YES
    user_id=667728
    Originator: YES

    Seems to work with 1.0.3 now.

     

Log in to post a comment.