How to select a point in an XY plot and they get its data
How to select a point in an XY plot and they get its data
I am interested in getting JChart for displaying a scatter plot. However I need to display it in such a fashion that if I click on one of the points in the chart, I need to get values of taht point and the do sime actions based on that.
I just wanted to know if JChart does that for me.
It will be nice if somebody can answer this question ASAP.
--Chandresh
I just wanted to know if JChart does that for me.
It will be nice if somebody can answer this question ASAP.
--Chandresh
Re: How to select a point in an XY plot and they get its dat
Hi Chandresh,
Some work has been done in this direction, but the API is not all there yet.
Maybe all you need is to call the getAnchorValue() method in the ValueAxis?
Look in the mouseClicked() method in JFreeChartPanel to see how the mouse click coordinates are passed to the chart, then to the plot. In the XYPlot.handleClick() method there is some code that works out the data values that correspond to the point that was clicked - that gets used for drawing crosshairs, and storing the anchor point for zooming.
There's still work to do on this code...
Regards,
DG
Some work has been done in this direction, but the API is not all there yet.
Maybe all you need is to call the getAnchorValue() method in the ValueAxis?
Look in the mouseClicked() method in JFreeChartPanel to see how the mouse click coordinates are passed to the chart, then to the plot. In the XYPlot.handleClick() method there is some code that works out the data values that correspond to the point that was clicked - that gets used for drawing crosshairs, and storing the anchor point for zooming.
There's still work to do on this code...
Regards,
DG
Re: How to select a point in an XY plot and they get its dat
I tried to look into it and I am getting very close to it.
However I need some help from you. I got to the point where I am getting the value of the click. However cross hair finds the value of the closest point in the dataset and then goes to the point Can you tell me how does it calculate the new point and put it at that point. If I can get to know that , I guess my problem will be solved.
Also it will be nice if we can get the index of the dataset being displayed.
Thanks
--Chandresh
However I need some help from you. I got to the point where I am getting the value of the click. However cross hair finds the value of the closest point in the dataset and then goes to the point Can you tell me how does it calculate the new point and put it at that point. If I can get to know that , I guess my problem will be solved.
Also it will be nice if we can get the index of the dataset being displayed.
Thanks
--Chandresh
Re: How to select a point in an XY plot and they get its dat
David,
I actually found out the code which gets the X and Y value of the point which gets crosshaired.
However I need to know if there are any issues with licensing of the product. I am going to distibute this API after making changes
Thanks
--Chandresh
I actually found out the code which gets the X and Y value of the point which gets crosshaired.
However I need to know if there are any issues with licensing of the product. I am going to distibute this API after making changes
Thanks
--Chandresh
Re: How to select a point in an XY plot and they get its dat
Hi Chandresh,
The GNU Lesser General Public Licence (LGPL) allows you to redistribute JFreeChart with your own applications. One of the main requirements is that you must make the source code to JFreeChart (including any changes you make to it) available to the users of your program. You don't need to publish the source code to other parts of your application, if you don't want to.
The LGPL includes other requirements too, like including the copyright and no warranty notices - you need to consult the licence for the full details.
Regards,
DG.
The GNU Lesser General Public Licence (LGPL) allows you to redistribute JFreeChart with your own applications. One of the main requirements is that you must make the source code to JFreeChart (including any changes you make to it) available to the users of your program. You don't need to publish the source code to other parts of your application, if you don't want to.
The LGPL includes other requirements too, like including the copyright and no warranty notices - you need to consult the licence for the full details.
Regards,
DG.
Re: How to select a point in an XY plot and they get its dat
Hi All, here's code that prints out the click point and the crosshair point in a popup menu, if anyone is interested:
import com.jrefinery.chart.*;
import com.jrefinery.chart.event.*;
import com.jrefinery.chart.tooltips.*;
import com.jrefinery.data.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
/**
* Title: Description: Copyright: Copyright (c) 2001 Company:
*
* @author
* @created February 22, 2002
* @version 1.0
*/
public class PSHAXYPlot
extends XYPlot
implements
HorizontalValuePlot,
VerticalValuePlot {
protected int javaX = 0;
protected int javaY = 0;
/**
* Description of the Field
*/
protected double clickedX = 0, clickedY = 0;
/**
* Description of the Field
*/
protected boolean mouseClicked = false;
/**
* Description of the Field
*/
protected CrosshairInfo crosshairInfo = new CrosshairInfo();
protected JPopupMenu menu = new JPopupMenu();
protected JComponent menuComp = null;
/**
* Constructs an XYPlot with the specified axes (other attributes take
* default values).
*
* @param horizontalAxis The horizontal axis.
* @param verticalAxis The vertical axis.
*/
public PSHAXYPlot( ValueAxis horizontalAxis, ValueAxis verticalAxis ) {
super( horizontalAxis, verticalAxis );
}
/**
* Constructs a new XY plot.
*
* @param horizontalAxis The horizontal axis.
* @param verticalAxis The vertical axis.
* @param insets Amount of blank space around the plot area.
* @param background The Paint used to fill the plot background.
* @param outlineStroke The Stroke used to draw an outline around the
* plot.
* @param outlinePaint The color used to draw the plot outline.
*/
public PSHAXYPlot( ValueAxis horizontalAxis, ValueAxis verticalAxis,
Insets insets, Paint background,
Stroke outlineStroke, Paint outlinePaint ) {
super( horizontalAxis, verticalAxis,
insets, background,
outlineStroke, outlinePaint );
}
public void setComponent(JComponent comp){
this.menuComp = comp;
}
/**
* Handles a 'click' on the plot by updating the anchor values...
*
* @param x Description of the Parameter
* @param y Description of the Parameter
* @param info Description of the Parameter
*/
public void handleClick( int x, int y, DrawInfo info ) {
//System.out.println( "Here 1: " + x + ", " + y );
// set the anchor value for the horizontal axis...
ValueAxis hva = this.getDomainAxis();
double hvalue = hva.translateJava2DtoValue( ( float ) x, info.getDataArea() );
hva.setAnchorValue( hvalue );
hva.setCrosshairValue( hvalue );
// set the anchor value for the vertical axis...
ValueAxis vva = this.getRangeAxis();
double vvalue = vva.translateJava2DtoValue( ( float ) y, info.getDataArea() );
vva.setAnchorValue( vvalue );
vva.setCrosshairValue( vvalue );
mouseClicked = true;
this.clickedX = hvalue;
this.clickedY = vvalue;
this.javaX = x;
this.javaY = y;
}
/**
* Draws the XY plot on a Java 2D graphics device (such as the screen or a
* printer). <P>
*
* XYPlot now relies on an XYItemRenderer to draw each item in the plot.
* This allows the visual representation of the plot to be changed easily.
*
* @param g2 The graphics device.
* @param info Collects chart drawing information (null permitted).
* @param plotArea Description of the Parameter
*/
public void draw( Graphics2D g2, Rectangle2D plotArea, DrawInfo info ) {
// set up info collection...
ToolTipsCollection tooltips = null;
if ( info != null ) {
info.setPlotArea( plotArea );
tooltips = info.getToolTipsCollection();
}
// adjust the drawing area for plot insets (if any)...
if ( insets != null ) {
plotArea.setRect( plotArea.getX() + insets.left,
plotArea.getY() + insets.top,
plotArea.getWidth() - insets.left - insets.right,
plotArea.getHeight() - insets.top - insets.bottom );
}
// estimate the area required for drawing the axes...
HorizontalAxis hAxis = getHorizontalAxis();
VerticalAxis vAxis = getVerticalAxis();
double hAxisAreaHeight = hAxis.reserveHeight( g2, this, plotArea );
Rectangle2D vAxisArea = vAxis.reserveAxisArea( g2, this, plotArea, hAxisAreaHeight );
// ...and therefore what is left for the plot itself...
Rectangle2D dataArea = new Rectangle2D.Double( plotArea.getX() + vAxisArea.getWidth(),
plotArea.getY(),
plotArea.getWidth() - vAxisArea.getWidth(),
plotArea.getHeight() - hAxisAreaHeight );
if ( info != null ) {
info.setDataArea( dataArea );
}
crosshairInfo = new CrosshairInfo();
crosshairInfo.setCrosshairDistance( Double.POSITIVE_INFINITY );
crosshairInfo.setAnchorX( this.getDomainAxis().getAnchorValue() );
crosshairInfo.setAnchorY( this.getRangeAxis().getAnchorValue() );
// draw the plot background and axes...
drawOutlineAndBackground( g2, dataArea );
this.horizontalAxis.draw( g2, plotArea, dataArea );
this.verticalAxis.draw( g2, plotArea, dataArea );
// now get the data and plot it (the visual representation will depend on the renderer
// that has been set)...
XYDataset data = this.getDataset();
if ( data != null ) {
Shape originalClip = g2.getClip();
g2.clip( dataArea );
drawVerticalLines( g2, dataArea );
drawHorizontalLines( g2, dataArea );
double transRangeZero = this.getRangeAxis().translateValueToJava2D( 0.0, dataArea );
int seriesCount = data.getSeriesCount();
for ( int series = 0; series < seriesCount; series++ ) {
int itemCount = data.getItemCount( series );
for ( int item = 0; item < itemCount; item++ ) {
Shape tooltipArea = renderer.drawItem( g2, dataArea, info, this,
( ValueAxis ) horizontalAxis,
( ValueAxis ) verticalAxis,
data, series, item,
transRangeZero, crosshairInfo );
// add a tooltip for the item...
if ( tooltips != null ) {
if ( this.toolTipGenerator == null ) {
toolTipGenerator = new StandardXYToolTipGenerator();
}
String tip = this.toolTipGenerator.generateToolTip( data, series, item );
if ( tooltipArea != null ) {
tooltips.addToolTip( tip, tooltipArea );
}
}
}
}
// draw vertical crosshair if required...
ValueAxis hva = ( ValueAxis ) this.horizontalAxis;
hva.setCrosshairValue( crosshairInfo.getCrosshairX() );
if ( hva.isCrosshairVisible() ) {
this.drawVerticalLine( g2, dataArea, hva.getCrosshairValue(),
hva.getCrosshairStroke(),
hva.getCrosshairPaint() );
}
// draw horizontal crosshair if required...
ValueAxis vva = ( ValueAxis ) this.verticalAxis;
vva.setCrosshairValue( crosshairInfo.getCrosshairY() );
if ( vva.isCrosshairVisible() ) {
this.drawHorizontalLine( g2, dataArea, vva.getCrosshairValue(),
vva.getCrosshairStroke(),
vva.getCrosshairPaint() );
}
g2.setClip( originalClip );
}
if(mouseClicked){
mouseClicked = false;
StringBuffer b = new StringBuffer();
b.append("X = ");
b.append(clickedX);
b.append(": Y = ");
b.append(clickedY);
StringBuffer b2 = new StringBuffer();
b2.append("Data X = ");
b2.append(crosshairInfo.getCrosshairX());
b2.append(": Data Y = ");
b2.append(crosshairInfo.getCrosshairY());
Font font = new Font("Dialog", Font.PLAIN,
;
menu.removeAll();
menu.add( b.toString() );
menu.add( b2.toString() );
menu.setBackground(Color.white);
menu.setFont(font);
menu.setBorder(BorderFactory.createLineBorder(Color.blue));
int x = javaX + 5;
int y = javaY + 5;
menu.show(menuComp, x, y);
System.out.println("Java X = " + javaX + ": Y = " + javaY);
System.out.println(b.toString());
System.out.println(b2.toString());
//draw( g2, plotArea, info );
}
}
}
import com.jrefinery.chart.*;
import com.jrefinery.chart.event.*;
import com.jrefinery.chart.tooltips.*;
import com.jrefinery.data.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
/**
* Title: Description: Copyright: Copyright (c) 2001 Company:
*
* @author
* @created February 22, 2002
* @version 1.0
*/
public class PSHAXYPlot
extends XYPlot
implements
HorizontalValuePlot,
VerticalValuePlot {
protected int javaX = 0;
protected int javaY = 0;
/**
* Description of the Field
*/
protected double clickedX = 0, clickedY = 0;
/**
* Description of the Field
*/
protected boolean mouseClicked = false;
/**
* Description of the Field
*/
protected CrosshairInfo crosshairInfo = new CrosshairInfo();
protected JPopupMenu menu = new JPopupMenu();
protected JComponent menuComp = null;
/**
* Constructs an XYPlot with the specified axes (other attributes take
* default values).
*
* @param horizontalAxis The horizontal axis.
* @param verticalAxis The vertical axis.
*/
public PSHAXYPlot( ValueAxis horizontalAxis, ValueAxis verticalAxis ) {
super( horizontalAxis, verticalAxis );
}
/**
* Constructs a new XY plot.
*
* @param horizontalAxis The horizontal axis.
* @param verticalAxis The vertical axis.
* @param insets Amount of blank space around the plot area.
* @param background The Paint used to fill the plot background.
* @param outlineStroke The Stroke used to draw an outline around the
* plot.
* @param outlinePaint The color used to draw the plot outline.
*/
public PSHAXYPlot( ValueAxis horizontalAxis, ValueAxis verticalAxis,
Insets insets, Paint background,
Stroke outlineStroke, Paint outlinePaint ) {
super( horizontalAxis, verticalAxis,
insets, background,
outlineStroke, outlinePaint );
}
public void setComponent(JComponent comp){
this.menuComp = comp;
}
/**
* Handles a 'click' on the plot by updating the anchor values...
*
* @param x Description of the Parameter
* @param y Description of the Parameter
* @param info Description of the Parameter
*/
public void handleClick( int x, int y, DrawInfo info ) {
//System.out.println( "Here 1: " + x + ", " + y );
// set the anchor value for the horizontal axis...
ValueAxis hva = this.getDomainAxis();
double hvalue = hva.translateJava2DtoValue( ( float ) x, info.getDataArea() );
hva.setAnchorValue( hvalue );
hva.setCrosshairValue( hvalue );
// set the anchor value for the vertical axis...
ValueAxis vva = this.getRangeAxis();
double vvalue = vva.translateJava2DtoValue( ( float ) y, info.getDataArea() );
vva.setAnchorValue( vvalue );
vva.setCrosshairValue( vvalue );
mouseClicked = true;
this.clickedX = hvalue;
this.clickedY = vvalue;
this.javaX = x;
this.javaY = y;
}
/**
* Draws the XY plot on a Java 2D graphics device (such as the screen or a
* printer). <P>
*
* XYPlot now relies on an XYItemRenderer to draw each item in the plot.
* This allows the visual representation of the plot to be changed easily.
*
* @param g2 The graphics device.
* @param info Collects chart drawing information (null permitted).
* @param plotArea Description of the Parameter
*/
public void draw( Graphics2D g2, Rectangle2D plotArea, DrawInfo info ) {
// set up info collection...
ToolTipsCollection tooltips = null;
if ( info != null ) {
info.setPlotArea( plotArea );
tooltips = info.getToolTipsCollection();
}
// adjust the drawing area for plot insets (if any)...
if ( insets != null ) {
plotArea.setRect( plotArea.getX() + insets.left,
plotArea.getY() + insets.top,
plotArea.getWidth() - insets.left - insets.right,
plotArea.getHeight() - insets.top - insets.bottom );
}
// estimate the area required for drawing the axes...
HorizontalAxis hAxis = getHorizontalAxis();
VerticalAxis vAxis = getVerticalAxis();
double hAxisAreaHeight = hAxis.reserveHeight( g2, this, plotArea );
Rectangle2D vAxisArea = vAxis.reserveAxisArea( g2, this, plotArea, hAxisAreaHeight );
// ...and therefore what is left for the plot itself...
Rectangle2D dataArea = new Rectangle2D.Double( plotArea.getX() + vAxisArea.getWidth(),
plotArea.getY(),
plotArea.getWidth() - vAxisArea.getWidth(),
plotArea.getHeight() - hAxisAreaHeight );
if ( info != null ) {
info.setDataArea( dataArea );
}
crosshairInfo = new CrosshairInfo();
crosshairInfo.setCrosshairDistance( Double.POSITIVE_INFINITY );
crosshairInfo.setAnchorX( this.getDomainAxis().getAnchorValue() );
crosshairInfo.setAnchorY( this.getRangeAxis().getAnchorValue() );
// draw the plot background and axes...
drawOutlineAndBackground( g2, dataArea );
this.horizontalAxis.draw( g2, plotArea, dataArea );
this.verticalAxis.draw( g2, plotArea, dataArea );
// now get the data and plot it (the visual representation will depend on the renderer
// that has been set)...
XYDataset data = this.getDataset();
if ( data != null ) {
Shape originalClip = g2.getClip();
g2.clip( dataArea );
drawVerticalLines( g2, dataArea );
drawHorizontalLines( g2, dataArea );
double transRangeZero = this.getRangeAxis().translateValueToJava2D( 0.0, dataArea );
int seriesCount = data.getSeriesCount();
for ( int series = 0; series < seriesCount; series++ ) {
int itemCount = data.getItemCount( series );
for ( int item = 0; item < itemCount; item++ ) {
Shape tooltipArea = renderer.drawItem( g2, dataArea, info, this,
( ValueAxis ) horizontalAxis,
( ValueAxis ) verticalAxis,
data, series, item,
transRangeZero, crosshairInfo );
// add a tooltip for the item...
if ( tooltips != null ) {
if ( this.toolTipGenerator == null ) {
toolTipGenerator = new StandardXYToolTipGenerator();
}
String tip = this.toolTipGenerator.generateToolTip( data, series, item );
if ( tooltipArea != null ) {
tooltips.addToolTip( tip, tooltipArea );
}
}
}
}
// draw vertical crosshair if required...
ValueAxis hva = ( ValueAxis ) this.horizontalAxis;
hva.setCrosshairValue( crosshairInfo.getCrosshairX() );
if ( hva.isCrosshairVisible() ) {
this.drawVerticalLine( g2, dataArea, hva.getCrosshairValue(),
hva.getCrosshairStroke(),
hva.getCrosshairPaint() );
}
// draw horizontal crosshair if required...
ValueAxis vva = ( ValueAxis ) this.verticalAxis;
vva.setCrosshairValue( crosshairInfo.getCrosshairY() );
if ( vva.isCrosshairVisible() ) {
this.drawHorizontalLine( g2, dataArea, vva.getCrosshairValue(),
vva.getCrosshairStroke(),
vva.getCrosshairPaint() );
}
g2.setClip( originalClip );
}
if(mouseClicked){
mouseClicked = false;
StringBuffer b = new StringBuffer();
b.append("X = ");
b.append(clickedX);
b.append(": Y = ");
b.append(clickedY);
StringBuffer b2 = new StringBuffer();
b2.append("Data X = ");
b2.append(crosshairInfo.getCrosshairX());
b2.append(": Data Y = ");
b2.append(crosshairInfo.getCrosshairY());
Font font = new Font("Dialog", Font.PLAIN,

menu.removeAll();
menu.add( b.toString() );
menu.add( b2.toString() );
menu.setBackground(Color.white);
menu.setFont(font);
menu.setBorder(BorderFactory.createLineBorder(Color.blue));
int x = javaX + 5;
int y = javaY + 5;
menu.show(menuComp, x, y);
System.out.println("Java X = " + javaX + ": Y = " + javaY);
System.out.println(b.toString());
System.out.println(b2.toString());
//draw( g2, plotArea, info );
}
}
}
Re: How to select a point in an XY plot and they get its dat
Steven, the above code is very helpful. Thanks so much!
Re: How to select a point in an XY plot and they get its dat
I'll second that. I really appreciate it when others help out here in the JFreeChart forum, as I don't always have enough time to answer every question as well as I'd like to.
Regards,
Dave Gilbert
Regards,
Dave Gilbert