Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#281 Mouse Zoom only works from top left going down and right

open
David Gilbert
None
5
2012-09-18
2011-07-08
Fodge
No

When using a ChartPanel with mouse zooming enabled, the zoom box is only drawn and zooming only occurs when the mouse is dragged from top left to bottom right. The rectangle coordinates should be normalized and then sent to zooming/zoom-box drawing. Otherwise, it is practically possible to zoom in on, say, the very left edge or the very top edge.

Discussion


  • Anonymous
    2011-12-03

    Hi guys,
    refering to Martin Höllers hints, i startet to create a Patch for the ChartPanel.java

    Please have a closer look to it.
    Furthermore I hope i keep all coding conventions.

    Regards,
    Robert

     

  • Anonymous
    2011-12-03

    Index: ChartPanel.java

    --- ChartPanel.java (revision 2440)
    +++ ChartPanel.java (working copy)
    @@ -539,6 +539,13 @@
    */
    private List overlays;

    +
    + /** BUGFIX ID: 3358964
    + "Mouse Zoom only works from top left going down and right" -
    + Flag to change Zooming Behavior
    + */
    + private boolean zoomAllDirections = false;
    +
    /**
    * Constructs a panel that displays the specified chart.
    *
    @@ -759,7 +766,27 @@
    return this.chart;
    }

    +
    + /**
    + * Returns if ZoomAllDirection is set.
    + *
    + * @return Boolean
    + */
    + public boolean isZoomAllDirections() {
    + return zoomAllDirections;
    + }
    +
    /**
    + * Enable / Disable ZoomAllDirection.
    + *
    + * @param Enable / Disable Zooming All Direction
    + */
    + public void setZoomAllDirections(boolean zoomAllDirections) {
    + this.zoomAllDirections = zoomAllDirections;
    + }
    +
    +
    + /**
    * Sets the chart that is displayed in the panel.
    *
    * @param chart the chart (<code>null</code> permitted).
    @@ -2006,6 +2033,10 @@
    scaledDataArea.getWidth(), ymax - this.zoomPoint.getY());
    }

    + if (zoomAllDirections) {
    + correctZoomRectangle();
    + }
    +
    // Draw the new zoom rectangle...
    if (this.useBuffer) {
    repaint();
    @@ -2018,6 +2049,28 @@
    g2.dispose();

    }
    +
    +
    + /**
    + * Can be called to correct the coordinates, width and height of the zoomRectangle
    + * (i.e. when dragging the mouse from bottom right to top left)
    + */
    + private void correctZoomRectangle() {
    +
    + double x = zoomRectangle.getX();
    + double y = zoomRectangle.getY();
    + double w = zoomRectangle.getWidth();
    + double h = zoomRectangle.getHeight();
    +
    + if (w < 0 && h < 0) {
    + zoomRectangle.setRect(x + w, y + h, -w, -h);
    + } else if (w < 0) {
    + zoomRectangle.setRect(x + w, y, -w, h);
    + } else if (h < 0){
    + zoomRectangle.setRect(x, y + h, w, -h);
    + }
    + }
    +

    /**
    * Handles a 'mouse released' event. On Windows, we need to check if this
    @@ -2052,9 +2105,9 @@
    boolean zoomTrigger2 = vZoom && Math.abs(e.getY()
    - this.zoomPoint.getY()) >= this.zoomTriggerDistance;
    if (zoomTrigger1 || zoomTrigger2) {
    - if ((hZoom && (e.getX() < this.zoomPoint.getX()))
    - || (vZoom && (e.getY() < this.zoomPoint.getY()))) {
    - restoreAutoBounds();
    + if (!zoomAllDirections && ((hZoom && (e.getX() < this.zoomPoint.getX()))
    + || (vZoom && (e.getY() < this.zoomPoint.getY())))) {
    + restoreAutoBounds();
    }
    else {
    double x, y, w, h;
    @@ -2067,27 +2120,28 @@
    // will be true, so we can just test for either being false;
    // otherwise both are true
    if (!vZoom) {
    - x = this.zoomPoint.getX();
    + x = this.zoomRectangle.getX();
    y = screenDataArea.getMinY();
    w = Math.min(this.zoomRectangle.getWidth(),
    - maxX - this.zoomPoint.getX());
    + maxX - this.zoomRectangle.getX());
    h = screenDataArea.getHeight();
    }
    else if (!hZoom) {
    x = screenDataArea.getMinX();
    - y = this.zoomPoint.getY();
    + y = this.zoomRectangle.getY();
    w = screenDataArea.getWidth();
    h = Math.min(this.zoomRectangle.getHeight(),
    - maxY - this.zoomPoint.getY());
    + maxY - this.zoomRectangle.getY());
    }
    else {
    - x = this.zoomPoint.getX();
    - y = this.zoomPoint.getY();
    + x = this.zoomRectangle.getX();
    + y = this.zoomRectangle.getY();
    w = Math.min(this.zoomRectangle.getWidth(),
    - maxX - this.zoomPoint.getX());
    + maxX - this.zoomRectangle.getX());
    h = Math.min(this.zoomRectangle.getHeight(),
    - maxY - this.zoomPoint.getY());
    + maxY - this.zoomRectangle.getY());
    }
    +
    Rectangle2D zoomArea = new Rectangle2D.Double(x, y, w, h);
    zoom(zoomArea);
    }
    @@ -2095,29 +2149,32 @@
    this.zoomRectangle = null;
    }
    else {
    - // erase the zoom rectangle
    +
    + if (zoomAllDirections) {
    + correctZoomRectangle();
    + }
    +
    + // erase the zoom rectangle
    Graphics2D g2 = (Graphics2D) getGraphics();
    if (this.useBuffer) {
    - repaint();
    + repaint();
    }
    else {
    - drawZoomRectangle(g2, true);
    + drawZoomRectangle(g2, true);
    }
    g2.dispose();
    this.zoomPoint = null;
    this.zoomRectangle = null;
    - }
    -
    + }
    }

    else if (e.isPopupTrigger()) {
    - if (this.popup != null) {
    - displayPopupMenu(e.getX(), e.getY());
    - }
    + if (this.popup != null) {
    + displayPopupMenu(e.getX(), e.getY());
    + }
    }
    + }

    - }
    -
    /**
    * Receives notification of mouse clicks on the panel. These are
    * translated and passed on to any registered {@link ChartMouseListener}s.

     
  • David Gilbert
    David Gilbert
    2012-09-18

    That's by design...zooming dragging up and left resets the zoom. I agree with you that it is a bit hard to zoom on the top left edge though, and the proposed path looks like a reasonable solution. Moving to the patch tracker.

     
  • David Gilbert
    David Gilbert
    2012-09-18

    • assigned_to: nobody --> mungady
    • milestone: 547194 -->