JFreeChart:在鼠标单击时获取数据源值

时间:2010-07-22 12:44:25

标签: java mouse jfreechart

我有一个显示进程内存状态的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的文档也非常缺乏,我猜他们正试图让人们购买他们的开发人员指南)。

2 个答案:

答案 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;