【问题标题】:JFreeChart : obtain data source value on mouse clickJFreeChart:鼠标点击获取数据源值
【发布时间】:2010-07-22 12:44:24
【问题描述】:

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

【问题讨论】:

    标签: java mouse jfreechart


    【解决方案1】:

    如果您在项目上单击 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());
    }
    }
    

    【讨论】:

    • 我应该注册哪个事件和哪个对象?我尝试将更改侦听器添加到 JFreeChart,但它的事件没有 getEntity。
    • 我认为它的 ChartChangelistner ... 类似
    【解决方案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;
    

    【讨论】:

    • 好吧,我已经看过ChartMouseLIsener,事件中的信息是相当无用的。问题不在于如何添加监听器,而是如何从事件中获取相关数据。
    • 可以使用ChartEvent.getEntity()获取鼠标下的形状(条、线)jfree.org/jfreechart/api/javadoc/org/jfree/chart/entity/…
    • 是的,我已经看到了 getShape() API 调用。我所追求的是这个形状所代表的数据。形状本身取决于图表的缩放和视口。
    猜你喜欢
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多