Intraday chart time zone problem

Discussion about JFreeChart related to stockmarket charts.
Locked
jfreechart-200905
Posts: 7
Joined: Fri Oct 17, 2008 2:23 pm

Intraday chart time zone problem

Post by jfreechart-200905 » Wed Oct 22, 2008 9:10 am

Hello together

I have a problem with intraday charts in different time zones (Version jFreeChart 1.0.11). It seems the date axis uses the default time zone of the jdk (in my case Europe/Berlin) to draw the date axis. The code makes 1) a chart for the time zone Europe/Zurich and 2) America/New_York with exactly the same data. I case 2) the axis has als - wrongly - the default time zone.

Code: Select all


import java.awt.Color;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Minute;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;

public class TimeSeriesTimeZone extends ApplicationFrame {

   JFreeChart chart = null;

   public TimeSeriesTimeZone(String title, String ric, String stTimeZone) {
      super(title);
      XYDataset dataset = createDataset( ric, stTimeZone);
      
      JFreeChart chart = createChart(dataset, ric, stTimeZone);
      ChartPanel chartPanel = new ChartPanel(chart, false);
      chartPanel.setPreferredSize(new java.awt.Dimension(240, 170));
      chartPanel.setMouseZoomable(true, false);
      setContentPane(chartPanel);

   }

   private static JFreeChart createChart(XYDataset dataset, String ric, String stTimeZone) {
      JFreeChart chart = ChartFactory.createTimeSeriesChart(ric,
            stTimeZone, null, dataset, false, false, false);
      chart.setBackgroundPaint(Color.white);
      XYPlot plot = (XYPlot) chart.getPlot();
      plot.setBackgroundPaint(Color.white);
      plot.setDomainGridlinePaint(Color.lightGray);
      plot.setRangeGridlinePaint(Color.lightGray);
      plot.setAxisOffset(new RectangleInsets(5, 5, 5, 5));
      plot.setDomainCrosshairVisible(true);
      plot.setRangeCrosshairVisible(true);
      plot.setAxisOffset(new RectangleInsets(0.0, 0.0, 0.0, 0.0));

      XYItemRenderer xyitemrenderer = plot.getRenderer();
      if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
         XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyitemrenderer;
         renderer.setSeriesPaint(0, new Color(81, 140, 255));
         renderer.setBaseShapesVisible(false);
      }

      Calendar cal = Calendar.getInstance();
      cal.set(Calendar.HOUR_OF_DAY, 8);
      cal.set(Calendar.MINUTE, 59);
      cal.set(Calendar.SECOND, 0);
      Date startDate = new Date(cal.getTimeInMillis());
      cal.set(Calendar.HOUR_OF_DAY, 18);
      cal.set(Calendar.MINUTE, 0);
      cal.set(Calendar.SECOND, 0);
      Date endDate = new Date(cal.getTimeInMillis());

      DateAxis timeAxis = (DateAxis)plot.getDomainAxis();
      timeAxis.setDateFormatOverride(new SimpleDateFormat("HH:mm z"));
      timeAxis.setTickUnit(new DateTickUnit(DateTickUnit.HOUR, 3));
      timeAxis.setVerticalTickLabels(false);
      timeAxis.setRange(startDate, endDate);
      timeAxis.setTimeZone(TimeZone.getTimeZone(stTimeZone));
      timeAxis.setTickLabelsVisible(true);
      plot.setDomainAxis(timeAxis);

      ValueAxis rangeAxis = plot.getRangeAxis(); // Last price

      chart.clearSubtitles();
      chart.setBorderVisible(false);
      // ChartUtilities.applyCurrentTheme(chart);

      return chart;

   }

   private static XYDataset createDataset(String ric, String stTimeZone) {
      TimeSeries timeseries = new TimeSeries(ric, Minute.class);
      Day today = new Day();
      for (int i = 9; i < 18; i++) {
         Minute m0 = new Minute(0, new Hour(i, today));
         Minute m1 = new Minute(10, new Hour(i, today));
         Minute m2 = new Minute(20, new Hour(i, today));
         Minute m3 = new Minute(30, new Hour(i, today));
         Minute m4 = new Minute(40, new Hour(i, today));
         Minute m5 = new Minute(50, new Hour(i, today));
         double tmp1 = Math.random() * 2.0;
         double tmp2 = Math.random() * 2.0;
         double tmp3 = Math.random() * 2.0;
         double tmp4 = Math.random() * 2.0;
         double tmp5 = Math.random() * 2.0;
         double tmp6 = Math.random() * 2.0;
         timeseries.add(m0, tmp1);
         timeseries.add(m1, tmp2);
         timeseries.add(m2, tmp3);
         timeseries.add(m3, tmp4);
         timeseries.add(m4, tmp5);
         timeseries.add(m5, tmp6);
      }

      TimeSeriesCollection dataset = new TimeSeriesCollection(TimeZone.getTimeZone(stTimeZone));
      dataset.addSeries(timeseries);
      return dataset;
   }


   public static void main(String args[]) {
      TimeSeriesTimeZone timeSeriesZurich = new TimeSeriesTimeZone(
            "Time Series Zurich", "CSGN.VX", "Europe/Zurich");
      timeSeriesZurich.pack();
      RefineryUtilities.centerFrameOnScreen(timeSeriesZurich);
      timeSeriesZurich.setVisible(true);
      
      TimeSeriesTimeZone timeSeriesNewYork = new TimeSeriesTimeZone(
            "Time Series New York", "CS.N", "America/New_York");
      timeSeriesNewYork.pack();
      RefineryUtilities.centerFrameOnScreen(timeSeriesNewYork);
      timeSeriesNewYork.setVisible(true);
      
   }
}


I found that in the jfreechart class DateAxis the methods refreshTicksVertical() and refreshTicksHorizontal() do not format the tick date with the set time zone, so that the default timezone is used.
Is this correct? Or is my code faulty?

Thanks in advance for your help

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

Post by skunk » Wed Oct 22, 2008 2:05 pm

Did you try calling this method

Code: Select all

public void setTimeZone(TimeZone zone)
on your Calendar and SimpleDateFormat?

jfreechart-200905
Posts: 7
Joined: Fri Oct 17, 2008 2:23 pm

Post by jfreechart-200905 » Wed Oct 22, 2008 3:39 pm

Thanks for the suggestion

But I am not able to try it this week.

Nevertheless, I found that the methods refreshTicksVertical() and refreshTicksHorizontal() in the DataAxis class draw the Date Axis labels without formatting it with the set time zone.
This looks to me like a bug. What do you think?

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

Post by skunk » Wed Oct 22, 2008 4:28 pm

Not a bug, just use the correct DateAxis constructor

Code: Select all

public DateAxis(String label, TimeZone zone, Locale locale)
or call

Code: Select all

public void setTimeZone(TimeZone zone)
This will update the formatters used with the correct timezone. If you are overriding the DateFormatter, then you should make sure that it is configured with the desired timezone.

Locked