首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JFreeChart MouseListener不解析图表元素

JFreeChart MouseListener不解析图表元素
EN

Stack Overflow用户
提问于 2011-11-03 17:50:43
回答 2查看 6.4K关注 0票数 4

我有堆叠的条形图,在这里我想能够选择堆栈中的单个条形图。但是ChartMouseListener并没有将ChartMouseEvent解析为相应的ChartEntity。下面是侦听器片段:

代码语言:javascript
复制
    public void chartMouseClicked(ChartMouseEvent event){
        ChartEntity entity = event.getEntity();
        if(entity != null && (entity instanceof XYItemEntity) ){
            XYItemEntity item = (XYItemEntity)entity;
            renderer.select(item.getSeriesIndex(), item.getItem());
            return;
        }

        // deselect
        renderer.select(-1,-1);
    }

问题是,当我明显地单击一些条形图时,event.getEntity()返回null。注意,并非所有的条子都会失效。我越往右端走,坐标的移动就越明显。下面的快照显示所选的条形图在单击外部时实际出现。我在SWT组合中使用JFreeChart。有人能确认这是一种错误行为还是有一个解决办法吗?

下面是完整的sscce,在运行它并单击条形图之后,它会显示出小指。然后重新调整窗口的大小,并尝试选择条形-它将错过。我认为这是新尺寸的功用。

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Paint;
import java.util.Random;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.event.RendererChangeEvent;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StackedXYBarRenderer;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeTableXYDataset;
import org.jfree.data.xy.TableXYDataset;
import org.jfree.experimental.chart.swt.ChartComposite;

public class StackedChartSwt {
    private StackedRenderer renderer;
    private Color[] colors = new Color[]{
            new Color(230,240,255), 
            new Color(240,255,240), 
            new Color(255,255,255), 
            new Color(255,255,240), 
            new Color(255,240,240), 
            new Color(240,240,240)
    };

    public StackedChartSwt(){
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());

        JFreeChart chart = createStackedChart(createStackedDataset());
        ChartComposite chartComposite = new ChartComposite(shell, SWT.NONE, chart, false, false, false, false, false);
        chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
        chartComposite.setRangeZoomable(false);
        chartComposite.setMenu(null);
        chartComposite.addChartMouseListener(new ThisMouseListener());
        shell.setSize(800, 600);
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
              display.sleep();
            }
          }

          display.dispose();        
    }

    private JFreeChart createStackedChart(TableXYDataset tablexydataset) {
        DateAxis dateaxis = new DateAxis();
        dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
        NumberAxis numberaxis = new NumberAxis("Event counts");
        renderer = new StackedRenderer();
        XYPlot plot = new XYPlot(tablexydataset, dateaxis, numberaxis, renderer);
        plot.setBackgroundPaint(Color.white);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.lightGray);

        JFreeChart chart = new JFreeChart(null, plot);
        chart.setBackgroundPaint(Color.white);
        chart.setBorderVisible(false);
        chart.setBorderPaint(null);

        return chart;
    }

    class StackedRenderer extends StackedXYBarRenderer{
        int selectedRow=-1, selectedCol=-1;
        public StackedRenderer(){
            setDrawBarOutline(true);
            setBarPainter(new StandardXYBarPainter());
            setShadowVisible(false);
            setSeriesPaint(0, Color.blue);
            setMargin(0.2);
        }

        public void select(int row, int col){
            selectedRow = row;
            selectedCol = col;
            notifyListeners(new RendererChangeEvent(this));
        }

        @Override
        public Paint getItemPaint(final int row, final int col){
            if(row == selectedRow && col == selectedCol)
                return Color.pink;
            return colors[row];
        }
    } 

    class ThisMouseListener implements ChartMouseListener{
        public void chartMouseMoved(ChartMouseEvent event){
        }

        public void chartMouseClicked(ChartMouseEvent event){
            ChartEntity entity = event.getEntity();
            if(entity != null && (entity instanceof XYItemEntity) ){
                XYItemEntity item = (XYItemEntity)entity;
                renderer.select(item.getSeriesIndex(), item.getItem());
                return;
            }

            // deselect
            renderer.select(-1,-1);
        }
    }

    private TableXYDataset createStackedDataset(){
        Random random = new Random(0);
        TimeTableXYDataset ds = new TimeTableXYDataset();
        Day day = new Day();
        for( int i = 0; i < 24; i++ ){
            Hour hour = new Hour( i, day );
            ds.add(hour, random.nextInt( 20 ), "A");
            ds.add(hour, random.nextInt( 20 ), "B");
            ds.add(hour, random.nextInt( 20 ), "C");
            ds.add(hour, random.nextInt( 20 ), "D");
            ds.add(hour, random.nextInt( 20 ), "E");
            ds.add(hour, random.nextInt( 20 ), "F");
        }

        return ds;
    }

    public static void main(String[] args){
        new StackedChartSwt();
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-06 10:00:20

好吧,我发现问题了。在SWT中,有几个构造函数可以创建ChartComposite,大多数使用默认值指定最小/最大宽度和高度。在我的例子中,每当我扩大了DEFAULT_MAXIMUM_DRAW_WIDTH (800 to )上面的图表时,坐标就开始变得混乱。因此,解决方案是使用完整的构造函数并为显示指定相关的边界。很难破解..。主要原因是缺乏适当的文件。

票数 4
EN

Stack Overflow用户

发布于 2011-11-03 22:56:53

示例性渲染器在从Swing运行时具有正确的几何形状,如下所示。我不知道为什么SWT会出问题,但这个结果可能会缩小搜索范围。

代码语言:javascript
复制
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Paint;
import java.util.Random;
import javax.swing.JFrame;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.event.RendererChangeEvent;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StackedXYBarRenderer;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeTableXYDataset;
import org.jfree.data.xy.TableXYDataset;

public class StackedChartSwing {

    private ChartPanel panel;
    private StackedRenderer renderer;
    private Color[] colors = new Color[]{
        new Color(230, 240, 255),
        new Color(240, 255, 240),
        new Color(255, 255, 255),
        new Color(255, 255, 240),
        new Color(255, 240, 240),
        new Color(240, 240, 240)
    };

    public StackedChartSwing() {
        JFreeChart chart = createStackedChart(createStackedDataset());
        panel = new ChartPanel(chart);
        panel.addChartMouseListener(new ThisMouseListener());
    }

    private JFreeChart createStackedChart(TableXYDataset tablexydataset) {
        DateAxis dateaxis = new DateAxis();
        dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
        NumberAxis numberaxis = new NumberAxis("Event counts");
        renderer = new StackedRenderer();
        XYPlot plot = new XYPlot(tablexydataset, dateaxis, numberaxis, renderer);
        plot.setBackgroundPaint(Color.white);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.lightGray);

        JFreeChart chart = new JFreeChart(null, plot);
        chart.setBackgroundPaint(Color.white);
        chart.setBorderVisible(false);
        chart.setBorderPaint(null);

        return chart;
    }

    class StackedRenderer extends StackedXYBarRenderer {

        int selectedRow = -1, selectedCol = -1;

        public StackedRenderer() {
            setDrawBarOutline(true);
            setBarPainter(new StandardXYBarPainter());
            setShadowVisible(false);
            setSeriesPaint(0, Color.blue);
            setMargin(0.2);
        }

        public void select(int row, int col) {
            selectedRow = row;
            selectedCol = col;
            notifyListeners(new RendererChangeEvent(this));
        }

        @Override
        public Paint getItemPaint(final int row, final int col) {
            if (row == selectedRow && col == selectedCol) {
                return Color.pink;
            }
            return colors[row];
        }
    }

    class ThisMouseListener implements ChartMouseListener {

        @Override
        public void chartMouseMoved(ChartMouseEvent event) {
        }

        @Override
        public void chartMouseClicked(ChartMouseEvent event) {
            ChartEntity entity = event.getEntity();
            if (entity != null && (entity instanceof XYItemEntity)) {
                XYItemEntity item = (XYItemEntity) entity;
                renderer.select(item.getSeriesIndex(), item.getItem());
                return;
            }
            // deselect
            renderer.select(-1, -1);
        }
    }

    private TableXYDataset createStackedDataset() {
        Random random = new Random(0);
        TimeTableXYDataset ds = new TimeTableXYDataset();
        Day day = new Day();
        for (int i = 0; i < 24; i++) {
            Hour hour = new Hour(i, day);
            ds.add(hour, random.nextInt(20), "A");
            ds.add(hour, random.nextInt(20), "B");
            ds.add(hour, random.nextInt(20), "C");
            ds.add(hour, random.nextInt(20), "D");
            ds.add(hour, random.nextInt(20), "E");
            ds.add(hour, random.nextInt(20), "F");
        }

        return ds;
    }

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new StackedChartSwing().display();
            }
        });
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7999587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档