new methods for zooming around a given location (x,y)

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
havfrue
Posts: 29
Joined: Mon Nov 03, 2003 4:49 pm

new methods for zooming around a given location (x,y)

Post by havfrue » Mon Jun 14, 2004 11:17 am

I have added some methods that zooms around a given location. When the mouse is pressed I start a timer and call these methods from within
mouse pressed method. This way you can easily zoom in and out arounf a point of interest. Just wanted to share them if anyone's interested. Is this something that you would consider putting into a new version of jfreechart, David?

Code: Select all

 public void mousePressed(MouseEvent evt) {

        try {
       
            if (isZoomMode()) {
                final int x = evt.getX();
                final int y = evt.getY();
                final boolean firstTime = true;
                if (evt.getButton() == MouseEvent.BUTTON1) {
                    removeTimer();
                    if (_continuousZoomEnable) {
                        if (evt.isShiftDown()) {
                            _timer = new Timer(90, new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
                                    zoomAroundPoint(x, y, 1 / ZOOM_FACTOR_H, 1 / ZOOM_FACTOR_V);
                                }
                            });
                            _timer.setInitialDelay(500);
                            _timer.start();
                        } else {
                            _timer = new Timer(90, new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
                                    zoomAroundPoint(x, y, ZOOM_FACTOR_H, ZOOM_FACTOR_V);
                                }
                            });
                            _timer.setInitialDelay(500);
                            _timer.start();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  private final void zoomAroundPoint(int x, int y, double zoomFactor_horisontal, double zoomFactor_vertical) {
        boolean truescale = false;
        JFreeChart chart = _chartPanel.getChart();
        ChartRenderingInfo info = _chartPanel.getChartRenderingInfo();

          zoomHorisontalAroundPoint(x, y, zoomFactor_horisontal);          
           zoomVerticalAroundPoint(x, y, zoomFactor_vertical);           
    }

private final void zoomHorisontalAroundPoint(int x, int y, double zoomFactor) {
        JFreeChart chart = _chartPanel.getChart();
        ChartRenderingInfo info = _chartPanel.getChartRenderingInfo();
        if (chart.getPlot() instanceof XYPlot) {
            XYPlot plot = (XYPlot) chart.getPlot();
            if (plot == null) {
                return;
            }

            ValueAxis axis = plot.getDomainAxis();
            if (ChartPanelUtils.isValidAxis(axis)) {

                if ((zoomFactor > 0.0d) && (axis.getRange().getLength() > 0.0d)) {
                    double newAxisLength = axis.getRange().getLength() * zoomFactor;
                    double oldMinVal = axis.getRange().getLowerBound();
                    double oldMaxVal = axis.getRange().getUpperBound();
                    double anchorValue = axis.java2DToValue(x, info.getChartArea(), plot.getDomainAxisEdge());
                    Point2D point = ChartPanelUtils.translateJava2DToValue(x, y, _chartPanel);

                    if (point == null) {
                        return;
                    }
                    anchorValue = point.getX();
                    double anchorPosition = ((anchorValue - oldMinVal) / (oldMaxVal - oldMinVal));
                    double newMinVal = anchorValue - newAxisLength * anchorPosition;
                    double newMaxVal = 0;
                    if (newMinVal < _minXDatasetValue) {
                        newMinVal = _minXDatasetValue;
                    }
                    newMaxVal = newMinVal + newAxisLength;
                    if (newMaxVal > _maxXDatasetValue) {
                        newMaxVal = _maxXDatasetValue;
                    }
                    axis.setRange(newMinVal, newMaxVal);
                } else {
                    //TODO
                    //  axis.setAutoRange(true);
                    axis.setRange(_minXDatasetValue, _maxXDatasetValue);
                }
            }
        }
    }

    private final void zoomVerticalAroundPoint(int x, int y, double zoomFactor) {
        JFreeChart chart = _chartPanel.getChart();
        ChartRenderingInfo info = _chartPanel.getChartRenderingInfo();
        if (chart.getPlot() instanceof XYPlot) {
            XYPlot plot = (XYPlot) chart.getPlot();
            if (plot == null) {
                return;
            }

            ValueAxis axis = plot.getRangeAxis();
            if (ChartPanelUtils.isValidAxis(axis)) {

                if ((zoomFactor > 0.0d) && (axis.getRange().getLength() > 0.0d)) {
                    double newAxisLength = axis.getRange().getLength() * zoomFactor;
                    double oldMinVal = axis.getRange().getLowerBound();
                    double oldMaxVal = axis.getRange().getUpperBound();
                    double anchorValue = axis.java2DToValue(y, info.getChartArea(), plot.getRangeAxisEdge());
                    Point2D point = ChartPanelUtils.translateJava2DToValue(x, y, _chartPanel);

                    if (point == null) {
                        return;
                    }
                    anchorValue = point.getY();
                    double anchorPosition = ((anchorValue - oldMinVal) / (oldMaxVal - oldMinVal));
                    double newMinVal = anchorValue - newAxisLength * anchorPosition;
                    double newMaxVal = 0;
                    if (newMinVal < _minYDatasetValue) {
                        newMinVal = _minYDatasetValue;
                    }
                    newMaxVal = newMinVal + newAxisLength;
                    if (newMaxVal > _maxYDatasetValue) {
                        newMaxVal = _maxYDatasetValue;
                    }
                    axis.setRange(newMinVal, newMaxVal);
                } else {
                    axis.setRange(_minXDatasetValue, _maxXDatasetValue);
                }
            }
        }
    }
[/code]

BigWillyStyle42
Posts: 58
Joined: Wed Jun 02, 2004 1:37 pm

Post by BigWillyStyle42 » Mon Jun 21, 2004 8:11 pm

This makes a lot more sense then the current implementation of the zoom menu item which seems to only zoom in/out on the exact center of your plot.

Locked