2

QUESTION RESOLVED: solution is changing to JFreeChart v1.0.15


I have a very peculiar problem.

What I have set up is a file that sends a url request to the Yahoo Finance website and then uses the results to draw a JFreeChart in a JFrame.

What I just can't get my head around is the following:

For certain url requests, the JFrame crashes

It starts, but only shows a white screen. Whereas for other requests, my program works fine.

Example

For example:

This request:

"http://ichart.yahoo.com/table.csv?s=GOOG&a=0&b=1&c=2011&d=6&e=24&f=2013&g=d&ignore=.csv";

works fine.

But this request:

"http://ichart.yahoo.com/table.csv?s=GOOG&a=2&b=1&c=2012&d=6&e=24&f=2013&g=d&ignore=.csv";

causes an error.

How is this possible?

Note

I know the following:

  • JFrame crashes but JVM doesn't make note of it (doesn't notice that it crashes)
  • Downloading of the stock quotes (the information that JFreeChart uses) goes perfect in both cases
  • The code for downloading the data and displaying it in the JFreeChart comes from this site (the code posted by RoyW » Sat May 10, 2008 7:52 am).
  • The amount of data coming in doesn't seem a problem because in request 1, there are more data points than in request 2
  • The way I download the data doesn't matter (I tried both reading directly from the url and I tried saving the .csv file to a folder and then reading from the folder)
  • The problem doesn't occur randomly: I've tried launching the JFrame (recompiling the code and then running it) multiple times but the 'wrong' quote crashes the JFrame everytime.

Extra information

Something that might have to do with it:

  • When I launch the graph with a correct quote and I drag the graph around, something weird happens. At a certain interval, it seems every weekend, the candlesticks get smaller and smaller untill they are only a stripe. Then when I drag across the weekend, they become thicker again until they are normal size again. This seems to happen for every weekend. Refer to the following pictures:

enter image description here enter image description here enter image description here

So it got me thinking that it might have something to do with trading days. But this doesn't make any sense either because 1/1/2011 (request 1) falls on a Saturday and 3/1/2012 (request 2) falls on a Thursday while request 1 was successful and request 2 failed.

I am absolutely clueless as to what I should do.

All help greatly appreciated.

Update

On request, here is the SSCCE with trashgod's suggestions (using JFreechart lib v1.0.14).

    import org.jfree.chart.*;
    import org.jfree.chart.axis.*;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.CandlestickRenderer;
    import org.jfree.data.xy.*;

    import javax.swing.*;
    import java.awt.*;
    import java.io.*;
    import java.net.URL;
    import java.text.*;
    import java.util.*;
    import java.util.List;

    public class CandlestickDemo2 extends JFrame {
        public CandlestickDemo2(String stockSymbol) {
            super("CandlestickDemo");
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            DateAxis    domainAxis       = new DateAxis("Date");
            NumberAxis  rangeAxis        = new NumberAxis("Price");
            CandlestickRenderer renderer = new CandlestickRenderer();
            XYDataset   dataset          = getDataSet(stockSymbol);

            XYPlot mainPlot = new XYPlot(dataset, domainAxis, rangeAxis, renderer);

            //Do some setting up, see the API Doc
            renderer.setSeriesPaint(0, Color.BLACK);
            renderer.setDrawVolume(false);
            rangeAxis.setAutoRangeIncludesZero(false);
            domainAxis.setTimeline( SegmentedTimeline.newMondayThroughFridayTimeline() );

            //Now create the chart and chart panel
            JFreeChart chart = new JFreeChart(stockSymbol, null, mainPlot, false);
            ChartPanel chartPanel = new ChartPanel(chart, false);
            chartPanel.setPreferredSize(new Dimension(600, 300));

            this.add(chartPanel);
            this.pack();
        }
        protected AbstractXYDataset getDataSet(String stockSymbol) {
            //This is the dataset we are going to create
            DefaultOHLCDataset result = null;
            //This is the data needed for the dataset
            OHLCDataItem[] data;

            //This is where we go get the data, replace with your own data source
            data = getData(stockSymbol);

            //Create a dataset, an Open, High, Low, Close dataset
            result = new DefaultOHLCDataset(stockSymbol, data);

            return result;
        }
        //This method uses yahoo finance to get the OHLC data
        protected OHLCDataItem[] getData(String stockSymbol) {
            List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>();
            try {
                String strUrl= "http://ichart.finance.yahoo.com/table.csv?s=GOOG&a=2&b=1&c=2012&d=6&e=24&f=2013&g=d&ignore=.csv";
                URL url = new URL(strUrl);
                BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
                DateFormat df = new SimpleDateFormat("y-M-d");

                String inputLine;
                in.readLine();
                while ((inputLine = in.readLine()) != null) {
                    StringTokenizer st = new StringTokenizer(inputLine, ",");

                    Date date       = df.parse( st.nextToken() );
                    double open     = Double.parseDouble( st.nextToken() );
                    double high     = Double.parseDouble( st.nextToken() );
                    double low      = Double.parseDouble( st.nextToken() );
                    double close    = Double.parseDouble( st.nextToken() );
                    double volume   = Double.parseDouble( st.nextToken() );
                    double adjClose = Double.parseDouble( st.nextToken() );

                    OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume);
                    dataItems.add(item);
                }
                in.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            //Data from Yahoo is from newest to oldest. Reverse so it is oldest to newest
            Collections.reverse(dataItems);

            //Convert the list into an array
            OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]);

            return data;
        }

        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new CandlestickDemo2("GOOG").setVisible(true);
                }
            });
        }
    }

This generates a JFrame that displays nothing but a white screen. Try changing the strUrl to

 "http://ichart.finance.yahoo.com/table.csv?s=GOOG&a=0&b=1&c=2011&d=6&e=24&f=2013&g=d&ignore=.csv";

and you will notice that it works fine.

Update

Solved it! The problem was the JFreeChart version. Changing from v1.0.14 to v1.0.15 solved everything. Kudos to trashgod for (unknowingly) solving my issue by answering extensively and mentioning the library version used.

Does anybody know how I can help others that are having the same issue? Is there a portal somewhere where I can make note of this bug?

Jean-Paul
  • 19,910
  • 9
  • 62
  • 88
  • 1
    *"**Extra information**"* For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Aug 24 '13 at 00:19
  • @AndrewThompson: Please read my third point in the **Note** section. Thank you – Jean-Paul Aug 24 '13 at 00:27
  • @nachokk: It crashes by not displaying **anything**. Whereas normally, the JFrame shows several JButtons, JPanels etc..: now it just shows a white screen. So it launches, but displays nothing but a white 'container' so to speak. I hope you get the idea. – Jean-Paul Aug 24 '13 at 00:29
  • but the gui is freezing or something? May be you are blocking the `EDT` , are you using `SwingWorker` ? – nachokk Aug 24 '13 at 00:32
  • @Jean-Paul Please read my comment again. It does not recommend 'linking to code' but 'posting an SSCCE'. I do not know whether that link leads to an SSCCE but if it is, *edit it into the question.* Links outside SO tend to rot, and many people will not be willing, or able, to follow external links. – Andrew Thompson Aug 24 '13 at 00:36
  • 1
    @AndrewThompson makes a compelling case, but the [author](http://stackoverflow.com/users/2592874/david-gilbert) has maintained the forum for over a decade. – trashgod Aug 24 '13 at 02:43
  • @AndrewThompson: I've added the SSCCE. – Jean-Paul Aug 24 '13 at 10:21

1 Answers1

4

CandlestickDemo works for me with v1.0.15 and either of your queries. I made two changes:

  • Construct the GUI on the event dispatch thread; failure to do so causes a data race with non-deterministic results:

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new CandlestickDemo("GOOG").setVisible(true);
        }
    });
    
  • Omit the backing buffer, although it's probably irrelevant:

    ChartPanel chartPanel = new ChartPanel(chart, false);
    
  • Addendum: For reference, it looks like a call to ParamChecks.nullNotPermitted() was applied in r2692, replacing an explicit check, but the renderer was otherwise unchanged.

  • Addendum: Under v1.0.14, the example works correctly with the DefaultTimeline of DateAxis, which changed substantially in the interim.

  • Addendum: @David Gilbert notes that the relevant changes may be found in r2465.

image

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Your suggestions don't work; please see my update. I'm now going to change [tag:jfreechart] v1.0.14 to v1.0.15 to see if it makes any difference. – Jean-Paul Aug 24 '13 at 10:26
  • The library version did indeed solve the issue. Thank you so much for your precision, detailism and quick response! Awesome! – Jean-Paul Aug 24 '13 at 10:40
  • @Jean-Paul: Glad you got it sorted; sadly, I don't see a change that would account for your observation; more above. – trashgod Aug 24 '13 at 11:45
  • Weird. I double checked [ceteris paribus](http://www.investopedia.com/terms/c/ceterisparibus.asp) and I'm 100% sure that it has to do with the change of library from v1.0.14 to v1.0.15. So somehow it must have effect. – Jean-Paul Aug 24 '13 at 11:57
  • 1
    I have to agree. Thank you for linking on [forum](http://www.jfree.org/forum/viewtopic.php?f=10&t=24521#p176756). – trashgod Aug 24 '13 at 15:13
  • You're welcome. If you feel like it, you can try my [new question](http://stackoverflow.com/questions/18419795/jfreechart-candlestick-chart-weird-behaviour-on-drag). – Jean-Paul Aug 24 '13 at 15:18
  • I just wanted to add that the update from 1.0.14 to 1.0.15 includes this bug fix which would explain the behavior: http://sourceforge.net/p/jfreechart/code/2465/ – David Gilbert Aug 29 '13 at 20:03
  • @DavidGilbert: Thanks! Answer updated. Please consider posting an answer [here](http://stackoverflow.com/q/18419795/230513). – trashgod Aug 29 '13 at 20:35