我有一个显示进程内存状态的JFreeChart实例,初始化如下:
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);
稍后我在TimeSeriesCollection中为每个TimeSeries添加值。我想以某种方式知道 - 当用户点击图表时 - 与该列相关联的时间,或者甚至更好 - 该值的索引是什么。
我查看了JFreeChart和ChartMouseListener类,但我无法弄清楚如何做到这一点(JFreeChart的文档也非常缺乏,我猜他们正试图让人们购买他们的开发人员指南)。
答案 0 :(得分:3)
如果单击项目上的dead,则event.getEntity()函数返回XYItem,然后从那里开始
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());
但是,如果您没有点击该项目本身,但您的十字准线设置为自动锁定数据,在这种情况下十字准线将移动到最近的项目,但由于该项目尚未被点击,您将无法获得XYItem因此你无法知道系列和项索引,为了解决这个问题,下面有这个代码,它应该放在catch子句中,而上面提到的代码应该在try子句中
首先定义一个在域和范围内采用十字准线值的函数以及Xydataset,这个函数返回一个内部类对象,它将项目索引和系列索引分组
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;
}
}
如何使用它?
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());
}
}
答案 1 :(得分:2)
hmm应该可以工作:
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;