Get Area or Elements in zoomed Scatterplot

前端 未结 1 1489
轮回少年
轮回少年 2020-12-20 13:03

I\'ve got the following problem. I want to zoom-in a Scatterplot and then select all the displayed elements.

It would be sufficient to somehow get the displayed area

1条回答
  •  轮回少年
    2020-12-20 13:24

    The poster found a solution to this by having the ScatterExample class implement the AxisChangeListener interface. The example has been updated to version 1.5. It also adds a table to display the history of the axis bound changes. The image shows the result of zooming, panning and clicking the zoom command buttons, Zoom In to Reset Y.

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Rectangle;
    import java.text.DecimalFormat;
    import java.text.NumberFormat;
    import java.util.Random;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JToolBar;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.event.AxisChangeEvent;
    import org.jfree.chart.event.AxisChangeListener;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    import org.jfree.chart.ChartFactory;
    import static org.jfree.chart.ChartPanel.*;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.Axis;
    import org.jfree.chart.axis.ValueAxis;
    
    public final class ScatterExample implements AxisChangeListener {
    
        private static final int N = 32; // data points per series
        private static final int R = 10; // initial axis bounds
        private final Random RANDOM = new Random();
        private ChartPanel chartPanel = new ChartPanel(null, false) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(400, 400);
            }
        };
        private final DefaultTableModel model = new DefaultTableModel(
            new String[]{"Axis", "lower bound", "upper bound"}, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        private final JTable table = new JTable(model) {
    
            @Override
            public Class getColumnClass(int column) {
                switch (column) {
                    case 0:
                        return String.class;
                    case 1:
                        return Double.class;
                    case 2:
                        return Double.class;
                    default:
                        return String.class;
                }
            }
    
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(250, 400);
            }
        };
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new ScatterExample()::display);
        }
    
        private void display() {
            XYSeriesCollection dataset = createSampleXYDataset();
            JFreeChart chart = ChartFactory.createScatterPlot(
                "Scatterplot", // chart title
                "X", // domain axis label
                "Y", // range axis label
                dataset, // data
                PlotOrientation.VERTICAL, // orientation
                true, // include legend?
                true, // tooltips? 
                false // URLs?
            );
            XYPlot plot = chart.getXYPlot();
            plot.setDomainPannable(true);
            plot.getDomainAxis().setRange(-R, R);
            plot.getDomainAxis().addChangeListener(this);
            plot.setRangePannable(true);
            plot.getRangeAxis().setRange(-R, R);
            plot.getRangeAxis().addChangeListener(this);
    
            chartPanel.setChart(chart);
            table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() {
                {
                    setHorizontalAlignment(JLabel.RIGHT);
                }
                NumberFormat f = new DecimalFormat("#.00");
    
                @Override
                protected void setValue(Object value) {
                    setText((value == null) ? "" : f.format(value));
                }
            });
    
            JFrame f = new JFrame("Axis Range Example");
            f.add(chartPanel);
            f.add(createControls(), BorderLayout.SOUTH);
            f.add(new JScrollPane(table), BorderLayout.EAST);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        private XYSeriesCollection createSampleXYDataset() {
            XYSeriesCollection d = new XYSeriesCollection();
            XYSeries series1 = new XYSeries("Series 1");
            XYSeries series2 = new XYSeries("Series 2");
            for (int i = 0; i < N; i++) {
                series1.add(RANDOM.nextGaussian(), RANDOM.nextGaussian());
                series2.add(RANDOM.nextGaussian(), RANDOM.nextGaussian());
            }
            d.addSeries(series1);
            d.addSeries(series2);
            return d;
        }
    
        @Override
        public void axisChanged(AxisChangeEvent event) {
            Axis changed = event.getAxis();
            ValueAxis domainAxis = chartPanel.getChart().getXYPlot().getDomainAxis();
            ValueAxis rangeAxis = chartPanel.getChart().getXYPlot().getRangeAxis();
            if (changed.equals(domainAxis)) {
                double lower = domainAxis.getLowerBound();
                double upper = domainAxis.getUpperBound();
                model.addRow(new Object[]{"Domain", lower, upper});
            }
            if (changed.equals(rangeAxis)) {
                double lower = rangeAxis.getLowerBound();
                double upper = rangeAxis.getUpperBound();
                model.addRow(new Object[]{"Range", lower, upper});
            }
            int last = table.getModel().getRowCount() - 1;
            Rectangle r = table.getCellRect(last, 0, true);
            table.scrollRectToVisible(r);
        }
    
        // @see https://stackoverflow.com/a/41544007/230513
        private JPanel createControls() {
            JPanel panel = new JPanel();
            JToolBar toolBar = new JToolBar();
            toolBar.add(createButton("Zoom In", ZOOM_IN_BOTH_COMMAND));
            toolBar.add(createButton("Zoom In X", ZOOM_IN_DOMAIN_COMMAND));
            toolBar.add(createButton("Zoom In Y", ZOOM_IN_RANGE_COMMAND));
            toolBar.add(createButton("Zoom Out", ZOOM_OUT_BOTH_COMMAND));
            toolBar.add(createButton("Zoom Out X", ZOOM_OUT_DOMAIN_COMMAND));
            toolBar.add(createButton("Zoom Out Y", ZOOM_OUT_RANGE_COMMAND));
            toolBar.add(createButton("Reset", ZOOM_RESET_BOTH_COMMAND));
            toolBar.add(createButton("Reset X", ZOOM_RESET_DOMAIN_COMMAND));
            toolBar.add(createButton("Reset Y", ZOOM_RESET_RANGE_COMMAND));
            panel.add(toolBar);
            return panel;
        }
    
        private JButton createButton(String name, String command) {
            final JButton b = new JButton(name);
            b.setActionCommand(command);
            b.addActionListener(chartPanel);
            return b;
        }
    }
    

    0 讨论(0)
提交回复
热议问题