/*
* CrossHairPanel.java
*
* Created on April 7, 2006, 9:24 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package spicefe;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.text.DecimalFormat;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfree.chart.annotations.XYAnnotation;
import org.jfree.chart.annotations.XYDrawableAnnotation;
import org.jfree.chart.annotations.XYPointerAnnotation;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
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.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.Range;
import org.jfree.data.xy.XYDataset;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.title.LegendTitle;
import org.jfree.ui.LengthAdjustmentType;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;
import org.jfree.ui.TextAnchor;
/**
* A crosshair demo.
*/
public class CrossHairPanel extends JPanel implements ChangeListener, ChartMouseListener {
private JKnob knob;
private JFreeChart c;
private ChartPanel cp = null;
/**
* Creates a new demo panel.
*/
public CrossHairPanel(JFreeChart chart) {
super(new GridBagLayout());
cp = new ChartPanel(chart);
GridBagConstraints cons = new GridBagConstraints();
cons.fill = GridBagConstraints.BOTH;
cons.weighty = 0.5;
cons.weightx = 0.5;
cons.gridx = 0;
cons.gridy = 0;
add(cp,cons);
cp.addChartMouseListener(this);
this.c = chart;
XYPlot plot = (XYPlot) chart.getPlot();
//JPanel controls = new JPanel(new BorderLayout());
this.knob = new JKnob(0);
this.knob.setToolTipText("Use this to set the location and angle of graph annotations.");
this.knob.addChangeListener(this);
cons.weighty = 0.0;
cons.weightx = 0.0;
cons.gridx = 0;
cons.gridy = 1;
cons.fill = GridBagConstraints.NONE;
//controls.add(this.knob,BorderLayout.CENTER);
//add(controls, cons);
add(this.knob, cons);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
/*XYItemRenderer renderer = plot.getRenderer();
if (renderer instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer rr = (XYLineAndShapeRenderer) renderer;
rr.setShapesVisible(true);
rr.setShapesFilled(true);
*
*
}
double xx = plot.getDomainCrosshairValue();
double xx = plot.getRangeCrosshairValue();
*/
}
/**
* Handles a state change event.
*
* @param event the event.
*/
public void stateChanged(ChangeEvent event) {
/*int value = this.knob.getValue();
XYPlot plot = c.getXYPlot();
ValueAxis domainAxis = plot.getDomainAxis();
Range range = domainAxis.getRange();
double c = domainAxis.getLowerBound() + (value / 360.0) * range.getLength();
plot.setDomainCrosshairValue(c);
*/
}
public void chartMouseClicked(ChartMouseEvent event) {
//System.out.println("we got a click");
if (event.getTrigger().getClickCount()>1) {
//System.out.println("we got multiple clicks");
if (this.getChartPanel() != null) {
JFreeChart chart = this.getChartPanel().getChart();
if (chart != null) {
XYPlot plot = chart.getXYPlot();
XYDataset dataset = plot.getDataset();
Comparable seriesKey = dataset.getSeriesKey(0);
double xx = plot.getDomainCrosshairValue();
double yy = plot.getRangeCrosshairValue();
//System.out.println("X="+xx+" Y="+yy);
/* Taken from the Demo program to add a circle and
* label around the right point
*/
CircleDrawer cd = new CircleDrawer(
Color.red, new BasicStroke(1.0f), null
);
XYAnnotation locationSelected = new XYDrawableAnnotation( xx, yy, 11, 11, cd );
plot.addAnnotation(locationSelected);
XYPointerAnnotation pointer = new XYPointerAnnotation(
formatAnnotation( xx, yy).toString(), xx, yy, Math.PI - knob.getAngle() );
pointer.setBaseRadius(35.0);
pointer.setTipRadius(10.0);
pointer.setFont(new Font("SansSerif", Font.PLAIN, 9));
pointer.setPaint(Color.blue);
pointer.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);
//this just corrects for label slightly overlapping the
//arrow at certain angles.
if (Math.cos(this.knob.getAngle())<0 && Math.sin(this.knob.getAngle())<0) {
pointer.setLabelOffset(8.0);
pointer.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
}
if (Math.cos(this.knob.getAngle())<0 && Math.sin(this.knob.getAngle())>0) {
pointer.setLabelOffset(5.0);
pointer.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
}
plot.addAnnotation(pointer);
}
}
}
}
public ChartPanel getChartPanel() {
return cp;
}
public void chartMouseMoved(ChartMouseEvent event) {
}
private StringBuilder formatAnnotation(double xx, double yy) {
DecimalFormat engFormatter = new DecimalFormat("#00.#E0");
DecimalFormat dFormatter = new DecimalFormat("##0.##");
String xout, yout;
if (Math.abs(xx)>1e3)
xout = engFormatter.format(xx);
else if (Math.abs(xx)<0.1)
xout = engFormatter.format(xx);
else
xout = dFormatter.format(xx);
if (Math.abs(yy)>1e3 )
yout = engFormatter.format(yy);
else if (Math.abs(yy)<0.1)
yout = engFormatter.format(yy);
else
yout = dFormatter.format(yy);
StringBuilder outStr = new StringBuilder("[ ");
outStr.append(xout);
outStr.append(", ");
outStr.append(yout);
outStr.append(" ]");
return outStr;
}
}