Page 1 of 1

BUG: CombinedDomainXYPlot with CandlestickRenderer

Posted: Fri Dec 07, 2012 12:08 am
by Aquajock

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;

 * 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 ////////////////////////////////////////////////////
	public void run()
	// make dataset
		Calendar oCalendar = Calendar.getInstance();
		OHLCDataItem[] voOHLCDataItem = new OHLCDataItem[gknDays];
		int iC;
		int iH = 0;
		int iL = 0;
		int iO = 1000;
		for (int i = 0; i < gknDays; )
			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());
	// make and show frame
		JFrame oJFrame = new JFrame();
		oJFrame.setContentPane(new ChartPanel(new JFreeChart(oPlotCombined)));
	// set dataset
		oPlot0.setDataset(oDataset); // LOOK HERE
		oPlot1.setDataset(oDataset); // LOOK HERE

Re: BUG: CombinedDomainXYPlot with CandlestickRenderer

Posted: Sat Jan 05, 2013 12:05 pm
by david.gilbert
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.

Re: BUG: CombinedDomainXYPlot with CandlestickRenderer

Posted: Sat Jan 05, 2013 1:23 pm
by david.gilbert
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

Re: BUG: CombinedDomainXYPlot with CandlestickRenderer

Posted: Tue Jan 08, 2013 1:08 am
by Aquajock
Thank you. BTW Nice piece of work, this.