2010-07-22 10 views
7

devo un'istanza JFreeChart che visualizza lo stato della memoria processo, inizializzata come segue:JFreeChart: ottenere valore dell'origine dati sul mouse scegliere

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); 

Successivamente aggiungo valori per ciascuno TimeSeries nel TimeSeriesCollection. Vorrei sapere in qualche modo - quando l'utente fa clic sul grafico - o sul tempo associato a tale colonna, o anche meglio - qual è l'indice del valore.

Ho esaminato le classi JFreeChart e ChartMouseListener, ma non sono riuscito a capire come farlo (anche la documentazione di JFreeChart è fastidiosamente scarsa, suppongo che stiano cercando di convincere la gente a comprare la guida dello sviluppatore).

risposta

2

hmm dovrebbe funzionare, se si sostituisce le ultime due righe da qualcosa di simile:

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

Bene, ho già guardato ChartMouseLIstener, l'informazione nell'evento è piuttosto inutile. la domanda non è come aggiungere un listener - ma piuttosto come ottenere i dati rilevanti dall'evento. –

+0

puoi usare ChartEvent.getEntity() per ottenere la forma (barra, linea) sotto il mouse http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/entity/ChartEntity.html – fasseg

+0

+ 1, funziona come un campione! – trashgod

3

se si fa clic sulla voce morta, la funzione event.getEntity() restituisce XYItem e poi da lì in poi

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()); 

tuttavia in caso non si fa clic sull'oggetto stesso, ma il mirino è impostato su blocco automatico dei dati, in tal caso il mirino si sposta al punto più vicino, ma dal momento che l'articolo non è stato fatto clic, non sarà in grado di ottenere XYItem e quindi non è possibile conoscere la serie e l'indice di articolo, per risolvere questo problema c'è questo codice qui sotto, dovrebbe essere inserito nella clausola catch mentre il codice sopra menzionato dovrebbe essere nella clausola try

definire prima una funzione che avrà valore di crosshair su dominio e intervallo e anche Xydataset, questo funzioni restituisce un oggetto di classe interna che raggruppa l'indice di articolo e l'indice di 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; 
     } 
    } 

come si usa?

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 quale evento dovrei registrarmi e su quale oggetto? Ho provato ad aggiungere un listener di modifiche a JFreeChart, ma l'evento non ha getEntity. –

+0

Penso che il suo ChartChangelistner ... qualcosa del genere – user482963

Problemi correlati