Get value of a point on xy chart
Get value of a point on xy chart
How can I get the value of a single point (both x and y axis) when using mouse point to that point on xy chart or a vertical line scroll through the chart ?
Please help !!! Thanks
Please help !!! Thanks
Is there anyway I can get the source code for these demo files ? I'm doing school proj. Thanks
My email is phu.t.tran@ou.edu
My email is phu.t.tran@ou.edu
The source to the demo is part of the $50 documentation package that the author sells separately. I can't send it to you, but perhaps when David sees this he will have other options.
Alternatively, if one of the other users who sees this has working code in this topic area, they will send you an excerpt from their own code.
Personally, I haven't got this part of the package figured out yet so I'm afraid that I can't help you.
Alternatively, if one of the other users who sees this has working code in this topic area, they will send you an excerpt from their own code.
Personally, I haven't got this part of the package figured out yet so I'm afraid that I can't help you.
Best regards,
Don
Don
Ok through JFreeChart API, I can set the crosshair using these methods
xyplot.setDomainCrosshairVisible(true);
xyplot.setDomainCrosshairLockedOnData(true); xyplot.setRangeCrosshairVisible(true);
xyplot.setRangeCrosshairLockedOnData(true);
I can get the value by these two methods
xyplot.getRangeCrosshairValue();
xyplot.getDomainCrosshairValue();
I just need a suggestion about how to get the value whenever someone click at some points on the chart. Can mouse listener do that ? Thanks
xyplot.setDomainCrosshairVisible(true);
xyplot.setDomainCrosshairLockedOnData(true); xyplot.setRangeCrosshairVisible(true);
xyplot.setRangeCrosshairLockedOnData(true);
I can get the value by these two methods
xyplot.getRangeCrosshairValue();
xyplot.getDomainCrosshairValue();
I just need a suggestion about how to get the value whenever someone click at some points on the chart. Can mouse listener do that ? Thanks
I just try to get the value to print out to the console. It always lags behind. For ex I click on the point(2,3). It prints out the previous point clicked. If I click another point, it will print out 2 3. Idea ? Thanks
chartPanel.addChartMouseListener(this);
public void chartMouseClicked(ChartMouseEvent e) {
System.out.println(plot.getRangeCrosshairValue());
System.out.println(plot.getDomainCrosshairValue());
}
chartPanel.addChartMouseListener(this);
public void chartMouseClicked(ChartMouseEvent e) {
System.out.println(plot.getRangeCrosshairValue());
System.out.println(plot.getDomainCrosshairValue());
}
Hi -
Here is a code fragment that I wrote and is being used in an SWT Composite. It does the following:
1. If a left mouse click occurs (presumably on or near a point on my XYSeriesCollection based chart) the standard JFree chart mouse code will mark the point with both a horizontal and a vertical crosshair marker and my ChartMouseListener will read the X and Y data values from this point and display them in 2 SWT text labels that are located elsewhere in a very complex set of nested SWT composites in using a String.format compatible string of something like "X: %6.12f" and "Y: %6.12f" where the %6.12f is a double precision mixed mode floating point number conversion that receives the retrieved data values from the chart. Note that I have enabled the feature that causes the crosshairs to lock onto the nearest data point automatically elsewhere in the code. Also, note that the chart composite update() method is invoked prior to retrieving the chart mouse event. If you omit that step, you will retrieve the previous crosshair event rather than the current crosshair event as others have mentioned in this post already.
2. If a control-left mouse click occurs, my ChartMouseListener will drop both a horizontal and a vertical marker line (this is different than the crosshair marker which is not persistent). The vertical marker line also gets the X and Y data values stuffed into a marker annotation label. The constant "NL" is a system independent newline character string created elsewhere in the program.
3. If a shift-control-left mouse click occurs, the ChartMouseListener will attempt to remove a previously dropped set of marker lines, although you have to perform this close enough to the original data point that the mouse click finds the same point.
Some useful debug print statements were left in - you will want to delete those before you release any code.
Here is a code fragment and the entirety of the ChartMouseListener nested class:
package somePackage;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.Format;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.jdom.Element;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.LogarithmicAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.experimental.chart.annotations.XYTitleAnnotation;
import org.jfree.experimental.chart.swt.ChartComposite;
import org.jfree.ui.LengthAdjustmentType;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
public class ScopeComposite extends Composite {
/**
* Note: JFree Chart mouse events require a special listener interface class
* implementation that is separate and different from the SWT mouse listener
* interface so that it will work with either Swing or SWT/JFace. At its core,
* JFreeChart is using AWT mouse events, not SWT mouse events. Care must be
* taken in how imports are organized since the classes have the same names.
*/
class MyChartMouseListener implements ChartMouseListener {
MouseEvent tr;
int x, y;
double chartX, chartY;
int ctrlShiftClickMask = InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK;
public void chartMouseClicked(ChartMouseEvent e) {
tr = e.getTrigger();
System.out.printf("MyChartMouseListener: ChartMouseEvent %s triggered by %s occurred\n", e.getSource().toString(), tr.paramString());
//Crosshair values are not valid until after the chart has been updated
scopeChartComposite.update();
scopeXYPlot = scopeChart.getXYPlot();
if (tr.getButton() == MouseEvent.BUTTON1) {
if ((tr.getModifiersEx() & ctrlShiftClickMask) == ctrlShiftClickMask) {
//Ctrl-Shift Click is used to remove an existing marker
ValueMarker marker = new ValueMarker(scopeXYPlot.getDomainCrosshairValue());
marker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
marker.setPaint(markerLineColor);
marker.setLabel(String.format("X: %-1.3f%sY: %-1.3f", scopeXYPlot.getDomainCrosshairValue(), NL, scopeXYPlot.getRangeCrosshairValue()));
marker.setLabelPaint(markerLabelColor);
marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
marker.setLabelFont(markerLabelFont);
marker.setStroke(markerStroke);
scopeXYPlot.removeDomainMarker(marker);
marker = new ValueMarker(scopeXYPlot.getRangeCrosshairValue());
marker.setPaint(markerLineColor);
marker.setStroke(markerStroke);
scopeXYPlot.removeRangeMarker(marker);
System.out.printf("MyChartMouseListener: Ctrl-Shift-Click detected, marker removed [%s]\n", marker.getLabel());
scopeChartComposite.update();
} else if ((tr.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) {
//Left mouse Ctrl-Click occurred
ValueMarker marker = new ValueMarker(scopeXYPlot.getDomainCrosshairValue());
marker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
marker.setPaint(markerLineColor);
marker.setLabel(String.format("X: %-1.3f%sY: %-1.3f", scopeXYPlot.getDomainCrosshairValue(), NL, scopeXYPlot.getRangeCrosshairValue()));
marker.setLabelPaint(markerLabelColor);
marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
marker.setLabelFont(markerLabelFont);
marker.setStroke(markerStroke);
scopeXYPlot.addDomainMarker(marker);
marker = new ValueMarker(scopeXYPlot.getRangeCrosshairValue());
marker.setPaint(markerLineColor);
marker.setStroke(markerStroke);
scopeXYPlot.addRangeMarker(marker);
System.out.printf("MyChartMouseListener: Ctrl-Click detected, marker added [%s]\n", marker.getLabel());
scopeChartComposite.update();
} else {
//Normal left mouse click occurred
System.out.printf("MyChartMouseListener: normal click detected; params = [%s] detected\n", tr.paramString());
double crossHairX = scopeXYPlot.getDomainCrosshairValue();
double crossHairY = scopeXYPlot.getRangeCrosshairValue();
XLabel.setText(String.format("X: (Sec)%s%8.4f", NL, crossHairX));
YLabel.setText(String.format("Y: (P/U)%s%8.4f", NL, crossHairY));
}
} else {
System.out.printf("MyChartMouseListener: some other button pressed [e=%s]\n", tr.paramString());
}
}
public void chartMouseMoved(ChartMouseEvent e) {
}
}
//The bulk of this class is omitted here
}
Here is the code fragment that added the ChartMouseListener:
MyChartMouseListener processChartMouseEvent = new MyChartMouseListener();
ChartComposite frame;
... omitted application specific code
frame.addChartMouseListener(processChartMouseEvent);
Hope that this helps everyone trying to figure out how to handle the mouse events and display specific data point values.
Also, as someone else remarked in another related post, a ChartMouseListener is NOT the same as a MouseListener! You will waste a lot of time if you get the two confused (I know, I did
)
Sorry that my copy and paste somehow lost all of the leading white space characters - Is there some other way to include code in this Internet Explorer bulletin board based sorry excuse for a "text editor"?
Here is a code fragment that I wrote and is being used in an SWT Composite. It does the following:
1. If a left mouse click occurs (presumably on or near a point on my XYSeriesCollection based chart) the standard JFree chart mouse code will mark the point with both a horizontal and a vertical crosshair marker and my ChartMouseListener will read the X and Y data values from this point and display them in 2 SWT text labels that are located elsewhere in a very complex set of nested SWT composites in using a String.format compatible string of something like "X: %6.12f" and "Y: %6.12f" where the %6.12f is a double precision mixed mode floating point number conversion that receives the retrieved data values from the chart. Note that I have enabled the feature that causes the crosshairs to lock onto the nearest data point automatically elsewhere in the code. Also, note that the chart composite update() method is invoked prior to retrieving the chart mouse event. If you omit that step, you will retrieve the previous crosshair event rather than the current crosshair event as others have mentioned in this post already.
2. If a control-left mouse click occurs, my ChartMouseListener will drop both a horizontal and a vertical marker line (this is different than the crosshair marker which is not persistent). The vertical marker line also gets the X and Y data values stuffed into a marker annotation label. The constant "NL" is a system independent newline character string created elsewhere in the program.
3. If a shift-control-left mouse click occurs, the ChartMouseListener will attempt to remove a previously dropped set of marker lines, although you have to perform this close enough to the original data point that the mouse click finds the same point.
Some useful debug print statements were left in - you will want to delete those before you release any code.
Here is a code fragment and the entirety of the ChartMouseListener nested class:
package somePackage;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.Format;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.jdom.Element;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.LogarithmicAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.experimental.chart.annotations.XYTitleAnnotation;
import org.jfree.experimental.chart.swt.ChartComposite;
import org.jfree.ui.LengthAdjustmentType;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
public class ScopeComposite extends Composite {
/**
* Note: JFree Chart mouse events require a special listener interface class
* implementation that is separate and different from the SWT mouse listener
* interface so that it will work with either Swing or SWT/JFace. At its core,
* JFreeChart is using AWT mouse events, not SWT mouse events. Care must be
* taken in how imports are organized since the classes have the same names.
*/
class MyChartMouseListener implements ChartMouseListener {
MouseEvent tr;
int x, y;
double chartX, chartY;
int ctrlShiftClickMask = InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK;
public void chartMouseClicked(ChartMouseEvent e) {
tr = e.getTrigger();
System.out.printf("MyChartMouseListener: ChartMouseEvent %s triggered by %s occurred\n", e.getSource().toString(), tr.paramString());
//Crosshair values are not valid until after the chart has been updated
scopeChartComposite.update();
scopeXYPlot = scopeChart.getXYPlot();
if (tr.getButton() == MouseEvent.BUTTON1) {
if ((tr.getModifiersEx() & ctrlShiftClickMask) == ctrlShiftClickMask) {
//Ctrl-Shift Click is used to remove an existing marker
ValueMarker marker = new ValueMarker(scopeXYPlot.getDomainCrosshairValue());
marker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
marker.setPaint(markerLineColor);
marker.setLabel(String.format("X: %-1.3f%sY: %-1.3f", scopeXYPlot.getDomainCrosshairValue(), NL, scopeXYPlot.getRangeCrosshairValue()));
marker.setLabelPaint(markerLabelColor);
marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
marker.setLabelFont(markerLabelFont);
marker.setStroke(markerStroke);
scopeXYPlot.removeDomainMarker(marker);
marker = new ValueMarker(scopeXYPlot.getRangeCrosshairValue());
marker.setPaint(markerLineColor);
marker.setStroke(markerStroke);
scopeXYPlot.removeRangeMarker(marker);
System.out.printf("MyChartMouseListener: Ctrl-Shift-Click detected, marker removed [%s]\n", marker.getLabel());
scopeChartComposite.update();
} else if ((tr.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) {
//Left mouse Ctrl-Click occurred
ValueMarker marker = new ValueMarker(scopeXYPlot.getDomainCrosshairValue());
marker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
marker.setPaint(markerLineColor);
marker.setLabel(String.format("X: %-1.3f%sY: %-1.3f", scopeXYPlot.getDomainCrosshairValue(), NL, scopeXYPlot.getRangeCrosshairValue()));
marker.setLabelPaint(markerLabelColor);
marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
marker.setLabelFont(markerLabelFont);
marker.setStroke(markerStroke);
scopeXYPlot.addDomainMarker(marker);
marker = new ValueMarker(scopeXYPlot.getRangeCrosshairValue());
marker.setPaint(markerLineColor);
marker.setStroke(markerStroke);
scopeXYPlot.addRangeMarker(marker);
System.out.printf("MyChartMouseListener: Ctrl-Click detected, marker added [%s]\n", marker.getLabel());
scopeChartComposite.update();
} else {
//Normal left mouse click occurred
System.out.printf("MyChartMouseListener: normal click detected; params = [%s] detected\n", tr.paramString());
double crossHairX = scopeXYPlot.getDomainCrosshairValue();
double crossHairY = scopeXYPlot.getRangeCrosshairValue();
XLabel.setText(String.format("X: (Sec)%s%8.4f", NL, crossHairX));
YLabel.setText(String.format("Y: (P/U)%s%8.4f", NL, crossHairY));
}
} else {
System.out.printf("MyChartMouseListener: some other button pressed [e=%s]\n", tr.paramString());
}
}
public void chartMouseMoved(ChartMouseEvent e) {
}
}
//The bulk of this class is omitted here
}
Here is the code fragment that added the ChartMouseListener:
MyChartMouseListener processChartMouseEvent = new MyChartMouseListener();
ChartComposite frame;
... omitted application specific code
frame.addChartMouseListener(processChartMouseEvent);
Hope that this helps everyone trying to figure out how to handle the mouse events and display specific data point values.
Also, as someone else remarked in another related post, a ChartMouseListener is NOT the same as a MouseListener! You will waste a lot of time if you get the two confused (I know, I did

Sorry that my copy and paste somehow lost all of the leading white space characters - Is there some other way to include code in this Internet Explorer bulletin board based sorry excuse for a "text editor"?
Best regards,
Don
Don
Thx for the code..i have 2 question---
1) could u also tell me that do i need to implement the following code---
---public void chartMouseMoved(ChartMouseEvent e)
for MouseListener or any other method? my requirement is only to get the points when mouse is clicked?
2) do u know any method like ToolTip to see the points when clicked the mouse on graph?
thx in advance....
1) could u also tell me that do i need to implement the following code---
---public void chartMouseMoved(ChartMouseEvent e)
for MouseListener or any other method? my requirement is only to get the points when mouse is clicked?
2) do u know any method like ToolTip to see the points when clicked the mouse on graph?
thx in advance....
As you can see from the code fragment, I did not implement any code for ChartMouseMoved. Since ChartMouseListener is an interface, you must implement all of its defined methods, even if they are only blank.
I have made an initial attempt to get tool tips to work, but I have not been successful yet. Basically, nothing happens at all. I have seen several other posts regarding tool tips in SWT, but I haven't tried any of the advice yet. The consensus seems to be that tool tips had some problems under SWT, but that they have been fixed. However, I know that tool tips have not been implemented for all chart types across the board, so it may be that they haven't been implemented for my chart type - I really don't know yet.
I have made an initial attempt to get tool tips to work, but I have not been successful yet. Basically, nothing happens at all. I have seen several other posts regarding tool tips in SWT, but I haven't tried any of the advice yet. The consensus seems to be that tool tips had some problems under SWT, but that they have been fixed. However, I know that tool tips have not been implemented for all chart types across the board, so it may be that they haven't been implemented for my chart type - I really don't know yet.
Best regards,
Don
Don
Problem with ScopeComposite
Hello Don,
I have a prob in the mouselistener code..
could you please tell me what ---public class ScopeComposite extends Composite--- do?
i didnt find the package org.jfree.experimental.chart.swt.ChartComposite.
do i really need to implement the ScopeComposite? and do i need to make it public because i want to include it one existing public file so i cant make it public but when i made it comment...
// public class ScopeComposite extends Composite
it gave lot of error like it cant understand XYPlot and so on??
could you please tell me how to proceed?
Thx a lot
Anamika
I have a prob in the mouselistener code..
could you please tell me what ---public class ScopeComposite extends Composite--- do?
i didnt find the package org.jfree.experimental.chart.swt.ChartComposite.
do i really need to implement the ScopeComposite? and do i need to make it public because i want to include it one existing public file so i cant make it public but when i made it comment...
// public class ScopeComposite extends Composite
it gave lot of error like it cant understand XYPlot and so on??
could you please tell me how to proceed?
Thx a lot
Anamika
ScopeComposite was just the name of my particular application class. You must have a class, but it does not need to extend Composite. It could be main(), for example, or "private class MyClass" for example.
"public class ScopeComposite extends Composite" is unique to my application - just ignore it.
The package org.jfree.experimental.chart.swt.ChartComposite is a required part of using JFreeChart in SWT. When you download the JFreeChart source code, you will get the experimental SWT support stuff. You must include that package in your class path as well. The "experimental" part of JFreeChart is where JFree.org puts code that is not considered to be fully released yet. That is currently the status of the SWT support.
If you don't want to re-build the JFreeChart source, I believe that all of the jar files are already available pre-compiled, including the experimental jar files. These jar files must show up on your class path, one way or another, or Java won't be able to find the classes. You will find these jar files in the outermost directory of the JFreeChart download from Sourceforge.net.
"public class ScopeComposite extends Composite" is unique to my application - just ignore it.
The package org.jfree.experimental.chart.swt.ChartComposite is a required part of using JFreeChart in SWT. When you download the JFreeChart source code, you will get the experimental SWT support stuff. You must include that package in your class path as well. The "experimental" part of JFreeChart is where JFree.org puts code that is not considered to be fully released yet. That is currently the status of the SWT support.
If you don't want to re-build the JFreeChart source, I believe that all of the jar files are already available pre-compiled, including the experimental jar files. These jar files must show up on your class path, one way or another, or Java won't be able to find the classes. You will find these jar files in the outermost directory of the JFreeChart download from Sourceforge.net.
Best regards,
Don
Don