2010-07-22 13 views
7

que tienen una instancia JFreeChart que muestra el estado de la memoria del proceso, inicializa como sigue:JFreeChart: obtener valor de la fuente de datos de clic del ratón

m_data = new TimeSeriesCollection(); 
TimeSeries vmsize = new TimeSeries("VMSize"); 
TimeSeries resident = new TimeSeries("Resisdent"); 
TimeSeries shared = new TimeSeries("Shared memory"); 
TimeSeries code = new TimeSeries("Code"); 
TimeSeries data = new TimeSeries("Data"); 
m_data.addSeries(vmsize); 
m_data.addSeries(resident); 
m_data.addSeries(shared); 
m_data.addSeries(code); 
m_data.addSeries(data); 
JFreeChart chart = ChartFactory.createTimeSeriesChart("Memory usage", "Time", "Size", m_data, true, true, false); 
m_chart = new ChartPanel(chart); 

Más tarde añadir valores a cada uno TimeSeries en el TimeSeriesCollection. Me gustaría de alguna manera saber, cuando el usuario hace clic en el Gráfico, ya sea qué hora está asociada con esa columna, o incluso mejor, cuál es el índice del valor.

Miré las clases JFreeChart y ChartMouseListener, pero no pude encontrar la manera de hacerlo (también la documentación de JFreeChart es increíblemente escasa, supongo que están intentando que la gente compre su guía para desarrolladores).

Respuesta

2

hmm debería funcionar, si se reemplaza las dos últimas líneas por algo como esto:

ChartPanel panel=new ChartPanel(ChartFactory.createTimeSeriesChart("Memory usage", "Time", "Size", m_data, true, true, false))); 
panel.addChartMouseListener(new ChartMouseListener(){ 
    void chartMouseClicked(ChartMouseEvent e){ 
     [...do something on click...] 
    } 
    void chartMouseMoved(ChartMouseEvent e){ 
     [...do something on move...] 
    } 
}); 
return panel; 
+0

Bueno, ya he visto ChartMouseLIstener, la información en el caso es bastante inútil. la pregunta no es cómo agregar un oyente, sino cómo obtener los datos relevantes del evento. –

+0

puede usar ChartEvent.getEntity() para obtener la forma (barra, línea) debajo del mouse http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/entity/ChartEntity.html – fasseg

+0

+ 1, funciona como un campeón! – trashgod

3

si hace clic muerto en el artículo, la función event.getEntity() devuelve XYItem y luego a partir de ahí en adelante

XYItemEntity xyitem=(XYItemEntity) event.getEntity(); // get clicked entity 
XYDataset dataset = (XYDataset)xyitem.getDataset(); // get data set 
System.out.println(xyitem.getItem()+" item of "+xyitem.getSeriesIndex()+"series"); 
System.out.println(dataset.getXValue(xyitem.getSeriesIndex(), xyitem.getItem())); 
System.out.println(dataset.getYValue(xyitem.getSeriesIndex(), xyitem.getItem())); 
Comparable comparable=dataset.getSeriesKey(0); 
XYPlot xyplot = (XYPlot) event.getChart().getPlot(); 
System.out.println(xyplot.getRangeCrosshairValue()); 

sin embargo en caso que usted no hace clic en el elemento en sí, sino el punto de mira está puesto en bloqueo automático en los datos, en este caso, el punto de mira se moverá al punto más cercano, pero ya que el artículo no se ha hecho clic, no será capaz de obtener el XYItem y, por lo tanto, no puede conocer el índice de la serie y el elemento, para resolver este problema hay este código a continuación, debe colocarse en la cláusula de captura mientras que el código mencionado anteriormente debe estar en la cláusula try

primero defina una función que tomará valor de cruz en el dominio y rango y también Xydataset, esto función devuelve un objeto de la clase interna que el índice de los grupos de artículos y el índice serie

public static SeriesAndItemIndex getItemIndex(double domainVal,double rangeVal,XYDataset xydataset){ 
Comparable comparable; 
int indexOf; 
for(int i=0;i<xydataset.getSeriesCount();i++){ 

comparable = xydataset.getSeriesKey(i); 
    indexOf=xydataset.indexOf(comparable); 
for(int j=0 ; j<xydataset.getItemCount(indexOf);j++){ 

    double x=xydataset.getXValue(indexOf, j); 
    double y=xydataset.getYValue(indexOf, j); 

    if(x == domainVal && y==rangeVal){ 
     return new SeriesAndItemIndex(j,indexOf);//return item index and series index 
       } 


      } 
     } 
     return null; 
    } 

private static class SeriesAndItemIndex{ ///inner CLASS to group series and item clicked index 
     public int itemIndex; 
     public int seriesIndex; 
     public SeriesAndItemIndex(int i,int s){ 
      itemIndex=i; 
      seriesIndex=s; 
     } 

     @Override 
     public String toString(){ 
      return "itemIndex="+itemIndex+",seriesIndex="+seriesIndex; 
     } 
    } 

cómo se utiliza?

try{......code block from the top 

}catch(Exception e){ 

Object source=event.getSource(); 
JFreeChart chartpanel=(JFreeChart)source; 
XYPlot xyplot = (XYPlot) chartpanel.getPlot(); 
XYDataset xydataset= xyplot.getDataset(); 
double d=xyplot.getDomainCrosshairValue(); //get crosshair X value 
double r =xyplot.getRangeCrosshairValue(); //get crosshair y value 
SeriesAndItemIndex index=getItemIndex(d,r,xydataset); 
if(index != null){ 
    System.out.println(index.toString()); 
} 
} 
+0

¿A qué evento debo registrarme y en qué objeto? Intenté agregar un detector de cambios al JFreeChart, pero el evento no tiene getEntity. –

+0

Creo que es ChartChangelistner ... algo así – user482963

Cuestiones relacionadas