JFreeChart: получить значение источника данных по щелчку мыши - PullRequest
7 голосов
/ 22 июля 2010

У меня есть экземпляр 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);

Позже я добавляю значения к каждому TimeSeries в TimeSeriesCollection.Я хотел бы как-то узнать - когда пользователь нажимает на Диаграмму - или в какое время, связанное с этим столбцом, или даже лучше - каков индекс значения.но я не мог понять, как это сделать (документация JFreeChart досадно скудна, наверное, они пытаются заставить людей купить руководство для разработчиков).

Ответы [ 2 ]

3 голосов
/ 09 мая 2011

если вы щелкнете мертвым по элементу, функция 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());
}
}
2 голосов
/ 22 июля 2010

хмм должно работать, если заменить две последние строки чем-то вроде этого:

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