2012-03-13 16 views
6

Estoy tratando de obtener las coordenadas del punto al que se hizo clic con el mouse en un gráfico de diagrama de dispersión.¿Cómo obtener las coordenadas de un punto con un clic del mouse con JFreeChart?

Cuando hace clic en un punto, "Haga clic en evento!" y las coordenadas están impresas en la consola. Cuando hace clic en el botón "Probar", "Prueba" y las coordenadas se imprimen en la consola.

Problema: Las coordenadas impresas después de hacer clic en el botón están actualizadas. Las coordenadas impresas después de hacer clic en un punto son las de el punto previamente seleccionado.

¿Cómo puedo solucionar eso (de modo que cuando hago clic en un punto, se muestran las coordenadas del nuevo punto seleccionado)?

package graph; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.util.Random; 

import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

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.NumberAxis; 
import org.jfree.chart.axis.NumberTickUnit; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYItemRenderer; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 

/** 
* @see http://stackoverflow.com/questions/7231824 
* @see http://stackoverflow.com/questions/7205742 
* @see http://stackoverflow.com/questions/7208657 
* @see http://stackoverflow.com/questions/7071057 
*/ 
public class GraphFrameOld extends JFrame { 

    private static final int N = 32; 
    private static final String title = "Scatter Plot Pannel"; 
    private static final Random rand = new Random(); 
    private final XYSeries added = new XYSeries("Added"); 

    private static XYPlot xyPlot; 

    public GraphFrameOld(String s) { 
     super(s); 
     final ChartPanel chartPanel = createGraphPanel(); 

     this.add(chartPanel, BorderLayout.CENTER); 
     JPanel control = new JPanel(); 
     control.add(new JButton(new AbstractAction("Add") { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       for (int i = 0; i < N; i++) { 
        added.add(rand.nextDouble(), rand.nextDouble()); 
       } 
      } 
     })); 

     control.add(new JButton(new AbstractAction("Test") { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Test"); 
       System.out.println(xyPlot.getDomainCrosshairValue() + " " 
         + xyPlot.getRangeCrosshairValue()); 

      } 
     })); 

     // add click event 
     chartPanel.addChartMouseListener(new ChartMouseListener() { 
      @Override 
      public void chartMouseClicked(ChartMouseEvent e) { 
       System.out.println("Click event!"); 
       XYPlot xyPlot2 = chartPanel.getChart().getXYPlot(); 
        // Problem: the coordinates displayed are the one of the previously selected point ! 
       System.out.println(xyPlot2.getDomainCrosshairValue() + " " 
         + xyPlot2.getRangeCrosshairValue()); 
      } 

      @Override 
      public void chartMouseMoved(ChartMouseEvent arg0) { 
      } 
     }); 

     this.add(control, BorderLayout.SOUTH); 
    } 

    private ChartPanel createGraphPanel() { 
     JFreeChart jfreechart = ChartFactory 
       .createScatterPlot(title, "X", "Y", createSampleData(), 
         PlotOrientation.VERTICAL, true, true, false); 
     xyPlot = (XYPlot) jfreechart.getPlot(); 
     xyPlot.setDomainCrosshairVisible(true); 
     xyPlot.setRangeCrosshairVisible(true); 
     XYItemRenderer renderer = xyPlot.getRenderer(); 
     renderer.setSeriesPaint(0, Color.blue); 
     NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); 
     domain.setRange(0.00, 1.00); 
     domain.setTickUnit(new NumberTickUnit(0.1)); 
     domain.setVerticalTickLabels(true); 
     NumberAxis range = (NumberAxis) xyPlot.getRangeAxis(); 
     range.setRange(0.0, 1.0); 
     range.setTickUnit(new NumberTickUnit(0.1)); 
     return new ChartPanel(jfreechart); 
    } 

    private XYDataset createSampleData() { 
     XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); 
     XYSeries series = new XYSeries("Random"); 
     for (int i = 0; i < N * N; i++) { 
      double x = rand.nextDouble(); 
      double y = rand.nextDouble(); 
      series.add(x, y); 
     } 
     xySeriesCollection.addSeries(series); 
     xySeriesCollection.addSeries(added); 
     return xySeriesCollection; 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       GraphFrameOld demo = new GraphFrameOld(title); 
       demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       demo.pack(); 
       demo.setLocationRelativeTo(null); 
       demo.setVisible(true); 
      } 
     }); 
    } 
} 

Respuesta

5

Mi conjetura es que su oyente ratón se las llama antes de la jfreechart (internos) oyente es, por lo que el punto de cruz aún no se actualiza cuando el código ejecuta (apunte a la selección anterior todavía). Al poner su código chartMouseClicked en una invocación, Later debería solucionarlo.

0

Intenta extraer de ChartMouseEvent e:

e.x 
e.y 
+0

Probé 'e.getChart(). GetXYPlot(). GetDomainCrosshairValue()'. El mismo problema –

1

El problema es que el rediseño del gráfico también se desencadena por el evento del mouse y por lo tanto no se garantiza que esto haya finalizado en el momento en que se activa el detector de eventos.

Debería escuchar otro punto que garantiza que el redibujado haya finalizado. Puede usar chartProgressListener y filtrar cuando se haya completado el redibujado. El código adaptado no es muy elegante y es posible que tenga algunos más controles, pero parece que para hacer el trabajo:.

package graph; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.MouseEvent; 
import java.util.Random; 

import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

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.NumberAxis; 
import org.jfree.chart.axis.NumberTickUnit; 
import org.jfree.chart.entity.ChartEntity; 
import org.jfree.chart.event.*; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYItemRenderer; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 

/** 
* @see http://stackoverflow.com/questions/7231824 
* @see http://stackoverflow.com/questions/7205742 
* @see http://stackoverflow.com/questions/7208657 
* @see http://stackoverflow.com/questions/7071057 
*/ 
public class GraphFrameOld extends JFrame { 

    private static final int N = 32; 
    private static final String title = "Scatter Plot Pannel"; 
    private static final Random rand = new Random(); 
    private final XYSeries added = new XYSeries("Added"); 

    private static XYPlot xyPlot; 

    public GraphFrameOld(String s) { 
    super(s); 
    final ChartPanel chartPanel = createGraphPanel(); 

    this.add(chartPanel, BorderLayout.CENTER); 
    JPanel control = new JPanel(); 
    control.add(new JButton(new AbstractAction("Add") { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     for (int i = 0; i < N; i++) { 
      added.add(rand.nextDouble(), rand.nextDouble()); 
     } 
     } 
    })); 

    control.add(new JButton(new AbstractAction("Test") { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
     System.out.println("Test"); 
     System.out.println(xyPlot.getDomainCrosshairValue() + " " 
      + xyPlot.getRangeCrosshairValue()); 

     } 
    })); 



    this.add(control, BorderLayout.SOUTH); 
    } 

    private ChartPanel createGraphPanel() { 
    JFreeChart jfreechart = ChartFactory 
     .createScatterPlot(title, "X", "Y", createSampleData(), 
      PlotOrientation.VERTICAL, true, true, false); 



    xyPlot = (XYPlot) jfreechart.getPlot(); 
    xyPlot.setDomainCrosshairVisible(true); 
    xyPlot.setRangeCrosshairVisible(true); 
    XYItemRenderer renderer = xyPlot.getRenderer(); 
    renderer.setSeriesPaint(0, Color.red); 
    NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); 
    domain.setRange(0.00, 1.00); 

    domain.setTickUnit(new NumberTickUnit(0.1)); 
    domain.setVerticalTickLabels(true); 
    NumberAxis range = (NumberAxis) xyPlot.getRangeAxis(); 
    range.setRange(0.0, 1.0); 
    range.setTickUnit(new NumberTickUnit(0.1)); 
    final ChartPanel result = new ChartPanel(jfreechart); 

     jfreechart.addProgressListener(new ChartProgressListener() { 

     @Override 
     public void chartProgress(ChartProgressEvent cpe) { 
     if(cpe.getType()==ChartProgressEvent.DRAWING_FINISHED){ 
     System.out.println("Click event!"); 
     XYPlot xyPlot2 = result.getChart().getXYPlot(); 
     System.out.println(xyPlot2.getDomainCrosshairValue() + " " 
      + xyPlot2.getRangeCrosshairValue()); 
     } 
     } 
    }); 


    return result; 
    } 

    private XYDataset createSampleData() { 
    XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); 
    XYSeries series = new XYSeries("Random"); 
    for (int i = 0; i < N * N; i++) { 
     double x = rand.nextDouble(); 
     double y = rand.nextDouble(); 
     series.add(x, y); 
    } 
    xySeriesCollection.addSeries(series); 
    xySeriesCollection.addSeries(added); 
    return xySeriesCollection; 
    } 

    public static void main(String args[]) { 
    EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
     GraphFrameOld demo = new GraphFrameOld(title); 
     demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     demo.pack(); 
     demo.setLocationRelativeTo(null); 
     demo.setVisible(true); 
     } 
    }); 
    } 
} 
0

e.getTrigger() getX()

trabajó para mí!

System.out.println(e.getTrigger().getX() + " " + e.getTrigger().getY()); 
Cuestiones relacionadas