this is a first but wokring try. please have a look at it and tell me if it's the right way to go.
Code: Select all
diff -ruN -X jfreechart.exclude jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/plot/CrosshairState.java jfreechart-1.0.0-rc1\source/org/jfree/chart/plot/CrosshairState.java
--- jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/plot/CrosshairState.java 2005-06-02 17:41:34.000000000 +0200
+++ jfreechart-1.0.0-rc1\source/org/jfree/chart/plot/CrosshairState.java 2005-10-04 21:36:39.415749300 +0200
@@ -49,6 +49,8 @@
import java.awt.geom.Point2D;
+import org.jfree.chart.axis.ValueAxis;
+
/**
* Maintains state information about crosshairs on a plot.
*
@@ -73,9 +75,15 @@
/** The x-value for the crosshair point. */
private double crosshairX;
+ /** The x-axis for the crosshair point */
+ private ValueAxis crosshairXAxis;
+
/** The y-value for the crosshair point. */
private double crosshairY;
+ /** The y-axis for the crosshair point */
+ private ValueAxis crosshairYAxis;
+
/**
* The smallest distance so far between the anchor point and a data point.
*/
@@ -158,6 +166,37 @@
}
+ public void updateCrosshairPoint(double x, double y, double transX,
+ double transY, PlotOrientation orientation, ValueAxis domainAxis, ValueAxis rangeAxis) {
+
+ if (this.anchor != null) {
+ double d = 0.0;
+ if (this.calculateDistanceInDataSpace) {
+ d = (x - this.anchorX) * (x - this.anchorX)
+ + (y - this.anchorY) * (y - this.anchorY);
+ } else {
+ double xx = this.anchor.getX();
+ double yy = this.anchor.getY();
+ if (orientation == PlotOrientation.HORIZONTAL) {
+ double temp = yy;
+ yy = xx;
+ xx = temp;
+ }
+ d = (transX - xx) * (transX - xx) + (transY - yy)
+ * (transY - yy);
+ }
+
+ if (d < this.distance) {
+ this.crosshairX = x;
+ this.crosshairY = y;
+ this.crosshairXAxis = domainAxis;
+ this.crosshairYAxis = rangeAxis;
+ this.distance = d;
+ }
+ }
+
+ }
+
/**
* Evaluates an x-value and if it is the closest to the anchor point it
* becomes the new crosshair point.
@@ -177,6 +216,17 @@
}
+ public void updateCrosshairX(double candidateX, ValueAxis domainAxis) {
+
+ double d = Math.abs(candidateX - this.anchorX);
+ if (d < this.distance) {
+ this.crosshairX = candidateX;
+ this.crosshairXAxis = domainAxis;
+ this.distance = d;
+ }
+
+ }
+
/**
* Evaluates a y-value and if it is the closest to the anchor point it
* becomes the new crosshair point.
@@ -196,6 +246,17 @@
}
+ public void updateCrosshairY(double candidateY, ValueAxis rangeAxis) {
+
+ double d = Math.abs(candidateY - this.anchorY);
+ if (d < this.distance) {
+ this.crosshairY = candidateY;
+ this.crosshairYAxis = rangeAxis;
+ this.distance = d;
+ }
+
+ }
+
/**
* Sets the anchor point. This is usually the mouse click point in a chart
* panel, and the crosshair point will often be the data item that is
@@ -245,4 +306,32 @@
this.crosshairY = y;
}
+ /**
+ * @return Returns the crosshairXAxis.
+ */
+ public ValueAxis getCrosshairXAxis() {
+ return crosshairXAxis;
+ }
+
+ /**
+ * @param crosshairXAxis The crosshairXAxis to set.
+ */
+ public void setCrosshairXAxis(ValueAxis crosshairXAxis) {
+ this.crosshairXAxis = crosshairXAxis;
+ }
+
+ /**
+ * @return Returns the crosshairYAxis.
+ */
+ public ValueAxis getCrosshairYAxis() {
+ return crosshairYAxis;
+ }
+
+ /**
+ * @param crosshairYAxis The crosshairYAxis to set.
+ */
+ public void setCrosshairYAxis(ValueAxis crosshairYAxis) {
+ this.crosshairYAxis = crosshairYAxis;
+ }
+
}
diff -ruN -X jfreechart.exclude jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/plot/XYPlot.java jfreechart-1.0.0-rc1\source/org/jfree/chart/plot/XYPlot.java
--- jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/plot/XYPlot.java 2005-06-02 17:41:32.000000000 +0200
+++ jfreechart-1.0.0-rc1\source/org/jfree/chart/plot/XYPlot.java 2005-10-05 10:45:07.352344800 +0200
@@ -349,6 +349,9 @@
/** The domain crosshair value. */
private double domainCrosshairValue;
+ /** The domain axis used if the crosshair is locked on data */
+ private ValueAxis domainCrosshairAxis;
+
/** The pen/brush used to draw the crosshair (if any). */
private transient Stroke domainCrosshairStroke;
@@ -367,6 +370,9 @@
/** The range crosshair value. */
private double rangeCrosshairValue;
+ /** The range axis used if the crosshair is locked on data */
+ private ValueAxis rangeCrosshairAxis;
+
/** The pen/brush used to draw the crosshair (if any). */
private transient Stroke rangeCrosshairStroke;
@@ -523,11 +529,13 @@
this.domainCrosshairVisible = false;
this.domainCrosshairValue = 0.0;
+ this.domainCrosshairAxis = null;
this.domainCrosshairStroke = DEFAULT_CROSSHAIR_STROKE;
this.domainCrosshairPaint = DEFAULT_CROSSHAIR_PAINT;
this.rangeCrosshairVisible = false;
this.rangeCrosshairValue = 0.0;
+ this.rangeCrosshairAxis = null;
this.rangeCrosshairStroke = DEFAULT_CROSSHAIR_STROKE;
this.rangeCrosshairPaint = DEFAULT_CROSSHAIR_PAINT;
@@ -2186,44 +2194,53 @@
PlotOrientation orient = getOrientation();
+ // update crosshair location
+ setDomainCrosshairAxis(crosshairState.getCrosshairXAxis(), false);
+ setRangeCrosshairAxis(crosshairState.getCrosshairYAxis(), false);
+ setDomainCrosshairValue(crosshairState.getCrosshairX(), false);
+ setRangeCrosshairValue(crosshairState.getCrosshairY(), false);
+
// draw domain crosshair if required...
if (!this.domainCrosshairLockedOnData && anchor != null) {
- double xx = getDomainAxis().java2DToValue(
+ double xx = getDomainCrosshairAxis().java2DToValue(
anchor.getX(), dataArea, getDomainAxisEdge()
);
crosshairState.setCrosshairX(xx);
}
- setDomainCrosshairValue(crosshairState.getCrosshairX(), false);
- if (isDomainCrosshairVisible()) {
+ if (isDomainCrosshairVisible() && getDomainCrosshairAxis() != null
+ && getDomainCrosshairAxis().getRange().contains(getDomainCrosshairValue())) {
double x = getDomainCrosshairValue();
Paint paint = getDomainCrosshairPaint();
Stroke stroke = getDomainCrosshairStroke();
+ ValueAxis domainAxis = getDomainCrosshairAxis();
+ ValueAxis rangeAxis = getRangeCrosshairAxis();
if (orient == PlotOrientation.HORIZONTAL) {
- drawHorizontalLine(g2, dataArea, x, stroke, paint);
+ drawHorizontalLine(g2, dataArea, x, stroke, paint, domainAxis, rangeAxis);
}
else if (orient == PlotOrientation.VERTICAL) {
- drawVerticalLine(g2, dataArea, x, stroke, paint);
+ drawVerticalLine(g2, dataArea, x, stroke, paint, domainAxis, rangeAxis);
}
}
// draw range crosshair if required...
if (!this.rangeCrosshairLockedOnData && anchor != null) {
- double yy = getRangeAxis().java2DToValue(
+ double yy = getRangeCrosshairAxis().java2DToValue(
anchor.getY(), dataArea, getRangeAxisEdge()
);
crosshairState.setCrosshairX(yy);
}
- setRangeCrosshairValue(crosshairState.getCrosshairY(), false);
- if (isRangeCrosshairVisible()
- && getRangeAxis().getRange().contains(getRangeCrosshairValue())) {
+ if (isRangeCrosshairVisible() && getRangeCrosshairAxis() != null
+ && getRangeCrosshairAxis().getRange().contains(getRangeCrosshairValue())) {
double y = getRangeCrosshairValue();
Paint paint = getRangeCrosshairPaint();
Stroke stroke = getRangeCrosshairStroke();
+ ValueAxis domainAxis = getDomainCrosshairAxis();
+ ValueAxis rangeAxis = getRangeCrosshairAxis();
if (orient == PlotOrientation.HORIZONTAL) {
- drawVerticalLine(g2, dataArea, y, stroke, paint);
+ drawVerticalLine(g2, dataArea, y, stroke, paint, domainAxis, rangeAxis);
}
else if (orient == PlotOrientation.VERTICAL) {
- drawHorizontalLine(g2, dataArea, y, stroke, paint);
+ drawHorizontalLine(g2, dataArea, y, stroke, paint, domainAxis, rangeAxis);
}
}
@@ -2928,6 +2945,36 @@
}
/**
+ * Utility method for drawing a horizontal line across the data area of the
+ * plot.
+ *
+ * @param g2 the graphics device.
+ * @param dataArea the data area.
+ * @param value the coordinate, where to draw the line.
+ * @param stroke the stroke to use.
+ * @param paint the paint to use.
+ * @param domainAxis the domain axis to which the value is mapped
+ * @param rangeAxis the range axis to which the value is mapped
+ */
+ protected void drawHorizontalLine(Graphics2D g2, Rectangle2D dataArea,
+ double value, Stroke stroke, Paint paint, ValueAxis domainAxis, ValueAxis rangeAxis) {
+
+ ValueAxis axis = rangeAxis;
+ if (getOrientation() == PlotOrientation.HORIZONTAL) {
+ axis = domainAxis;
+ }
+ if (axis.getRange().contains(value)) {
+ double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT);
+ Line2D line = new Line2D.Double(dataArea.getMinX(), yy, dataArea
+ .getMaxX(), yy);
+ g2.setStroke(stroke);
+ g2.setPaint(paint);
+ g2.draw(line);
+ }
+
+ }
+
+ /**
* Utility method for drawing a vertical line on the data area of the plot.
*
* @param g2 the graphics device.
@@ -2958,6 +3005,36 @@
}
/**
+ * Utility method for drawing a vertical line on the data area of the plot.
+ *
+ * @param g2 the graphics device.
+ * @param dataArea the data area.
+ * @param value the coordinate, where to draw the line.
+ * @param stroke the stroke to use.
+ * @param paint the paint to use.
+ * @param domainAxis the domain axis to which the value is mapped
+ * @param rangeAxis the range axis to which the value is mapped
+ */
+ protected void drawVerticalLine(Graphics2D g2, Rectangle2D dataArea,
+ double value, Stroke stroke, Paint paint, ValueAxis domainAxis, ValueAxis rangeAxis) {
+
+ ValueAxis axis = domainAxis;
+ if (getOrientation() == PlotOrientation.HORIZONTAL) {
+ axis = rangeAxis;
+ }
+ if (axis.getRange().contains(value)) {
+ double xx = axis.valueToJava2D(value, dataArea,
+ RectangleEdge.BOTTOM);
+ Line2D line = new Line2D.Double(xx, dataArea.getMinY(), xx,
+ dataArea.getMaxY());
+ g2.setStroke(stroke);
+ g2.setPaint(paint);
+ g2.draw(line);
+ }
+
+ }
+
+ /**
* Handles a 'click' on the plot by updating the anchor values...
*
* @param x the x-coordinate, where the click occurred, in Java2D space.
@@ -3242,6 +3319,15 @@
}
/**
+ * Returns the domain axis to which the crosshair value has been mapped
+ *
+ * @return The axis.
+ */
+ public ValueAxis getDomainCrosshairAxis() {
+ return this.domainCrosshairAxis;
+ }
+
+ /**
* Sets the domain crosshair value and sends a {@link PlotChangeEvent} to
* all registered listeners (provided that the domain crosshair is visible).
*
@@ -3251,6 +3337,17 @@
setDomainCrosshairValue(value, true);
}
+ /*
+ * Sets the axis to which the domain crosshair value has been mapped
+ * <P>
+ * @param axis the domain axis
+ * @param notify a flag that controls whether or not listeners are
+ * notified.
+ */
+ public void setDomainCrosshairAxis(ValueAxis axis, boolean notify) {
+ this.domainCrosshairAxis = axis;
+ }
+
/**
* Sets the domain crosshair value and, if requested, sends a
* {@link PlotChangeEvent} to all registered listeners (provided that the
@@ -3364,6 +3461,15 @@
}
/**
+ * Returns the range axis to which the crosshair value has been mapped
+ *
+ * @return The axis.
+ */
+ public ValueAxis getRangeCrosshairAxis() {
+ return this.rangeCrosshairAxis;
+ }
+
+ /**
* Sets the domain crosshair value.
* <P>
* Registered listeners are notified that the plot has been modified, but
@@ -3392,6 +3498,20 @@
}
}
+ /*
+ * Sets the axis to which the range crosshair value has been mapped
+ * <P>
+ * @param axis the range axis
+ * @param notify a flag that controls whether or not listeners are
+ * notified.
+ */
+ public void setRangeCrosshairAxis(ValueAxis axis, boolean notify) {
+ this.rangeCrosshairAxis = axis;
+ if (isRangeCrosshairVisible() && notify) {
+ notifyListeners(new PlotChangeEvent(this));
+ }
+ }
+
/**
* Returns the Stroke used to draw the crosshair (if visible).
*
diff -ruN -X jfreechart.exclude jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java jfreechart-1.0.0-rc1\source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java
--- jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java 2005-06-02 17:41:34.000000000 +0200
+++ jfreechart-1.0.0-rc1\source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java 2005-10-04 21:32:57.442140300 +0200
@@ -1317,6 +1317,36 @@
}
}
+
+ protected void updateCrosshairValues(CrosshairState crosshairState,
+ double x, double y, double transX, double transY,
+ PlotOrientation orientation,
+ ValueAxis domainAxis, ValueAxis rangeAxis) {
+
+ if (orientation == null) {
+ throw new IllegalArgumentException("Null 'orientation' argument.");
+ }
+
+ if (crosshairState != null) {
+ // do we need to update the crosshair values?
+ if (this.plot.isDomainCrosshairLockedOnData()) {
+ if (this.plot.isRangeCrosshairLockedOnData()) {
+ // both axes
+ crosshairState.updateCrosshairPoint(x, y, transX, transY,
+ orientation, domainAxis, rangeAxis);
+ } else {
+ // just the domain axis...
+ crosshairState.updateCrosshairX(x, domainAxis);
+ }
+ } else {
+ if (this.plot.isRangeCrosshairLockedOnData()) {
+ // just the range axis...
+ crosshairState.updateCrosshairY(y, rangeAxis);
+ }
+ }
+ }
+
+ }
/**
* Draws an item label.
diff -ruN -X jfreechart.exclude jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/renderer/xy/XYLineAndShapeRenderer.java jfreechart-1.0.0-rc1\source/org/jfree/chart/renderer/xy/XYLineAndShapeRenderer.java
--- jfreechart-1.0.0-rc1-orig\source/org/jfree/chart/renderer/xy/XYLineAndShapeRenderer.java 2005-06-02 17:41:32.000000000 +0200
+++ jfreechart-1.0.0-rc1\source/org/jfree/chart/renderer/xy/XYLineAndShapeRenderer.java 2005-10-04 21:33:56.668484700 +0200
@@ -1053,7 +1053,7 @@
}
updateCrosshairValues(
- crosshairState, x1, y1, transX1, transY1, plot.getOrientation()
+ crosshairState, x1, y1, transX1, transY1, plot.getOrientation(), domainAxis, rangeAxis
);
// add an entity for the item...