Click on a line
Click on a line
Hi !
I created a XYLineChart and i would like that the user can click on a line (to display some data).
Can I do that (with a ChartMouseListener?)and if yes, how?
Thank you very much
I created a XYLineChart and i would like that the user can click on a line (to display some data).
Can I do that (with a ChartMouseListener?)and if yes, how?
Thank you very much
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Add a ChartMouseListener to the ChartPanel, and it will return the ChartEntity for a mouse click. You should be able to determine from the entity which data item it relates to, and get the actual values by querying the dataset directly.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


I did a test :
When I click on a point, it takes me "org.free.chart.entity.XYItemEntity@..." ok !
But when I click on a line, it takes me "null" ! So how I can take the ChartEntity corresponding to my line?
Code: Select all
public void chartMouseClicked(ChartMouseEvent e){
ChartEntity ce = e.getEntity();
System.out.println(ce);};
But when I click on a line, it takes me "null" ! So how I can take the ChartEntity corresponding to my line?
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
There isn't one for the line...so you'll need to amend the renderer to insert one.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


I've got a trick(?).
I used a mouse point in a chart and line equation with two points..
so, i need a "mouse point" in a chart.
-- two points for line equation can get in a dataset.
For knows axis of a mouse point, I used "anchor".
I think, "anchor" is used for a tooltip. it is axis for drawing a tooltip. ( I think this is not correct. just I think.. -0-;)
I'm sorry for my english... -_-;;
I will show you sample code.. let's understand with following code.. -0-/;
with this code, we can get a mouse point in chart.
next time, I compared with a mouse point(mouseX, mouseY) and line equation..
I think a mouse point nearest line within a boundary, is that what we want. so, if I click near a line, then I think "click a line".
can u understand?? -_-;;
I'm so sorry for my english.... T^T.
I used a mouse point in a chart and line equation with two points..
so, i need a "mouse point" in a chart.
-- two points for line equation can get in a dataset.
For knows axis of a mouse point, I used "anchor".
I think, "anchor" is used for a tooltip. it is axis for drawing a tooltip. ( I think this is not correct. just I think.. -0-;)
I'm sorry for my english... -_-;;
I will show you sample code.. let's understand with following code.. -0-/;
Code: Select all
//==============================
//initial
ChartMouseEvent event;
ChartPanel chartPanel;
//==============================
// mouseX, mouseY : mouse point in chart
Insets insets = chartPanel.getInsets();
int anchorX = (int) ((event.getTrigger().getPoint().getX() - insets.left) / chartPanel.getScaleX());
int anchorY = (int) ((event.getTrigger().getPoint().getY() - insets.top) / chartPanel.getScaleY());
PlotRenderingInfo renderingInfo = (PlotRenderingInfo) chartPanel.getChartRenderingInfo().getPlotInfo();
double mouseX = domainAxis.java2DToValue(anchorX, renderingInfo.getDataArea(), RectangleEdge.BOTTOM);
double mouseY = rangeAxis.java2DToValue(anchorY, renderingInfo.getDataArea(), RectangleEdge.LEFT);
next time, I compared with a mouse point(mouseX, mouseY) and line equation..
I think a mouse point nearest line within a boundary, is that what we want. so, if I click near a line, then I think "click a line".
can u understand?? -_-;;
I'm so sorry for my english.... T^T.

Tokdo belongs to Korea.
Not a 'sea of japan', But a 'East Sea(Dong hae)'
Not a 'sea of japan', But a 'East Sea(Dong hae)'
Hi all,
I am working on something to make it possible to detect line clicks on XY chart. What I came up with is the following:
Edit the XYLineAndShapeRenderer to create polygons for every line, create something like a XYEntityItem, add this "XYLineItem" to a List, make this List available to the outside.
I'm not yet sure what classes I have to change to make this working, but I think this is a correct solution, similar way as for entities, and the polygons are create before the actual mouse click.
To be able to detect the actual click one should iterate the list and check if a mouse coordinate is inside a polygon.
Someone got any more ideas/remarks? About this method, but also about the classes I need to edit.
TiA,
Alexander
I am working on something to make it possible to detect line clicks on XY chart. What I came up with is the following:
Edit the XYLineAndShapeRenderer to create polygons for every line, create something like a XYEntityItem, add this "XYLineItem" to a List, make this List available to the outside.
I'm not yet sure what classes I have to change to make this working, but I think this is a correct solution, similar way as for entities, and the polygons are create before the actual mouse click.
To be able to detect the actual click one should iterate the list and check if a mouse coordinate is inside a polygon.
Someone got any more ideas/remarks? About this method, but also about the classes I need to edit.
TiA,
Alexander
-
- Posts: 35
- Joined: Tue Mar 28, 2006 1:10 am
- Location: La Jolla
- Contact:
This is working for me
Code: Select all
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.plot.CrosshairState;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ShapeUtilities;
public class XYLineAndShapeRendererThatRecordsLinesAsEntities extends
XYLineAndShapeRenderer {
protected void drawSecondaryPass(
Graphics2D g,
XYPlot plot,
XYDataset dataset,
int pass,
int series,
int item,
ValueAxis domainAxis,
Rectangle2D dataArea,
ValueAxis rangeAxis,
CrosshairState crosshairState,
EntityCollection entities) {
Shape entityArea = null;
double x1 = dataset.getXValue(series, item);
double y1 = dataset.getYValue(series, item);
if (Double.isNaN(y1) || Double.isNaN(x1))
return;
PlotOrientation orientation = plot.getOrientation();
RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);
if (getItemShapeVisible(series, item)) {
Shape shape = getItemShape(series, item);
shape = translated(orientation, transX1, transY1, shape);
entityArea = shape;
if (shape.intersects(dataArea)) {
drawFilledShape(g, series, item, shape);
drawOutlines(g, series, item, shape);
}
}
drawItemLabel(g, dataset, series, item, y1, orientation, transX1, transY1);
updateCrosshairValues(crosshairState, x1, y1, transX1, transY1, plot.getOrientation());
addEntity(entities, entityArea, dataset, series, item, transX1, transY1);
if (item < dataset.getItemCount(series) - 1) {
double x2 = dataset.getXValue(series, item + 1);
double y2 = dataset.getYValue(series, item + 1);
double transX2 = domainAxis.valueToJava2D(x2, dataArea, xAxisLocation);
double transY2 = rangeAxis.valueToJava2D(y2, dataArea, yAxisLocation);
entityArea = shapeAroundSegment(transX1, transY1, transX2, transY2, getDefaultEntityRadius());
addEntity(entities, entityArea, dataset, series, item, transX1, transY1);
}
}
protected void addEntity(
EntityCollection entities,
Shape area,
XYDataset dataset,
int series,
int item,
double entityX,
double entityY) {
if (entities == null)
return;
super.addEntity(entities, area, dataset, series, item, entityX, entityY);
}
private Shape translated(PlotOrientation orientation, double x, double y, Shape shape) {
if (orientation == PlotOrientation.HORIZONTAL)
return ShapeUtilities.createTranslatedShape(shape, y, x);
if (orientation == PlotOrientation.VERTICAL)
return ShapeUtilities.createTranslatedShape(shape, x, y);
return shape;
}
private void drawFilledShape(Graphics2D g, int series, int item, Shape shape) {
if (!getItemShapeFilled(series, item))
return;
final Paint paint = getUseFillPaint() ? getItemFillPaint(series, item) : getItemPaint(series, item);
g.setPaint(paint);
g.fill(shape);
}
private void drawOutlines(Graphics2D g, int series, int item, Shape shape) {
if (!getDrawOutlines())
return;
final Paint paint = getUseOutlinePaint() ? getItemOutlinePaint(series, item) : getItemPaint(series, item);
g.setPaint(paint);
g.setStroke(getItemOutlineStroke(series, item));
g.draw(shape);
}
private void drawItemLabel(Graphics2D g, XYDataset dataset, int series, int item, double y1, PlotOrientation orientation, double transX1, double transY1) {
if (!isItemLabelVisible(series, item))
return;
final boolean horizontal = orientation == PlotOrientation.HORIZONTAL;
double xx = horizontal ? transY1 : transX1;
double yy = horizontal ? transX1 : transY1;
drawItemLabel(g, orientation, dataset, series, item, xx, yy, (y1 < 0.0));
}
static Shape shapeAroundSegment(double x1, double y1, double x2, double y2, double r) {
final double dX = x2 - x1;
final double dY = y2 - y1;
final double dT = Math.sqrt(dX*dX + dY*dY);
final double rX = r * dY / dT;
final double rY = r * dX / dT;
Point2D p1 = new Point2D.Double(x1 + rX, y1 + rY);
Point2D p2 = new Point2D.Double(x2 + rX, y2 + rY);
Point2D p3 = new Point2D.Double(x2 - rX, y2 - rY);
Point2D p4 = new Point2D.Double(x1 - rX, y1 - rY);
GeneralPath path = new GeneralPath();
path.moveTo((float)p1.getX(), (float)p1.getY());
path.lineTo((float)p2.getX(), (float)p2.getY());
path.lineTo((float)p3.getX(), (float)p3.getY());
path.lineTo((float)p4.getX(), (float)p4.getY());
path.lineTo((float)p1.getX(), (float)p1.getY());
path.closePath();
return path;
}
}
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Hi Carl,
Thanks for the code. I added an item in the Patch Manager, because I might come back and add this as an optional feature in the XYLineAndShapeRenderer class:
https://sourceforge.net/tracker/index.p ... tid=315494
Thanks for the code. I added an item in the Patch Manager, because I might come back and add this as an optional feature in the XYLineAndShapeRenderer class:
https://sourceforge.net/tracker/index.p ... tid=315494
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader

