BUG: CombinedDomainXYPlot with CandlestickRenderer

Discussion about JFreeChart related to stockmarket charts.

BUG: CombinedDomainXYPlot with CandlestickRenderer

Postby Aquajock » Fri Dec 07, 2012 12:08 am

Code: Select all
package chart;

import java.awt.EventQueue;
import java.util.Calendar;

import javax.swing.JFrame;
import javax.swing.WindowConstants;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.data.xy.DefaultOHLCDataset;
import org.jfree.data.xy.OHLCDataItem;

/**
* This is an example of a CombinedDomainXYPlot that misbehaves with CandlestickRenderer.
* Note that the datasets of the subplots are not set at instantiation.
* Instead, they are set later using #setDataset(Dataset).
* Running the code as shown results in the first plot being only partially rendered.
* Swapping the lines labeled LOOK HERE results in the second plot being only partially rendered.
* Adding more subplots results in the first plot whose dataset is set exhibiting this problem.
* Telling me to set the dataset in the constructors doesn't solve the problem.
* Built with JFreeChart 1.0.14.
*/
public class MultiPlotProblem implements Runnable
   {
// MAIN ///////////////////////////////////////////////////////////////////////
   
   static public void main(String[] avs){EventQueue.invokeLater(new MultiPlotProblem());}
   
// STATIC VARIABLES ///////////////////////////////////////////////////////////
   
   static final int   gknDays   = 365;
   static final double   gkdDay   = 2*Math.PI/gknDays;
   
// CONSTRUCTORS ///////////////////////////////////////////////////////////////
   
   public MultiPlotProblem() {super();}

// PUBLIC INSTANCE METHODS ////////////////////////////////////////////////////
   
   @Override
   public void run()
      {
   // make dataset
      Calendar oCalendar = Calendar.getInstance();
      oCalendar.set(Calendar.YEAR,2010);
      OHLCDataItem[] voOHLCDataItem = new OHLCDataItem[gknDays];
      int iC;
      int iH = 0;
      int iL = 0;
      int iO = 1000;
      for (int i = 0; i < gknDays; )
         {
         oCalendar.set(Calendar.DAY_OF_YEAR,++i);
         int iSin = (int)(Math.sin(gkdDay*i*2)*100);
         iC = iO+iSin;
         iH = Math.max(iC,iO)+Math.abs(iSin);
         iL = Math.min(iC,iO)-Math.abs(iSin);
         voOHLCDataItem[i-1] = new OHLCDataItem(oCalendar.getTime(),iO,iH,iL,iC,iH-iL);
         iO = iC;
         }
      DefaultOHLCDataset oDataset = new DefaultOHLCDataset("",voOHLCDataItem);
      
   // make combined plot
      XYPlot oPlot0 = new XYPlot(null,null,new NumberAxis(),new CandlestickRenderer());
      XYPlot oPlot1 = new XYPlot(null,null,new NumberAxis(),new CandlestickRenderer());
      CombinedDomainXYPlot oPlotCombined = new CombinedDomainXYPlot(new DateAxis());
      oPlotCombined.add(oPlot0);
      oPlotCombined.add(oPlot1);
      
   // make and show frame
      JFrame oJFrame = new JFrame();
      oJFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      oJFrame.setContentPane(new ChartPanel(new JFreeChart(oPlotCombined)));
      oJFrame.setSize(700,500);
      oJFrame.setVisible(true);
      
   // set dataset
      oPlot0.setDataset(oDataset); // LOOK HERE
      oPlot1.setDataset(oDataset); // LOOK HERE
      }
   }
Aquajock
 
Posts: 6
Joined: Fri Dec 07, 2012 12:03 am

Re: BUG: CombinedDomainXYPlot with CandlestickRenderer

Postby david.gilbert » Sat Jan 05, 2013 12:05 pm

Thanks for the example, I can reproduce the problem exactly as you described. It looks like an issue with the auto-range calculation on the y-axis, I will debug.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Ask your company to buy the JFreeChart Developer Guide
:idea: Check out other products sold by my company Object Refinery Limited
david.gilbert
JFreeChart Project Leader
 
Posts: 11653
Joined: Fri Mar 14, 2003 10:29 am

Re: BUG: CombinedDomainXYPlot with CandlestickRenderer

Postby david.gilbert » Sat Jan 05, 2013 1:23 pm

The issue is that when the first dataset is applied, the auto-range calculation is not triggered for the domain axis on the combined plot, and then the auto-range calculation for the y-axis of the subplot doesn't consider the full range of values. This is a bug, but I don't know the correct fix yet. A workaround is to call the method to set the dataset twice (just for the first one)...the second time around, the domain axis range is correct so the y-axis auto-range calculation works as it should:

Code: Select all
      oPlot0.setDataset(oDataset); // LOOK HERE
      oPlot0.setDataset(oDataset); // THIS LINE ADDED
      oPlot1.setDataset(oDataset); // LOOK HERE
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Ask your company to buy the JFreeChart Developer Guide
:idea: Check out other products sold by my company Object Refinery Limited
david.gilbert
JFreeChart Project Leader
 
Posts: 11653
Joined: Fri Mar 14, 2003 10:29 am

Re: BUG: CombinedDomainXYPlot with CandlestickRenderer

Postby Aquajock » Tue Jan 08, 2013 1:08 am

Thank you. BTW Nice piece of work, this.
Aquajock
 
Posts: 6
Joined: Fri Dec 07, 2012 12:03 am


Return to JFreeChart - Stockmarket

Who is online

Users browsing this forum: No registered users and 2 guests