getEntity() not working with altered PlotOrientation

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
IanMayo
Posts: 9
Joined: Mon Oct 31, 2005 10:15 am
Location: UK

getEntity() not working with altered PlotOrientation

Post by IanMayo » Thu Nov 11, 2010 12:16 pm

Hi all,
I'm trapping the chartMouseClicked event to let the user select a data-series in my TimeSeries plot. All is working fine, until I switch the PlotOrientation from Vertical to Horizontal - then the getEntity() method on the ChartMouseEvent just returns the background plot - it fails to recognise that a series is being clicked on.

Below is a code sample to illustrate the problem. With the app open, you can click on a series and the console will confirm that the handler has detected an XYItemEntity. If you now hold down [Alt] and click the chart the plot orientation is switched to horizontal. Now, clicking on a series just returns a 'PlotEntitry'. I suspect the getEntity() algorithm isn't recognising that the orientation has changed - since on occasion it's possible to click on an empty area and get an XYItemEntity returned.

I'd welcome advice/support in this area.
cheers,
Ian

Code: Select all

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class MouseClickProblemDemo extends ApplicationFrame
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * @param title
	 *          the frame title.
	 */
	public MouseClickProblemDemo(String title)
	{
		super(title);

		TimeSeries s1 = new TimeSeries("Series to click");
		s1.add(new Month(2, 2001), 181.8);
		s1.add(new Month(3, 2001), 167.3);
		s1.add(new Month(4, 2001), 153.8);
		s1.add(new Month(5, 2001), 167.6);
		s1.add(new Month(6, 2001), 158.8);
		s1.add(new Month(7, 2001), 148.3);
		s1.add(new Month(8, 2001), 153.9);
		s1.add(new Month(9, 2001), 142.7);
		s1.add(new Month(10, 2001), 123.2);

		TimeSeriesCollection dataset = new TimeSeriesCollection();
		dataset.addSeries(s1);

		final JFreeChart chart = ChartFactory.createTimeSeriesChart(
				"[Alt]-click to switch orientation", // title
				"Time axis", // x-axis label
				"Value axis", // y-axis label
				dataset, // data
				false, // create legend?
				false, // generate tooltips?
				false // generate URLs?
				);
		
		ChartPanel chartPanel = new ChartPanel(chart);

		chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));

		chartPanel.addChartMouseListener(new ChartMouseListener()
		{
			public void chartMouseMoved(ChartMouseEvent arg0)
			{
			}

			public void chartMouseClicked(ChartMouseEvent arg0)
			{
				System.out.println("clicked on:" + arg0.getEntity());
				
				if(arg0.getTrigger().isAltDown())
				{
					if(chart.getXYPlot().getOrientation() == PlotOrientation.HORIZONTAL)
						chart.getXYPlot().setOrientation(PlotOrientation.VERTICAL);
					else
						chart.getXYPlot().setOrientation(PlotOrientation.HORIZONTAL);
				}
			}
		});
		setContentPane(chartPanel);
	}

	/**
	 * Starting point for the demonstration application.
	 * 
	 * @param args
	 *          ignored.
	 */
	public static void main(String[] args)
	{
		MouseClickProblemDemo demo = new MouseClickProblemDemo("Time Series Demo 1");
		demo.pack();
		RefineryUtilities.centerFrameOnScreen(demo);
		demo.setVisible(true);
	}

}

IanMayo
Posts: 9
Joined: Mon Oct 31, 2005 10:15 am
Location: UK

Re: getEntity() not working with altered PlotOrientation

Post by IanMayo » Fri Nov 12, 2010 5:14 pm

After some support from am algorithmically gifted colleague of mine I'm now aware of the solution to this problem.

The addEntity method is responsible for creating the 'hotspot' it reacts to, using its x and y coordinates. When the addEntity method is generating the hotspot ellipse shape it switches around the x & y coordinates if the plot is in PlotOrientation.Horizontal mode. Unfortunately this isn't necessary, since the coordinates have already been switched in the drawSecondaryPass method - resulting in testing the x and y against an unswitched set of coordinates.

Here's what the addEntity method in AbstractXYItemRenderer should look like:

Code: Select all

	protected void addEntity(EntityCollection entities, Shape area,
				XYDataset dataset, int series, int item, double entityX,
				double entityY) {
			if (!getItemCreateEntity(series, item)) {
				return;
			}
			Shape hotspot = area;
			if (hotspot == null) {
				double r = getDefaultEntityRadius();
				double w = r * 4;
				hotspot = new Ellipse2D.Double(entityX - r, entityY - r, w, w);
			}
			...
			}
Can anybody advise on how to get this fix into the trunk?

Ian

Locked